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 Variable of interest

This notebook is about making inferences about the true average number of hours, \(\mu\), worked per week by Americans employed part-time or full-time. The variable was coded as \(HRS1\) in the GSS Codebook, on page 118. The survey asked: “If working full or part time, how many hours did you work last week, all jobs?”

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 and tabulate some descriptive statistics.

library(foreign) # Used to read STATA (*.DTA) files
gss2016 <- read.dta("GSS2016.DTA")
# The variable we are interested in.
# The NA's were people that were not employed either full-time or part-time.
gss2016_hrs <- gss2016$hrs1[!is.na(gss2016$hrs1)]
num_obs <- length(gss2016_hrs)
sample_mean <- mean(gss2016_hrs)
sample_sd <- sd(gss2016_hrs)
summary_df <- data.frame(c(num_obs, sample_mean, sample_sd))
rownames(summary_df) <- c("Number of observations", "Sample mean", "Sample standard deviation")
colnames(summary_df) <- c("Sample statistics")
summary_df

4.0 \(95\%\) confidence interval of the average number of hours worked

We can compute a \(95\%\) condifence interval for the true average number of hours worked by Americans employed part- or full-time, \(\mu\), by using the Central Limit Theorem (CLT). The CLT says that the sampling distribution of a statistic, in this case a mean, is approximately normal, with the true population average, \(\mu\), as its mean, and the standard error of the sample, \(SE=\frac{\sigma}{\sqrt n}\), as its standard deviation, where \(\sigma\) is the standard deviation of the population and \(n\) the size of each sample.

\[ \bar{x}\sim\ N(mean = \mu, sd=\frac{\sigma}{\sqrt n}) \]

If we were able to draw many samples of equal size of the number of hours worked by Americans employed part- or full-time, and computed the mean of each sample, the CLT says the distribution of that mean is approximately normal.

In reality, we can only draw one sample from the population. We typically don’t know either \(\mu\) or \(\sigma\) of the population. We can use the sample’s standard deviation, \(s\), as a proxy for \(\sigma\), but we still don’t know \(\mu\). We don’t know where the average of the sample we have drawn, \(\bar{x}\), falls in the sampling distribution, but from the CLT, we do know that the means of \(95\%\) of the samples drawn will fall within \(1.96\cdot \frac{s}{\sqrt n}=1.96\cdot SE\) of \(\mu\). Therefore, for \(95\%\) of the samples we draw, an interval within \(1.96\cdot SE\) of \(\bar{x}\) will include the true mean of the population. For any sample whose \(\bar{x}\) falls within \(1.96\cdot SE\) of \(\mu\), which will happen \(95\%\) of the time, we are \(95\%\) confident that an interval centered around \(\bar{x}\) and within \(1.96\cdot SE\) of \(\bar{x}\) will contain the true mean of the population.

4.1 An example

To make the point graphically, suppose we have a population with a true mean \(\mu=10.0\) and \(\sigma=5.0\), and we draw a sample of size \(n=100\). Per the CLT, the distribution of sample means taken from that population is approximately normal: \(\bar{x}\sim\ N(mean = 10.0, sd=\frac{5.0}{\sqrt{100} }=0.5)\). Any sample drawn from the population whose mean \(\bar{x}\) falls within \((10.0-1.96\cdot0.5,\ 10.0+1.96\cdot0.5)=(9.02,\ 10.98)\) will have a \(95\%\) confidence interval that contains the true mean, \(\mu=10.0\). If we draw a sample from the population, and the sample mean \(\bar{x}=10.8\), the \(95\%\) confidence interval centered around \(\bar{x}=10.8\) will contain the true mean \(\mu=10.0\). The \(95\%\) confidence interval will be: \((10.8-1.96\cdot0.5,\ 10.8+1.96\cdot0.5)=(9.82,\ 11.78)\).

If we are unlucky and draw a sample whose mean \(\bar{x}\) falls in the shaded area, which should only happen \(5\%\) of the time, its \(95\%\) confidence interval will not include the true mean \(\mu=10.0\).

4.2 Conditions for the confidence interval

The confidence interval for the true average number of hours worked, \(\mu\), is given by:

\[ \bar{x}\pm z^{*}\cdot SE \]

where \(\bar{x}\) is the mean of the sample, \(z^*\) is the critical value corresponding to the confidence level we want, and the standard error \(SE\) is given by

\[ SE=\frac{s}{\sqrt{n}} \]

where \(s\) is the standard deviation of the sample and \(n\) is the number of observations in the sample.

The conditions for the validity of the confidence interval are:

  1. Sampled observations must be independent.

  2. The sample size is large: \(n\geq 30\)

  3. The distribution of sample observations is not strongly skewed.

The survey respondents are a random subset of the population and are independent of each other. The sample size of \(1646\) is greater than \(30\), so that takes care of the second condition. Finally, we can plot the distribution of the sample to check that it is not strongly skewed either way.

hist(gss2016_hrs, breaks=seq(0,90,5), main = "Distribution of hours worked by Americans each week", xlab = "Hours worked weekly")

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)
cat("z-value corresponding to 95% confidence interval:", z_star)
z-value corresponding to 95% confidence interval: 1.959964

4.4 Standard error of the sample

Next we compute the standard error \(SE=\frac{s}{\sqrt{n}}\):

se = sample_sd / sqrt(num_obs)
cat("Standard error SE =", se)
Standard error SE = 0.3550878

4.5 Confidence interval

We can now compute the confidence interval bounds:

conf_int_lb <- sample_mean - z_star * se
conf_int_ub <- sample_mean + z_star * se
cat("Confidence interval lower bound:", conf_int_lb, "\nConfidence interval upper bound:", conf_int_ub)
Confidence interval lower bound: 40.21838 
Confidence interval upper bound: 41.6103

Hence, our confidence interval is \[ \bar{x}\pm z^{*}\cdot SE=40.9143\pm 1.96\cdot 0.3551=(40.2184, 41.6103) \]

We are \(95\%\) confident that the true mean of hours worked by Americans, \(\mu\), is between \(40.2184\) and \(41.6103\). If we draw \(100\) samples of the number of hours worked by Americans employed part-time or full-time and compute the average and confidence interval for each of the samples, \(95\) of those confidence intervals will contain the true mean, \(\mu\).

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\).

For example, can try to answer whether Americans, on average, work more than 40 hours a week. The framework for the hypothesis test would be as follows:

\[ H_{0}:\mu = 40,\ Americans\ work\ 40\ hours\ a\ week,\ on\ average \\ H_{a}:\mu >40,\ Americans\ work\ more\ than\ 40\ hours\ a\ week,\ on\ average \]

One look at the \(95\%\) confidence interval \((40.2184, 41.6103)\) we just computed tells us we can reject the null hypothesis. Since we are \(95\%\) sure that the true mean \(\mu\) lies between \(40.2184\) and \(41.6103\), we conclude the data provides strong evidence to reject the null. We believe Americans employed part-time or full-time work more than \(40\) hours a week, on average.

5.1 The p-value

The p-value quantifies the strength of the evidence against the null hypothesis. We compute it by asking 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. Typically, we use a \(5\%\) significance level as the threshold to reject the null. If the p-value is less than \(5\%\), we reject the null in favor of the alternative.

For our hypothesis framework, under \(H_0\) and the CLT, \(\bar{x}\) is approximately normally distributed, with a mean \(\mu = 40\) and \(SE=0.3551\). What is the probability of drawing a sample with a mean \(\bar{x}=40.9143\) or higher, given that the null hypothesis is true?

\[ P(drawing\ a\ sample\ where\ the\ average\ number\ of\ hours\ worked\\ is\ 40.9143\ or\ higher\ |\ H_{0}\ is\ true) \\ P(\bar{x}\ \geq\ 40.9143\ |\ \mu = 40.0) \]

We can do it graphically:

#http://www.statmethods.net/advgraphs/probability.html
mu <- 40.0
# x = mu +/- 4 std_dev's
x <- seq(-4,4,length=1000)*se + mu
hx <- dnorm(x, mu ,se)
lb <- sample_mean; ub <- max(x) 
plot(x, hx, type="n", xlab="Average number of hours worked", ylab="", main="Sampling distribution under null hypothesis", axes=FALSE)
i <- x >= lb & x <= ub # indexes of x where x >= than sample_mean
lines(x, hx) # plots normal distribution
polygon(c(lb,x[i],ub), c(0,hx[i],0), col="red") # shades area where x >= sample_mean in red
axis(1, at=seq(38, 42, 0.1), pos=0) # draws axis
abline(v=mu)
grid()

That probability is the area under the sampling distribution shaded in red in the plot. It can be computed using pnorm().

area <- pnorm(q = sample_mean, mean = mu, sd = se, lower.tail = FALSE)
cat("Our p-value:", area)
Our p-value: 0.005012547

So the probability of drawing the sample we have under the null hypothesis is \(0.005\). This is our p-value. There is a \(0.5\%\) chance of drawing the sample data we have if the null hypothesis is true. Therefore, we reject the null hypothesis at the \(5\%\) significance level, and conclude the data provides convincing evidence that Americans employed part-time or full-time work more than 40 hours a week, on average.

We can also ask whether the data provides sufficent evidence that Americans work fewer than \(42\) hours of week, on average. In that case, our null hypothesis is that Americans work \(42\) hours a week, on average, and the alternative hypothesis is that they work fewer.

\[ H_{0}:\mu = 42,\ Americans\ work\ 42\ hours\ a\ week,\ on\ average \\ H_{a}:\mu <42,\ Americans\ work\ fewer\ than\ 42\ hours\ a\ week,\ on\ average \]

Again we draw the sampling distribution under the null hypothesis

mu <- 42.0
# x = mu +/- 4 std_dev's
x <- seq(-4,4,length=1000)*se + mu
hx <- dnorm(x, mu ,se)
lb <- min(x); ub <- sample_mean 
plot(x, hx, type="n", xlab="Average number of hours worked", ylab="", main="Sampling distribution under null hypothesis", axes=FALSE)
i <- x >= lb & x <= ub # indexes of x where x <= than sample_mean
lines(x, hx) # plots normal distribution
polygon(c(lb,x[i],ub), c(0,hx[i],0), col="red") # shades area where x <= sample_mean in red
axis(1, at=seq(40, 44, 0.1), pos=0) # draws axis
abline(v=mu)
grid()

Under the null hypothesis and the CLT, we live in a world in which the sampling distribution of average number of hours worked is centered at \(\mu = 42.0\) and has a standard deviation of \(se=0.3551\). In such a world, we have drawn a sample where the mean is \(\bar{x}=\) \(40.9143\) hours worked. What is the probability of drawing a sample with a mean \(\bar{x}\) as low or lower, if in fact \(\mu=42.0\)?

\[ P(drawing\ a\ sample\ where\ the\ average\ number\ of\ hours\ worked\\ is\ 40.9143\ or\ lower\ |\ H_{0}\ is\ true) \\ P(\bar{x}\ \leq\ 40.9143\ |\ \mu = 42.0) \]

Looking at the tiny red area in the plot, we can surmise it’s pretty small probability. It can be computed using pnorm().

area <- pnorm(q = sample_mean, mean = mu, sd = se, lower.tail = TRUE)
cat("Our p-value:", area)
Our p-value: 0.001116155

So our p-value, the probability of drawing a sample where the average number of hours is \(40.9143\) or fewer under the null hypothesis, is about \(0.001\). Therefore, we reject the null hypothesis at the \(5\%\) significance level, and conclude the data collected provides convincing evidence that Americans work fewer than \(42\) hours a week, on average.

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

LS0tDQp0aXRsZTogIkluZmVyZW5jZSBvbiBhIHBvcHVsYXRpb24gbWVhbiINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KYm9keSwgdGQgew0KICAgZm9udC1zaXplOiAxOHB4Ow0KfQ0KaDEgew0KICBmb250LXNpemU6IDMycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDIgew0KICBmb250LXNpemU6IDI4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDMgew0KICBmb250LXNpemU6IDI0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KaDQgew0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KY29kZS5yew0KICBmb250LXNpemU6IDE2cHg7DQp9DQpwcmUgew0KICBmb250LXNpemU6IDE2cHgNCn0NCjwvc3R5bGU+DQoNCiMjIDEuMCBJbnRyb2R1Y3Rpb24NCg0KVGhlIFtHZW5lcmFsIFNvY2lhbCBTdXJ2ZXkgKEdTUyldKGh0dHA6Ly9nc3Mubm9yYy5vcmcvKSBpcyBhIHNvY2lvbG9naWNhbCBzdXJ2ZXkgdXNlZCB0byBjb2xsZWN0IGRhdGEgb24gYSB3aWRlIHZhcmlldHkgb2YgZGVtb2dyYXBoaWMgY2hhcmFjdGVyaXN0aWNzIGFuZCBhdHRpdHVkZXMgb2YgcmVzaWRlbnRzIG9mIHRoZSBVbml0ZWQgU3RhdGVzLiBUaGUgZGF0YSBoYXMgYmVlbiBjb2xsZWN0ZWQgc2luY2UgMTk3MiwgYXBwcm94aW1hdGVseSBldmVyeSAyIHllYXJzLCBieSB0aGUgW05hdGlvbmFsIE9waW5pb24gUmVzZWFyY2ggQ2VudGVyIChOT1JDKV0oaHR0cDovL3d3dy5ub3JjLm9yZy9QYWdlcy9kZWZhdWx0LmFzcHgpIGF0IHRoZSBVbml2ZXJzaXR5IG9mIENoaWNhZ28uIFRoZSBsYXRlc3QgZGF0YSBpcyBmcm9tIHRoZSBzcHJpbmcgb2YgMjAxNi4gVGhlIGRhdGEgZm9yIHRoZSBlYWNoIHllYXIgdGhlIHN1cnZleSB3YXMgY2FycmllZCBvdXQgY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwOi8vZ3NzLm5vcmMub3JnL2dldC10aGUtZGF0YS9zdGF0YSkgaW4gU1RBVEEgZm9ybWF0LCBhbmQgW2hlcmVdKGh0dHA6Ly9nc3Mubm9yYy5vcmcvZ2V0LXRoZS1kYXRhL3Nwc3MpIGluIFNQU1MgZm9ybWF0LiBUaGUgW0dTUyBDb2RlYm9va10oaHR0cDovL2dzcy5ub3JjLm9yZy9HZXQtRG9jdW1lbnRhdGlvbiksIGluIFBERiBmb3JtYXQsIGRvY3VtZW50cyB0aGUgc3VydmV5IGRhdGEgZm9yIGFsbCB5ZWFycy4gVGhlIFIgbm90ZWJvb2sgY2FuIGJlIGZvdW5kIGluIHRoZSBwcm9qZWN04oCZcyBbR2l0aHViIHBhZ2VdKGh0dHBzOi8vZ2l0aHViLmNvbS9jYXJsb3Nyb3Ivc3RhdC1pbmYtbWVhbnMpLg0KDQoNCiMjIDIuMCBWYXJpYWJsZSBvZiBpbnRlcmVzdA0KDQpUaGlzIG5vdGVib29rIGlzIGFib3V0IG1ha2luZyBpbmZlcmVuY2VzIGFib3V0IHRoZSB0cnVlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzLCAkXG11JCwgd29ya2VkIHBlciB3ZWVrIGJ5IEFtZXJpY2FucyBlbXBsb3llZCBwYXJ0LXRpbWUgb3IgZnVsbC10aW1lLiBUaGUgdmFyaWFibGUgd2FzIGNvZGVkIGFzICRIUlMxJCBpbiB0aGUgW0dTUyBDb2RlYm9va10oaHR0cDovL2dzcy5ub3JjLm9yZy9kb2N1bWVudHMvY29kZWJvb2svR1NTX0NvZGVib29rX21haW5ib2R5LnBkZiksIG9uIHBhZ2UgMTE4LiBUaGUgc3VydmV5IGFza2VkOiAqKiJJZiB3b3JraW5nIGZ1bGwgb3IgcGFydCB0aW1lLCBob3cgbWFueSBob3VycyBkaWQgeW91IHdvcmsgbGFzdCB3ZWVrLCBhbGwgam9icz8iKioNCg0KDQojIyAzLjAgUmVhZGluZyB0aGUgZGF0YQ0KDQpUaGUgUiBsaWJyYXJ5IFsqKmZvcmVpZ24qKl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2ZvcmVpZ24vZm9yZWlnbi5wZGYpIGFsbG93cyBSIHRvIHJlYWQgaW4gU1RBVEEgZmlsZXMsIGFtb25nIG90aGVycy4gV2UgY2FuIHRoZW4gZ2V0IHRoZSB2YXJpYWJsZSB3ZSB3YW50IGFzIGEgc2luZ2xlIGNvbHVtbnMgdmVjdG9yIGFuZCB0YWJ1bGF0ZSBzb21lIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MuIA0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShmb3JlaWduKSAjIFVzZWQgdG8gcmVhZCBTVEFUQSAoKi5EVEEpIGZpbGVzDQpnc3MyMDE2IDwtIHJlYWQuZHRhKCJHU1MyMDE2LkRUQSIpDQojIFRoZSB2YXJpYWJsZSB3ZSBhcmUgaW50ZXJlc3RlZCBpbi4NCiMgVGhlIE5BJ3Mgd2VyZSBwZW9wbGUgdGhhdCB3ZXJlIG5vdCBlbXBsb3llZCBlaXRoZXIgZnVsbC10aW1lIG9yIHBhcnQtdGltZS4NCmdzczIwMTZfaHJzIDwtIGdzczIwMTYkaHJzMVshaXMubmEoZ3NzMjAxNiRocnMxKV0NCg0KbnVtX29icyA8LSBsZW5ndGgoZ3NzMjAxNl9ocnMpDQpzYW1wbGVfbWVhbiA8LSBtZWFuKGdzczIwMTZfaHJzKQ0Kc2FtcGxlX3NkIDwtIHNkKGdzczIwMTZfaHJzKQ0Kc3VtbWFyeV9kZiA8LSBkYXRhLmZyYW1lKGMobnVtX29icywgc2FtcGxlX21lYW4sIHNhbXBsZV9zZCkpDQpyb3duYW1lcyhzdW1tYXJ5X2RmKSA8LSBjKCJOdW1iZXIgb2Ygb2JzZXJ2YXRpb25zIiwgIlNhbXBsZSBtZWFuIiwgIlNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24iKQ0KY29sbmFtZXMoc3VtbWFyeV9kZikgPC0gYygiU2FtcGxlIHN0YXRpc3RpY3MiKQ0Kc3VtbWFyeV9kZg0KYGBgDQoNCg0KIyMgNC4wICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBob3VycyB3b3JrZWQNCg0KV2UgY2FuIGNvbXB1dGUgYSAkOTVcJSQgY29uZGlmZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHRydWUgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgd29ya2VkIGJ5IEFtZXJpY2FucyBlbXBsb3llZCBwYXJ0LSBvciBmdWxsLXRpbWUsICRcbXUkLCBieSB1c2luZyB0aGUgW0NlbnRyYWwgTGltaXQgVGhlb3JlbSAoQ0xUKV0oaHR0cDovL3d3dy5zdGF0LndtaWNoLmVkdS9zMTYwL2Jvb2svbm9kZTQzLmh0bWwpLiBUaGUgQ0xUIHNheXMgdGhhdCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgc3RhdGlzdGljLCBpbiB0aGlzIGNhc2UgYSBtZWFuLCBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbCwgd2l0aCB0aGUgdHJ1ZSBwb3B1bGF0aW9uIGF2ZXJhZ2UsICRcbXUkLCBhcyBpdHMgbWVhbiwgYW5kIHRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgc2FtcGxlLCAkU0U9XGZyYWN7XHNpZ21hfXtcc3FydCBufSQsIGFzIGl0cyBzdGFuZGFyZCBkZXZpYXRpb24sIHdoZXJlICRcc2lnbWEkIGlzIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHBvcHVsYXRpb24gYW5kICRuJCB0aGUgc2l6ZSBvZiBlYWNoIHNhbXBsZS4gDQoNCiQkDQpcYmFye3h9XHNpbVwgTihtZWFuID0gXG11LCBzZD1cZnJhY3tcc2lnbWF9e1xzcXJ0IG59KQ0KJCQNCg0KSWYgd2Ugd2VyZSBhYmxlIHRvIGRyYXcgbWFueSBzYW1wbGVzIG9mIGVxdWFsIHNpemUgb2YgdGhlIG51bWJlciBvZiBob3VycyB3b3JrZWQgYnkgQW1lcmljYW5zIGVtcGxveWVkIHBhcnQtIG9yIGZ1bGwtdGltZSwgYW5kIGNvbXB1dGVkIHRoZSBtZWFuIG9mIGVhY2ggc2FtcGxlLCB0aGUgQ0xUIHNheXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGF0IG1lYW4gaXMgYXBwcm94aW1hdGVseSBub3JtYWwuDQoNCkluIHJlYWxpdHksIHdlIGNhbiBvbmx5IGRyYXcgb25lIHNhbXBsZSBmcm9tIHRoZSBwb3B1bGF0aW9uLiBXZSB0eXBpY2FsbHkgZG9uJ3Qga25vdyBlaXRoZXIgJFxtdSQgb3IgJFxzaWdtYSQgb2YgdGhlIHBvcHVsYXRpb24uIFdlIGNhbiB1c2UgdGhlIHNhbXBsZSdzIHN0YW5kYXJkIGRldmlhdGlvbiwgJHMkLCBhcyBhIHByb3h5IGZvciAkXHNpZ21hJCwgYnV0IHdlIHN0aWxsIGRvbid0IGtub3cgJFxtdSQuIFdlIGRvbid0IGtub3cgd2hlcmUgdGhlIGF2ZXJhZ2Ugb2YgdGhlIHNhbXBsZSB3ZSBoYXZlIGRyYXduLCAkXGJhcnt4fSQsIGZhbGxzIGluIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24sIGJ1dCBmcm9tIHRoZSBDTFQsIHdlIGRvIGtub3cgdGhhdCB0aGUgbWVhbnMgb2YgJDk1XCUkIG9mIHRoZSBzYW1wbGVzIGRyYXduIHdpbGwgZmFsbCB3aXRoaW4gJDEuOTZcY2RvdCBcZnJhY3tzfXtcc3FydCBufT0xLjk2XGNkb3QgU0UkIG9mICRcbXUkLiBUaGVyZWZvcmUsIGZvciAkOTVcJSQgb2YgdGhlIHNhbXBsZXMgd2UgZHJhdywgYW4gaW50ZXJ2YWwgd2l0aGluICQxLjk2XGNkb3QgU0UkIG9mICRcYmFye3h9JCB3aWxsIGluY2x1ZGUgdGhlIHRydWUgbWVhbiBvZiB0aGUgcG9wdWxhdGlvbi4gRm9yIGFueSBzYW1wbGUgd2hvc2UgJFxiYXJ7eH0kIGZhbGxzIHdpdGhpbiAkMS45NlxjZG90IFNFJCBvZiAkXG11JCwgd2hpY2ggd2lsbCBoYXBwZW4gJDk1XCUkIG9mIHRoZSB0aW1lLCB3ZSBhcmUgJDk1XCUkIGNvbmZpZGVudCB0aGF0IGFuIGludGVydmFsIGNlbnRlcmVkIGFyb3VuZCAkXGJhcnt4fSQgYW5kIHdpdGhpbiAkMS45NlxjZG90IFNFJCBvZiAkXGJhcnt4fSQgd2lsbCBjb250YWluIHRoZSB0cnVlIG1lYW4gb2YgdGhlIHBvcHVsYXRpb24uDQoNCiMjIyA0LjEgQW4gZXhhbXBsZQ0KDQpUbyBtYWtlIHRoZSBwb2ludCBncmFwaGljYWxseSwgc3VwcG9zZSB3ZSBoYXZlIGEgcG9wdWxhdGlvbiB3aXRoIGEgdHJ1ZSBtZWFuICRcbXU9MTAuMCQgYW5kICRcc2lnbWE9NS4wJCwgYW5kIHdlIGRyYXcgYSBzYW1wbGUgb2Ygc2l6ZSAkbj0xMDAkLiBQZXIgdGhlIENMVCwgdGhlIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgbWVhbnMgdGFrZW4gZnJvbSB0aGF0IHBvcHVsYXRpb24gaXMgYXBwcm94aW1hdGVseSBub3JtYWw6ICRcYmFye3h9XHNpbVwgTihtZWFuID0gMTAuMCwgc2Q9XGZyYWN7NS4wfXtcc3FydHsxMDB9IH09MC41KSQuIEFueSBzYW1wbGUgZHJhd24gZnJvbSB0aGUgcG9wdWxhdGlvbiB3aG9zZSBtZWFuICRcYmFye3h9JCBmYWxscyB3aXRoaW4gJCgxMC4wLTEuOTZcY2RvdDAuNSxcIDEwLjArMS45NlxjZG90MC41KT0oOS4wMixcIDEwLjk4KSQgd2lsbCBoYXZlIGEgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgdGhhdCBjb250YWlucyB0aGUgdHJ1ZSBtZWFuLCAkXG11PTEwLjAkLiBJZiB3ZSBkcmF3IGEgc2FtcGxlIGZyb20gdGhlIHBvcHVsYXRpb24sIGFuZCB0aGUgc2FtcGxlIG1lYW4gJFxiYXJ7eH09MTAuOCQsIHRoZSAkOTVcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBjZW50ZXJlZCBhcm91bmQgJFxiYXJ7eH09MTAuOCQgd2lsbCBjb250YWluIHRoZSB0cnVlIG1lYW4gJFxtdT0xMC4wJC4gVGhlICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIHdpbGwgYmU6ICQoMTAuOC0xLjk2XGNkb3QwLjUsXCAxMC44KzEuOTZcY2RvdDAuNSk9KDkuODIsXCAxMS43OCkkLg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiNodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbA0KDQpuIDwtIDEwMDsgc2lnbWEgPC0gNS4wDQptdSA8LSAxMC4wOyBzZSA8LSBzaWdtYSAvIHNxcnQobikNCg0KIyB4ID0gbXUgKy8tIDQgc3RkX2RldidzDQp4IDwtIHNlcSgtNCw0LGxlbmd0aD0xMDAwKSpzZSArIG11DQpoeCA8LSBkbm9ybSh4LCBtdSAsc2UpDQoNCnVwcGVyX2JvdW5kIDwtIG11ICsgMS45NiAqIHNlIA0KbG93ZXJfYm91bmQgPC0gbXUgLSAxLjk2ICogc2UgDQoNCnBsb3QoeCwgaHgsIHR5cGU9Im4iLCB4bGFiID0gIiIsIHlsYWI9IiIsIG1haW49IlNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBhIG1lYW4iLCBheGVzPUZBTFNFKQ0KDQppIDwtIHggPj0gdXBwZXJfYm91bmQgJiB4IDw9IG1heCh4KSAjIGluZGV4ZXMgb2YgeCB3aGVyZSB4ID49IHVwcGVyX2JvdW5kDQpsaW5lcyh4LCBoeCkgIyBwbG90cyBub3JtYWwgZGlzdHJpYnV0aW9uDQpwb2x5Z29uKGModXBwZXJfYm91bmQseFtpXSxtYXgoeCkpLCBjKDAsaHhbaV0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgd2hlcmUgeCA+PSB1cHBlcl9ib3VuZCByZWQNCg0KaiA8LSB4ID49IG1pbih4KSAmIHggPD0gbG93ZXJfYm91bmQgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA8PSBsb3dlcl9ib3VuZA0KcG9seWdvbihjKG1pbih4KSx4W2pdLGxvd2VyX2JvdW5kKSwgYygwLGh4W2pdLDApLCBjb2w9ImdyZXkiKSAjIHNoYWRlcyBhcmVhIHdoZXJlIHggPD0gbG93ZXJfYm91bmQgcmVkDQoNCmF4aXMoMSwgYXQ9c2VxKDgsIDEyLCAwLjIpLCBwb3M9MCkgIyBkcmF3cyBheGlzDQphYmxpbmUodj1tdSkNCmdyaWQoKQ0KDQp4X2JhciA8LSAxMC44DQpheGlzKDEsIGF0PWMoeF9iYXIgLSAxLjk2ICogc2UsIHhfYmFyLCB4X2JhciArIDEuOTYgKiBzZSksIHBvcz0tMC4xNSwgY29sID0gImJsdWUiLCBsd2QgPSAyLCBsd2QudGlja3MgPSAxKSANCg0KdGV4dCh4ID0gOC4yLCB5ID0gMC43LCBsYWJlbHMgPSBleHByZXNzaW9uKHBhc3RlKG11LCAiID0gMTAuMCIpKSkNCnRleHQoeCA9IDguMiwgeSA9IDAuNjQsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoc2lnbWEsICIgPSAgNS4wIikpKQ0KdGV4dCh4ID0gOC4yLCB5ID0gMC41OCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuLCAiID0gMTAwIikpKQ0KdGV4dCh4ID0gOC4yLCB5ID0gMC41MiwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShiYXIoeCksICIgPTEwLjgiKSkpDQpgYGANCg0KSWYgd2UgYXJlIHVubHVja3kgYW5kICBkcmF3IGEgc2FtcGxlIHdob3NlIG1lYW4gJFxiYXJ7eH0kIGZhbGxzIGluIHRoZSBzaGFkZWQgYXJlYSwgd2hpY2ggc2hvdWxkIG9ubHkgaGFwcGVuICQ1XCUkIG9mIHRoZSB0aW1lLCBpdHMgJDk1XCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgd2lsbCBub3QgaW5jbHVkZSB0aGUgdHJ1ZSBtZWFuICRcbXU9MTAuMCQuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KI2h0dHA6Ly93d3cuc3RhdG1ldGhvZHMubmV0L2FkdmdyYXBocy9wcm9iYWJpbGl0eS5odG1sDQoNCm4gPC0gMTAwOyBzaWdtYSA8LSA1LjANCm11IDwtIDEwLjA7IHNlIDwtIHNpZ21hIC8gc3FydChuKQ0KDQojIHggPSBtdSArLy0gNCBzdGRfZGV2J3MNCnggPC0gc2VxKC00LDQsbGVuZ3RoPTEwMDApKnNlICsgbXUNCmh4IDwtIGRub3JtKHgsIG11ICxzZSkNCg0KdXBwZXJfYm91bmQgPC0gbXUgKyAxLjk2ICogc2UgDQpsb3dlcl9ib3VuZCA8LSBtdSAtIDEuOTYgKiBzZSANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWIgPSAiIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIGEgbWVhbiIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSB1cHBlcl9ib3VuZCAmIHggPD0gbWF4KHgpICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPj0gdXBwZXJfYm91bmQNCmxpbmVzKHgsIGh4KSAjIHBsb3RzIG5vcm1hbCBkaXN0cmlidXRpb24NCnBvbHlnb24oYyh1cHBlcl9ib3VuZCx4W2ldLG1heCh4KSksIGMoMCxoeFtpXSwwKSwgY29sPSJncmV5IikgIyBzaGFkZXMgYXJlYSB3aGVyZSB4ID49IHVwcGVyX2JvdW5kIHJlZA0KDQpqIDwtIHggPj0gbWluKHgpICYgeCA8PSBsb3dlcl9ib3VuZCAjIGluZGV4ZXMgb2YgeCB3aGVyZSB4IDw9IGxvd2VyX2JvdW5kDQpwb2x5Z29uKGMobWluKHgpLHhbal0sbG93ZXJfYm91bmQpLCBjKDAsaHhbal0sMCksIGNvbD0iZ3JleSIpICMgc2hhZGVzIGFyZWEgd2hlcmUgeCA8PSBsb3dlcl9ib3VuZCByZWQNCg0KYXhpcygxLCBhdD1zZXEoOCwgMTIsIDAuMiksIHBvcz0wKSAjIGRyYXdzIGF4aXMNCmFibGluZSh2PW11KQ0KZ3JpZCgpDQoNCnhfYmFyIDwtIDguOQ0KYXhpcygxLCBhdD1jKHhfYmFyIC0gMS45NiAqIHNlLCB4X2JhciwgeF9iYXIgKyAxLjk2ICogc2UpLCBwb3M9LTAuMTUsIGNvbCA9ICJyZWQiLCBsd2QgPSAyLCBsd2QudGlja3MgPSAxKSANCg0KdGV4dCh4ID0gOC4yLCB5ID0gMC43LCBsYWJlbHMgPSBleHByZXNzaW9uKHBhc3RlKG11LCAiID0gMTAuMCIpKSkNCnRleHQoeCA9IDguMiwgeSA9IDAuNjQsIGxhYmVscyA9IGV4cHJlc3Npb24ocGFzdGUoc2lnbWEsICIgPSAgNS4wIikpKQ0KdGV4dCh4ID0gOC4yLCB5ID0gMC41OCwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShuLCAiID0gMTAwIikpKQ0KdGV4dCh4ID0gOC4yLCB5ID0gMC41MiwgbGFiZWxzID0gZXhwcmVzc2lvbihwYXN0ZShiYXIoeCksICIgPSAgOC45IikpKQ0KYGBgDQoNCiMjIyA0LjIgQ29uZGl0aW9ucyBmb3IgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KVGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSB0cnVlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHdvcmtlZCwgJFxtdSQsIGlzIGdpdmVuIGJ5Og0KDQokJA0KXGJhcnt4fVxwbSB6XnsqfVxjZG90IFNFDQokJA0KDQp3aGVyZSAkXGJhcnt4fSQgaXMgdGhlIG1lYW4gb2YgdGhlIHNhbXBsZSwgJHpeKiQgaXMgdGhlIGNyaXRpY2FsIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGNvbmZpZGVuY2UgbGV2ZWwgd2Ugd2FudCwgYW5kIHRoZSBzdGFuZGFyZCBlcnJvciAkU0UkIGlzIGdpdmVuIGJ5IA0KDQokJA0KU0U9XGZyYWN7c317XHNxcnR7bn19DQokJA0KDQp3aGVyZSAkcyQgaXMgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgc2FtcGxlIGFuZCAkbiQgaXMgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgaW4gdGhlIHNhbXBsZS4NCg0KVGhlIGNvbmRpdGlvbnMgZm9yIHRoZSB2YWxpZGl0eSBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBhcmU6DQoNCjEuIFNhbXBsZWQgb2JzZXJ2YXRpb25zIG11c3QgYmUgaW5kZXBlbmRlbnQuDQoNCjIuIFRoZSBzYW1wbGUgc2l6ZSBpcyBsYXJnZTogJG5cZ2VxIDMwJA0KDQozLiBUaGUgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBvYnNlcnZhdGlvbnMgaXMgbm90IHN0cm9uZ2x5IHNrZXdlZC4NCg0KVGhlIHN1cnZleSByZXNwb25kZW50cyBhcmUgYSByYW5kb20gc3Vic2V0IG9mIHRoZSBwb3B1bGF0aW9uIGFuZCBhcmUgaW5kZXBlbmRlbnQgb2YgZWFjaCBvdGhlci4gVGhlIHNhbXBsZSBzaXplIG9mICQxNjQ2JCBpcyBncmVhdGVyIHRoYW4gJDMwJCwgc28gdGhhdCB0YWtlcyBjYXJlIG9mIHRoZSBzZWNvbmQgY29uZGl0aW9uLiBGaW5hbGx5LCB3ZSBjYW4gcGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgdG8gY2hlY2sgdGhhdCBpdCBpcyBub3Qgc3Ryb25nbHkgc2tld2VkIGVpdGhlciB3YXkuDQoNCmBgYHtyfQ0KaGlzdChnc3MyMDE2X2hycywgYnJlYWtzPXNlcSgwLDkwLDUpLCBtYWluID0gIkRpc3RyaWJ1dGlvbiBvZiBob3VycyB3b3JrZWQgYnkgQW1lcmljYW5zIGVhY2ggd2VlayIsIHhsYWIgPSAiSG91cnMgd29ya2VkIHdlZWtseSIpDQpgYGANCg0KIyMjIDQuMyBDcml0aWNhbCB2YWx1ZSAkel4qJA0KDQpUaGUgJHpeKiQgY29ycmVzcG9uZGluZyB0byBhICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsIGluIHRoZSBbc3RhbmRhcmQgbm9ybWFsIGRpc3RyaWJ1dGlvbl0oaHR0cHM6Ly93d3cubWF0aHNpc2Z1bi5jb20vZGF0YS9zdGFuZGFyZC1ub3JtYWwtZGlzdHJpYnV0aW9uLXRhYmxlLmh0bWwpIGlzIGFwcHJveGltYXRlbHkgMS45Ni4gV2UgY2FuIGNvbXB1dGUgaXQgbW9yZSBleGFjdGx5IHVzaW5nIFI6DQoNCmBgYHtyfQ0Kel9zdGFyIDwtIHFub3JtKHAgPSAwLjAyNSwgbWVhbiA9IDAsIHNkID0gMSwgbG93ZXIudGFpbCA9IEZBTFNFKQ0KY2F0KCJ6LXZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWw6Iiwgel9zdGFyKQ0KYGBgDQoNCiMjIyA0LjQgU3RhbmRhcmQgZXJyb3Igb2YgdGhlIHNhbXBsZQ0KDQpOZXh0IHdlIGNvbXB1dGUgdGhlIHN0YW5kYXJkIGVycm9yICRTRT1cZnJhY3tzfXtcc3FydHtufX0kOg0KDQpgYGB7cn0NCnNlID0gc2FtcGxlX3NkIC8gc3FydChudW1fb2JzKQ0KY2F0KCJTdGFuZGFyZCBlcnJvciBTRSA9Iiwgc2UpDQpgYGANCg0KIyMjIDQuNSBDb25maWRlbmNlIGludGVydmFsDQoNCldlIGNhbiBub3cgY29tcHV0ZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBib3VuZHM6DQoNCmBgYHtyfQ0KY29uZl9pbnRfbGIgPC0gc2FtcGxlX21lYW4gLSB6X3N0YXIgKiBzZQ0KY29uZl9pbnRfdWIgPC0gc2FtcGxlX21lYW4gKyB6X3N0YXIgKiBzZQ0KY2F0KCJDb25maWRlbmNlIGludGVydmFsIGxvd2VyIGJvdW5kOiIsIGNvbmZfaW50X2xiLCAiXG5Db25maWRlbmNlIGludGVydmFsIHVwcGVyIGJvdW5kOiIsIGNvbmZfaW50X3ViKQ0KYGBgDQoNCg0KSGVuY2UsIG91ciBjb25maWRlbmNlIGludGVydmFsIGlzDQokJA0KXGJhcnt4fVxwbSB6XnsqfVxjZG90IFNFPTQwLjkxNDNccG0gMS45NlxjZG90IDAuMzU1MT0oNDAuMjE4NCwgNDEuNjEwMykNCiQkDQoNCldlIGFyZSAkOTVcJSQgY29uZmlkZW50IHRoYXQgdGhlIHRydWUgbWVhbiBvZiBob3VycyB3b3JrZWQgYnkgQW1lcmljYW5zLCAkXG11JCwgaXMgYmV0d2VlbiAkNDAuMjE4NCQgYW5kICQ0MS42MTAzJC4gSWYgd2UgZHJhdyAkMTAwJCBzYW1wbGVzIG9mIHRoZSBudW1iZXIgb2YgaG91cnMgd29ya2VkIGJ5IEFtZXJpY2FucyBlbXBsb3llZCBwYXJ0LXRpbWUgb3IgZnVsbC10aW1lIGFuZCBjb21wdXRlIHRoZSBhdmVyYWdlIGFuZCBjb25maWRlbmNlIGludGVydmFsIGZvciBlYWNoIG9mIHRoZSBzYW1wbGVzLCAkOTUkIG9mIHRob3NlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIHdpbGwgY29udGFpbiB0aGUgdHJ1ZSBtZWFuLCAkXG11JC4NCg0KIyMgNS4wIEh5cG90aGVzaXMgdGVzdGluZw0KDQpXZSBjYW4gdXNlIHRoZSBDTFQgYW5kIHRoZSBkYXRhIGNvbGxlY3RlZCB0byBjb25zdHJ1Y3QgYSBoeXBvdGhlc2lzIHRlc3RpbmcgZnJhbWV3b3JrLiBUaGUgaHlwb3RoZXNpcyB0ZXN0IGNvbnNpZGVycyB0d28gcG9zc2libGUgaW50ZXJwcmV0YXRpb25zIG9mIG91ciBkYXRhLCBhIG51bGwgaHlwb3RoZXNpcyAkSF8wJCwgYW5kIGFuIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgJEhfYSQuICRIXzAkIGJhc2ljYWxseSBzYXlzIHRoYXQgdGhlIHNhbXBsZWQgZGF0YSBjb3VsZCBoYXZlIGJlZW4gZHJhd24gc2ltcGx5IGJ5IGNoYW5jZSwgYW5kIHNvLCBpdCBpcyBtaXNsZWFkaW5nLiBUaGVyZSBpcyAibm90aGluZyBnb2luZyBvbiIuICRIX2EkIHRha2VzIHRoZSB2aWV3IHRoYXQgdGhlIGRhdGEgY29sbGVjdGVkIHJldmVhbHMgdGhhdCAic29tZXRoaW5nICppcyogZ29pbmcgb24iLiBXZSB3aWxsIGVpdGhlciByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBpbiBmYXZvciBvZiB0aGlzIGFsdGVybmF0aXZlLCBvciB3ZSB3aWxsIGZhaWwgdG8gcmVqZWN0IGl0IGFuZCBjb25jbHVkZSB0aGUgc2FtcGxlZCBkYXRhIGNvdWxkIGhhdmUgYmVlbiBkcmF3biBzaW1wbHkgYnkgY2hhbmNlLiBOb3RlIHRoYXQgZXZlbiBpZiB3ZSBmYWlsIHRvIHJlamVjdCAkSF8wJCwgdGhhdCBkb2VzIG5vdCBtZWFuIHdlIGFjY2VwdCBpdCBhcyB0aGUgZ3JvdW5kIHRydXRoLCBpdCdzIGp1c3QgdGhhdCB0aGUgZGF0YSB3ZSBoYXZlIGNvbGxlY3RlZCBkb2VzIG5vdCBhbGxvd3MgdXMgdG8gZGlzY2FyZCAkSF8wJC4NCjxicj4NCg0KRm9yIGV4YW1wbGUsIGNhbiB0cnkgdG8gYW5zd2VyIHdoZXRoZXIgQW1lcmljYW5zLCBvbiBhdmVyYWdlLCB3b3JrIG1vcmUgdGhhbiA0MCBob3VycyBhIHdlZWsuIFRoZSBmcmFtZXdvcmsgZm9yIHRoZSBoeXBvdGhlc2lzIHRlc3Qgd291bGQgYmUgYXMgZm9sbG93czoNCg0KJCQNCkhfezB9OlxtdSA9IDQwLFwgQW1lcmljYW5zXCB3b3JrXCA0MFwgaG91cnNcIGFcIHdlZWssXCBvblwgYXZlcmFnZQ0KXFwNCkhfe2F9OlxtdSA+NDAsXCBBbWVyaWNhbnNcIHdvcmtcIG1vcmVcIHRoYW5cIDQwXCBob3Vyc1wgYVwgd2VlayxcIG9uXCBhdmVyYWdlIA0KJCQNCg0KT25lIGxvb2sgYXQgdGhlICQ5NVwlJCBjb25maWRlbmNlIGludGVydmFsICQoNDAuMjE4NCwgNDEuNjEwMykkIHdlIGp1c3QgY29tcHV0ZWQgdGVsbHMgdXMgd2UgY2FuIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLiBTaW5jZSB3ZSBhcmUgJDk1XCUkIHN1cmUgdGhhdCB0aGUgdHJ1ZSBtZWFuICRcbXUkIGxpZXMgYmV0d2VlbiAkNDAuMjE4NCQgYW5kICQ0MS42MTAzJCwgd2UgY29uY2x1ZGUgdGhlIGRhdGEgcHJvdmlkZXMgc3Ryb25nIGV2aWRlbmNlIHRvIHJlamVjdCB0aGUgbnVsbC4gV2UgYmVsaWV2ZSBBbWVyaWNhbnMgZW1wbG95ZWQgcGFydC10aW1lIG9yIGZ1bGwtdGltZSB3b3JrIG1vcmUgdGhhbiAkNDAkIGhvdXJzIGEgd2Vlaywgb24gYXZlcmFnZS4NCg0KIyMjIDUuMSBUaGUgcC12YWx1ZQ0KDQpUaGUgcC12YWx1ZSBxdWFudGlmaWVzIHRoZSBzdHJlbmd0aCBvZiB0aGUgZXZpZGVuY2UgYWdhaW5zdCB0aGUgbnVsbCBoeXBvdGhlc2lzLiBXZSBjb21wdXRlIGl0IGJ5IGFza2luZyBvdXJzZWx2ZXMsIGdpdmVuIHRoYXQgdGhlIG51bGwgaHlwb3RoZXNpcyAkSF8wJCBpcyB0cnVlLCB3aGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBvYnNlcnZpbmcgZGF0YSBhcyBleHRyZW1lIG9yIG1vcmUgYXMgdGhlIG9uZSB3ZSBoYXZlLg0KDQokJA0KUChvYnNlcnZpbmdcIGRhdGFcIGFzXCBleHRyZW1lXCBvclwgbW9yZVwgfFwgSF97MH1cIGlzXCB0cnVlKQ0KJCQNCg0KVGhhdCBwcm9iYWJpbGl0eSBpcyB0aGUgcC12YWx1ZS4gVHlwaWNhbGx5LCB3ZSB1c2UgYSAkNVwlJCBzaWduaWZpY2FuY2UgbGV2ZWwgYXMgdGhlIHRocmVzaG9sZCB0byByZWplY3QgdGhlIG51bGwuIElmIHRoZSBwLXZhbHVlIGlzIGxlc3MgdGhhbiAkNVwlJCwgd2UgcmVqZWN0IHRoZSBudWxsIGluIGZhdm9yIG9mIHRoZSBhbHRlcm5hdGl2ZS4NCg0KRm9yIG91ciBoeXBvdGhlc2lzIGZyYW1ld29yaywgdW5kZXIgJEhfMCQgYW5kIHRoZSBDTFQsICRcYmFye3h9JCBpcyBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLCB3aXRoIGEgbWVhbiAkXG11ID0gNDAkIGFuZCAkU0U9MC4zNTUxJC4gV2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2YgZHJhd2luZyBhIHNhbXBsZSB3aXRoIGEgbWVhbiAkXGJhcnt4fT00MC45MTQzJCBvciBoaWdoZXIsIGdpdmVuIHRoYXQgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0cnVlPw0KDQokJA0KUChkcmF3aW5nXCBhXCBzYW1wbGVcIHdoZXJlXCB0aGVcIGF2ZXJhZ2VcIG51bWJlclwgb2ZcIGhvdXJzXCB3b3JrZWRcXCBpc1wgNDAuOTE0M1wgb3JcIGhpZ2hlclwgfFwgSF97MH1cIGlzXCB0cnVlKQ0KXFwNClAoXGJhcnt4fVwgXGdlcVwgNDAuOTE0M1wgfFwgXG11ID0gIDQwLjApDQokJA0KDQpXZSBjYW4gZG8gaXQgZ3JhcGhpY2FsbHk6DQpgYGB7cn0NCiNodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbA0KDQptdSA8LSA0MC4wDQoNCiMgeCA9IG11ICsvLSA0IHN0ZF9kZXYncw0KeCA8LSBzZXEoLTQsNCxsZW5ndGg9MTAwMCkqc2UgKyBtdQ0KaHggPC0gZG5vcm0oeCwgbXUgLHNlKQ0KDQpsYiA8LSBzYW1wbGVfbWVhbjsgdWIgPC0gbWF4KHgpIA0KDQpwbG90KHgsIGh4LCB0eXBlPSJuIiwgeGxhYj0iQXZlcmFnZSBudW1iZXIgb2YgaG91cnMgd29ya2VkIiwgeWxhYj0iIiwgbWFpbj0iU2FtcGxpbmcgZGlzdHJpYnV0aW9uIHVuZGVyIG51bGwgaHlwb3RoZXNpcyIsIGF4ZXM9RkFMU0UpDQoNCmkgPC0geCA+PSBsYiAmIHggPD0gdWIgIyBpbmRleGVzIG9mIHggd2hlcmUgeCA+PSB0aGFuIHNhbXBsZV9tZWFuDQpsaW5lcyh4LCBoeCkgIyBwbG90cyBub3JtYWwgZGlzdHJpYnV0aW9uDQpwb2x5Z29uKGMobGIseFtpXSx1YiksIGMoMCxoeFtpXSwwKSwgY29sPSJyZWQiKSAjIHNoYWRlcyBhcmVhIHdoZXJlIHggPj0gc2FtcGxlX21lYW4gaW4gcmVkDQoNCmF4aXMoMSwgYXQ9c2VxKDM4LCA0MiwgMC4xKSwgcG9zPTApICMgZHJhd3MgYXhpcw0KYWJsaW5lKHY9bXUpDQpncmlkKCkNCg0KYGBgDQoNClRoYXQgcHJvYmFiaWxpdHkgaXMgdGhlIGFyZWEgdW5kZXIgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBzaGFkZWQgaW4gcmVkIGluIHRoZSBwbG90LiBJdCBjYW4gYmUgY29tcHV0ZWQgdXNpbmcgYHBub3JtKClgLg0KYGBge3J9DQphcmVhIDwtIHBub3JtKHEgPSBzYW1wbGVfbWVhbiwgbWVhbiA9IG11LCBzZCA9IHNlLCBsb3dlci50YWlsID0gRkFMU0UpDQpjYXQoIk91ciBwLXZhbHVlOiIsIGFyZWEpDQpgYGANCg0KU28gdGhlIHByb2JhYmlsaXR5IG9mIGRyYXdpbmcgdGhlIHNhbXBsZSB3ZSBoYXZlIHVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgJDAuMDA1JC4gVGhpcyBpcyBvdXIgW3AtdmFsdWVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1AtdmFsdWUpLiBUaGVyZSBpcyBhICQwLjVcJSQgY2hhbmNlIG9mIGRyYXdpbmcgdGhlIHNhbXBsZSBkYXRhIHdlIGhhdmUgaWYgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0cnVlLiBUaGVyZWZvcmUsIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIGF0IHRoZSAkNVwlJCBzaWduaWZpY2FuY2UgbGV2ZWwsIGFuZCBjb25jbHVkZSB0aGUgZGF0YSBwcm92aWRlcyBjb252aW5jaW5nIGV2aWRlbmNlIHRoYXQgQW1lcmljYW5zIGVtcGxveWVkIHBhcnQtdGltZSBvciBmdWxsLXRpbWUgd29yayBtb3JlIHRoYW4gNDAgaG91cnMgYSB3ZWVrLCBvbiBhdmVyYWdlLg0KDQpXZSBjYW4gYWxzbyBhc2sgd2hldGhlciB0aGUgZGF0YSBwcm92aWRlcyBzdWZmaWNlbnQgZXZpZGVuY2UgdGhhdCBBbWVyaWNhbnMgd29yayBmZXdlciB0aGFuICQ0MiQgaG91cnMgb2Ygd2Vlaywgb24gYXZlcmFnZS4gSW4gdGhhdCBjYXNlLCBvdXIgbnVsbCBoeXBvdGhlc2lzIGlzIHRoYXQgQW1lcmljYW5zIHdvcmsgJDQyJCBob3VycyBhIHdlZWssIG9uIGF2ZXJhZ2UsIGFuZCB0aGUgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyBpcyB0aGF0IHRoZXkgd29yayBmZXdlci4NCg0KJCQNCkhfezB9OlxtdSA9IDQyLFwgQW1lcmljYW5zXCB3b3JrXCA0MlwgaG91cnNcIGFcIHdlZWssXCBvblwgYXZlcmFnZQ0KXFwNCkhfe2F9OlxtdSA8NDIsXCBBbWVyaWNhbnNcIHdvcmtcIGZld2VyXCB0aGFuXCA0MlwgaG91cnNcIGFcIHdlZWssXCBvblwgYXZlcmFnZQ0KJCQNCg0KQWdhaW4gd2UgZHJhdyB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHVuZGVyIHRoZSBudWxsIGh5cG90aGVzaXMNCmBgYHtyfQ0KbXUgPC0gNDIuMA0KDQojIHggPSBtdSArLy0gNCBzdGRfZGV2J3MNCnggPC0gc2VxKC00LDQsbGVuZ3RoPTEwMDApKnNlICsgbXUNCmh4IDwtIGRub3JtKHgsIG11ICxzZSkNCg0KbGIgPC0gbWluKHgpOyB1YiA8LSBzYW1wbGVfbWVhbiANCg0KcGxvdCh4LCBoeCwgdHlwZT0ibiIsIHhsYWI9IkF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIHdvcmtlZCIsIHlsYWI9IiIsIG1haW49IlNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB1bmRlciBudWxsIGh5cG90aGVzaXMiLCBheGVzPUZBTFNFKQ0KDQppIDwtIHggPj0gbGIgJiB4IDw9IHViICMgaW5kZXhlcyBvZiB4IHdoZXJlIHggPD0gdGhhbiBzYW1wbGVfbWVhbg0KbGluZXMoeCwgaHgpICMgcGxvdHMgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KcG9seWdvbihjKGxiLHhbaV0sdWIpLCBjKDAsaHhbaV0sMCksIGNvbD0icmVkIikgIyBzaGFkZXMgYXJlYSB3aGVyZSB4IDw9IHNhbXBsZV9tZWFuIGluIHJlZA0KDQpheGlzKDEsIGF0PXNlcSg0MCwgNDQsIDAuMSksIHBvcz0wKSAjIGRyYXdzIGF4aXMNCmFibGluZSh2PW11KQ0KZ3JpZCgpDQpgYGANCg0KVW5kZXIgdGhlIG51bGwgaHlwb3RoZXNpcyBhbmQgdGhlIENMVCwgd2UgbGl2ZSBpbiBhIHdvcmxkIGluIHdoaWNoIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgYXZlcmFnZSBudW1iZXIgb2YgaG91cnMgd29ya2VkIGlzIGNlbnRlcmVkIGF0ICRcbXUgPSA0Mi4wJCBhbmQgaGFzIGEgc3RhbmRhcmQgZGV2aWF0aW9uIG9mICRzZT0wLjM1NTEkLiBJbiBzdWNoIGEgd29ybGQsIHdlIGhhdmUgZHJhd24gYSBzYW1wbGUgd2hlcmUgdGhlIG1lYW4gaXMgJFxiYXJ7eH09JCAkNDAuOTE0MyQgaG91cnMgd29ya2VkLiBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBvZiBkcmF3aW5nIGEgc2FtcGxlIHdpdGggYSBtZWFuICRcYmFye3h9JCBhcyBsb3cgb3IgbG93ZXIsIGlmIGluIGZhY3QgJFxtdT00Mi4wJD8gDQoNCiQkDQpQKGRyYXdpbmdcIGFcIHNhbXBsZVwgd2hlcmVcIHRoZVwgYXZlcmFnZVwgbnVtYmVyXCBvZlwgaG91cnNcIHdvcmtlZFxcIGlzXCA0MC45MTQzXCBvclwgbG93ZXJcIHxcIEhfezB9XCBpc1wgdHJ1ZSkNClxcDQpQKFxiYXJ7eH1cIFxsZXFcIDQwLjkxNDNcIHxcIFxtdSA9ICA0Mi4wKQ0KJCQNCg0KTG9va2luZyBhdCB0aGUgdGlueSByZWQgYXJlYSBpbiB0aGUgcGxvdCwgd2UgY2FuIHN1cm1pc2UgaXQncyBwcmV0dHkgc21hbGwgcHJvYmFiaWxpdHkuIEl0IGNhbiBiZSBjb21wdXRlZCB1c2luZyBgcG5vcm0oKWAuDQoNCmBgYHtyfQ0KYXJlYSA8LSBwbm9ybShxID0gc2FtcGxlX21lYW4sIG1lYW4gPSBtdSwgc2QgPSBzZSwgbG93ZXIudGFpbCA9IFRSVUUpDQpjYXQoIk91ciBwLXZhbHVlOiIsIGFyZWEpDQpgYGANCg0KU28gb3VyIFtwLXZhbHVlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QLXZhbHVlKSwgdGhlIHByb2JhYmlsaXR5IG9mIGRyYXdpbmcgYSBzYW1wbGUgd2hlcmUgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIGlzICQ0MC45MTQzJCBvciBmZXdlciB1bmRlciB0aGUgbnVsbCBoeXBvdGhlc2lzLCBpcyBhYm91dCAkMC4wMDEkLiBUaGVyZWZvcmUsIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIGF0IHRoZSAkNVwlJCBzaWduaWZpY2FuY2UgbGV2ZWwsIGFuZCBjb25jbHVkZSB0aGUgZGF0YSBjb2xsZWN0ZWQgcHJvdmlkZXMgY29udmluY2luZyBldmlkZW5jZSB0aGF0IEFtZXJpY2FucyB3b3JrIGZld2VyIHRoYW4gJDQyJCBob3VycyBhIHdlZWssIG9uIGF2ZXJhZ2UuDQoNCiMjIFJlZmVyZW5jZXMNCg0KMS4gw4dldGlua2F5YS1SdW5kZWwsIE0uICoqKkRhdGEgQW5hbHlzaXMgYW5kIFN0YXRpc3RpY2FsIEluZmVyZW5jZSoqKi4gU3ByaW5nIDIwMTQuIFtDb3Vyc2VyYV0od3d3LmNvdXJzZXJhLm9yZykuDQoNCjIuIERpZXosIEQuLCBCYXJyLCBDLiwgw4dldGlua2F5YS1SdW5kZWwsIE0uICoqKk9wZW5JbnRybyBTdGF0aXN0aWNzLCBTZWNvbmQgRWRpdGlvbioqKi4gUERGLg0KDQozLiBOYXZpZGksIFcuICoqKlN0YXRpc3RpY3MgZm9yIGVuZ2luZWVycyBhbmQgc2NpZW50aXN0cywgVGhpcmQgRWRpdGlvbioqKi4gTmV3IFlvcms6IE1jR3JhdyBIaWxsLCAyMDExLg0KDQo0LiBVQ0xBIEluc3RpdHV0ZSBmb3IgRGlnaXRhbCBSZXNlcmFjaCBhbmQgRWR1Y2F0aW9uLCAqKipIT1cgQ0FOIEkgSU5DTFVERSBHUkVFSyBMRVRURVJTIElOIE1ZIFBMT1QgTEFCRUxTPyB8IFIgQ09ERSBGUkFHTUVOVFMqKiouIFJldHJpZXZlZCBmcm9tIFtodHRwczovL3N0YXRzLmlkcmUudWNsYS5lZHVdKGh0dHBzOi8vc3RhdHMuaWRyZS51Y2xhLmVkdS9yL2NvZGVmcmFnbWVudHMvZ3JlZWtfbGV0dGVycy8pDQoNCjUuIEthYmFjb2ZmLCBSLiAqKipQcm9iYWJpbGl0eSBQbG90cyoqKi4gUmV0cmlldmVkIGZyb20gW2h0dHA6Ly93d3cuc3RhdG1ldGhvZHMubmV0XShodHRwOi8vd3d3LnN0YXRtZXRob2RzLm5ldC9hZHZncmFwaHMvcHJvYmFiaWxpdHkuaHRtbCkNCg0KNi4gQ2FybG9zIENpbmVsbGkgYW5kIFRvbSwgKioqQ29kZSBjaHVuayBmb250IHNpemUgaW4gUm1hcmtkb3duIHdpdGgga25pdHIgYW5kIGxhdGV4KioqLiBSZXRyaWV2ZWQgZnJvbSBbaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbV0oaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjU2NDYzMzMvY29kZS1jaHVuay1mb250LXNpemUtaW4tcm1hcmtkb3duLXdpdGgta25pdHItYW5kLWxhdGV4KQ==