1.0 Introduction

The General Social Survey (GSS) is a sociological survey used to collect data on a wide variety of demographic characteristics and attitudes of residents of the United States. The data has been collected since 1972, approximately every 2 years, by the National Opinion Research Center (NORC) at the University of Chicago. The latest data is from the spring of 2016. The data for the each year the survey was carried out can be found here in STATA format, and here in SPSS format. The GSS Codebook, in PDF format, documents the survey data for all years. The R notebook can be found in the project’s Github page.

2.0 Variables of interest

This notebook is about making inferences about the true difference in proportion of gun ownership between two populations: Americans who don’t live within a 1-mile radius of an area they fear, and Americans who do. The survey’s interviewer asked respondents: “Do you happen to have in your home any guns or revolvers?”, and coded the response as \(OWNGUN\). Respondents were also asked: “Is there any area right around here–that is, within a mile–where you would be afraid to walk alone at night?”, and their reponse was coded as \(FEAR\).

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:

  1. Sampled observations must be independent, both within groups and between groups.

  2. 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.

  1. Sampled observations must be independent, both within groups and between groups.

  2. 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.

References

  1. Çetinkaya-Rundel, M. Data Analysis and Statistical Inference. Spring 2014. Coursera.

  2. Diez, D., Barr, C., Çetinkaya-Rundel, M. OpenIntro Statistics, Second Edition. PDF.

  3. Navidi, W. Statistics for engineers and scientists, Third Edition. New York: McGraw Hill, 2011.

  4. UCLA Institute for Digital Reserach and Education, HOW CAN I INCLUDE GREEK LETTERS IN MY PLOT LABELS? | R CODE FRAGMENTS. Retrieved from https://stats.idre.ucla.edu

  5. Kabacoff, R. Probability Plots. Retrieved from http://www.statmethods.net

  6. Carlos Cinelli and Tom, Code chunk font size in Rmarkdown with knitr and latex. Retrieved from https://stackoverflow.com

  7. DrewConway and Christopher DuBois, Getting LaTeX into R Plots. Retrieved from https://stackoverflow.com

LS0tDQp0aXRsZTogIkNvbXBhcmluZyB0d28gcG9wdWxhdGlvbiBwcm9wb3J0aW9ucyINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KYm9keSwgdGQgew0KICAgZm9udC1zaXplOiAxOHB4Ow0KfQ0KaDEgew0KICBmb250LXNpemU6IDMycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDIgew0KICBmb250LXNpemU6IDI4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDMgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDQgew0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KY29kZS5yew0KICBmb250LXNpemU6IDE2cHg7DQp9DQpwcmUgew0KICBmb250LXNpemU6IDE2cHgNCn0NCjwvc3R5bGU+DQoNCiMjIDEuMCBJbnRyb2R1Y3Rpb24NCg0KVGhlIFtHZW5lcmFsIFNvY2lhbCBTdXJ2ZXkgKEdTUyldKGh0dHA6Ly9nc3Mubm9yYy5vcmcvKSBpcyBhIHNvY2lvbG9naWNhbCBzdXJ2ZXkgdXNlZCB0byBjb2xsZWN0IGRhdGEgb24gYSB3aWRlIHZhcmlldHkgb2YgZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGFuZCBhdHRpdHVkZXMgb2YgcmVzaWRlbnRzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBUaGUgZGF0YSBoYXMgYmVlbiBjb2xsZWN0ZWQgc2luY2UgMTk3MiwgYXBwcm94aW1hdGVseSBldmVyeSAyIHllYXJzLCBieSB0aGUgW05hdGlvbmFsIE9waW5pb24gUmVzZWFyY2ggQ2VudGVyIChOT1JDKV0oaHR0cDovL3d3dy5ub3JjLm9yZy9QYWdlcy9kZWZhdWx0LmFzcHgpIGF0IHRoZSBVbml2ZXJzaXR5IG9mIENoaWNhZ28uIFRoZSBsYXRlc3QgZGF0YSBpcyBmcm9tIHRoZSBzcHJpbmcgb2YgMjAxNi4gVGhlIGRhdGEgZm9yIHRoZSBlYWNoIHllYXIgdGhlIHN1cnZleSB3YXMgY2FycmllZCBvdXQgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwOi8vZ3NzLm5vcmMub3JnL2dldC10aGUtZGF0YS9zdGF0YSkgaW4gU1RBVEEgZm9ybWF0LCBhbmQgW2hlcmVdKGh0dHA6Ly9nc3Mubm9yYy5vcmcvZ2V0LXRoZS1kYXRhL3Nwc3MpIGluIFNQU1MgZm9ybWF0LiBUaGUgW0dTUyBDb2RlYm9va10oaHR0cDovL2dzcy5ub3JjLm9yZy9HZXQtRG9jdW1lbnRhdGlvbiksIGluIFBERiBmb3JtYXQsIGRvY3VtZW50cyB0aGUgc3VydmV5IGRhdGEgZm9yIGFsbCB5ZWFycy4gVGhlIFIgbm90ZWJvb2sgY2FuIGJlIGZvdW5kIGluIHRoZSBwcm9qZWN0J3MgW0dpdGh1YiBwYWdlXShodHRwczovL2dpdGh1Yi5jb20vY2FybG9zcm9yL3N0YXQtaW5mLWNvbXBhcmluZy10d28tcHJvcG9ydGlvbnMpLg0KDQojIyAyLjAgVmFyaWFibGVzIG9mIGludGVyZXN0DQoNClRoaXMgbm90ZWJvb2sgaXMgYWJvdXQgbWFraW5nIGluZmVyZW5jZXMgYWJvdXQgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9uIG9mIGd1biBvd25lcnNoaXAgYmV0d2VlbiB0d28gcG9wdWxhdGlvbnM6IEFtZXJpY2FucyB3aG8gZG9uJ3QgbGl2ZSB3aXRoaW4gYSAxLW1pbGUgcmFkaXVzIG9mIGFuIGFyZWEgdGhleSBmZWFyLCBhbmQgQW1lcmljYW5zIHdobyBkby4gVGhlIHN1cnZleSdzIGludGVydmlld2VyIGFza2VkIHJlc3BvbmRlbnRzOiAqKiJEbyB5b3UgaGFwcGVuIHRvIGhhdmUgaW4geW91ciBob21lIGFueSBndW5zIG9yIHJldm9sdmVycz8iKiosIGFuZCBjb2RlZCB0aGUgcmVzcG9uc2UgYXMgJE9XTkdVTiQuIFJlc3BvbmRlbnRzIHdlcmUgYWxzbyBhc2tlZDogKioiSXMgdGhlcmUgYW55IGFyZWEgcmlnaHQgYXJvdW5kIGhlcmUtLXRoYXQgaXMsIHdpdGhpbiBhIG1pbGUtLXdoZXJlIHlvdSB3b3VsZCBiZSBhZnJhaWQgdG8gd2FsayBhbG9uZSBhdCBuaWdodD8iKiosIGFuZCB0aGVpciByZXBvbnNlIHdhcyBjb2RlZCBhcyAkRkVBUiQuDQoNCiMjIDMuMCBSZWFkaW5nIHRoZSBkYXRhDQoNClRoZSBSIGxpYnJhcnkgWyoqZm9yZWlnbioqXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZm9yZWlnbi9mb3JlaWduLnBkZikgYWxsb3dzIFIgdG8gcmVhZCBpbiBTVEFUQSBmaWxlcywgYW1vbmcgb3RoZXJzLiBXZSBjYW4gdGhlbiBnZXQgdGhlIHZhcmlhYmxlIHdlIHdhbnQgYXMgYSBzaW5nbGUgY29sdW1ucyB2ZWN0b3IuDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShmb3JlaWduKSAjIFVzZWQgdG8gcmVhZCBTVEFUQSAoKi5EVEEpIGZpbGVzDQpnc3MyMDE2IDwtIHJlYWQuZHRhKCJHU1MyMDE2LkRUQSIpICMgcmVhZCB0aGUgZmlsZQ0KZ3NzMjAxNl9ndW5fZmVhciA8LSBnc3MyMDE2W2MoIm93bmd1biIsICJmZWFyIildICMgb25seSBuZWVkIHR3byBmaWVsZHMNCg0Kc3VtbWFyeShnc3MyMDE2X2d1bl9mZWFyKQ0KYGBgDQoNClRoZSBOQSdzIGNvbnNpc3RlIG9mIHBlb3BsZSB0byB3aG9tIHRoZSBxdWVzdGlvbnMgd2VyZSBub3QgcG9zZWQuIFdlIGNhbiByZW1vdmUgdGhlbSBmcm9tIGJvdGggY29sdW1ucy4NCg0KYGBge3J9DQpnc3MyMDE2X2d1bl9mZWFyIDwtIGdzczIwMTZfZ3VuX2ZlYXJbIWlzLm5hKGdzczIwMTZfZ3VuX2ZlYXIkb3duZ3VuKSAmICFpcy5uYShnc3MyMDE2X2d1bl9mZWFyJGZlYXIpLF0NCg0Kc3VtbWFyeShnc3MyMDE2X2d1bl9mZWFyKQ0KYGBgDQoNCk5vdyBjb21wdXRlIHRoZSBwcm9wb3J0aW9uIG9mIGd1biBvd25lcnNoaXAgYW1vbmcgdGhlIHR3byBwb3B1bGF0aW9ucw0KYGBge3J9DQojIE51bWJlciB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyIGJ1dCBvd24gZ3VuDQpuX25vZmVhcl9vd25ndW4gPC0gbnJvdyhnc3MyMDE2X2d1bl9mZWFyW2dzczIwMTZfZ3VuX2ZlYXIkZmVhciA9PSAibm8iICYgZ3NzMjAxNl9ndW5fZmVhciRvd25ndW4gPT0gInllcyIsXSkNCg0KIyBUb3RhbCB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyDQpuXzEgPC0gbnJvdyhnc3MyMDE2X2d1bl9mZWFyW2dzczIwMTZfZ3VuX2ZlYXIkZmVhciA9PSAibm8iLF0pDQoNCiMgUG9pbnQgZXN0aW1hdGUgb2YgcHJvcG9ydGlvbiB3aG8gZG9uJ3QgbGl2ZSBpbiBhcmVhIHRoZXkgZmVhciBidXQgb3duIGd1bg0KcF9oYXQxIDwtIG5fbm9mZWFyX293bmd1biAvIG5fMQ0KDQojIE51bWJlciB3aG8gZG8gbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyIGFuZCBvd24gZ3VuDQpuX2ZlYXJfb3duZ3VuIDwtIG5yb3coZ3NzMjAxNl9ndW5fZmVhcltnc3MyMDE2X2d1bl9mZWFyJGZlYXIgPT0gInllcyIgJiBnc3MyMDE2X2d1bl9mZWFyJG93bmd1biA9PSAieWVzIixdKQ0KDQojIFRvdGFsIHdobyBkbyBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXINCm5fMiA8LSBucm93KGdzczIwMTZfZ3VuX2ZlYXJbZ3NzMjAxNl9ndW5fZmVhciRmZWFyID09ICJ5ZXMiLF0pDQoNCiMgUHJvcG9ydGlvbiB3aG8gZG8gbGl2ZSBpbiBhcmVhIHRoZXkgZmVhciBhbmQgb3duIGd1bg0KcF9oYXQyIDwtIG5fZmVhcl9vd25ndW4gLyBuXzINCg0KcF9kaWZmX2hhdCA8LSBwX2hhdDEgLSBwX2hhdDINCg0KY2F0KCJQcm9wb3J0aW9uIG9mIHBlb3BsZSB3aG8gb3duIGd1bnMgd2hvIGRvbid0IGxpdmUgaW4gYW4gYXJlYSB0aGV5IGZlYXI6IiwgcF9oYXQxLCAiXG5Qcm9wb3J0aW9uIG9mIHBlb3BsZSB3aG8gb3duIGd1bnMgd2hvIGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhcjoiLCBwX2hhdDIsICJcbkRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgMiBwcm9wb3J0aW9uczoiLCBwX2RpZmZfaGF0KQ0KYGBgDQoNClNvIHRoZSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgcHJvcG9ydGlvbiBvZiBndW4gb3duZXJzaGlwIGlzIGhpZ2hlciBhbW9uZyB0aG9zZSB3aG8gKmRvbid0KiBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXIuIEkgd291bGQgaGF2ZSBndWVzc2VkIHRoZSBvcHBvc2l0ZS4NCg0KIyMjIDMuMSBTdW1tYXJpemluZyB0aGUgZGF0YQ0KDQpXZSBjYW4gdGFidWxhdGUgdGhlIGRhdGEgZnJvbSB0aGUgdHdvIHBvcHVsYXRpb25zIHNvIHRoYXQgc3Vic2VxdWVudCBjb21wdXRhdGlvbnMgYXJlIGVhc2llciB0byBmb2xsb3cuDQoNCmBgYHtyfQ0KIyBOdW1iZXIgd2hvIGRvbid0IGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhciBhbmQgZG9uJ3Qgb3duIGd1bg0Kbl9ub2ZlYXJfbm9ndW4gPC0gbnJvdyhnc3MyMDE2X2d1bl9mZWFyW2dzczIwMTZfZ3VuX2ZlYXIkZmVhciA9PSAibm8iICYgZ3NzMjAxNl9ndW5fZmVhciRvd25ndW4gPT0gIm5vIixdKQ0KDQojIE51bWJlciB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyIGFuZCByZWZ1c2VkIHRvIGFuc3dlcg0Kbl9ub2ZlYXJfcmVmdXNlZCA8LSBucm93KGdzczIwMTZfZ3VuX2ZlYXJbZ3NzMjAxNl9ndW5fZmVhciRmZWFyID09ICJubyIgJiBnc3MyMDE2X2d1bl9mZWFyJG93bmd1biA9PSAicmVmdXNlZCIsXSkNCg0KIyBOdW1iZXIgd2hvIGRvIGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhciBidXQgZG9uJ3Qgb3duIGd1bg0Kbl9mZWFyX25vZ3VuIDwtIG5yb3coZ3NzMjAxNl9ndW5fZmVhcltnc3MyMDE2X2d1bl9mZWFyJGZlYXIgPT0gInllcyIgJiBnc3MyMDE2X2d1bl9mZWFyJG93bmd1biA9PSAibm8iLF0pDQoNCiMgTnVtYmVyIHdobyBkbyBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXIgYW5kIHJlZnVzZWQgdG8gYW5zd2VyDQpuX2ZlYXJfcmVmdXNlZCA8LSBucm93KGdzczIwMTZfZ3VuX2ZlYXJbZ3NzMjAxNl9ndW5fZmVhciRmZWFyID09ICJ5ZXMiICYgZ3NzMjAxNl9ndW5fZmVhciRvd25ndW4gPT0gInJlZnVzZWQiLF0pDQoNCiMgQ3JlYXRpbmcgb25lIGNvbHVtbiBmb3IgZWFjaCBwb3B1bGF0aW9uDQpuX25vZmVhciA8LSBjKG5fbm9mZWFyX293bmd1biwgbl9ub2ZlYXJfbm9ndW4sIG5fbm9mZWFyX3JlZnVzZWQsIG5fMSwgcF9oYXQxKQ0Kbl9mZWFyIDwtIGMobl9mZWFyX293bmd1biwgbl9mZWFyX25vZ3VuLCBuX2ZlYXJfcmVmdXNlZCwgbl8yLCBwX2hhdDIpDQoNCnN1bW1hcnlfZGYgPC0gZGF0YS5mcmFtZShuX25vZmVhciwgbl9mZWFyKSAjIGNyZWF0aW5nIGRmDQpyb3duYW1lcyhzdW1tYXJ5X2RmKSA8LSBjKCJPd24gZ3VuIiwgIkRvbid0IG93biBndW4iLCAiUmVmdXNlZCB0byBhbnN3ZXIiLCAiVG90YWwiLCAiRXN0aW1hdGUgb2YgcHJvcG9ydGlvbiBvZiBndW4gb3duZXJzaGlwIikNCmNvbG5hbWVzKHN1bW1hcnlfZGYpIDwtIGMoIk5vIEZlYXIiLCAiRmVhciIpDQpzdW1tYXJ5X2RmDQpgYGANCg0KVGhlICJObyBGZWFyIiBwb3B1bGF0aW9uIGlzIGNvbXByaXNlZCBvZiByZXNwb25kZW50cyB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyOyB0aGUgIkZlYXIiIHBvcHVsYXRpb24gaXMgY29tcHJpc2VkIG9mIHRob3NlIHRoYXQgZG8uDQoNCiMjIDQuMCAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBvZiB0aGUgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHByb3BvcnRpb25zIG9mIGd1biBvd25lcnNoaXANCg0KV2UgY2FuIGNvbXB1dGUgYSAkOTVcJSQgY29uZGlmZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9uIG9mIGd1biBvd25lcnNoaXAsICRwX3tkaWZmfSQsIGJldHdlZW4gQW1lcmljYW5zIHdobyBkb24ndCBsaXZlIG5lYXIgYW4gYXJlYSB0aGV5IGZlYXIsIGFuZCB0aG9zZSB0aGF0IGRvLCBieSB1c2luZyB0aGUgW0NlbnRyYWwgTGltaXQgVGhlb3JlbSAoQ0xUKV0oaHR0cDovL3d3dy5zdGF0LndtaWNoLmVkdS9zMTYwL2Jvb2svbm9kZTQzLmh0bWwpLiBUaGUgQ0xUIHNheXMgdGhhdCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgc3RhdGlzdGljLCBpbiB0aGlzIGNhc2UgYSBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMsIGlzIGFwcHJveGltYXRlbHkgbm9ybWFsLCB3aXRoIHRoZSB0cnVlIGRpZmZlcmVuY2UsICRwX3tkaWZmfSQsIGFzIGl0cyBtZWFuLCBhbmQgdGhlIHN0YW5kYXJkIGVycm9yIG9mIHRoZSBzYW1wbGUsICRTRT1cc3FydHtcZnJhY3twXzFcY2RvdCAoMS1wXzEpfXtuXzF9ICsgXGZyYWN7cF8yXGNkb3QgKDEtcF8yKX17bl8yfX0kLCBhcyBpdHMgc3RhbmRhcmQgZGV2aWF0aW9uLCB3aGVyZSAkbl8xJCBhbmQgJG5fMiQgYXJlIHRoZSBzaXplcyBvZiBlYWNoIHNldCBvZiBzYW1wbGVzLiANCg0KDQokJA0KXGhhdHtwfV97ZGlmZn1cc2ltXCBOKG1lYW4gPSBwX3tkaWZmfSwgc2Q9XHNxcnR7XGZyYWN7cF8xXGNkb3QgKDEtcF8xKX17bl8xfSArIFxmcmFje3BfMlxjZG90ICgxLXBfMil9e25fMn19KQ0KJCQNCg0KSWYgd2Ugd2VyZSBhYmxlIHRvIGRyYXcgbWFueSBzYW1wbGVzIGZyb20gYm90aCBwb3B1bGF0aW9ucyAoQW1lcmljYW5zIHdobyBkb24ndCBsaXZlIG5lYXJieSBhbiBhcmVhIHRoZXkgZmVhciwgYW5kIHRob3NlIHRoYXQgZG8pLCBhbmQgY29tcHV0ZWQgdGhlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgYmV0d2VlbiBlYWNoIHR3by1zYW1wbGUgc2V0LCAkXGhhdHtwfV97ZGlmZn09XGhhdHtwXzF9LVxoYXR7cF8yfSQsIHRoZSBDTFQgc2F5cyB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoYXQgcHJvcG9ydGlvbiBkaWZmZXJlbmNlIGlzIG5lYXJseSBub3JtYWwuIFNpbmNlIHdlIHR5cGljYWxseSBkb24ndCBrbm93IGVpdGhlciAkcF8xJCBvciAkcF8yJCwgdGhlIHRydWUgcG9wdWxhdGlvbiBwcm9wb3J0aW9ucyBvZiBndW4gb3duZXJzaGlwLCB3ZSB3aWxsIHVzZSB0aGVpciBwb2ludCBlc3RpbWF0ZXMgJFxoYXR7cH1fMSQgYW5kICRcaGF0e3B9XzIkIGFzIHByb3hpZXMgZm9yIHRoZSBwdXJwb3NlcyBvZiBjb21wdXRpbmcgdGhlIHN0YW5kYXJkIGVycm9yICRTRV97KFxoYXR7cH1fMSAtIFxoYXR7cH1fMil9JCBvZiB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCkluIHJlYWxpdHksIHdlIGNhbiBvbmx5IGRyYXcgb25lIHNhbXBsZSBmcm9tIHRoZSBwb3B1bGF0aW9uLiBXZSB0eXBpY2FsbHkgZG9uJ3Qga25vdyB0aGUgdHJ1ZSBwcm9wb3J0aW9ucyBvZiBndW4gb3duZXJzaGlwIG9mIHRoZSB0d28gcG9wdWxhdGlvbnMsICRwXzEkIGFuZCAkcF8yJC4gV2UgYWxzbyBkb24ndCBrbm93IHdoZXJlIHRoZSBkaWZmZXJlbmNlIGluIHNhbXBsZSBwcm9wb3J0aW9ucyB3ZSBoYXZlIGRyYXduLCAkXGhhdHtwfV97ZGlmZn09XGhhdHtwXzF9LVxoYXR7cF8yfSQsIGZhbGxzIGluIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24sIGJ1dCBmcm9tIHRoZSBDTFQsIHdlIGRvIGtub3cgdGhhdCB0aGUgcHJvcG9ydGlvbnMgb2YgJDk1XCUkIG9mIHRoZSBzYW1wbGVzIGRyYXduIHdpbGwgZmFsbCB3aXRoaW4gJDEuOTZcY2RvdCBcc3FydHtcZnJhY3twXzFcY2RvdCAoMS1wXzEpfXtuXzF9ICsgXGZyYWN7cF8yXGNkb3QgKDEtcF8yKX17bl8yfX09MS45NlxjZG90IFNFJCBvZiAkcF97ZGlmZn0kLiBGb3IgJDk1XCUkIG9mIHRoZSBzYW1wbGVzIHdlIGRyYXcsIGFuIGludGVydmFsIHdpdGhpbiAkMS45NlxjZG90IFxzcXJ0e1xmcmFje1xoYXR7cH1fMVxjZG90ICgxLVxoYXR7cH1fMSl9e25fMX0gKyBcZnJhY3tcaGF0e3B9XzJcY2RvdCAoMS1caGF0e3B9XzIpfXtuXzJ9fT0xLjk2XGNkb3QgU0VfeyhcaGF0e3B9XzEgLSBcaGF0e3B9XzIpfSQgb2YgJFxoYXR7cH1fe2RpZmZ9JCB3aWxsIGluY2x1ZGUgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9uIGJldHdlZW4gdGhlIHR3byBwb3B1bGF0aW9ucy4gRm9yIGFueSB0d28tc2FtcGxlIHNldCB3aG9zZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIGVzdGltYXRlICRcaGF0e3B9X3tkaWZmfSQgZmFsbHMgd2l0aGluICQxLjk2XGNkb3QgU0UkIG9mICRwX3tkaWZmfSQsIHdoaWNoIHdpbGwgaGFwcGVuICQ5NVwlJCBvZiB0aGUgdGltZSwgd2UgYXJlICQ5NVwlJCBjb25maWRlbnQgdGhhdCBhbiBpbnRlcnZhbCBjZW50ZXJlZCBhcm91bmQgJFxoYXR7cH1fe2RpZmZ9JCBhbmQgd2l0aGluICQxLjk2XGNkb3QgU0VfeyhcaGF0e3B9XzEgLSBcaGF0e3B9XzIpfSQgb2YgJFxoYXR7cH1fe2RpZmZ9JCB3aWxsIGNvbnRhaW4gdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiB0aGUgdHdvIHBvcHVsYXRpb25zLg0KDQoqKiQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIG9mIHRoZSBkaWZmZXJlbmNlIGluIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMgb2YgZ3VuIG93bmVyc2hpcDoqKg0KDQokJA0KXGhhdHtwfV97ZGlmZn0gXHBtIDEuOTZcY2RvdCBTRV97KFxoYXR7cH1fMSAtIFxoYXR7cH1fMil9ID0gXGhhdHtwfV97ZGlmZn0gXHBtIDEuOTZcY2RvdCBcc3FydHtcZnJhY3tcaGF0e3B9XzFcY2RvdCAoMS1caGF0e3B9XzEpfXtuXzF9ICsgXGZyYWN7XGhhdHtwfV8yXGNkb3QgKDEtXGhhdHtwfV8yKX17bl8yfX0NCiQkDQoNCiMjIyA0LjEgQW4gZXhhbXBsZQ0KDQpJdCBpcyBtdWNoIGVhc2llciB0byB1bmRlcnN0YW5kIHdpdGggYW4gYWN0dWFsIGV4YW1wbGUgYW5kIGEgcGxvdC4gU3VwcG9zZSB3ZSBoYXZlIHR3byBwb3B1bGF0aW9ucyB3aXRoIHRydWUgcHJvcG9ydGlvbnMgJHBfMT0wLjYkIGFuZCAkcF8yPTAuNSQsIGFuZCBzbyBhIHRydWUgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiAkcF97ZGlmZn09cF8xLXBfMj0wLjEkIGJldHdlZW4gdGhlbSwgYW5kIHdlIGRyYXcgYSBzYW1wbGUgb2Ygc2l6ZSAkbl8xPW5fMj01MDAkIGZyb20gZWFjaCBwb3B1bGF0aW9uLiBQZXIgdGhlIENMVCwgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGlmZmVyZW5jZSBpbiBzYW1wbGUgcHJvcG9ydGlvbnMgdGFrZW4gZnJvbSB0aG9zZSB0d28gcG9wdWxhdGlvbnMgaXMgYXBwcm94aW1hdGVseSBub3JtYWw6ICRcaGF0e3B9X3tkaWZmfVxzaW1cIE4obWVhbiA9IDAuMSwgc2Q9XHNxcnR7XGZyYWN7MC42XGNkb3QgKDEtMC42KX17NTAwfSArIFxmcmFjezAuNVxjZG90ICgxLTAuNSl9ezUwMH19PTAuMDMxMykkLiBBbnkgdHdvLXNhbXBsZSBzZXQgZHJhd24gZnJvbSB0aGUgdHdvIHBvcHVsYXRpb25zIHdob3NlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgZXN0aW1hdGUgJFxoYXR7cH1fe2RpZmZ9JCBmYWxscyB3aXRoaW4gJCgwLjEtMS45NlxjZG90MC4wMzEzLFwgMC4xKzEuOTZcY2RvdDAuMDMxMyk9KDAuMDM4NyxcIDAuMTYxMykkIHdpbGwgaGF2ZSBhICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIHRoYXQgY29udGFpbnMgdGhlIHRydWUgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHByb3BvcnRpb25zLCAkcD0wLjEkLiBJZiB3ZSBkcmF3IGEgc2FtcGxlIGZyb20gZWFjaCBwb3B1bGF0aW9uLCBhbmQgdGhlIHNhbXBsZXMnIHByb3BvcnRpb25zIGFyZSAkXGhhdHtwfV8xPTAuNTgzMyQgYW5kICRcaGF0e3B9XzI9MC40Mzc1JCwgYW5kIHNvIHRoZWlyIGRpZmZlcmVuY2UgaXMgJFxoYXR7cH1fe2RpZmZ9PTAuMTQ1OCQsIHRoZSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBjZW50ZXJlZCBhcm91bmQgJFxoYXR7cH1fe2RpZmZ9PTAuMTQ1OCQgd2lsbCBjb250YWluIHRoZSB0cnVlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgJHBfe2RpZmZ9PTAuMSQuIFNpbmNlIHRoZSBwZXJzb24gdGFraW5nIHRoZSBzYW1wbGVzIHR5cGljYWxseSBkb2Vzbid0IGtub3cgZWl0aGVyICRwXzEkIG9yICRwXzIkLCBzaGUgd2lsbCB1c2UgaGVyIHNhbXBsZXMnICRcaGF0e3B9XzE9MC41ODMzJCBhbmQgJFxoYXR7cH1fMj0wLjQzNzUkIHRvIGNvbXB1dGUgJFNFX3soXGhhdHtwfV8xIC0gXGhhdHtwfV8yKX0kLCBmb3IgdGhlIHB1cnBvc2VzIG9mIGNvbXB1dGluZyB0aGUgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwuICRTRV97KFxoYXR7cH1fMSAtIFxoYXR7cH1fMil9JCB3aWxsIGJlOiAkU0VfeyhcaGF0e3B9XzEgLSBcaGF0e3B9XzIpfT1cc3FydHtcZnJhY3swLjU4MzNcY2RvdCAoMS0wLjU4MzMpfXs1MDB9ICsgXGZyYWN7MC40Mzc1XGNkb3QgKDEtMC40Mzc1KX17NTAwfX09XHNxcnR7NC44NjFlLTQrNC45MjE5ZS00fT0wLjAzMTMkLCBhbmQgdGhlICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIHdpbGwgYmU6ICQoMC4xNDU4LTEuOTZcY2RvdDAuMDMxMyxcIDAuMTQ1OCsxLjk2XGNkb3QwLjAzMTMpPSgwLjA4NDUsXCAwLjIwNzEpJCwgd2hpY2ggY29udGFpbnMgdGhlIHRydWUgcHJvcG9ydGlvbiBkaWZmZXJlbmNlICRwX3tkaWZmfT0wLjEkLg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiNodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbA0KDQpuXzFfZXhhbXBsZSA8LSA1MDA7IG5fMl9leGFtcGxlIDwtIDUwMA0KcF8xIDwtIDAuNjA7IHBfMiA8LSAwLjUwOyBwX2RpZmYgPC0gcF8xIC0gcF8yDQpzZSA8LSBzcXJ0KHBfMSAqICgxIC0gcF8xKSAvIG5fMV9leGFtcGxlICsgcF8yICogKDEgLSBwXzIpIC8gbl8yX2V4YW1wbGUpDQoNCiMgeCA9IHBfZGlmZiArLy0gNCBzdGRfZGV2J3MNCnggPC0gc2VxKC00LDQsbGVuZ3RoPTEwMDApKnNlICsgcF9kaWZmDQpoeCA8LSBkbm9ybSh4LCBwX2RpZmYgLHNlKQ0KDQojIFZhbHVlcyB1c2VkIHRvIHNoYWRlIGFyZWFzIHVuZGVyIHRoZSBjdXJ2ZQ0KdXBwZXJfYm91bmQgPC0gcF9kaWZmICsgMS45NiAqIHNlIA0KbG93ZXJfYm91bmQgPC0gcF9kaWZmIC0gMS45NiAqIHNlIA0KDQpwbG90KHgsIGh4LCB0eXBlPSJuIiwgeGxhYiA9ICIiLCB5bGFiPSIiLCBtYWluPSJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIiwgYXhlcz1GQUxTRSkNCg0KaSA8LSB4ID49IHVwcGVyX2JvdW5kICYgeCA8PSBtYXgoeCkgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA+PSB1cHBlcl9ib3VuZA0KbGluZXMoeCwgaHgpICMgcGxvdHMgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KcG9seWdvbihjKHVwcGVyX2JvdW5kLHhbaV0sbWF4KHgpKSwgYygwLGh4W2ldLDApLCBjb2w9ImdyZXkiKSAjIHNoYWRlcyBhcmVhIGdyZXkgd2hlcmUgeCA+PSB1cHBlcl9ib3VuZA0KDQpqIDwtIHggPj0gbWluKHgpICYgeCA8PSBsb3dlcl9ib3VuZCAjIGluZGV4ZXMgb2YgeCB3aGVyZSB4IDw9IHRoYW4gbG93ZXJfYm91bmQNCnBvbHlnb24oYyhtaW4oeCkseFtqXSxsb3dlcl9ib3VuZCksIGMoMCxoeFtqXSwwKSwgY29sPSJncmV5IikgIyBzaGFkZXMgYXJlYSBncmV5IHdoZXJlIHggPD0gbG93ZXJfYm91bmQNCg0KYXhpcygxLCBhdD1zZXEoMC4wMCwgMC4yLCAwLjAyKSwgcG9zPTApICMgZHJhd3MgYXhpcw0KYWJsaW5lKHY9cF9kaWZmKQ0KZ3JpZCgpDQoNCnBfMV9oYXQgPC0gMC41ODMzOyBwXzJfaGF0IDwtIDAuNDM3NTsgcF9kaWZmX2hhdF9leGFtcGxlIDwtIDAuMTQ1OA0Kc2VfcF9kaWZmX2hhdCA8LSBzcXJ0KHBfMV9oYXQgKiAoMSAtIHBfMV9oYXQpIC8gbl8xX2V4YW1wbGUgKyBwXzJfaGF0ICogKDEgLSBwXzJfaGF0KSAvIG5fMl9leGFtcGxlKQ0KYXhpcygxLCBhdD1jKHBfZGlmZl9oYXRfZXhhbXBsZSAtIDEuOTYgKiBzZV9wX2RpZmZfaGF0LCBwX2RpZmZfaGF0X2V4YW1wbGUsIHBfZGlmZl9oYXRfZXhhbXBsZSArIDEuOTYgKiBzZV9wX2RpZmZfaGF0KSwgcG9zPS0yLjUsIGNvbCA9ICJibHVlIiwgbHdkID0gMiwgbHdkLnRpY2tzID0gMSkgDQoNCnRleHQoeCA9IDAuMDE1LCB5ID0gMTEsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUocFtkaWZmXSwgIiA9IDAuMSIpKSkNCnRleHQoeCA9IDAuMDIsIHkgPSAxMCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuWzFdLCAiID0gIiwgblsyXSwgICIgPSA1MDAiKSkpDQp0ZXh0KHggPSAwLjAyLCB5ID0gOSwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRSwgIiA9IDAuMDMxMyIpKSkNCnRleHQoeCA9IDAuMDIxLCB5ID0gOCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShoYXQocClbZGlmZl0sICIgPSAwLjE0NTgiKSkpDQp0ZXh0KHggPSAwLjAyNSwgeSA9IDYuNSwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRVtoYXQocClbMV0taGF0KHApWzJdXSwgIiA9IDAuMDMxMyIpKSkNCmBgYA0KDQpJZiB3ZSBhcmUgdW5sdWNreSBhbmQgIGRyYXcgc2FtcGxlcyB3aG9zZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zICRcaGF0e3B9X3tkaWZmfSQgZmFsbHMgaW4gdGhlIHNoYWRlZCBhcmVhLCB3aGljaCBzaG91bGQgb25seSBoYXBwZW4gJDVcJSQgb2YgdGhlIHRpbWUsIGl0cyAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCB3aWxsIG5vdCBpbmNsdWRlIHRoZSB0cnVlIGRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbnMgJHBfe2RpZmZ9PTAuMSQuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kbl8xX2V4YW1wbGUgPC0gNTAwOyBuXzJfZXhhbXBsZSA8LSA1MDANCnBfMSA8LSAwLjYwOyBwXzIgPC0gMC41MDsgcF9kaWZmIDwtIHBfMSAtIHBfMg0Kc2UgPC0gc3FydChwXzEgKiAoMSAtIHBfMSkgLyBuXzFfZXhhbXBsZSArIHBfMiAqICgxIC0gcF8yKSAvIG5fMl9leGFtcGxlKQ0KDQojIHggPSBwX2RpZmYgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZSArIHBfZGlmZg0KaHggPC0gZG5vcm0oeCwgcF9kaWZmICxzZSkNCg0KIyBWYWx1ZXMgdXNlZCB0byBzaGFkZSBhcmVhcyB1bmRlciB0aGUgY3VydmUNCnVwcGVyX2JvdW5kIDwtIHBfZGlmZiArIDEuOTYgKiBzZSANCmxvd2VyX2JvdW5kIDwtIHBfZGlmZiAtIDEuOTYgKiBzZSANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWIgPSAiIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSB1cHBlcl9ib3VuZCAmIHggPD0gbWF4KHgpICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCmxpbmVzKHgsIGh4KSAjIHBsb3RzIG5vcm1hbCBkaXN0cmlidXRpb24NCnBvbHlnb24oYyh1cHBlcl9ib3VuZCx4W2ldLG1heCh4KSksIGMoMCxoeFtpXSwwKSwgY29sPSJncmV5IikgIyBzaGFkZXMgYXJlYSBncmV5IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gbG93ZXJfYm91bmQgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA8PSB0aGFuIGxvd2VyX2JvdW5kDQpwb2x5Z29uKGMobWluKHgpLHhbal0sbG93ZXJfYm91bmQpLCBjKDAsaHhbal0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgZ3JleSB3aGVyZSB4IDw9IGxvd2VyX2JvdW5kDQoNCmF4aXMoMSwgYXQ9c2VxKDAuMDAsIDAuMiwgMC4wMiksIHBvcz0wKSAjIGRyYXdzIGF4aXMNCmFibGluZSh2PXBfZGlmZikNCmdyaWQoKQ0KDQpwXzFfaGF0IDwtIDAuNTE7IHBfMl9oYXQgPC0gMC40ODsgcF9kaWZmX2hhdF9leGFtcGxlIDwtIDAuMDMNCnNlX3BfZGlmZl9oYXQgPC0gc3FydChwXzFfaGF0ICogKDEgLSBwXzFfaGF0KSAvIG5fMV9leGFtcGxlICsgcF8yX2hhdCAqICgxIC0gcF8yX2hhdCkgLyBuXzJfZXhhbXBsZSkNCmF4aXMoMSwgYXQ9YyhwX2RpZmZfaGF0X2V4YW1wbGUgLSAxLjk2ICogc2VfcF9kaWZmX2hhdCwgcF9kaWZmX2hhdF9leGFtcGxlLCBwX2RpZmZfaGF0X2V4YW1wbGUgKyAxLjk2ICogc2VfcF9kaWZmX2hhdCksIHBvcz0tMi41LCBjb2wgPSAicmVkIiwgbHdkID0gMiwgbHdkLnRpY2tzID0gMSkgDQoNCnRleHQoeCA9IDAuMDE1LCB5ID0gMTEsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUocFtkaWZmXSwgIiA9IDAuMSIpKSkNCnRleHQoeCA9IDAuMDIsIHkgPSAxMCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuWzFdLCAiID0gIiwgblsyXSwgICIgPSA1MDAiKSkpDQp0ZXh0KHggPSAwLjAyLCB5ID0gOSwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShTRSwgIiA9IDAuMDMxMyIpKSkNCnRleHQoeCA9IDAuMDE3LCB5ID0gOCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShoYXQocClbZGlmZl0sICIgPSAwLjAzIikpKQ0KdGV4dCh4ID0gMC4wMjYsIHkgPSA2LjUsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoU0VbaGF0KHApWzFdLWhhdChwKVsyXV0sICIgPSAwLjAzMTYiKSkpDQpgYGANCg0KDQoNCiMjIyA0LjIgQ29uZGl0aW9ucyBmb3IgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KVGhlIGNvbmRpdGlvbnMgZm9yIHRoZSB2YWxpZGl0eSBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBhcmU6DQoNCjEuIFNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQsIGJvdGggd2l0aGluIGdyb3VwcyBhbmQgYmV0d2VlbiBncm91cHMuDQoNCjIuIEVhY2ggc2FtcGxlIHNob3VsZCBoYXZlIGF0IGxlYXN0IDEwIHN1Y2Nlc3NzZXMgYW5kIDEwIGZhaWx1cmVzOg0KDQokJA0Kbl8xXGNkb3RcaGF0e3B9XzFcZ2VxMTBcIGFuZFwgbl8yXGNkb3QoMSAtIFxoYXR7cH1fMilcZ2VxMTANCiQkDQoNCiQkDQpuXzJcY2RvdFxoYXR7cH1fMlxnZXExMFwgYW5kXCBuXzJcY2RvdCgxIC0gXGhhdHtwfV8yKVxnZXExMA0KJCQNCg0KVG8gdmVyaWZ5IHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBmaXJzdCBhc3N1bXB0aW9uLCB0aGF0IHNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQgd2l0aGluIGdyb3Vwcywgd2UgY2hlY2sgdGhhdCB0aGUgc2FtcGxlZCByZXNwb25kZW50cyB3aXRoaW4gZWFjaCBncm91cCAodGhvc2Ugd2hvIGRvbid0IGxpdmUgd2l0aGluIDEgbWlsZSBvZiBhbiBhcmVhIHRoZXkgZmVhciwgYW5kIHRob3NlIHRoYXQgZG8pIGFyZSByYW5kb21seSBzYW1wbGVkLCBhbmQgZWFjaCBvZiB0aGUgdHdvIHNhbXBsZXMgd2FzIGRvbmUgd2l0aG91dCByZXBsYWNlbWVudCwgYW5kIGVhY2ggc2FtcGxlIHJlcHJlc2VudHMgbGVzcyB0aGFuICQxMFwlJCBvZiB0aGVpciByZXNwZWN0aXZlIHBvcHVsYXRpb25zLiBFLmcuLCBmb3IgdGhlIGdyb3VwIGZyb20gdGhlIHBvcHVsYXRpb24gd2hvIGRvbid0IGxpdmUgbmVhciBhbiBhcmVhIHRoZXkgZmVhciwgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMsIGFib3V0ICQxMzAwJCwgaXMgY2VydGFpbmx5IG11Y2ggbGVzcyB0aGFuICQxMFwlJCBvZiB0aGUgZW50aXJlIFUuUy4gcG9wdWxhdGlvbiB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyLg0KDQpUbyB2ZXJpZnkgdGhlIHNlY29uZCBwYXJ0IG9mIHRoZSBmaXJzdCBhc3N1bXB0aW9uLCB3ZSBub3RlIHRoYXQgYW55IHJlc3BvbmRlbnQgZnJvbSB0aGUgbm8tZmVhciBzYW1wbGUgaXMgaW5kZXBlbmRlbnQgZnJvbSBhbnkgcmVzcG9uZGVudCBmcm9tIHRoZSBmZWFyIHNhbXBsZS4NCg0KTm93IHdlIGNoZWNrIHRoZSB2YWxpZGl0eSBvZiB0aGUgc2Vjb25kIGFzc3VtcHRpb24gYnkgdmVyaWZ5aW5nIHRoZSBzdWNjZXNzLWZhaWx1cmUgY29uZGl0aW9ucyBmb3IgYm90aCBzYW1wbGVzOg0KDQpgYGB7cn0NCnNhbXBsZV8xX3N1Y2Nlc3NlcyA8LSBuXzEgKiBwX2hhdDENCnNhbXBsZV8xX2ZhaWx1cmVzIDwtIG5fMSAqICgxIC0gcF9oYXQxKQ0KDQpzYW1wbGVfMl9zdWNjZXNzZXMgPC0gbl8yICogcF9oYXQyDQpzYW1wbGVfMl9mYWlsdXJlcyA8LSBuXzIgKiAoMSAtIHBfaGF0MikNCg0KY2F0KCJOdW1iZXIgb2Ygc3VjY2Vzc2VzIGluIHRoZSBmaXJzdCBzYW1wbGU6IiwgZmxvb3Ioc2FtcGxlXzFfc3VjY2Vzc2VzKSwgIlxuTnVtYmVyIG9mIGZhaWx1cmVzIGluIHRoZSBmaXJzdCBzYW1wbGU6IiwgZmxvb3Ioc2FtcGxlXzFfZmFpbHVyZXMpLCAiXG5OdW1iZXIgb2Ygc3VjY2Vzc2VzIGluIHRoZSBzZWNvbmQgc2FtcGxlOiIsIGZsb29yKHNhbXBsZV8yX3N1Y2Nlc3NlcyksICJcbk51bWJlciBvZiBmYWlsdXJlcyBpbiB0aGUgc2Vjb25kIHNhbXBsZToiLCBmbG9vcihzYW1wbGVfMl9mYWlsdXJlcykpDQpgYGANCg0KDQojIyMgNC4zIENyaXRpY2FsIHZhbHVlICR6XiokDQoNClRoZSAkel4qJCBjb3JyZXNwb25kaW5nIHRvIGEgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW4gdGhlIFtzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uXShodHRwczovL3d3dy5tYXRoc2lzZnVuLmNvbS9kYXRhL3N0YW5kYXJkLW5vcm1hbC1kaXN0cmlidXRpb24tdGFibGUuaHRtbCkgaXMgYXBwcm94aW1hdGVseSAxLjk2LiBXZSBjYW4gY29tcHV0ZSBpdCBtb3JlIGV4YWN0bHkgdXNpbmcgUjoNCg0KYGBge3J9DQp6X3N0YXIgPC0gcW5vcm0ocCA9IDAuMDI1LCBtZWFuID0gMCwgc2QgPSAxLCBsb3dlci50YWlsID0gRkFMU0UpDQp6X3N0YXINCmBgYA0KDQojIyMgNC40IFN0YW5kYXJkIGVycm9yDQoNCkNvbXB1dGluZyB0aGUgc3RhbmRhcmQgZXJyb3Igb2YgdGhlIHNhbXBsZQ0KYGBge3J9DQpzZSA8LSBzcXJ0KHBfaGF0MSAqICgxIC0gcF9oYXQxKSAvIG5fMSArIHBfaGF0MiAqICgxIC0gcF9oYXQyKSAvIG5fMikNCmNhdCgiU3RhbmRhcmQgZXJyb3Igb2YgdGhlIHNhbXBsZToiLCBzZSkNCmBgYA0KDQojIyMgNC41IENvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KQ29tcHV0aW5nIHRoZSBjb25maWRlbmNlIGludGVydmFsIGJvdW5kcw0KYGBge3J9DQpjb25mX2ludF9sYiA8LSBwX2RpZmZfaGF0IC0gel9zdGFyICogc2UNCmNvbmZfaW50X3ViIDwtIHBfZGlmZl9oYXQgKyB6X3N0YXIgKiBzZQ0KY2F0KCJDb25maWRlbmNlIGludGVydmFsIGxvd2VyIGJvdW5kIiwgY29uZl9pbnRfbGIsICJcbkNvbmZpZGVuY2UgaW50ZXJ2YWwgdXBwZXIgYm91bmQiLCBjb25mX2ludF91YikNCmBgYA0KPGJyPg0KDQpIZW5jZSwgb3VyIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMNCiQkDQowLjA5MDFccG0gMS45NlxjZG90IDAuMDIyMj0oMC4wNDY2LCAwLjEzMzQpDQokJA0KDQpXZSBhcmUgJDk1XCUkIGNvbmZpZGVudCB0aGF0IHRoZSB0cnVlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMgaXMgYmV0d2VlbiAkMC4wNDY2JCBhbmQgJDAuMTMzNCQuDQoNCiMjIDUuMCBIeXBvdGhlc2lzIHRlc3RpbmcNCg0KV2UgY2FuIHVzZSB0aGUgQ0xUIGFuZCB0aGUgZGF0YSBjb2xsZWN0ZWQgdG8gY29uc3RydWN0IGEgaHlwb3RoZXNpcyB0ZXN0aW5nIGZyYW1ld29yay4gVGhlIGh5cG90aGVzaXMgdGVzdCBjb25zaWRlcnMgdHdvIHBvc3NpYmxlIGludGVycHJldGF0aW9ucyBvZiBvdXIgZGF0YSwgYSBudWxsIGh5cG90aGVzaXMgJEhfMCQsIGFuZCBhbiBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzICRIX2EkLiAkSF8wJCBiYXNpY2FsbHkgc2F5cyB0aGF0IHRoZSBzYW1wbGVkIGRhdGEgY291bGQgaGF2ZSBiZWVuIGRyYXduIHNpbXBseSBieSBjaGFuY2UsIGFuZCBzbywgaXQgaXMgbWlzbGVhZGluZy4gVGhlcmUgaXMgIm5vdGhpbmcgZ29pbmcgb24iLiAkSF9hJCB0YWtlcyB0aGUgdmlldyB0aGF0IHRoZSBkYXRhIGNvbGxlY3RlZCByZXZlYWxzIHRoYXQgInNvbWV0aGluZyAqaXMqIGdvaW5nIG9uIi4gV2Ugd2lsbCBlaXRoZXIgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgaW4gZmF2b3Igb2YgdGhpcyBhbHRlcm5hdGl2ZSwgb3Igd2Ugd2lsbCBmYWlsIHRvIHJlamVjdCBpdCBhbmQgY29uY2x1ZGUgdGhlIHNhbXBsZWQgZGF0YSBjb3VsZCBoYXZlIGJlZW4gZHJhd24gc2ltcGx5IGJ5IGNoYW5jZS4gTm90ZSB0aGF0IGV2ZW4gaWYgd2UgZmFpbCB0byByZWplY3QgJEhfMCQsIHRoYXQgZG9lcyBub3QgbWVhbiB3ZSBhY2NlcHQgaXQgYXMgdGhlIGdyb3VuZCB0cnV0aCwgaXQncyBqdXN0IHRoYXQgdGhlIGRhdGEgd2UgaGF2ZSBjb2xsZWN0ZWQgZG9lcyBub3QgYWxsb3dzIHVzIHRvIGRpc2NhcmQgJEhfMCQuDQoNClN1cHBvc2Ugd2Ugd2FudCB0byBmaW5kIG91dCBpZiB0aGUgJDAuMDkwMSQgZGlmZmVyZW5jZSBpbiBwb3B1bGF0aW9uIHByb3BvcnRpb25zIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIE91ciBudWxsIGh5cG90aGVzaXMgJEhfMCQgaXM6DQoNCiQkDQpIXzA6IFRoZVwgdHJ1ZVwgZGlmZmVyZW5jZVwgaW5cIHRoZVwgdHdvXCBwb3B1bGF0aW9uXCBwcm9wb3J0aW9uc1wgcF8xLXBfMj0gcF97ZGlmZn09MA0KXFwNCkhfYTogcF97ZGlmZn1cbmVxIDANCiQkDQoNClRvIHBlcmZvcm0gdGhlIHRlc3QsIHdlIGFzc3VtZSB0aGF0ICRIXzAkIGlzIHRydWUgYW5kIGFzaywgZ2l2ZW4gdGhhdCAkSF8wJCBpcyB0cnVlLCBob3cgcHJvYmFibGUgaXQgaXMgdG8gb2JzZXJ2ZSBkYXRhIGFzIGV4dHJlbWUgb3IgbW9yZSBhcyB0aGUgb25lIHdlIGhhdmUuDQoNCiMjIyA1LjEgVGhlIG51bGwgaHlwb3RoZXNpcyBwcm9wb3J0aW9uICRwX3twb29sfSQNCg0KVW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcyAkSF8wJCwgd2UgYXNzdW1lIHRoZSB0cnVlIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMgJHBfMSQgYW5kICRwXzIkIGFyZSB0aGUgc2FtZSwgYnV0IHdoYXQgYXJlIHRoZXkgZXF1YWwgdG8/IEluIG90aGVyIHdvcmRzLCAkcF8xPXBfMj0/JCBUaGUgc3RhbmRhcmQgZXJyb3IgZm9ybXVsYSB1bmRlciAkSF8wJCBzaG91bGQgdXNlIGEgY29tbW9uIHZhbHVlIHJhdGhlciBmb3IgJHAkIHJhdGhlciB0aGFuIHRoZSAkMiQgZXN0aW1hdGVzICRcaGF0IHBfMSQgYW5kICRcaGF0IHBfMiQsIGdpdmVuIHRoYXQgd2UgYXJlIGFyZ3VpbmcgdGhhdCAkcF8xPXBfMiQuIEEgZ29vZCBwb2ludCBlc3RpbWF0ZSBmb3IgdGhpcyBjb21tb24gdmFsdWUgY2FuIGJlIG9idGFpbmVkIGJ5ICpwb29saW5nKiB0aGUgInN1Y2Nlc3NlcyIgZnJvbSBib3RoIHNhbXBsZXMuIEluIHRoaXMgY2FzZSwgdGhlIHN1Y2Nlc3NlcyBhcmUgdGhlIHJlc3BvbmRlbnRzIGZyb20gYm90aCBncm91cHMgdGhhdCBsaXZlIGluIGEgcGxhY2Ugd2hlcmUgZ3VucyBhcmUga2VwdC4NCg0KJCQNClxoYXR7cH1fe3Bvb2x9PVxmcmFje3RvdGFsXCBudW1iZXJcIG9mXCByZXNwb25kZW50c1wgd2hvXCBvd25cIGd1bnN9e25fMSArIG5fMn0NCiQkDQoNCkNvbXB1dGluZyAkXGhhdHtwfV97cG9vbH0kDQpgYGB7cn0NCnBfcG9vbGVkIDwtIChuX25vZmVhcl9vd25ndW4gKyBuX2ZlYXJfb3duZ3VuKSAvIChuXzEgKyBuXzIpDQpjYXQoIkVzdGltYXRlIG9mIHBvb2xlZCBwcm9wb3J0aW9uOiIsIHBfcG9vbGVkKQ0KYGBgDQoNCg0KVGhlIHN0YW5kYXJkIGVycm9yIGNhbiB0aGVuIGJlIGNvbXB1dGVkIHNpbWlsYXJseSBhcyBiZWZvcmU6DQoNCiQkDQpTRV97cG9vbGVkfT1cc3FydHtcZnJhY3tcaGF0e3B9X3twb29sZWR9XGNkb3QgKDEtXGhhdHtwfV97cG9vbGVkfSl9e25fMX0gKyBcZnJhY3tcaGF0e3B9X3twb29sZWR9XGNkb3QgKDEtXGhhdHtwfV97cG9vbGVkfSl9e25fMn19DQokJA0KDQpDb21wdXRpbmcgJFNFX3twb29sZWR9JDoNCmBgYHtyfQ0Kc2VfcG9vbGVkIDwtIHNxcnQocF9wb29sZWQgKiAoMSAtIHBfcG9vbGVkKSAvIG5fMSArIHBfcG9vbGVkICogKDEgLSBwX3Bvb2xlZCkgLyBuXzIpDQpjYXQoIlN0YW5kYXJkIGVycm9yIHVuZGVyIG51bGwgaHlwb3RoZXNpcyB1c2luZyBwb29sZWQgcHJvcG9ydGlvbiBlc3RpbWF0ZToiLCBzZV9wb29sZWQpDQpgYGANCg0KIyMjIDUuMiBDb25kaXRpb25zIGZvciBoeXBvdGhlc2lzIHRlc3RpbmcNCg0KVGhlIGNvbmRpdGlvbnMgdG8gcGVyZm9ybSB0aGUgaHlwb3RoZXNpcyB0ZXN0IGFyZSBzaW1pbGFyIHRvIHRoZSBvbmVzIHdlIGNoZWNrZWQgdG8gY29tcHV0ZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbC4NCg0KMS4gU2FtcGxlZCBvYnNlcnZhdGlvbnMgbXVzdCBiZSBpbmRlcGVuZGVudCwgYm90aCB3aXRoaW4gZ3JvdXBzIGFuZCBiZXR3ZWVuIGdyb3Vwcy4NCg0KMi4gRWFjaCBzYW1wbGUgc2hvdWxkIGhhdmUgYXQgbGVhc3QgMTAgc3VjY2Vzc3NlcyBhbmQgMTAgZmFpbHVyZXMuIFdlIHVzZSB0aGUgcG9vbGVkIHByb3BvcnRpb24gJFxoYXR7cH1fe3Bvb2x9JCB0byBjb21wdXRlIHRoZSBudW1iZXJzIG9mIHN1Y2Nlc3NlcyBhbmQgZmFpbHVyZXM6DQoNCiQkDQpuXzFcY2RvdFxoYXR7cH1fe3Bvb2x9XGdlcTEwXCBhbmRcIG5fMVxjZG90KDEgLSBcaGF0e3B9X3twb29sfSlcZ2VxMTANCiQkDQoNCiQkDQpuXzJcY2RvdFxoYXR7cH1fe3Bvb2x9XGdlcTEwXCBhbmRcIG5fMlxjZG90KDEgLSBcaGF0e3B9X3twb29sfSlcZ2VxMTANCiQkDQoNClZlcmlmeWluZyB0aGUgc3VjY2Vzcy1mYWlsdXJlIGNvbmRpdGlvbnMgZm9yIGh5cG90aGVzaXMgdGVzdGluZzoNCmBgYHtyfQ0Kc2FtcGxlXzFfc3VjY2Vzc2VzIDwtIG5fMSAqIHBfcG9vbGVkDQpzYW1wbGVfMV9mYWlsdXJlcyA8LSBuXzEgKiAoMSAtIHBfcG9vbGVkKQ0KDQpzYW1wbGVfMl9zdWNjZXNzZXMgPC0gbl8yICogcF9wb29sZWQNCnNhbXBsZV8yX2ZhaWx1cmVzIDwtIG5fMiAqICgxIC0gcF9wb29sZWQpDQoNCmNhdCgiU3VjY2Vzcy1mYWlsdXJlIGNvbmRpdGlvbnMgZm9yIGh5cG90aGVzaXMgdGVzdGluZywgdXNpbmcgcF9wb29sZWQ6IiwgIlxuTnVtYmVyIG9mIHN1Y2Nlc3NlcyBpbiB0aGUgZmlyc3Qgc2FtcGxlOiIsIGZsb29yKHNhbXBsZV8xX3N1Y2Nlc3NlcyksICJcbk51bWJlciBvZiBmYWlsdXJlcyBpbiB0aGUgZmlyc3Qgc2FtcGxlOiIsIGZsb29yKHNhbXBsZV8xX2ZhaWx1cmVzKSwgIlxuTnVtYmVyIG9mIHN1Y2Nlc3NlcyBpbiB0aGUgc2Vjb25kIHNhbXBsZToiLCBmbG9vcihzYW1wbGVfMl9zdWNjZXNzZXMpLCAiXG5OdW1iZXIgb2YgZmFpbHVyZXMgaW4gdGhlIHNlY29uZCBzYW1wbGU6IiwgZmxvb3Ioc2FtcGxlXzJfZmFpbHVyZXMpKQ0KYGBgDQoNCiMjIyA1LjMgVGhlIHAtdmFsdWUNCg0KV2UgaGF2ZSB0byBhc2sgb3Vyc2VsdmVzLCBnaXZlbiB0aGF0IHRoZSBudWxsIGh5cG90aGVzaXMgJEhfMCQgaXMgdHJ1ZSwgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2Ygb2JzZXJ2aW5nIGRhdGEgYXMgZXh0cmVtZSBvciBtb3JlIGFzIHRoZSBvbmUgd2UgaGF2ZT8NCg0KJCQNClAob2JzZXJ2aW5nXCBkYXRhXCBhc1wgZXh0cmVtZVwgb3JcIG1vcmVcIHxcIEhfezB9XCBpc1wgdHJ1ZSkNCiQkDQoNClRoYXQgcHJvYmFiaWxpdHkgaXMgdGhlIHAtdmFsdWUuDQoNCk91ciBoeXBvdGhlc2lzIHRlc3QgaXMgdHdvLXNpZGVkLiBUaGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRoYXQgJHBfe2RpZmZ9PTAkLCBzbyBieSBhc2tpbmcgd2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgJG9ic2VydmluZ1wgZGF0YVwgYXNcIGV4dHJlbWVcIG9yXCBtb3JlJCBpbiBhIHdvcmxkIGluIHdoaWNoIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgdHJ1ZSwgd2UgYXJlIHdvbmRlcmluZyBob3cgcHJvYmFibGUgaXQgaXMgdG8gZHJhdyBhIHNhbXBsZSB3aXRoIGEgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiAkMC4wOTAxJCBvciBoaWdoZXIgbGlrZSB0aGUgb25lIHdlIGhhdmUgZHJhd24sIG9yIG9uZSB3aXRoIGEgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyBvZiAkLTAuMDkwMSQgb3IgbG93ZXIuIExldCdzIHNlZSBpdCBncmFwaGljYWxseS4NCg0KYGBge3J9DQojaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvYWR2Z3JhcGhzL3Byb2JhYmlsaXR5Lmh0bWwNCg0KcF9kaWZmIDwtIDAuMDANCg0KIyB4ID0gcF9kaWZmICsvLSA1IHN0ZF9kZXYncw0KeCA8LSBzZXEoLTUsNSxsZW5ndGg9MTAwMCkqc2VfcG9vbGVkICsgcF9kaWZmDQpoeCA8LSBkbm9ybSh4LCBwX2RpZmYsIHNlX3Bvb2xlZCkNCg0KIyBWYWx1ZXMgdXNlZCB0byBzaGFkZSBhcmVhIHVuZGVyIGN1cnZlDQpsYiA8LSBwX2RpZmZfaGF0OyB1YiA8LSBtYXgoeCkNCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWI9IkRpZmZlcmVuY2UgaW4gcHJvcG9ydGlvbiBvZiBndW4gb3duZXJzaGlwIGJldHdlZW5cbiB0aG9zZSB3aG8gZG9uJ3QgbGl2ZSBuZWFyIGFuIGFyZWEgdGhleSBmZWFyLCBhbmQgdGhvc2UgdGhhdCBkbyIsIHlsYWI9IiIsIG1haW49IlNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB1bmRlciBudWxsIGh5cG90aGVzaXMiLCBheGVzPUZBTFNFKQ0KDQpsaW5lcyh4LCBoeCkgIyBwbG90cyBub3JtYWwgZGlzdHJpYnV0aW9uDQoNCmkgPC0geCA+PSBsYiAmIHggPD0gdWIgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA+PSB0aGFuIGxiDQpwb2x5Z29uKGMobGIseFtpXSx1YiksIGMoMCxoeFtpXSwwKSwgY29sPSJyZWQiKSAjIHNoYWRlcyBhcmVhIHdoZXJlIHggPj0gcF9kaWZmX2hhdCBpbiByZWQNCg0KbGluZXMoeFtpXSwgaHhbaV0sIGx3ZCA9IDQsIGNvbCA9ICJyZWQiKSAjICJzaGFkZXMgYXJlYSIgd2hlcmUgeCA+PSBwX2RpZmZfaGF0IGluIHJlZA0KIyBpbiByZWFsaXR5IGl0J3MganVzdCBkcmF3aW5nIGEgdGhpY2tlciByZWQgbGluZSBvbiB0b3Agb2YgdGhlIG9yaWdpbmFsDQojIHNpbmNlIHNoYWRpbmcgdXNpbmcgdGhlIHBvbHlnb24oKSBmdW5jdGlvbiB3aWxsIHNob3cgbm90aGluZyBiL2MgdGhlIGFyZWEgaXMgc28gc21hbGwNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gLWxiICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPD0gLXBkaWZmX2hhdA0KDQpsaW5lcyh4W2pdLCBoeFtqXSwgbHdkID0gNCwgY29sID0gInJlZCIpICMgInNoYWRlcyBhcmVhIiB3aGVyZSB4IDw9IC1wX2RpZmZfaGF0IGluIHJlZA0KIyBpbiByZWFsaXR5IGl0J3MganVzdCBkcmF3aW5nIGEgdGhpY2tlciByZWQgbGluZSBvbiB0b3Agb2YgdGhlIG9yaWdpbmFsDQojIHNpbmNlIHNoYWRpbmcgdXNpbmcgdGhlIHBvbHlnb24oKSBmdW5jdGlvbiB3aWxsIHNob3cgbm90aGluZyBiL2MgdGhlIGFyZWEgaXMgc28gc21hbGwNCg0KYXhpcygxLCBhdD1zZXEoLTAuMTIsIDAuMTIsIDAuMDEpLCBwb3M9MCkgIyBkcmF3cyBheGlzDQphYmxpbmUodj1wX2RpZmYpDQpncmlkKCkNCmBgYA0KDQpXZSBhcmUgYXNraW5nIGhvdyBwcm9iYWJsZSBpdCBpcyB0byBkcmF3IGEgc2FtcGxlIHdpdGggYSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIHRoYXQgaXMgJDAuMDkwMSQgb3IgbW9yZSBhd2F5IGZyb20gdGhlIGFzc3VtZWQgZGlmZmVyZW5jZSBpbiBwcm9wb3J0aW9ucyAodW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcykgb2YgJDAkLCBpbiBlaXRoZXIgZGlyZWN0aW9uLiBUaGF0IGlzLCAkXGZyYWN7MC4wOTAxfXswLjAyMzB9ID0gMy45MiQgc3RhbmRhcmQgZGV2aWF0aW9ucyBhd2F5IGZyb20gJDAkLiBUaGUgcHJvYmFiaWxpdHkgb2YgdGhhdCBvY2N1cnJpbmcgaXMgdmVyeSBzbWFsbCBpbmRlZWQ7IGl0IGlzIHJlcHJlc2VudGVkIGJ5IHRoZSBzaGFkZWQgYXJlYSBpbiB0aGUgcGxvdC4gSW4gcmVhbGl0eSwgSSBqdXN0IHRoaWNrZW5lZCB0aGUgbGluZSBhbmQgY29sb3JlZCBpdCByZWQgc2luY2UgdGhlIGFyZWEgaXMgdG9vIHNtYWxsIHRvIHNob3cuDQo8YnI+DQoNClVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMsIHdlIGxpdmUgaW4gYSB3b3JsZCBpbiB3aGljaCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb24gb2YgZ3VuIG93bmVyc2hpcCBiZXR3ZWVuIHR3byBncm91cHMgaXMgY2VudGVyZWQgYXQgJHBfe2RpZmZ9ID0gMCQgYW5kIGhhcyBhIHN0YW5kYXJkIGRldmlhdGlvbiBvZiAkMC4wMjMwJC4gSW4gc3VjaCBhIHdvcmxkLCB3ZSBoYXZlIGRyYXduIGEgc2FtcGxlIHdoZXJlIHRoZSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb25zIGlzICRcaGF0e3B9X3tkaWZmfT0wLjA5MDEkLiBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBkcmF3aW5nIGEgc2FtcGxlIHdpdGggYSBkaWZmZXJlbmNlIGluIHByb3BvcnRpb24gJFxoYXR7cH1fe2RpZmZ9JCBhcyBoaWdoIG9yIGhpZ2hlciwgaW4gZWl0aGVyIGRpcmVjdGlvbiwgaW4gYSB3b3JsZCBpbiB3aGljaCB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRydWU/DQoNCiQkDQpQKGRyYXdpbmdcIGFcIHNhbXBsZVwgd2hlcmVcIHRoZVwgZGlmZmVyZW5jZVwgaW5cIHBvcHVsYXRpb25cIHByb3BvcnRpb25zXFwgaXNcIGFzXCBsYXJnZVwgb3JcIGxhcmdlclwgdGhhblwgMC4wOTAxIHxcIEhfezB9XCBpc1wgdHJ1ZSkNClxcDQpQKFxoYXR7cH1fe2RpZmZ9XCBcZ2VxXCAwLjA5MDFcIG9yXCBcaGF0e3B9X3tkaWZmfVwgXGxlcVwgLTAuMDkwMSB8XCBwX3tkaWZmfSA9ICAwKQ0KJCQNCg0KVGhhdCBwcm9iYWJpbGl0eSBpcyB0aGUgYXJlYSB1bmRlciB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHNoYWRlZCBpbiByZWQgaW4gdGhlIHBsb3QgKGFsdGhvdWdoIGl0IGlzIGludmlzaWJsZSBiZWNhdXNlIGl0IGlzIHNvIHNtYWxsKS4gSXQgY2FuIGJlIGNvbXB1dGVkIHVzaW5nIGBwbm9ybSgpYC4NCmBgYHtyfQ0KYXJlYSA8LSAyICogcG5vcm0ocSA9IHBfZGlmZl9oYXQsIG1lYW4gPSBwX2RpZmYsIHNkID0gc2VfcG9vbGVkLCBsb3dlci50YWlsID0gRkFMU0UpDQojIE11bHRpcGxpZWQgYnkgMiBiZWNhdXNlIHRoZSBoeXBvdGhlc2lzIHRlc3QgaXMgdHdvLXNpZGVkLg0KY2F0KCJPdXIgcC12YWx1ZToiLCBhcmVhKQ0KYGBgDQoNCg0KU28gb3VyIFtwLXZhbHVlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QLXZhbHVlKSwgdGhlIHByb2JhYmlsaXR5IG9mIGRyYXdpbmcgYSBzYW1wbGUgd2l0aCAkXGhhdHtwfV97ZGlmZn09MC4wOTAxJCBvciBoaWdoZXIsIG9yIG9uZSAkXGhhdHtwfV97ZGlmZn09LTAuMDkwMSQgb3IgbG93ZXIsIHVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMsIGlzIGFib3V0ICQ4Ljc1M2UtNSQuIEF0IHRoZSAkNVwlJCBzaWduaWZpY2FuY2UgbGV2ZWwsIHdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBiZWNhdXNlIHRoZSBzYW1wbGUgZGF0YSBwcm92aWRlcyBjb252aW5jaW5nIGV2aWRlbmNlIHRvIGRvIHNvLiANCg0KIyMgUmVmZXJlbmNlcw0KDQoxLiDDh2V0aW5rYXlhLVJ1bmRlbCwgTS4gKioqRGF0YSBBbmFseXNpcyBhbmQgU3RhdGlzdGljYWwgSW5mZXJlbmNlKioqLiBTcHJpbmcgMjAxNC4gW0NvdXJzZXJhXShodHRwOi8vd3d3LmNvdXJzZXJhLm9yZykuDQoNCjIuIERpZXosIEQuLCBCYXJyLCBDLiwgw4dldGlua2F5YS1SdW5kZWwsIE0uICoqKk9wZW5JbnRybyBTdGF0aXN0aWNzLCBTZWNvbmQgRWRpdGlvbioqKi4gUERGLg0KDQozLiBOYXZpZGksIFcuICoqKlN0YXRpc3RpY3MgZm9yIGVuZ2luZWVycyBhbmQgc2NpZW50aXN0cywgVGhpcmQgRWRpdGlvbioqKi4gTmV3IFlvcms6IE1jR3JhdyBIaWxsLCAyMDExLg0KDQo0LiBVQ0xBIEluc3RpdHV0ZSBmb3IgRGlnaXRhbCBSZXNlcmFjaCBhbmQgRWR1Y2F0aW9uLCAqKipIT1cgQ0FOIEkgSU5DTFVERSBHUkVFSyBMRVRURVJTIElOIE1ZIFBMT1QgTEFCRUxTPyB8IFIgQ09ERSBGUkFHTUVOVFMqKiouIFJldHJpZXZlZCBmcm9tIFtodHRwczovL3N0YXRzLmlkcmUudWNsYS5lZHVdKGh0dHBzOi8vc3RhdHMuaWRyZS51Y2xhLmVkdS9yL2NvZGVmcmFnbWVudHMvZ3JlZWtfbGV0dGVycy8pDQoNCjUuIEthYmFjb2ZmLCBSLiAqKipQcm9iYWJpbGl0eSBQbG90cyoqKi4gUmV0cmlldmVkIGZyb20gW2h0dHA6Ly93d3cuc3RhdG1ldGhvZHMubmV0XShodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbCkNCg0KNi4gQ2FybG9zIENpbmVsbGkgYW5kIFRvbSwgKioqQ29kZSBjaHVuayBmb250IHNpemUgaW4gUm1hcmtkb3duIHdpdGgga25pdHIgYW5kIGxhdGV4KioqLiBSZXRyaWV2ZWQgZnJvbSBbaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbV0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjU2NDYzMzMvY29kZS1jaHVuay1mb250LXNpemUtaW4tcm1hcmtkb3duLXdpdGgta25pdHItYW5kLWxhdGV4KQ0KDQo3LiBEcmV3Q29ud2F5IGFuZCBDaHJpc3RvcGhlciBEdUJvaXMsICoqKkdldHRpbmcgTGFUZVggaW50byBSIFBsb3RzKioqLiBSZXRyaWV2ZWQgZnJvbSBbaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbV0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTM5NTEwNS9nZXR0aW5nLWxhdGV4LWludG8tci1wbG90cyk=