3.0 Reading the data
The R library foreign allows R to read in STATA files, among others. We can then get the variable we want as a single columns vector.
library(foreign) # Used to read STATA (*.DTA) files
gss2016 <- read.dta("GSS2016.DTA") # read the file
gss2016_gun_fear <- gss2016[c("owngun", "fear")] # only need two fields
summary(gss2016_gun_fear)
owngun fear
yes : 593 yes : 604
no :1246 no :1271
refused: 50 NA : 0
NA : 0 DK : 0
DK : 0 IAP : 0
IAP : 0 NA's: 992
NA's : 978
The NA’s consiste of people to whom the questions were not posed. We can remove them from both columns.
gss2016_gun_fear <- gss2016_gun_fear[!is.na(gss2016_gun_fear$owngun) & !is.na(gss2016_gun_fear$fear),]
summary(gss2016_gun_fear)
owngun fear
yes : 590 yes: 603
no :1236 no :1271
refused: 48 NA : 0
NA : 0 DK : 0
DK : 0 IAP: 0
IAP : 0
Now compute the proportion of gun ownership among the two populations
# Number who don't live near an area they fear but own gun
n_nofear_owngun <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "no" & gss2016_gun_fear$owngun == "yes",])
# Total who don't live near an area they fear
n_1 <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "no",])
# Point estimate of proportion who don't live in area they fear but own gun
p_hat1 <- n_nofear_owngun / n_1
# Number who do live near an area they fear and own gun
n_fear_owngun <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "yes" & gss2016_gun_fear$owngun == "yes",])
# Total who do live near an area they fear
n_2 <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "yes",])
# Proportion who do live in area they fear and own gun
p_hat2 <- n_fear_owngun / n_2
p_diff_hat <- p_hat1 - p_hat2
cat("Proportion of people who own guns who don't live in an area they fear:", p_hat1, "\nProportion of people who own guns who live near an area they fear:", p_hat2, "\nDifference between the 2 proportions:", p_diff_hat)
Proportion of people who own guns who don't live in an area they fear: 0.3438238
Proportion of people who own guns who live near an area they fear: 0.2537313
Difference between the 2 proportions: 0.09009242
So the point estimate of the proportion of gun ownership is higher among those who don’t live near an area they fear. I would have guessed the opposite.
3.1 Summarizing the data
We can tabulate the data from the two populations so that subsequent computations are easier to follow.
# Number who don't live near an area they fear and don't own gun
n_nofear_nogun <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "no" & gss2016_gun_fear$owngun == "no",])
# Number who don't live near an area they fear and refused to answer
n_nofear_refused <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "no" & gss2016_gun_fear$owngun == "refused",])
# Number who do live near an area they fear but don't own gun
n_fear_nogun <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "yes" & gss2016_gun_fear$owngun == "no",])
# Number who do live near an area they fear and refused to answer
n_fear_refused <- nrow(gss2016_gun_fear[gss2016_gun_fear$fear == "yes" & gss2016_gun_fear$owngun == "refused",])
# Creating one column for each population
n_nofear <- c(n_nofear_owngun, n_nofear_nogun, n_nofear_refused, n_1, p_hat1)
n_fear <- c(n_fear_owngun, n_fear_nogun, n_fear_refused, n_2, p_hat2)
summary_df <- data.frame(n_nofear, n_fear) # creating df
rownames(summary_df) <- c("Own gun", "Don't own gun", "Refused to answer", "Total", "Estimate of proportion of gun ownership")
colnames(summary_df) <- c("No Fear", "Fear")
summary_df
The “No Fear” population is comprised of respondents who don’t live near an area they fear; the “Fear” population is comprised of those that do.
4.0 \(95\%\) confidence interval of the difference in population proportions of gun ownership
We can compute a \(95\%\) condifence interval for the true difference in proportion of gun ownership, \(p_{diff}\), between Americans who don’t live near an area they fear, and those that do, by using the Central Limit Theorem (CLT). The CLT says that the sampling distribution of a statistic, in this case a difference between two population proportions, is approximately normal, with the true difference, \(p_{diff}\), as its mean, and the standard error of the sample, \(SE=\sqrt{\frac{p_1\cdot (1-p_1)}{n_1} + \frac{p_2\cdot (1-p_2)}{n_2}}\), as its standard deviation, where \(n_1\) and \(n_2\) are the sizes of each set of samples.
\[
\hat{p}_{diff}\sim\ N(mean = p_{diff}, sd=\sqrt{\frac{p_1\cdot (1-p_1)}{n_1} + \frac{p_2\cdot (1-p_2)}{n_2}})
\]
If we were able to draw many samples from both populations (Americans who don’t live nearby an area they fear, and those that do), and computed the difference in proportions between each two-sample set, \(\hat{p}_{diff}=\hat{p_1}-\hat{p_2}\), the CLT says the distribution of that proportion difference is nearly normal. Since we typically don’t know either \(p_1\) or \(p_2\), the true population proportions of gun ownership, we will use their point estimates \(\hat{p}_1\) and \(\hat{p}_2\) as proxies for the purposes of computing the standard error \(SE_{(\hat{p}_1 - \hat{p}_2)}\) of the \(95\%\) confidence interval.
In reality, we can only draw one sample from the population. We typically don’t know the true proportions of gun ownership of the two populations, \(p_1\) and \(p_2\). We also don’t know where the difference in sample proportions we have drawn, \(\hat{p}_{diff}=\hat{p_1}-\hat{p_2}\), falls in the sampling distribution, but from the CLT, we do know that the proportions of \(95\%\) of the samples drawn will fall within \(1.96\cdot \sqrt{\frac{p_1\cdot (1-p_1)}{n_1} + \frac{p_2\cdot (1-p_2)}{n_2}}=1.96\cdot SE\) of \(p_{diff}\). For \(95\%\) of the samples we draw, an interval within \(1.96\cdot \sqrt{\frac{\hat{p}_1\cdot (1-\hat{p}_1)}{n_1} + \frac{\hat{p}_2\cdot (1-\hat{p}_2)}{n_2}}=1.96\cdot SE_{(\hat{p}_1 - \hat{p}_2)}\) of \(\hat{p}_{diff}\) will include the true difference in proportion between the two populations. For any two-sample set whose difference in proportions estimate \(\hat{p}_{diff}\) falls within \(1.96\cdot SE\) of \(p_{diff}\), which will happen \(95\%\) of the time, we are \(95\%\) confident that an interval centered around \(\hat{p}_{diff}\) and within \(1.96\cdot SE_{(\hat{p}_1 - \hat{p}_2)}\) of \(\hat{p}_{diff}\) will contain the true difference in proportions of the two populations.
\(95\%\) confidence interval of the difference in population proportions of gun ownership:
\[
\hat{p}_{diff} \pm 1.96\cdot SE_{(\hat{p}_1 - \hat{p}_2)} = \hat{p}_{diff} \pm 1.96\cdot \sqrt{\frac{\hat{p}_1\cdot (1-\hat{p}_1)}{n_1} + \frac{\hat{p}_2\cdot (1-\hat{p}_2)}{n_2}}
\]
4.1 An example
It is much easier to understand with an actual example and a plot. Suppose we have two populations with true proportions \(p_1=0.6\) and \(p_2=0.5\), and so a true difference in proportions of \(p_{diff}=p_1-p_2=0.1\) between them, and we draw a sample of size \(n_1=n_2=500\) from each population. Per the CLT, the distribution of the difference in sample proportions taken from those two populations is approximately normal: \(\hat{p}_{diff}\sim\ N(mean = 0.1, sd=\sqrt{\frac{0.6\cdot (1-0.6)}{500} + \frac{0.5\cdot (1-0.5)}{500}}=0.0313)\). Any two-sample set drawn from the two populations whose difference in proportions estimate \(\hat{p}_{diff}\) falls within \((0.1-1.96\cdot0.0313,\ 0.1+1.96\cdot0.0313)=(0.0387,\ 0.1613)\) will have a \(95\%\) confidence interval that contains the true difference in population proportions, \(p=0.1\). If we draw a sample from each population, and the samples’ proportions are \(\hat{p}_1=0.5833\) and \(\hat{p}_2=0.4375\), and so their difference is \(\hat{p}_{diff}=0.1458\), the \(95\%\) confidence interval centered around \(\hat{p}_{diff}=0.1458\) will contain the true difference in proportions \(p_{diff}=0.1\). Since the person taking the samples typically doesn’t know either \(p_1\) or \(p_2\), she will use her samples’ \(\hat{p}_1=0.5833\) and \(\hat{p}_2=0.4375\) to compute \(SE_{(\hat{p}_1 - \hat{p}_2)}\), for the purposes of computing the \(95\%\) confidence interval. \(SE_{(\hat{p}_1 - \hat{p}_2)}\) will be: \(SE_{(\hat{p}_1 - \hat{p}_2)}=\sqrt{\frac{0.5833\cdot (1-0.5833)}{500} + \frac{0.4375\cdot (1-0.4375)}{500}}=\sqrt{4.861e-4+4.9219e-4}=0.0313\), and the \(95\%\) confidence interval will be: \((0.1458-1.96\cdot0.0313,\ 0.1458+1.96\cdot0.0313)=(0.0845,\ 0.2071)\), which contains the true proportion difference \(p_{diff}=0.1\).

If we are unlucky and draw samples whose difference in proportions \(\hat{p}_{diff}\) falls in the shaded area, which should only happen \(5\%\) of the time, its \(95\%\) confidence interval will not include the true difference in proportions \(p_{diff}=0.1\).

4.2 Conditions for the confidence interval
The conditions for the validity of the confidence interval are:
Sampled observations must be independent, both within groups and between groups.
Each sample should have at least 10 successses and 10 failures:
\[
n_1\cdot\hat{p}_1\geq10\ and\ n_2\cdot(1 - \hat{p}_2)\geq10
\]
\[
n_2\cdot\hat{p}_2\geq10\ and\ n_2\cdot(1 - \hat{p}_2)\geq10
\]
To verify the first part of the first assumption, that sampled observations must be independent within groups, we check that the sampled respondents within each group (those who don’t live within 1 mile of an area they fear, and those that do) are randomly sampled, and each of the two samples was done without replacement, and each sample represents less than \(10\%\) of their respective populations. E.g., for the group from the population who don’t live near an area they fear, the number of observations, about \(1300\), is certainly much less than \(10\%\) of the entire U.S. population who don’t live near an area they fear.
To verify the second part of the first assumption, we note that any respondent from the no-fear sample is independent from any respondent from the fear sample.
Now we check the validity of the second assumption by verifying the success-failure conditions for both samples:
sample_1_successes <- n_1 * p_hat1
sample_1_failures <- n_1 * (1 - p_hat1)
sample_2_successes <- n_2 * p_hat2
sample_2_failures <- n_2 * (1 - p_hat2)
cat("Number of successes in the first sample:", floor(sample_1_successes), "\nNumber of failures in the first sample:", floor(sample_1_failures), "\nNumber of successes in the second sample:", floor(sample_2_successes), "\nNumber of failures in the second sample:", floor(sample_2_failures))
Number of successes in the first sample: 437
Number of failures in the first sample: 834
Number of successes in the second sample: 153
Number of failures in the second sample: 449
4.3 Critical value \(z^*\)
The \(z^*\) corresponding to a \(95\%\) confidence interval in the standard normal distribution is approximately 1.96. We can compute it more exactly using R:
z_star <- qnorm(p = 0.025, mean = 0, sd = 1, lower.tail = FALSE)
z_star
[1] 1.959964
4.4 Standard error
Computing the standard error of the sample
se <- sqrt(p_hat1 * (1 - p_hat1) / n_1 + p_hat2 * (1 - p_hat2) / n_2)
cat("Standard error of the sample:", se)
Standard error of the sample: 0.02217028
4.5 Confidence interval
Computing the confidence interval bounds
conf_int_lb <- p_diff_hat - z_star * se
conf_int_ub <- p_diff_hat + z_star * se
cat("Confidence interval lower bound", conf_int_lb, "\nConfidence interval upper bound", conf_int_ub)
Confidence interval lower bound 0.04663947
Confidence interval upper bound 0.1335454
Hence, our confidence interval is \[
0.0901\pm 1.96\cdot 0.0222=(0.0466, 0.1334)
\]
We are \(95\%\) confident that the true difference between the two population proportions is between \(0.0466\) and \(0.1334\).
5.0 Hypothesis testing
We can use the CLT and the data collected to construct a hypothesis testing framework. The hypothesis test considers two possible interpretations of our data, a null hypothesis \(H_0\), and an alternative hypothesis \(H_a\). \(H_0\) basically says that the sampled data could have been drawn simply by chance, and so, it is misleading. There is “nothing going on”. \(H_a\) takes the view that the data collected reveals that “something is going on”. We will either reject the null hypothesis in favor of this alternative, or we will fail to reject it and conclude the sampled data could have been drawn simply by chance. Note that even if we fail to reject \(H_0\), that does not mean we accept it as the ground truth, it’s just that the data we have collected does not allows us to discard \(H_0\).
Suppose we want to find out if the \(0.0901\) difference in population proportions is statistically significant. Our null hypothesis \(H_0\) is:
\[
H_0: The\ true\ difference\ in\ the\ two\ population\ proportions\ p_1-p_2= p_{diff}=0
\\
H_a: p_{diff}\neq 0
\]
To perform the test, we assume that \(H_0\) is true and ask, given that \(H_0\) is true, how probable it is to observe data as extreme or more as the one we have.
5.1 The null hypothesis proportion \(p_{pool}\)
Under the null hypothesis \(H_0\), we assume the true population proportions \(p_1\) and \(p_2\) are the same, but what are they equal to? In other words, \(p_1=p_2=?\) The standard error formula under \(H_0\) should use a common value rather for \(p\) rather than the \(2\) estimates \(\hat p_1\) and \(\hat p_2\), given that we are arguing that \(p_1=p_2\). A good point estimate for this common value can be obtained by pooling the “successes” from both samples. In this case, the successes are the respondents from both groups that live in a place where guns are kept.
\[
\hat{p}_{pool}=\frac{total\ number\ of\ respondents\ who\ own\ guns}{n_1 + n_2}
\]
Computing \(\hat{p}_{pool}\)
p_pooled <- (n_nofear_owngun + n_fear_owngun) / (n_1 + n_2)
cat("Estimate of pooled proportion:", p_pooled)
Estimate of pooled proportion: 0.3148346
The standard error can then be computed similarly as before:
\[
SE_{pooled}=\sqrt{\frac{\hat{p}_{pooled}\cdot (1-\hat{p}_{pooled})}{n_1} + \frac{\hat{p}_{pooled}\cdot (1-\hat{p}_{pooled})}{n_2}}
\]
Computing \(SE_{pooled}\):
se_pooled <- sqrt(p_pooled * (1 - p_pooled) / n_1 + p_pooled * (1 - p_pooled) / n_2)
cat("Standard error under null hypothesis using pooled proportion estimate:", se_pooled)
Standard error under null hypothesis using pooled proportion estimate: 0.02296637
5.2 Conditions for hypothesis testing
The conditions to perform the hypothesis test are similar to the ones we checked to compute the confidence interval.
Sampled observations must be independent, both within groups and between groups.
Each sample should have at least 10 successses and 10 failures. We use the pooled proportion \(\hat{p}_{pool}\) to compute the numbers of successes and failures:
\[
n_1\cdot\hat{p}_{pool}\geq10\ and\ n_1\cdot(1 - \hat{p}_{pool})\geq10
\]
\[
n_2\cdot\hat{p}_{pool}\geq10\ and\ n_2\cdot(1 - \hat{p}_{pool})\geq10
\]
Verifying the success-failure conditions for hypothesis testing:
sample_1_successes <- n_1 * p_pooled
sample_1_failures <- n_1 * (1 - p_pooled)
sample_2_successes <- n_2 * p_pooled
sample_2_failures <- n_2 * (1 - p_pooled)
cat("Success-failure conditions for hypothesis testing, using p_pooled:", "\nNumber of successes in the first sample:", floor(sample_1_successes), "\nNumber of failures in the first sample:", floor(sample_1_failures), "\nNumber of successes in the second sample:", floor(sample_2_successes), "\nNumber of failures in the second sample:", floor(sample_2_failures))
Success-failure conditions for hypothesis testing, using p_pooled:
Number of successes in the first sample: 400
Number of failures in the first sample: 870
Number of successes in the second sample: 189
Number of failures in the second sample: 413
5.3 The p-value
We have to ask ourselves, given that the null hypothesis \(H_0\) is true, what is the probability of observing data as extreme or more as the one we have?
\[
P(observing\ data\ as\ extreme\ or\ more\ |\ H_{0}\ is\ true)
\]
That probability is the p-value.
Our hypothesis test is two-sided. The null hypothesis is that \(p_{diff}=0\), so by asking what is the probability of \(observing\ data\ as\ extreme\ or\ more\) in a world in which the null hypothesis is true, we are wondering how probable it is to draw a sample with a difference in proportions of \(0.0901\) or higher like the one we have drawn, or one with a difference in proportions of \(-0.0901\) or lower. Let’s see it graphically.
#http://www.statmethods.net/advgraphs/probability.html
p_diff <- 0.00
# x = p_diff +/- 5 std_dev's
x <- seq(-5,5,length=1000)*se_pooled + p_diff
hx <- dnorm(x, p_diff, se_pooled)
# Values used to shade area under curve
lb <- p_diff_hat; ub <- max(x)
plot(x, hx, type="n", xlab="Difference in proportion of gun ownership between\n those who don't live near an area they fear, and those that do", ylab="", main="Sampling distribution under null hypothesis", axes=FALSE)
lines(x, hx) # plots normal distribution
i <- x >= lb & x <= ub # indexes of x where x >= than lb
polygon(c(lb,x[i],ub), c(0,hx[i],0), col="red") # shades area where x >= p_diff_hat in red
lines(x[i], hx[i], lwd = 4, col = "red") # "shades area" where x >= p_diff_hat in red
# in reality it's just drawing a thicker red line on top of the original
# since shading using the polygon() function will show nothing b/c the area is so small
j <- x >= min(x) & x <= -lb # indexes of x where x <= -pdiff_hat
lines(x[j], hx[j], lwd = 4, col = "red") # "shades area" where x <= -p_diff_hat in red
# in reality it's just drawing a thicker red line on top of the original
# since shading using the polygon() function will show nothing b/c the area is so small
axis(1, at=seq(-0.12, 0.12, 0.01), pos=0) # draws axis
abline(v=p_diff)
grid()

We are asking how probable it is to draw a sample with a difference in proportions that is \(0.0901\) or more away from the assumed difference in proportions (under the null hypothesis) of \(0\), in either direction. That is, \(\frac{0.0901}{0.0230} = 3.92\) standard deviations away from \(0\). The probability of that occurring is very small indeed; it is represented by the shaded area in the plot. In reality, I just thickened the line and colored it red since the area is too small to show.
Under the null hypothesis, we live in a world in which the sampling distribution of the difference in proportion of gun ownership between two groups is centered at \(p_{diff} = 0\) and has a standard deviation of \(0.0230\). In such a world, we have drawn a sample where the difference in proportions is \(\hat{p}_{diff}=0.0901\). What is the probability of drawing a sample with a difference in proportion \(\hat{p}_{diff}\) as high or higher, in either direction, in a world in which the null hypothesis is true?
\[
P(drawing\ a\ sample\ where\ the\ difference\ in\ population\ proportions\\ is\ as\ large\ or\ larger\ than\ 0.0901 |\ H_{0}\ is\ true)
\\
P(\hat{p}_{diff}\ \geq\ 0.0901\ or\ \hat{p}_{diff}\ \leq\ -0.0901 |\ p_{diff} = 0)
\]
That probability is the area under the sampling distribution shaded in red in the plot (although it is invisible because it is so small). It can be computed using pnorm()
.
area <- 2 * pnorm(q = p_diff_hat, mean = p_diff, sd = se_pooled, lower.tail = FALSE)
# Multiplied by 2 because the hypothesis test is two-sided.
cat("Our p-value:", area)
Our p-value: 8.752652e-05
So our p-value, the probability of drawing a sample with \(\hat{p}_{diff}=0.0901\) or higher, or one \(\hat{p}_{diff}=-0.0901\) or lower, under the null hypothesis, is about \(8.753e-5\). At the \(5\%\) significance level, we can reject the null hypothesis because the sample data provides convincing evidence to do so.
LS0tDQp0aXRsZTogIkNvbXBhcmluZyB0d28gcG9wdWxhdGlvbiBwcm9wb3J0aW9ucyINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KYm9keSwgdGQgew0KICAgZm9udC1zaXplOiAxOHB4Ow0KfQ0KaDEgew0KICBmb250LXNpemU6IDMycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDIgew0KICBmb250LXNpemU6IDI4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDMgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDQgew0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KY29kZS5yew0KICBmb250LXNpemU6IDE2cHg7DQp9DQpwcmUgew0KICBmb250LXNpemU6IDE2cHgNCn0NCjwvc3R5bGU+DQoNCiMjIDEuMCBJbnRyb2R1Y3Rpb24NCg0KVGhlIFtHZW5lcmFsIFNvY2lhbCBTdXJ2ZXkgKEdTUyldKGh0dHA6Ly9nc3Mubm9yYy5vcmcvKSBpcyBhIHNvY2lvbG9naWNhbCBzdXJ2ZXkgdXNlZCB0byBjb2xsZWN0IGRhdGEgb24gYSB3aWRlIHZhcmlldHkgb2YgZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGFuZCBhdHRpdHVkZXMgb2YgcmVzaWRlbnRzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBUaGUgZGF0YSBoYXMgYmVlbiBjb2xsZWN0ZWQgc2luY2UgMTk3MiwgYXBwcm94aW1hdGVseSBldmVyeSAyIHllYXJzLCBieSB0aGUgW05hdGlvbmFsIE9waW5pb24gUmVzZWFyY2ggQ2VudGVyIChOT1JDKV0oaHR0cDovL3d3dy5ub3JjLm9yZy9QYWdlcy9kZWZhdWx0LmFzcHgpIGF0IHRoZSBVbml2ZXJzaXR5IG9mIENoaWNhZ28uIFRoZSBsYXRlc3QgZGF0YSBpcyBmcm9tIHRoZSBzcHJpbmcgb2YgMjAxNi4gVGhlIGRhdGEgZm9yIHRoZSBlYWNoIHllYXIgdGhlIHN1cnZleSB3YXMgY2FycmllZCBvdXQgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwOi8vZ3NzLm5vcmMub3JnL2dldC10aGUtZGF0YS9zdGF0YSkgaW4gU1RBVEEgZm9ybWF0LCBhbmQgW2hlcmVdKGh0dHA6Ly9nc3Mubm9yYy5vcmcvZ2V0LXRoZS1kYXRhL3Nwc3MpIGluIFNQU1MgZm9ybWF0LiBUaGUgW0dTUyBDb2RlYm9va10oaHR0cDovL2dzcy5ub3JjLm9yZy9HZXQtRG9jdW1lbnRhdGlvbiksIGluIFBERiBmb3JtYXQsIGRvY3VtZW50cyB0aGUgc3VydmV5IGRhdGEgZm9yIGFsbCB5ZWFycy4gVGhlIFIgbm90ZWJvb2sgY2FuIGJlIGZvdW5kIGluIHRoZSBwcm9qZWN0J3MgW0dpdGh1YiBwYWdlXShodHRwczovL2dpdGh1Yi5jb20vY2FybG9zcm9yL3N0YXQtaW5mLWNvbXBhcmluZy10d28tcHJvcG9ydGlvbnMpLg0KDQojIyAyLjAgVmFyaWFibGVzIG9mIGludGVyZXN0DQoNClRoaXMgbm90ZWJvb2sgaXMgYWJvdXQgbWFraW5nIGluZmVyZW5jZXMgYWJvdXQgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9uIG9mIGd1biBvd25lcnNoaXAgYmV0d2VlbiB0d28gcG9wdWxhdGlvbnM6IEFtZXJpY2FucyB3aG8gZG9uJ3QgbGl2ZSB3aXRoaW4gYSAxLW1pbGUgcmFkaXVzIG9mIGFuIGFyZWEgdGhleSBmZWFyLCBhbmQgQW1lcmljYW5zIHdobyBkby4gVGhlIHN1cnZleSdzIGludGVydmlld2VyIGFza2VkIHJlc3BvbmRlbnRzOiAqKiJEbyB5b3UgaGFwcGVuIHRvIGhhdmUgaW4geW91ciBob21lIGFueSBndW5zIG9yIHJldm9sdmVycz8iKiosIGFuZCBjb2RlZCB0aGUgcmVzcG9uc2UgYXMgJE9XTkdVTiQuIFJlc3BvbmRlbnRzIHdlcmUgYWxzbyBhc2tlZDogKioiSXMgdGhlcmUgYW55IGFyZWEgcmlnaHQgYXJvdW5kIGhlcmUtLXRoYXQgaXMsIHdpdGhpbiBhIG1pbGUtLXdoZXJlIHlvdSB3b3VsZCBiZSBhZnJhaWQgdG8gd2FsayBhbG9uZSBhdCBuaWdodD8iKiosIGFuZCB0aGVpciByZXBvbnNlIHdhcyBjb2RlZCBhcyAkRkVBUiQuDQoNCiMjIDMuMCBSZWFkaW5nIHRoZSBkYXRhDQoNClRoZSBSIGxpYnJhcnkgWyoqZm9yZWlnbioqXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZm9yZWlnbi9mb3JlaWduLnBkZikgYWxsb3dzIFIgdG8gcmVhZCBpbiBTVEFUQSBmaWxlcywgYW1vbmcgb3RoZXJzLiBXZSBjYW4gdGhlbiBnZXQgdGhlIHZhcmlhYmxlIHdlIHdhbnQgYXMgYSBzaW5nbGUgY29sdW1ucyB2ZWN0b3IuDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShmb3JlaWduKSAjIFVzZWQgdG8gcmVhZCBTVEFUQSAoKi5EVEEpIGZpbGVzDQpnc3MyMDE2IDwtIHJlYWQuZHRhKCJHU1MyMDE2LkRUQSIpICMgcmVhZCB0aGUgZmlsZQ0KZ3NzMjAxNl9ndW5fZmVhciA8LSBnc3MyMDE2W2MoIm93bmd1biIsICJmZWFyIildICMgb25seSBuZWVkIHR3byBmaWVsZHMNCg0Kc3VtbWFyeShnc3MyMDE2X2d1bl9mZWFyKQ0KYGBgDQoNClRoZSBOQSdzIGNvbnNpc3RlIG9mIHBlb3BsZSB0byB3aG9tIHRoZSBxdWVzdGlvbnMgd2VyZSBub3QgcG9zZWQuIFdlIGNhbiByZW1vdmUgdGhlbSBmcm9tIGJvdGggY29sdW1ucy4NCg0KYGBge3J9DQpnc3MyMDE2X2d1bl9mZWFyIDwtIGdzczIwMTZfZ3VuX2ZlYXJbIWlzLm5hKGdzczIwMTZfZ3VuX2ZlYXIkb3duZ3VuKSAmICFpcy5uYShnc3MyMDE2X2d1bl9mZWFyJGZlYXIpLF0NCg0Kc3VtbWFyeShnc3MyMDE2X2d1bl9mZWFyKQ0KYGBgDQoNCk5vdyBjb21wdXRlIHRoZSBwcm9wb3J0aW9uIG9mIGd1biBvd25lcnNoaXAgYW1vbmcgdGhlIHR3byBwb3B1bGF0aW9ucw0KYGBge3J9DQojIE51bWJlciB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyIGJ1dCBvd24gZ3VuDQpuX25vZmVhcl9vd25ndW4gPC0gbnJvdyhnc3MyMDE2X2d1bl9mZWFyW2dzczIwMTZfZ3VuX2ZlYXIkZmVhciA9PSAibm8iICYgZ3NzMjAxNl9ndW5fZmVhciRvd25ndW4gPT0gInllcyIsXSkNCg0KIyBUb3RhbCB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyDQpuXzEgPC0gbnJvdyhnc3MyMDE2X2d1bl9mZWFyW2dzczIwMTZfZ3VuX2ZlYXIkZmVhciA9PSAibm8iLF0pDQoNCiMgUG9pbnQgZXN0aW1hdGUgb2YgcHJvcG9ydGlvbiB3aG8gZG9uJ3QgbGl2ZSBpbiBhcmVhIHRoZXkgZmVhciBidXQgb3duIGd1bg0KcF9oYXQxIDwtIG5fbm9mZWFyX293bmd1biAvIG5fMQ0KDQojIE51bWJlciB3aG8gZG8gbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyIGFuZCBvd24gZ3VuDQpuX2ZlYXJfb3duZ3VuIDwtIG5yb3coZ3NzMjAxNl9ndW5fZmVhcltnc3MyMDE2X2d1bl9mZWFyJGZlYXIgPT0gInllcyIgJiBnc3MyMDE2X2d1bl9mZWFyJG93bmd1biA9PSAieWVzIixdKQ0KDQojIFRvdGFsIHdobyBkbyBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXINCm5fMiA8LSBucm93KGdzczIwMTZfZ3VuX2ZlYXJbZ3NzMjAxNl9ndW5fZmVhciRmZWFyID09ICJ5ZXMiLF0pDQoNCiMgUHJvcG9ydGlvbiB3aG8gZG8gbGl2ZSBpbiBhcmVhIHRoZXkgZmVhciBhbmQgb3duIGd1bg0KcF9oYXQyIDwtIG5fZmVhcl9vd25ndW4gLyBuXzINCg0KcF9kaWZmX2hhdCA8LSBwX2hhdDEgLSBwX2hhdDINCg0KY2F0KCJQcm9wb3J0aW9uIG9mIHBlb3BsZSB3aG8gb3duIGd1bnMgd2hvIGRvbid0IGxpdmUgaW4gYW4gYXJlYSB0aGV5IGZlYXI6IiwgcF9oYXQxLCAiXG5Qcm9wb3J0aW9uIG9mIHBlb3BsZSB3aG8gb3duIGd1bnMgd2hvIGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhcjoiLCBwX2hhdDIsICJcbkRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgMiBwcm9wb3J0aW9uczoiLCBwX2RpZmZfaGF0KQ0KYGBgDQoNClNvIHRoZSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgcHJvcG9ydGlvbiBvZiBndW4gb3duZXJzaGlwIGlzIGhpZ2hlciBhbW9uZyB0aG9zZSB3aG8gKmRvbid0KiBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXIuIEkgd291bGQgaGF2ZSBndWVzc2VkIHRoZSBvcHBvc2l0ZS4NCg0KIyMjIDMuMSBTdW1tYXJpemluZyB0aGUgZGF0YQ0KDQpXZSBjYW4gdGFidWxhdGUgdGhlIGRhdGEgZnJvbSB0aGUgdHdvIHBvcHVsYXRpb25zIHNvIHRoYXQgc3Vic2VxdWVudCBjb21wdXRhdGlvbnMgYXJlIGVhc2llciB0byBmb2xsb3cuDQoNCmBgYHtyfQ0KIyBOdW1iZXIgd2hvIGRvbid0IGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhciBhbmQgZG9uJ3Qgb3duIGd1bg0Kbl9ub2ZlYXJfbm9ndW4gPC0gbnJvdyhnc3MyMDE2X2d1bl9mZWFyW2dzczIwMTZfZ3VuX2ZlYXIkZmVhciA9PSAibm8iICYgZ3NzMjAxNl9ndW5fZmVhciRvd25ndW4gPT0gIm5vIixdKQ0KDQojIE51bWJlciB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyIGFuZCByZWZ1c2VkIHRvIGFuc3dlcg0Kbl9ub2ZlYXJfcmVmdXNlZCA8LSBucm93KGdzczIwMTZfZ3VuX2ZlYXJbZ3NzMjAxNl9ndW5fZmVhciRmZWFyID09ICJubyIgJiBnc3MyMDE2X2d1bl9mZWFyJG93bmd1biA9PSAicmVmdXNlZCIsXSkNCg0KIyBOdW1iZXIgd2hvIGRvIGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhciBidXQgZG9uJ3Qgb3duIGd1bg0Kbl9mZWFyX25vZ3VuIDwtIG5yb3coZ3NzMjAxNl9ndW5fZmVhcltnc3MyMDE2X2d1bl9mZWFyJGZlYXIgPT0gInllcyIgJiBnc3MyMDE2X2d1bl9mZWFyJG93bmd1biA9PSAibm8iLF0pDQoNCiMgTnVtYmVyIHdobyBkbyBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXIgYW5kIHJlZnVzZWQgdG8gYW5zd2VyDQpuX2ZlYXJfcmVmdXNlZCA8LSBucm93KGdzczIwMTZfZ3VuX2ZlYXJbZ3NzMjAxNl9ndW5fZmVhciRmZWFyID09ICJ5ZXMiICYgZ3NzMjAxNl9ndW5fZmVhciRvd25ndW4gPT0gInJlZnVzZWQiLF0pDQoNCiMgQ3JlYXRpbmcgb25lIGNvbHVtbiBmb3IgZWFjaCBwb3B1bGF0aW9uDQpuX25vZmVhciA8LSBjKG5fbm9mZWFyX293bmd1biwgbl9ub2ZlYXJfbm9ndW4sIG5fbm9mZWFyX3JlZnVzZWQsIG5fMSwgcF9oYXQxKQ0Kbl9mZWFyIDwtIGMobl9mZWFyX293bmd1biwgbl9mZWFyX25vZ3VuLCBuX2ZlYXJfcmVmdXNlZCwgbl8yLCBwX2hhdDIpDQoNCnN1bW1hcnlfZGYgPC0gZGF0YS5mcmFtZShuX25vZmVhciwgbl9mZWFyKSAjIGNyZWF0aW5nIGRmDQpyb3duYW1lcyhzdW1tYXJ5X2RmKSA8LSBjKCJPd24gZ3VuIiwgIkRvbid0IG93biBndW4iLCAiUmVmdXNlZCB0byBhbnN3ZXIiLCAiVG90YWwiLCAiRXN0aW1hdGUgb2YgcHJvcG9ydGlvbiBvZiBndW4gb3duZXJzaGlwIikNCmNvbG5hbWVzKHN1bW1hcnlfZGYpIDwtIGMoIk5vIEZlYXIiLCAiRmVhciIpDQpzdW1tYXJ5X2RmDQpgYGANCg0KVGhlICJObyBGZWFyIiBwb3B1bGF0aW9uIGlzIGNvbXByaXNlZCBvZiByZXNwb25kZW50cyB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyOyB0aGUgIkZlYXIiIHBvcHVsYXRpb24gaXMgY29tcHJpc2VkIG9mIHRob3NlIHRoYXQgZG8uDQoNCiMjIDQuMCAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBvZiB0aGUgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHByb3BvcnRpb25zIG9mIGd1biBvd25lcnNoaXANCg0KV2UgY2FuIGNvbXB1dGUgYSAkOTVcJSQgY29uZGlmZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9uIG9mIGd1biBvd25lcnNoaXAsICRwX3tkaWZmfSQsIGJldHdlZW4gQW1lcmljYW5zIHdobyBkb24ndCBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXIsIGFuZCB0aG9zZSB0aGF0IGRvLCBieSB1c2luZyB0aGUgW0NlbnRyYWwgTGltaXQgVGhlb3JlbSAoQ0xUKV0oaHR0cDovL3d3dy5zdGF0LndtaWNoLmVkdS9zMTYwL2Jvb2svbm9kZTQzLmh0bWwpLiBUaGUgQ0xUIHNheXMgdGhhdCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgc3RhdGlzdGljLCBpbiB0aGlzIGNhc2UgYSBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMsIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLCB3aXRoIHRoZSB0cnVlIGRpZmZlcmVuY2UsICRwX3tkaWZmfSQsIGFzIGl0cyBtZWFuLCBhbmQgdGhlIHN0YW5kYXJkIGVycm9yIG9mIHRoZSBzYW1wbGUsICRTRT1cc3FydHtcZnJhY3twXzFcY2RvdCAoMS1wXzEpfXtuXzF9ICsgXGZyYWN7cF8yXGNkb3QgKDEtcF8yKX17bl8yfX0kLCBhcyBpdHMgc3RhbmRhcmQgZGV2aWF0aW9uLCB3aGVyZSAkbl8xJCBhbmQgJG5fMiQgYXJlIHRoZSBzaXplcyBvZiBlYWNoIHNldCBvZiBzYW1wbGVzLiANCg0KDQokJA0KXGhhdHtwfV97ZGlmZn1cc2ltXCBOKG1lYW4gPSBwX3tkaWZmfSwgc2Q9XHNxcnR7XGZyYWN7cF8xXGNkb3QgKDEtcF8xKX17bl8xfSArIFxmcmFje3BfMlxjZG90ICgxLXBfMil9e25fMn19KQ0KJCQNCg0KSWYgd2Ugd2VyZSBhYmxlIHRvIGRyYXcgbWFueSBzYW1wbGVzIGZyb20gYm90aCBwb3B1bGF0aW9ucyAoQW1lcmljYW5zIHdobyBkb24ndCBsaXZlIG5lYXJieSBhbiBhcmVhIHRoZXkgZmVhciwgYW5kIHRob3NlIHRoYXQgZG8pLCBhbmQgY29tcHV0ZWQgdGhlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgYmV0d2VlbiBlYWNoIHR3by1zYW1wbGUgc2V0LCAkXGhhdHtwfV97ZGlmZn09XGhhdHtwXzF9LVxoYXR7cF8yfSQsIHRoZSBDTFQgc2F5cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoYXQgcHJvcG9ydGlvbiBkaWZmZXJlbmNlIGlzIG5lYXJseSBub3JtYWwuIFNpbmNlIHdlIHR5cGljYWxseSBkb24ndCBrbm93IGVpdGhlciAkcF8xJCBvciAkcF8yJCwgdGhlIHRydWUgcG9wdWxhdGlvbiBwcm9wb3J0aW9ucyBvZiBndW4gb3duZXJzaGlwLCB3ZSB3aWxsIHVzZSB0aGVpciBwb2ludCBlc3RpbWF0ZXMgJFxoYXR7cH1fMSQgYW5kICRcaGF0e3B9XzIkIGFzIHByb3hpZXMgZm9yIHRoZSBwdXJwb3NlcyBvZiBjb21wdXRpbmcgdGhlIHN0YW5kYXJkIGVycm9yICRTRV97KFxoYXR7cH1fMSAtIFxoYXR7cH1fMil9JCBvZiB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCkluIHJlYWxpdHksIHdlIGNhbiBvbmx5IGRyYXcgb25lIHNhbXBsZSBmcm9tIHRoZSBwb3B1bGF0aW9uLiBXZSB0eXBpY2FsbHkgZG9uJ3Qga25vdyB0aGUgdHJ1ZSBwcm9wb3J0aW9ucyBvZiBndW4gb3duZXJzaGlwIG9mIHRoZSB0d28gcG9wdWxhdGlvbnMsICRwXzEkIGFuZCAkcF8yJC4gV2UgYWxzbyBkb24ndCBrbm93IHdoZXJlIHRoZSBkaWZmZXJlbmNlIGluIHNhbXBsZSBwcm9wb3J0aW9ucyB3ZSBoYXZlIGRyYXduLCAkXGhhdHtwfV97ZGlmZn09XGhhdHtwXzF9LVxoYXR7cF8yfSQsIGZhbGxzIGluIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24sIGJ1dCBmcm9tIHRoZSBDTFQsIHdlIGRvIGtub3cgdGhhdCB0aGUgcHJvcG9ydGlvbnMgb2YgJDk1XCUkIG9mIHRoZSBzYW1wbGVzIGRyYXduIHdpbGwgZmFsbCB3aXRoaW4gJDEuOTZcY2RvdCBcc3FydHtcZnJhY3twXzFcY2RvdCAoMS1wXzEpfXtuXzF9ICsgXGZyYWN7cF8yXGNkb3QgKDEtcF8yKX17bl8yfX09MS45NlxjZG90IFNFJCBvZiAkcF97ZGlmZn0kLiBGb3IgJDk1XCUkIG9mIHRoZSBzYW1wbGVzIHdlIGRyYXcsIGFuIGludGVydmFsIHdpdGhpbiAkMS45NlxjZG90IFxzcXJ0e1xmcmFje1xoYXR7cH1fMVxjZG90ICgxLVxoYXR7cH1fMSl9e25fMX0gKyBcZnJhY3tcaGF0e3B9XzJcY2RvdCAoMS1caGF0e3B9XzIpfXtuXzJ9fT0xLjk2XGNkb3QgU0VfeyhcaGF0e3B9XzEgLSBcaGF0e3B9XzIpfSQgb2YgJFxoYXR7cH1fe2RpZmZ9JCB3aWxsIGluY2x1ZGUgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9uIGJldHdlZW4gdGhlIHR3byBwb3B1bGF0aW9ucy4gRm9yIGFueSB0d28tc2FtcGxlIHNldCB3aG9zZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIGVzdGltYXRlICRcaGF0e3B9X3tkaWZmfSQgZmFsbHMgd2l0aGluICQxLjk2XGNkb3QgU0UkIG9mICRwX3tkaWZmfSQsIHdoaWNoIHdpbGwgaGFwcGVuICQ5NVwlJCBvZiB0aGUgdGltZSwgd2UgYXJlICQ5NVwlJCBjb25maWRlbnQgdGhhdCBhbiBpbnRlcnZhbCBjZW50ZXJlZCBhcm91bmQgJFxoYXR7cH1fe2RpZmZ9JCBhbmQgd2l0aGluICQxLjk2XGNkb3QgU0VfeyhcaGF0e3B9XzEgLSBcaGF0e3B9XzIpfSQgb2YgJFxoYXR7cH1fe2RpZmZ9JCB3aWxsIGNvbnRhaW4gdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiB0aGUgdHdvIHBvcHVsYXRpb25zLg0KDQoqKiQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIG9mIHRoZSBkaWZmZXJlbmNlIGluIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMgb2YgZ3VuIG93bmVyc2hpcDoqKg0KDQokJA0KXGhhdHtwfV97ZGlmZn0gXHBtIDEuOTZcY2RvdCBTRV97KFxoYXR7cH1fMSAtIFxoYXR7cH1fMil9ID0gXGhhdHtwfV97ZGlmZn0gXHBtIDEuOTZcY2RvdCBcc3FydHtcZnJhY3tcaGF0e3B9XzFcY2RvdCAoMS1caGF0e3B9XzEpfXtuXzF9ICsgXGZyYWN7XGhhdHtwfV8yXGNkb3QgKDEtXGhhdHtwfV8yKX17bl8yfX0NCiQkDQoNCiMjIyA0LjEgQW4gZXhhbXBsZQ0KDQpJdCBpcyBtdWNoIGVhc2llciB0byB1bmRlcnN0YW5kIHdpdGggYW4gYWN0dWFsIGV4YW1wbGUgYW5kIGEgcGxvdC4gU3VwcG9zZSB3ZSBoYXZlIHR3byBwb3B1bGF0aW9ucyB3aXRoIHRydWUgcHJvcG9ydGlvbnMgJHBfMT0wLjYkIGFuZCAkcF8yPTAuNSQsIGFuZCBzbyBhIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiAkcF97ZGlmZn09cF8xLXBfMj0wLjEkIGJldHdlZW4gdGhlbSwgYW5kIHdlIGRyYXcgYSBzYW1wbGUgb2Ygc2l6ZSAkbl8xPW5fMj01MDAkIGZyb20gZWFjaCBwb3B1bGF0aW9uLiBQZXIgdGhlIENMVCwgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGlmZmVyZW5jZSBpbiBzYW1wbGUgcHJvcG9ydGlvbnMgdGFrZW4gZnJvbSB0aG9zZSB0d28gcG9wdWxhdGlvbnMgaXMgYXBwcm94aW1hdGVseSBub3JtYWw6ICRcaGF0e3B9X3tkaWZmfVxzaW1cIE4obWVhbiA9IDAuMSwgc2Q9XHNxcnR7XGZyYWN7MC42XGNkb3QgKDEtMC42KX17NTAwfSArIFxmcmFjezAuNVxjZG90ICgxLTAuNSl9ezUwMH19PTAuMDMxMykkLiBBbnkgdHdvLXNhbXBsZSBzZXQgZHJhd24gZnJvbSB0aGUgdHdvIHBvcHVsYXRpb25zIHdob3NlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgZXN0aW1hdGUgJFxoYXR7cH1fe2RpZmZ9JCBmYWxscyB3aXRoaW4gJCgwLjEtMS45NlxjZG90MC4wMzEzLFwgMC4xKzEuOTZcY2RvdDAuMDMxMyk9KDAuMDM4NyxcIDAuMTYxMykkIHdpbGwgaGF2ZSBhICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIHRoYXQgY29udGFpbnMgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHByb3BvcnRpb25zLCAkcD0wLjEkLiBJZiB3ZSBkcmF3IGEgc2FtcGxlIGZyb20gZWFjaCBwb3B1bGF0aW9uLCBhbmQgdGhlIHNhbXBsZXMnIHByb3BvcnRpb25zIGFyZSAkXGhhdHtwfV8xPTAuNTgzMyQgYW5kICRcaGF0e3B9XzI9MC40Mzc1JCwgYW5kIHNvIHRoZWlyIGRpZmZlcmVuY2UgaXMgJFxoYXR7cH1fe2RpZmZ9PTAuMTQ1OCQsIHRoZSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBjZW50ZXJlZCBhcm91bmQgJFxoYXR7cH1fe2RpZmZ9PTAuMTQ1OCQgd2lsbCBjb250YWluIHRoZSB0cnVlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgJHBfe2RpZmZ9PTAuMSQuIFNpbmNlIHRoZSBwZXJzb24gdGFraW5nIHRoZSBzYW1wbGVzIHR5cGljYWxseSBkb2Vzbid0IGtub3cgZWl0aGVyICRwXzEkIG9yICRwXzIkLCBzaGUgd2lsbCB1c2UgaGVyIHNhbXBsZXMnICRcaGF0e3B9XzE9MC41ODMzJCBhbmQgJFxoYXR7cH1fMj0wLjQzNzUkIHRvIGNvbXB1dGUgJFNFX3soXGhhdHtwfV8xIC0gXGhhdHtwfV8yKX0kLCBmb3IgdGhlIHB1cnBvc2VzIG9mIGNvbXB1dGluZyB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwuICRTRV97KFxoYXR7cH1fMSAtIFxoYXR7cH1fMil9JCB3aWxsIGJlOiAkU0VfeyhcaGF0e3B9XzEgLSBcaGF0e3B9XzIpfT1cc3FydHtcZnJhY3swLjU4MzNcY2RvdCAoMS0wLjU4MzMpfXs1MDB9ICsgXGZyYWN7MC40Mzc1XGNkb3QgKDEtMC40Mzc1KX17NTAwfX09XHNxcnR7NC44NjFlLTQrNC45MjE5ZS00fT0wLjAzMTMkLCBhbmQgdGhlICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIHdpbGwgYmU6ICQoMC4xNDU4LTEuOTZcY2RvdDAuMDMxMyxcIDAuMTQ1OCsxLjk2XGNkb3QwLjAzMTMpPSgwLjA4NDUsXCAwLjIwNzEpJCwgd2hpY2ggY29udGFpbnMgdGhlIHRydWUgcHJvcG9ydGlvbiBkaWZmZXJlbmNlICRwX3tkaWZmfT0wLjEkLg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiNodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbA0KDQpuXzFfZXhhbXBsZSA8LSA1MDA7IG5fMl9leGFtcGxlIDwtIDUwMA0KcF8xIDwtIDAuNjA7IHBfMiA8LSAwLjUwOyBwX2RpZmYgPC0gcF8xIC0gcF8yDQpzZSA8LSBzcXJ0KHBfMSAqICgxIC0gcF8xKSAvIG5fMV9leGFtcGxlICsgcF8yICogKDEgLSBwXzIpIC8gbl8yX2V4YW1wbGUpDQoNCiMgeCA9IHBfZGlmZiArLy0gNCBzdGRfZGV2J3MNCnggPC0gc2VxKC00LDQsbGVuZ3RoPTEwMDApKnNlICsgcF9kaWZmDQpoeCA8LSBkbm9ybSh4LCBwX2RpZmYgLHNlKQ0KDQojIFZhbHVlcyB1c2VkIHRvIHNoYWRlIGFyZWFzIHVuZGVyIHRoZSBjdXJ2ZQ0KdXBwZXJfYm91bmQgPC0gcF9kaWZmICsgMS45NiAqIHNlIA0KbG93ZXJfYm91bmQgPC0gcF9kaWZmIC0gMS45NiAqIHNlIA0KDQpwbG90KHgsIGh4LCB0eXBlPSJuIiwgeGxhYiA9ICIiLCB5bGFiPSIiLCBtYWluPSJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIiwgYXhlcz1GQUxTRSkNCg0KaSA8LSB4ID49IHVwcGVyX2JvdW5kICYgeCA8PSBtYXgoeCkgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA+PSB1cHBlcl9ib3VuZA0KbGluZXMoeCwgaHgpICMgcGxvdHMgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KcG9seWdvbihjKHVwcGVyX2JvdW5kLHhbaV0sbWF4KHgpKSwgYygwLGh4W2ldLDApLCBjb2w9ImdyZXkiKSAjIHNoYWRlcyBhcmVhIGdyZXkgd2hlcmUgeCA+PSB1cHBlcl9ib3VuZA0KDQpqIDwtIHggPj0gbWluKHgpICYgeCA8PSBsb3dlcl9ib3VuZCAjIGluZGV4ZXMgb2YgeCB3aGVyZSB4IDw9IHRoYW4gbG93ZXJfYm91bmQNCnBvbHlnb24oYyhtaW4oeCkseFtqXSxsb3dlcl9ib3VuZCksIGMoMCxoeFtqXSwwKSwgY29sPSJncmV5IikgIyBzaGFkZXMgYXJlYSBncmV5IHdoZXJlIHggPD0gbG93ZXJfYm91bmQNCg0KYXhpcygxLCBhdD1zZXEoMC4wMCwgMC4yLCAwLjAyKSwgcG9zPTApICMgZHJhd3MgYXhpcw0KYWJsaW5lKHY9cF9kaWZmKQ0KZ3JpZCgpDQoNCnBfMV9oYXQgPC0gMC41ODMzOyBwXzJfaGF0IDwtIDAuNDM3NTsgcF9kaWZmX2hhdF9leGFtcGxlIDwtIDAuMTQ1OA0Kc2VfcF9kaWZmX2hhdCA8LSBzcXJ0KHBfMV9oYXQgKiAoMSAtIHBfMV9oYXQpIC8gbl8xX2V4YW1wbGUgKyBwXzJfaGF0ICogKDEgLSBwXzJfaGF0KSAvIG5fMl9leGFtcGxlKQ0KYXhpcygxLCBhdD1jKHBfZGlmZl9oYXRfZXhhbXBsZSAtIDEuOTYgKiBzZV9wX2RpZmZfaGF0LCBwX2RpZmZfaGF0X2V4YW1wbGUsIHBfZGlmZl9oYXRfZXhhbXBsZSArIDEuOTYgKiBzZV9wX2RpZmZfaGF0KSwgcG9zPS0yLjUsIGNvbCA9ICJibHVlIiwgbHdkID0gMiwgbHdkLnRpY2tzID0gMSkgDQoNCnRleHQoeCA9IDAuMDE1LCB5ID0gMTEsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUocFtkaWZmXSwgIiA9IDAuMSIpKSkNCnRleHQoeCA9IDAuMDIsIHkgPSAxMCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuWzFdLCAiID0gIiwgblsyXSwgICIgPSA1MDAiKSkpDQp0ZXh0KHggPSAwLjAyLCB5ID0gOSwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRSwgIiA9IDAuMDMxMyIpKSkNCnRleHQoeCA9IDAuMDIxLCB5ID0gOCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShoYXQocClbZGlmZl0sICIgPSAwLjE0NTgiKSkpDQp0ZXh0KHggPSAwLjAyNSwgeSA9IDYuNSwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRVtoYXQocClbMV0taGF0KHApWzJdXSwgIiA9IDAuMDMxMyIpKSkNCmBgYA0KDQpJZiB3ZSBhcmUgdW5sdWNreSBhbmQgIGRyYXcgc2FtcGxlcyB3aG9zZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zICRcaGF0e3B9X3tkaWZmfSQgZmFsbHMgaW4gdGhlIHNoYWRlZCBhcmVhLCB3aGljaCBzaG91bGQgb25seSBoYXBwZW4gJDVcJSQgb2YgdGhlIHRpbWUsIGl0cyAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCB3aWxsIG5vdCBpbmNsdWRlIHRoZSB0cnVlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgJHBfe2RpZmZ9PTAuMSQuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kbl8xX2V4YW1wbGUgPC0gNTAwOyBuXzJfZXhhbXBsZSA8LSA1MDANCnBfMSA8LSAwLjYwOyBwXzIgPC0gMC41MDsgcF9kaWZmIDwtIHBfMSAtIHBfMg0Kc2UgPC0gc3FydChwXzEgKiAoMSAtIHBfMSkgLyBuXzFfZXhhbXBsZSArIHBfMiAqICgxIC0gcF8yKSAvIG5fMl9leGFtcGxlKQ0KDQojIHggPSBwX2RpZmYgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZSArIHBfZGlmZg0KaHggPC0gZG5vcm0oeCwgcF9kaWZmICxzZSkNCg0KIyBWYWx1ZXMgdXNlZCB0byBzaGFkZSBhcmVhcyB1bmRlciB0aGUgY3VydmUNCnVwcGVyX2JvdW5kIDwtIHBfZGlmZiArIDEuOTYgKiBzZSANCmxvd2VyX2JvdW5kIDwtIHBfZGlmZiAtIDEuOTYgKiBzZSANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWIgPSAiIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSB1cHBlcl9ib3VuZCAmIHggPD0gbWF4KHgpICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCmxpbmVzKHgsIGh4KSAjIHBsb3RzIG5vcm1hbCBkaXN0cmlidXRpb24NCnBvbHlnb24oYyh1cHBlcl9ib3VuZCx4W2ldLG1heCh4KSksIGMoMCxoeFtpXSwwKSwgY29sPSJncmV5IikgIyBzaGFkZXMgYXJlYSBncmV5IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gbG93ZXJfYm91bmQgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA8PSB0aGFuIGxvd2VyX2JvdW5kDQpwb2x5Z29uKGMobWluKHgpLHhbal0sbG93ZXJfYm91bmQpLCBjKDAsaHhbal0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgZ3JleSB3aGVyZSB4IDw9IGxvd2VyX2JvdW5kDQoNCmF4aXMoMSwgYXQ9c2VxKDAuMDAsIDAuMiwgMC4wMiksIHBvcz0wKSAjIGRyYXdzIGF4aXMNCmFibGluZSh2PXBfZGlmZikNCmdyaWQoKQ0KDQpwXzFfaGF0IDwtIDAuNTE7IHBfMl9oYXQgPC0gMC40ODsgcF9kaWZmX2hhdF9leGFtcGxlIDwtIDAuMDMNCnNlX3BfZGlmZl9oYXQgPC0gc3FydChwXzFfaGF0ICogKDEgLSBwXzFfaGF0KSAvIG5fMV9leGFtcGxlICsgcF8yX2hhdCAqICgxIC0gcF8yX2hhdCkgLyBuXzJfZXhhbXBsZSkNCmF4aXMoMSwgYXQ9YyhwX2RpZmZfaGF0X2V4YW1wbGUgLSAxLjk2ICogc2VfcF9kaWZmX2hhdCwgcF9kaWZmX2hhdF9leGFtcGxlLCBwX2RpZmZfaGF0X2V4YW1wbGUgKyAxLjk2ICogc2VfcF9kaWZmX2hhdCksIHBvcz0tMi41LCBjb2wgPSAicmVkIiwgbHdkID0gMiwgbHdkLnRpY2tzID0gMSkgDQoNCnRleHQoeCA9IDAuMDE1LCB5ID0gMTEsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUocFtkaWZmXSwgIiA9IDAuMSIpKSkNCnRleHQoeCA9IDAuMDIsIHkgPSAxMCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuWzFdLCAiID0gIiwgblsyXSwgICIgPSA1MDAiKSkpDQp0ZXh0KHggPSAwLjAyLCB5ID0gOSwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRSwgIiA9IDAuMDMxMyIpKSkNCnRleHQoeCA9IDAuMDE3LCB5ID0gOCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShoYXQocClbZGlmZl0sICIgPSAwLjAzIikpKQ0KdGV4dCh4ID0gMC4wMjYsIHkgPSA2LjUsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoU0VbaGF0KHApWzFdLWhhdChwKVsyXV0sICIgPSAwLjAzMTYiKSkpDQpgYGANCg0KDQoNCiMjIyA0LjIgQ29uZGl0aW9ucyBmb3IgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KVGhlIGNvbmRpdGlvbnMgZm9yIHRoZSB2YWxpZGl0eSBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBhcmU6DQoNCjEuIFNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQsIGJvdGggd2l0aGluIGdyb3VwcyBhbmQgYmV0d2VlbiBncm91cHMuDQoNCjIuIEVhY2ggc2FtcGxlIHNob3VsZCBoYXZlIGF0IGxlYXN0IDEwIHN1Y2Nlc3NzZXMgYW5kIDEwIGZhaWx1cmVzOg0KDQokJA0Kbl8xXGNkb3RcaGF0e3B9XzFcZ2VxMTBcIGFuZFwgbl8yXGNkb3QoMSAtIFxoYXR7cH1fMilcZ2VxMTANCiQkDQoNCiQkDQpuXzJcY2RvdFxoYXR7cH1fMlxnZXExMFwgYW5kXCBuXzJcY2RvdCgxIC0gXGhhdHtwfV8yKVxnZXExMA0KJCQNCg0KVG8gdmVyaWZ5IHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBmaXJzdCBhc3N1bXB0aW9uLCB0aGF0IHNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQgd2l0aGluIGdyb3Vwcywgd2UgY2hlY2sgdGhhdCB0aGUgc2FtcGxlZCByZXNwb25kZW50cyB3aXRoaW4gZWFjaCBncm91cCAodGhvc2Ugd2hvIGRvbid0IGxpdmUgd2l0aGluIDEgbWlsZSBvZiBhbiBhcmVhIHRoZXkgZmVhciwgYW5kIHRob3NlIHRoYXQgZG8pIGFyZSByYW5kb21seSBzYW1wbGVkLCBhbmQgZWFjaCBvZiB0aGUgdHdvIHNhbXBsZXMgd2FzIGRvbmUgd2l0aG91dCByZXBsYWNlbWVudCwgYW5kIGVhY2ggc2FtcGxlIHJlcHJlc2VudHMgbGVzcyB0aGFuICQxMFwlJCBvZiB0aGVpciByZXNwZWN0aXZlIHBvcHVsYXRpb25zLiBFLmcuLCBmb3IgdGhlIGdyb3VwIGZyb20gdGhlIHBvcHVsYXRpb24gd2hvIGRvbid0IGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhciwgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMsIGFib3V0ICQxMzAwJCwgaXMgY2VydGFpbmx5IG11Y2ggbGVzcyB0aGFuICQxMFwlJCBvZiB0aGUgZW50aXJlIFUuUy4gcG9wdWxhdGlvbiB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyLg0KDQpUbyB2ZXJpZnkgdGhlIHNlY29uZCBwYXJ0IG9mIHRoZSBmaXJzdCBhc3N1bXB0aW9uLCB3ZSBub3RlIHRoYXQgYW55IHJlc3BvbmRlbnQgZnJvbSB0aGUgbm8tZmVhciBzYW1wbGUgaXMgaW5kZXBlbmRlbnQgZnJvbSBhbnkgcmVzcG9uZGVudCBmcm9tIHRoZSBmZWFyIHNhbXBsZS4NCg0KTm93IHdlIGNoZWNrIHRoZSB2YWxpZGl0eSBvZiB0aGUgc2Vjb25kIGFzc3VtcHRpb24gYnkgdmVyaWZ5aW5nIHRoZSBzdWNjZXNzLWZhaWx1cmUgY29uZGl0aW9ucyBmb3IgYm90aCBzYW1wbGVzOg0KDQpgYGB7cn0NCnNhbXBsZV8xX3N1Y2Nlc3NlcyA8LSBuXzEgKiBwX2hhdDENCnNhbXBsZV8xX2ZhaWx1cmVzIDwtIG5fMSAqICgxIC0gcF9oYXQxKQ0KDQpzYW1wbGVfMl9zdWNjZXNzZXMgPC0gbl8yICogcF9oYXQyDQpzYW1wbGVfMl9mYWlsdXJlcyA8LSBuXzIgKiAoMSAtIHBfaGF0MikNCg0KY2F0KCJOdW1iZXIgb2Ygc3VjY2Vzc2VzIGluIHRoZSBmaXJzdCBzYW1wbGU6IiwgZmxvb3Ioc2FtcGxlXzFfc3VjY2Vzc2VzKSwgIlxuTnVtYmVyIG9mIGZhaWx1cmVzIGluIHRoZSBmaXJzdCBzYW1wbGU6IiwgZmxvb3Ioc2FtcGxlXzFfZmFpbHVyZXMpLCAiXG5OdW1iZXIgb2Ygc3VjY2Vzc2VzIGluIHRoZSBzZWNvbmQgc2FtcGxlOiIsIGZsb29yKHNhbXBsZV8yX3N1Y2Nlc3NlcyksICJcbk51bWJlciBvZiBmYWlsdXJlcyBpbiB0aGUgc2Vjb25kIHNhbXBsZToiLCBmbG9vcihzYW1wbGVfMl9mYWlsdXJlcykpDQpgYGANCg0KDQojIyMgNC4zIENyaXRpY2FsIHZhbHVlICR6XiokDQoNClRoZSAkel4qJCBjb3JyZXNwb25kaW5nIHRvIGEgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW4gdGhlIFtzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uXShodHRwczovL3d3dy5tYXRoc2lzZnVuLmNvbS9kYXRhL3N0YW5kYXJkLW5vcm1hbC1kaXN0cmlidXRpb24tdGFibGUuaHRtbCkgaXMgYXBwcm94aW1hdGVseSAxLjk2LiBXZSBjYW4gY29tcHV0ZSBpdCBtb3JlIGV4YWN0bHkgdXNpbmcgUjoNCg0KYGBge3J9DQp6X3N0YXIgPC0gcW5vcm0ocCA9IDAuMDI1LCBtZWFuID0gMCwgc2QgPSAxLCBsb3dlci50YWlsID0gRkFMU0UpDQp6X3N0YXINCmBgYA0KDQojIyMgNC40IFN0YW5kYXJkIGVycm9yDQoNCkNvbXB1dGluZyB0aGUgc3RhbmRhcmQgZXJyb3Igb2YgdGhlIHNhbXBsZQ0KYGBge3J9DQpzZSA8LSBzcXJ0KHBfaGF0MSAqICgxIC0gcF9oYXQxKSAvIG5fMSArIHBfaGF0MiAqICgxIC0gcF9oYXQyKSAvIG5fMikNCmNhdCgiU3RhbmRhcmQgZXJyb3Igb2YgdGhlIHNhbXBsZToiLCBzZSkNCmBgYA0KDQojIyMgNC41IENvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KQ29tcHV0aW5nIHRoZSBjb25maWRlbmNlIGludGVydmFsIGJvdW5kcw0KYGBge3J9DQpjb25mX2ludF9sYiA8LSBwX2RpZmZfaGF0IC0gel9zdGFyICogc2UNCmNvbmZfaW50X3ViIDwtIHBfZGlmZl9oYXQgKyB6X3N0YXIgKiBzZQ0KY2F0KCJDb25maWRlbmNlIGludGVydmFsIGxvd2VyIGJvdW5kIiwgY29uZl9pbnRfbGIsICJcbkNvbmZpZGVuY2UgaW50ZXJ2YWwgdXBwZXIgYm91bmQiLCBjb25mX2ludF91YikNCmBgYA0KPGJyPg0KDQpIZW5jZSwgb3VyIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMNCiQkDQowLjA5MDFccG0gMS45NlxjZG90IDAuMDIyMj0oMC4wNDY2LCAwLjEzMzQpDQokJA0KDQpXZSBhcmUgJDk1XCUkIGNvbmZpZGVudCB0aGF0IHRoZSB0cnVlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMgaXMgYmV0d2VlbiAkMC4wNDY2JCBhbmQgJDAuMTMzNCQuDQoNCiMjIDUuMCBIeXBvdGhlc2lzIHRlc3RpbmcNCg0KV2UgY2FuIHVzZSB0aGUgQ0xUIGFuZCB0aGUgZGF0YSBjb2xsZWN0ZWQgdG8gY29uc3RydWN0IGEgaHlwb3RoZXNpcyB0ZXN0aW5nIGZyYW1ld29yay4gVGhlIGh5cG90aGVzaXMgdGVzdCBjb25zaWRlcnMgdHdvIHBvc3NpYmxlIGludGVycHJldGF0aW9ucyBvZiBvdXIgZGF0YSwgYSBudWxsIGh5cG90aGVzaXMgJEhfMCQsIGFuZCBhbiBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzICRIX2EkLiAkSF8wJCBiYXNpY2FsbHkgc2F5cyB0aGF0IHRoZSBzYW1wbGVkIGRhdGEgY291bGQgaGF2ZSBiZWVuIGRyYXduIHNpbXBseSBieSBjaGFuY2UsIGFuZCBzbywgaXQgaXMgbWlzbGVhZGluZy4gVGhlcmUgaXMgIm5vdGhpbmcgZ29pbmcgb24iLiAkSF9hJCB0YWtlcyB0aGUgdmlldyB0aGF0IHRoZSBkYXRhIGNvbGxlY3RlZCByZXZlYWxzIHRoYXQgInNvbWV0aGluZyAqaXMqIGdvaW5nIG9uIi4gV2Ugd2lsbCBlaXRoZXIgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgaW4gZmF2b3Igb2YgdGhpcyBhbHRlcm5hdGl2ZSwgb3Igd2Ugd2lsbCBmYWlsIHRvIHJlamVjdCBpdCBhbmQgY29uY2x1ZGUgdGhlIHNhbXBsZWQgZGF0YSBjb3VsZCBoYXZlIGJlZW4gZHJhd24gc2ltcGx5IGJ5IGNoYW5jZS4gTm90ZSB0aGF0IGV2ZW4gaWYgd2UgZmFpbCB0byByZWplY3QgJEhfMCQsIHRoYXQgZG9lcyBub3QgbWVhbiB3ZSBhY2NlcHQgaXQgYXMgdGhlIGdyb3VuZCB0cnV0aCwgaXQncyBqdXN0IHRoYXQgdGhlIGRhdGEgd2UgaGF2ZSBjb2xsZWN0ZWQgZG9lcyBub3QgYWxsb3dzIHVzIHRvIGRpc2NhcmQgJEhfMCQuDQoNClN1cHBvc2Ugd2Ugd2FudCB0byBmaW5kIG91dCBpZiB0aGUgJDAuMDkwMSQgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHByb3BvcnRpb25zIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIE91ciBudWxsIGh5cG90aGVzaXMgJEhfMCQgaXM6DQoNCiQkDQpIXzA6IFRoZVwgdHJ1ZVwgZGlmZmVyZW5jZVwgaW5cIHRoZVwgdHdvXCBwb3B1bGF0aW9uXCBwcm9wb3J0aW9uc1wgcF8xLXBfMj0gcF97ZGlmZn09MA0KXFwNCkhfYTogcF97ZGlmZn1cbmVxIDANCiQkDQoNClRvIHBlcmZvcm0gdGhlIHRlc3QsIHdlIGFzc3VtZSB0aGF0ICRIXzAkIGlzIHRydWUgYW5kIGFzaywgZ2l2ZW4gdGhhdCAkSF8wJCBpcyB0cnVlLCBob3cgcHJvYmFibGUgaXQgaXMgdG8gb2JzZXJ2ZSBkYXRhIGFzIGV4dHJlbWUgb3IgbW9yZSBhcyB0aGUgb25lIHdlIGhhdmUuDQoNCiMjIyA1LjEgVGhlIG51bGwgaHlwb3RoZXNpcyBwcm9wb3J0aW9uICRwX3twb29sfSQNCg0KVW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcyAkSF8wJCwgd2UgYXNzdW1lIHRoZSB0cnVlIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMgJHBfMSQgYW5kICRwXzIkIGFyZSB0aGUgc2FtZSwgYnV0IHdoYXQgYXJlIHRoZXkgZXF1YWwgdG8/IEluIG90aGVyIHdvcmRzLCAkcF8xPXBfMj0/JCBUaGUgc3RhbmRhcmQgZXJyb3IgZm9ybXVsYSB1bmRlciAkSF8wJCBzaG91bGQgdXNlIGEgY29tbW9uIHZhbHVlIHJhdGhlciBmb3IgJHAkIHJhdGhlciB0aGFuIHRoZSAkMiQgZXN0aW1hdGVzICRcaGF0IHBfMSQgYW5kICRcaGF0IHBfMiQsIGdpdmVuIHRoYXQgd2UgYXJlIGFyZ3VpbmcgdGhhdCAkcF8xPXBfMiQuIEEgZ29vZCBwb2ludCBlc3RpbWF0ZSBmb3IgdGhpcyBjb21tb24gdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5ICpwb29saW5nKiB0aGUgInN1Y2Nlc3NlcyIgZnJvbSBib3RoIHNhbXBsZXMuIEluIHRoaXMgY2FzZSwgdGhlIHN1Y2Nlc3NlcyBhcmUgdGhlIHJlc3BvbmRlbnRzIGZyb20gYm90aCBncm91cHMgdGhhdCBsaXZlIGluIGEgcGxhY2Ugd2hlcmUgZ3VucyBhcmUga2VwdC4NCg0KJCQNClxoYXR7cH1fe3Bvb2x9PVxmcmFje3RvdGFsXCBudW1iZXJcIG9mXCByZXNwb25kZW50c1wgd2hvXCBvd25cIGd1bnN9e25fMSArIG5fMn0NCiQkDQoNCkNvbXB1dGluZyAkXGhhdHtwfV97cG9vbH0kDQpgYGB7cn0NCnBfcG9vbGVkIDwtIChuX25vZmVhcl9vd25ndW4gKyBuX2ZlYXJfb3duZ3VuKSAvIChuXzEgKyBuXzIpDQpjYXQoIkVzdGltYXRlIG9mIHBvb2xlZCBwcm9wb3J0aW9uOiIsIHBfcG9vbGVkKQ0KYGBgDQoNCg0KVGhlIHN0YW5kYXJkIGVycm9yIGNhbiB0aGVuIGJlIGNvbXB1dGVkIHNpbWlsYXJseSBhcyBiZWZvcmU6DQoNCiQkDQpTRV97cG9vbGVkfT1cc3FydHtcZnJhY3tcaGF0e3B9X3twb29sZWR9XGNkb3QgKDEtXGhhdHtwfV97cG9vbGVkfSl9e25fMX0gKyBcZnJhY3tcaGF0e3B9X3twb29sZWR9XGNkb3QgKDEtXGhhdHtwfV97cG9vbGVkfSl9e25fMn19DQokJA0KDQpDb21wdXRpbmcgJFNFX3twb29sZWR9JDoNCmBgYHtyfQ0Kc2VfcG9vbGVkIDwtIHNxcnQocF9wb29sZWQgKiAoMSAtIHBfcG9vbGVkKSAvIG5fMSArIHBfcG9vbGVkICogKDEgLSBwX3Bvb2xlZCkgLyBuXzIpDQpjYXQoIlN0YW5kYXJkIGVycm9yIHVuZGVyIG51bGwgaHlwb3RoZXNpcyB1c2luZyBwb29sZWQgcHJvcG9ydGlvbiBlc3RpbWF0ZToiLCBzZV9wb29sZWQpDQpgYGANCg0KIyMjIDUuMiBDb25kaXRpb25zIGZvciBoeXBvdGhlc2lzIHRlc3RpbmcNCg0KVGhlIGNvbmRpdGlvbnMgdG8gcGVyZm9ybSB0aGUgaHlwb3RoZXNpcyB0ZXN0IGFyZSBzaW1pbGFyIHRvIHRoZSBvbmVzIHdlIGNoZWNrZWQgdG8gY29tcHV0ZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbC4NCg0KMS4gU2FtcGxlZCBvYnNlcnZhdGlvbnMgbXVzdCBiZSBpbmRlcGVuZGVudCwgYm90aCB3aXRoaW4gZ3JvdXBzIGFuZCBiZXR3ZWVuIGdyb3Vwcy4NCg0KMi4gRWFjaCBzYW1wbGUgc2hvdWxkIGhhdmUgYXQgbGVhc3QgMTAgc3VjY2Vzc3NlcyBhbmQgMTAgZmFpbHVyZXMuIFdlIHVzZSB0aGUgcG9vbGVkIHByb3BvcnRpb24gJFxoYXR7cH1fe3Bvb2x9JCB0byBjb21wdXRlIHRoZSBudW1iZXJzIG9mIHN1Y2Nlc3NlcyBhbmQgZmFpbHVyZXM6DQoNCiQkDQpuXzFcY2RvdFxoYXR7cH1fe3Bvb2x9XGdlcTEwXCBhbmRcIG5fMVxjZG90KDEgLSBcaGF0e3B9X3twb29sfSlcZ2VxMTANCiQkDQoNCiQkDQpuXzJcY2RvdFxoYXR7cH1fe3Bvb2x9XGdlcTEwXCBhbmRcIG5fMlxjZG90KDEgLSBcaGF0e3B9X3twb29sfSlcZ2VxMTANCiQkDQoNClZlcmlmeWluZyB0aGUgc3VjY2Vzcy1mYWlsdXJlIGNvbmRpdGlvbnMgZm9yIGh5cG90aGVzaXMgdGVzdGluZzoNCmBgYHtyfQ0Kc2FtcGxlXzFfc3VjY2Vzc2VzIDwtIG5fMSAqIHBfcG9vbGVkDQpzYW1wbGVfMV9mYWlsdXJlcyA8LSBuXzEgKiAoMSAtIHBfcG9vbGVkKQ0KDQpzYW1wbGVfMl9zdWNjZXNzZXMgPC0gbl8yICogcF9wb29sZWQNCnNhbXBsZV8yX2ZhaWx1cmVzIDwtIG5fMiAqICgxIC0gcF9wb29sZWQpDQoNCmNhdCgiU3VjY2Vzcy1mYWlsdXJlIGNvbmRpdGlvbnMgZm9yIGh5cG90aGVzaXMgdGVzdGluZywgdXNpbmcgcF9wb29sZWQ6IiwgIlxuTnVtYmVyIG9mIHN1Y2Nlc3NlcyBpbiB0aGUgZmlyc3Qgc2FtcGxlOiIsIGZsb29yKHNhbXBsZV8xX3N1Y2Nlc3NlcyksICJcbk51bWJlciBvZiBmYWlsdXJlcyBpbiB0aGUgZmlyc3Qgc2FtcGxlOiIsIGZsb29yKHNhbXBsZV8xX2ZhaWx1cmVzKSwgIlxuTnVtYmVyIG9mIHN1Y2Nlc3NlcyBpbiB0aGUgc2Vjb25kIHNhbXBsZToiLCBmbG9vcihzYW1wbGVfMl9zdWNjZXNzZXMpLCAiXG5OdW1iZXIgb2YgZmFpbHVyZXMgaW4gdGhlIHNlY29uZCBzYW1wbGU6IiwgZmxvb3Ioc2FtcGxlXzJfZmFpbHVyZXMpKQ0KYGBgDQoNCiMjIyA1LjMgVGhlIHAtdmFsdWUNCg0KV2UgaGF2ZSB0byBhc2sgb3Vyc2VsdmVzLCBnaXZlbiB0aGF0IHRoZSBudWxsIGh5cG90aGVzaXMgJEhfMCQgaXMgdHJ1ZSwgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2Ygb2JzZXJ2aW5nIGRhdGEgYXMgZXh0cmVtZSBvciBtb3JlIGFzIHRoZSBvbmUgd2UgaGF2ZT8NCg0KJCQNClAob2JzZXJ2aW5nXCBkYXRhXCBhc1wgZXh0cmVtZVwgb3JcIG1vcmVcIHxcIEhfezB9XCBpc1wgdHJ1ZSkNCiQkDQoNClRoYXQgcHJvYmFiaWxpdHkgaXMgdGhlIHAtdmFsdWUuDQoNCk91ciBoeXBvdGhlc2lzIHRlc3QgaXMgdHdvLXNpZGVkLiBUaGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRoYXQgJHBfe2RpZmZ9PTAkLCBzbyBieSBhc2tpbmcgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgJG9ic2VydmluZ1wgZGF0YVwgYXNcIGV4dHJlbWVcIG9yXCBtb3JlJCBpbiBhIHdvcmxkIGluIHdoaWNoIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgdHJ1ZSwgd2UgYXJlIHdvbmRlcmluZyBob3cgcHJvYmFibGUgaXQgaXMgdG8gZHJhdyBhIHNhbXBsZSB3aXRoIGEgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiAkMC4wOTAxJCBvciBoaWdoZXIgbGlrZSB0aGUgb25lIHdlIGhhdmUgZHJhd24sIG9yIG9uZSB3aXRoIGEgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiAkLTAuMDkwMSQgb3IgbG93ZXIuIExldCdzIHNlZSBpdCBncmFwaGljYWxseS4NCg0KYGBge3J9DQojaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwNCg0KcF9kaWZmIDwtIDAuMDANCg0KIyB4ID0gcF9kaWZmICsvLSA1IHN0ZF9kZXYncw0KeCA8LSBzZXEoLTUsNSxsZW5ndGg9MTAwMCkqc2VfcG9vbGVkICsgcF9kaWZmDQpoeCA8LSBkbm9ybSh4LCBwX2RpZmYsIHNlX3Bvb2xlZCkNCg0KIyBWYWx1ZXMgdXNlZCB0byBzaGFkZSBhcmVhIHVuZGVyIGN1cnZlDQpsYiA8LSBwX2RpZmZfaGF0OyB1YiA8LSBtYXgoeCkNCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWI9IkRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbiBvZiBndW4gb3duZXJzaGlwIGJldHdlZW5cbiB0aG9zZSB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyLCBhbmQgdGhvc2UgdGhhdCBkbyIsIHlsYWI9IiIsIG1haW49IlNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB1bmRlciBudWxsIGh5cG90aGVzaXMiLCBheGVzPUZBTFNFKQ0KDQpsaW5lcyh4LCBoeCkgIyBwbG90cyBub3JtYWwgZGlzdHJpYnV0aW9uDQoNCmkgPC0geCA+PSBsYiAmIHggPD0gdWIgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA+PSB0aGFuIGxiDQpwb2x5Z29uKGMobGIseFtpXSx1YiksIGMoMCxoeFtpXSwwKSwgY29sPSJyZWQiKSAjIHNoYWRlcyBhcmVhIHdoZXJlIHggPj0gcF9kaWZmX2hhdCBpbiByZWQNCg0KbGluZXMoeFtpXSwgaHhbaV0sIGx3ZCA9IDQsIGNvbCA9ICJyZWQiKSAjICJzaGFkZXMgYXJlYSIgd2hlcmUgeCA+PSBwX2RpZmZfaGF0IGluIHJlZA0KIyBpbiByZWFsaXR5IGl0J3MganVzdCBkcmF3aW5nIGEgdGhpY2tlciByZWQgbGluZSBvbiB0b3Agb2YgdGhlIG9yaWdpbmFsDQojIHNpbmNlIHNoYWRpbmcgdXNpbmcgdGhlIHBvbHlnb24oKSBmdW5jdGlvbiB3aWxsIHNob3cgbm90aGluZyBiL2MgdGhlIGFyZWEgaXMgc28gc21hbGwNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gLWxiICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPD0gLXBkaWZmX2hhdA0KDQpsaW5lcyh4W2pdLCBoeFtqXSwgbHdkID0gNCwgY29sID0gInJlZCIpICMgInNoYWRlcyBhcmVhIiB3aGVyZSB4IDw9IC1wX2RpZmZfaGF0IGluIHJlZA0KIyBpbiByZWFsaXR5IGl0J3MganVzdCBkcmF3aW5nIGEgdGhpY2tlciByZWQgbGluZSBvbiB0b3Agb2YgdGhlIG9yaWdpbmFsDQojIHNpbmNlIHNoYWRpbmcgdXNpbmcgdGhlIHBvbHlnb24oKSBmdW5jdGlvbiB3aWxsIHNob3cgbm90aGluZyBiL2MgdGhlIGFyZWEgaXMgc28gc21hbGwNCg0KYXhpcygxLCBhdD1zZXEoLTAuMTIsIDAuMTIsIDAuMDEpLCBwb3M9MCkgIyBkcmF3cyBheGlzDQphYmxpbmUodj1wX2RpZmYpDQpncmlkKCkNCmBgYA0KDQpXZSBhcmUgYXNraW5nIGhvdyBwcm9iYWJsZSBpdCBpcyB0byBkcmF3IGEgc2FtcGxlIHdpdGggYSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIHRoYXQgaXMgJDAuMDkwMSQgb3IgbW9yZSBhd2F5IGZyb20gdGhlIGFzc3VtZWQgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyAodW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcykgb2YgJDAkLCBpbiBlaXRoZXIgZGlyZWN0aW9uLiBUaGF0IGlzLCAkXGZyYWN7MC4wOTAxfXswLjAyMzB9ID0gMy45MiQgc3RhbmRhcmQgZGV2aWF0aW9ucyBhd2F5IGZyb20gJDAkLiBUaGUgcHJvYmFiaWxpdHkgb2YgdGhhdCBvY2N1cnJpbmcgaXMgdmVyeSBzbWFsbCBpbmRlZWQ7IGl0IGlzIHJlcHJlc2VudGVkIGJ5IHRoZSBzaGFkZWQgYXJlYSBpbiB0aGUgcGxvdC4gSW4gcmVhbGl0eSwgSSBqdXN0IHRoaWNrZW5lZCB0aGUgbGluZSBhbmQgY29sb3JlZCBpdCByZWQgc2luY2UgdGhlIGFyZWEgaXMgdG9vIHNtYWxsIHRvIHNob3cuDQo8YnI+DQoNClVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMsIHdlIGxpdmUgaW4gYSB3b3JsZCBpbiB3aGljaCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb24gb2YgZ3VuIG93bmVyc2hpcCBiZXR3ZWVuIHR3byBncm91cHMgaXMgY2VudGVyZWQgYXQgJHBfe2RpZmZ9ID0gMCQgYW5kIGhhcyBhIHN0YW5kYXJkIGRldmlhdGlvbiBvZiAkMC4wMjMwJC4gSW4gc3VjaCBhIHdvcmxkLCB3ZSBoYXZlIGRyYXduIGEgc2FtcGxlIHdoZXJlIHRoZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIGlzICRcaGF0e3B9X3tkaWZmfT0wLjA5MDEkLiBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBkcmF3aW5nIGEgc2FtcGxlIHdpdGggYSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb24gJFxoYXR7cH1fe2RpZmZ9JCBhcyBoaWdoIG9yIGhpZ2hlciwgaW4gZWl0aGVyIGRpcmVjdGlvbiwgaW4gYSB3b3JsZCBpbiB3aGljaCB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRydWU/DQoNCiQkDQpQKGRyYXdpbmdcIGFcIHNhbXBsZVwgd2hlcmVcIHRoZVwgZGlmZmVyZW5jZVwgaW5cIHBvcHVsYXRpb25cIHByb3BvcnRpb25zXFwgaXNcIGFzXCBsYXJnZVwgb3JcIGxhcmdlclwgdGhhblwgMC4wOTAxIHxcIEhfezB9XCBpc1wgdHJ1ZSkNClxcDQpQKFxoYXR7cH1fe2RpZmZ9XCBcZ2VxXCAwLjA5MDFcIG9yXCBcaGF0e3B9X3tkaWZmfVwgXGxlcVwgLTAuMDkwMSB8XCBwX3tkaWZmfSA9ICAwKQ0KJCQNCg0KVGhhdCBwcm9iYWJpbGl0eSBpcyB0aGUgYXJlYSB1bmRlciB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHNoYWRlZCBpbiByZWQgaW4gdGhlIHBsb3QgKGFsdGhvdWdoIGl0IGlzIGludmlzaWJsZSBiZWNhdXNlIGl0IGlzIHNvIHNtYWxsKS4gSXQgY2FuIGJlIGNvbXB1dGVkIHVzaW5nIGBwbm9ybSgpYC4NCmBgYHtyfQ0KYXJlYSA8LSAyICogcG5vcm0ocSA9IHBfZGlmZl9oYXQsIG1lYW4gPSBwX2RpZmYsIHNkID0gc2VfcG9vbGVkLCBsb3dlci50YWlsID0gRkFMU0UpDQojIE11bHRpcGxpZWQgYnkgMiBiZWNhdXNlIHRoZSBoeXBvdGhlc2lzIHRlc3QgaXMgdHdvLXNpZGVkLg0KY2F0KCJPdXIgcC12YWx1ZToiLCBhcmVhKQ0KYGBgDQoNCg0KU28gb3VyIFtwLXZhbHVlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QLXZhbHVlKSwgdGhlIHByb2JhYmlsaXR5IG9mIGRyYXdpbmcgYSBzYW1wbGUgd2l0aCAkXGhhdHtwfV97ZGlmZn09MC4wOTAxJCBvciBoaWdoZXIsIG9yIG9uZSAkXGhhdHtwfV97ZGlmZn09LTAuMDkwMSQgb3IgbG93ZXIsIHVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMsIGlzIGFib3V0ICQ4Ljc1M2UtNSQuIEF0IHRoZSAkNVwlJCBzaWduaWZpY2FuY2UgbGV2ZWwsIHdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBiZWNhdXNlIHRoZSBzYW1wbGUgZGF0YSBwcm92aWRlcyBjb252aW5jaW5nIGV2aWRlbmNlIHRvIGRvIHNvLiANCg0KIyMgUmVmZXJlbmNlcw0KDQoxLiDDh2V0aW5rYXlhLVJ1bmRlbCwgTS4gKioqRGF0YSBBbmFseXNpcyBhbmQgU3RhdGlzdGljYWwgSW5mZXJlbmNlKioqLiBTcHJpbmcgMjAxNC4gW0NvdXJzZXJhXShodHRwOi8vd3d3LmNvdXJzZXJhLm9yZykuDQoNCjIuIERpZXosIEQuLCBCYXJyLCBDLiwgw4dldGlua2F5YS1SdW5kZWwsIE0uICoqKk9wZW5JbnRybyBTdGF0aXN0aWNzLCBTZWNvbmQgRWRpdGlvbioqKi4gUERGLg0KDQozLiBOYXZpZGksIFcuICoqKlN0YXRpc3RpY3MgZm9yIGVuZ2luZWVycyBhbmQgc2NpZW50aXN0cywgVGhpcmQgRWRpdGlvbioqKi4gTmV3IFlvcms6IE1jR3JhdyBIaWxsLCAyMDExLg0KDQo0LiBVQ0xBIEluc3RpdHV0ZSBmb3IgRGlnaXRhbCBSZXNlcmFjaCBhbmQgRWR1Y2F0aW9uLCAqKipIT1cgQ0FOIEkgSU5DTFVERSBHUkVFSyBMRVRURVJTIElOIE1ZIFBMT1QgTEFCRUxTPyB8IFIgQ09ERSBGUkFHTUVOVFMqKiouIFJldHJpZXZlZCBmcm9tIFtodHRwczovL3N0YXRzLmlkcmUudWNsYS5lZHVdKGh0dHBzOi8vc3RhdHMuaWRyZS51Y2xhLmVkdS9yL2NvZGVmcmFnbWVudHMvZ3JlZWtfbGV0dGVycy8pDQoNCjUuIEthYmFjb2ZmLCBSLiAqKipQcm9iYWJpbGl0eSBQbG90cyoqKi4gUmV0cmlldmVkIGZyb20gW2h0dHA6Ly93d3cuc3RhdG1ldGhvZHMubmV0XShodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbCkNCg0KNi4gQ2FybG9zIENpbmVsbGkgYW5kIFRvbSwgKioqQ29kZSBjaHVuayBmb250IHNpemUgaW4gUm1hcmtkb3duIHdpdGgga25pdHIgYW5kIGxhdGV4KioqLiBSZXRyaWV2ZWQgZnJvbSBbaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbV0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjU2NDYzMzMvY29kZS1jaHVuay1mb250LXNpemUtaW4tcm1hcmtkb3duLXdpdGgta25pdHItYW5kLWxhdGV4KQ0KDQo3LiBEcmV3Q29ud2F5IGFuZCBDaHJpc3RvcGhlciBEdUJvaXMsICoqKkdldHRpbmcgTGFUZVggaW50byBSIFBsb3RzKioqLiBSZXRyaWV2ZWQgZnJvbSBbaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbV0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTM5NTEwNS9nZXR0aW5nLWxhdGV4LWludG8tci1wbG90cyk=