Material Adapted from “Statistics of One and Two Samples”” by M.J. Crawley

Source: “Statistics: An Introduction Using R”

Some concepts to disscuss before working on the handout:

  1. Which of your variables is the response variable?

A dependent variable

  1. Which are the explanatory variables?

Variables that explain a model or a response variable e.g years_educ explaining salary.

  1. Are the explanatory variables continuous or categorical, or a mixture of both?

Both

e.g

Number_infections= intercept+region+income+pop+ufo2010+e

After the first run we learned that neither region nor ufo2010 is significant at a 5% sig level

Notes: region is categorical (east,west,central)and ufo is numerical

Number_infections=intercept+income+population+e

We then learned that the adjusted R square of the first model is higher than the one from model 2.

A potential solution might be creating an interaction term

pop_ufo=population*ufo2010

Number_infections=intercept+income+pop_ufo+e

Note: We just created an interaction term (numeric)

We then just learned that my Adjusted R-squared barely went up. My team believes that the variable to be considered should be region…

Let us create a new interaction term

pop_region=pop*region

  1. What kind of response variable have you got: is it a continuous measurement, a count, a proportion, a time-at-death or a category ?

We can have all of them

Estimating Parameters from Data

Data have a number of important properties, and it is useful to be able to quantify the following attributes:

Sample Size

In R, you find the size of a vector using length(name). The number of measurements of the response variable is known universally as \(n\).

Central Tendency

Averages from repeated bouts of sampling show a remarkable tendency to cluster around the arithmetic mean (central limit theorem).

The mode is the most frequently represented class of data. The median is the value of the response variable that lies in the middle of the ranked set of \(y\) values. It has the great advantage of not being sensitive to outliers. The (arithmetic) mean is the sum of the observations divided by the sample size.

Measuring Variation

A measure of variability is perhaps the most important quantity in statistical analysis. The greater the variability in the data, the greater will be our uncertainty in the values of parameters estimated from the data, and the lower will be our ability to distinguish between competing hypotheses about the data.

Consider the following data, y, which are simply plotted in the order in which they were measured:

y <- c(13,7,5,12,9,15,6,1,9,7,12)
# Plot data 
plot(y, ylim = c(0,18)) 

Visual inspection indicates substantial variation in y. But how to measure it? One way would be to specify the range of y values.

range(y) 
[1]  1 15

The minimum value of y is 1 and the maximum is 15. The variability is contained within the range, and to that extent it is a very useful measure. But it is not ideal for general purposes. For one thing, it is totally determined by outliers, and gives us no indication of more typical levels of variation.

How about fitting the average value of y through the data and measuring how far each individual y value departs from the mean?

plot(y, ylim = c(0,18)) 
# 2nd parameter says the slope of the fitted line is 0
abline(mean(y),0)

This divides the data into 5 points that are larger than the mean and 7 points that are smaller than the mean.

The sum of squares (differences) is the basis of all the measures of variability used in linear statistical analysis:

\[ \sum d^ 2 = \sum (y - \bar{y})^2 \]

We could not calculate \(\sum d^2\) before we knew the value of the mean \(\bar{y}\). And how did we know the value of \(\bar{y}\)? Well we did not know the value, we estimated it from the data. This leads us into a very important concept: degrees of freedom.

Degrees of Freedom: degrees of freedom (d.o.f) is the sample size, \(n\), minus the number of parameters, \(p\), estimated from the data.

In a linear regression we estimate two parameters from the data when we fit the model: \(y = mx + b\)

the intercept, \(b\), and the slope \(m\). Because we have estimated 2 parameters, we have \(n-2\) d.o.f

In a one way analysis of variance with 5 genotypes, we estimate 5 means from the data (one for each genotype) so we have \(n-5\) d.o.f. And so on.

Variance

Variance, denoted by \(s^2\), is defined as the sum of squares divided by the number of degrees of freedom:

\[ s^2 = \frac{\sum (y - \bar{y})^2}{n-1} \]

Example

The data in the following table come from 3 market gardens. The data show the ozone concentrations in parts per hundred million (pphm) on ten summer days. (hint:Create a csv file with the information listed in the table)

Garden A Garden B Garden C
3 5 3
4 5 3
4 6 2
3 7 1
2 4 10
3 4 4
1 3 3
3 5 11
5 6 3
2 5 10

We want to calculate the variance in ozone concentration for each garden

# Garden A
A <- c(3,4,4,3,2,3,1,3,5,2) 
# Garden B
B <- c(5,5,6,7,4,4,3,5,6,5) 
# Garden C
C <- c(3,3,2,1,10,4,3,11,3,10) 

We can use the function var() to find the variance:

s2A <- var(A)
s2B <- var(B)
s2C <- var(C)
# print the variances
c(s2A, s2B, s2C)
[1]  1.333333  1.333333 14.222222
# print the means
mean(A)
[1] 3
mean(B)
[1] 5
mean(C)
[1] 5

There are three important points to be made from this example:

  • two populations can have different means but the same variance (Gardens A & B)

  • two populations can have the same mean but different variances (Gardens B & C)

Is it a bad idea comparing means when the variances are different?Explain.

ratio_CB <- s2C/s2B
# is it bigger than 4 times the smaller variance?
ratio_CB > 4*s2B
[1] TRUE

Using Variance

We can use variance in two main ways:

Consider the properties that you would like a measure of unreliability to possess. - As the variance of the data increases what would happen to unreliability of estimated parameters ? - Would it go up or down ? - Unreliability would go up as variance increased, so we would want to have the variance on the top of any divisions in our formula for unreliability (i.e. in the numerator).

\(unreliability \propto s^2\)

What about sample size? - Would you want your estimate of unreliability to go up or down as sample size, \(n\), increased ? - You would want unreliability to go down as sample size went up, so you would put sample size on the bottom of the formula for unreliability (i.e. in the denominator)

\(unreliability \propto \frac{s^2}{n}\)

Now consider the units in which unreliability is measured. What are the units in which our current measure are expressed? Sample size is dimensionless, but variance has dimensions of mean squared. So if the mean was a length in \(cm\) the variance would be an area in \(cm^2\).

It would make good sense to have the dimensions of the unreliability measure and the parameter whose unreliability it is measuring to be the same:

\[ SE_{\bar{y}} = \sqrt{\frac{s^2}{n}} \]

Unreliability measures are called standard errors. What we have just calculated is the standard error of the mean.

We can easily calculate calculate the standard errors of each of our market garden means:

sqrt(s2A/10) 
[1] 0.3651484
sqrt(s2B/10) 
[1] 0.3651484
sqrt(s2C/10) 
[1] 1.19257

In written work one shows the unreliability of any estimated parameter in a formal, structured way like this:

The mean ozone concentration in Garden A was \(3.0 \pm 0.365\) (1 s.e., \(n = 10\))

You write plus or minus, then the unreliability measure then, in brackets, tell the reader what the unreliability measure is (in this case one standard error) and the size of the sample on which the parameter estimate was based (in this case, 10)).

A confidence interval shows the likely range in which the mean would fall if the sampling exercise were to be repeated. It is pretty clear that the confidence interval will get wider as the unreliability goes up, so

confidence interval \(\propto \sqrt \frac{s^2}{n}\)

But what do we mean by confidence ? Ask yourself this question: would the interval be wider or narrower if we wanted to be more confident that our repeat sample mean falls inside the interval?

You should be able to convince yourself that the more confident you want to be, the wider the interval will need to be. You can see this clearly by considering the limiting case of complete and absolute certainty. Nothing is certain in statistical science, so the interval would have to be infinitely wide. We can produce confidence intervals of different widths by specifying different levels of confidence. The higher the confidence, the wider the interval.

How exactly does this work? How do we turn the proportionality in the equation above into equality?

The answer is by resorting to an appropriate theoretical distribution. Suppose our sample size is too small to use the normal distribution (\(n < 30\), as here), then we traditionally use Student’s \(t\) distribution.

The values of Student’s \(t\) associated with different levels of confidence are tabulated but also available in the function qt, which gives the quantiles of the \(t\) distribution.

Confidence intervals are 2-tailed; the parameter may be larger or smaller than our estimate of it. Thus, if we want to establish a 95% confidence interval we need to calculate Student’s \(t\) associated with \(\alpha = 0.025\), that is, with \(0.01 \times \frac{(100-95)}{2}\)

The value is found like this for the left (0.025) and right (0.975) hand tails:

qt(0.025,9)
[1] -2.262157
qt(0.975,9)
[1] 2.262157
?qt

The first argument is the probability and the second is the degrees of freedom. This says that values as small as \(-2.262\) standard errors below the mean are to be expected in 2.5% of cases (\(p=0.025\)), and values as large as \(+2.262\) standard error above the mean with similar probability (\(p=0.975\))

Values of Student’s \(t\) are numbers of standard errors to be expected with specified probability and for a given number of degrees of freedom. The values of \(t\) for 99% are bigger than these (0.005 in each tail):

qt(0.995, 9)
[1] 3.249836

and the value for 99.5% bigger still (0.0025 in each tail):

qt(0.9975, 9)

Values of Student’s \(t\) like these appear in the formula for calculating the width of the confidence interval, and their inclusion is the reason why the width of the confidence interval goes up as our degree of confidence is increased. The other component of the formula, the standard error, is not affected by our choice of confidence level. So, finally, we can write down the formula for the confidence interval of a mean based on a small sample (\(n < 30\)):

\[ CI_{95\%} = t_{(\alpha = 0.025, d.o.f = n-1)} \times \sqrt \frac{s^2}{n} \]

For Garden B, therefore, we could write

qt(0.975,9)*sqrt(1.33333/10) 

The mean ozone concentration in Garden B was \(5.0 \pm 0.826\) (95% C.I., \(n = 10\)).

Quantiles

Quantiles are important summary statistics. They show the values of \(y\) that are associated with specified percentage points of the distribution of the \(y\) values. For instance, the 50% quantile is the same thing as the median.

The most commonly used quantiles are aimed at specifying the middle of a data set and the tails of a data set. By the middle of a data set we mean the values of \(y\) between which the middle 50% of the numbers lie. That is to say, the values of \(y\) that lie between the 25% and 75% quantiles. By the tails of a distribution we mean the extreme values of \(y\): for example, we might define the tails of a distribution as the values that are smaller than the 2.5% quantile or larger than the 97.5% quantile.

To see this, we can generate a vector called z containing 3000 random numbers drawn from a normal distribution using the function rnorm() with a mean of 0 and a standard deviation of 1 (i.e. the standard normal distribution)

z <-rnorm(3000)

We can see how close the mean really is to 0

mean(z)
[1] 0.03951211

But what about the tails of the distribution? We know that for an infinitely large sample, the standard normal should have 2.5% of its z values less than -1.96, and 97.5% of its values less than +1.96

So what is this sample of 3000 points like? We concatenate the two fractions 0.025 and 0.975 to make the second argument of quantile

quantile(z,c(0.025,0.975)) 

What if we try with 10,000 numbers?

z <- rnorm(10000)
quantile(z,c(.025,.975))
LS0tDQp0aXRsZTogIkdldHRpbmcgU3RhcnRlZCB3aXRoIFIsSUlJIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIA0KDQoqTWF0ZXJpYWwgQWRhcHRlZCBmcm9tICJTdGF0aXN0aWNzIG9mIE9uZSBhbmQgVHdvIFNhbXBsZXMiIiBieSBNLkouIENyYXdsZXkqDQoNClNvdXJjZTogW18iU3RhdGlzdGljczogQW4gSW50cm9kdWN0aW9uIFVzaW5nIFIiX10oaHR0cDovL3d3dy5iaW8uaWMuYWMudWsvcmVzZWFyY2gvY3Jhd2xleS9zdGF0aXN0aWNzL2V4ZXJjaXNlcy9SM1N0YXRpc3RpY3MucGRmKQ0KDQpTb21lIGNvbmNlcHRzIHRvIGRpc3NjdXNzIGJlZm9yZSB3b3JraW5nIG9uIHRoZSBoYW5kb3V0OiANCg0KMS4gV2hpY2ggb2YgeW91ciB2YXJpYWJsZXMgaXMgdGhlIF9yZXNwb25zZV8gdmFyaWFibGU/DQoNCkEgZGVwZW5kZW50IHZhcmlhYmxlDQoNCjIuIFdoaWNoIGFyZSB0aGUgX2V4cGxhbmF0b3J5XyB2YXJpYWJsZXM/DQoNClZhcmlhYmxlcyB0aGF0IGV4cGxhaW4gYSBtb2RlbCBvciBhIHJlc3BvbnNlIHZhcmlhYmxlIGUuZyB5ZWFyc19lZHVjIGV4cGxhaW5pbmcgc2FsYXJ5Lg0KDQozLiBBcmUgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBfY29udGludW91cyBvciBjYXRlZ29yaWNhbF8sIG9yIGEgbWl4dHVyZSBvZiBib3RoPw0KDQpCb3RoDQoNCmUuZw0KDQpOdW1iZXJfaW5mZWN0aW9ucz0gaW50ZXJjZXB0K3JlZ2lvbitpbmNvbWUrcG9wK3VmbzIwMTArZQ0KDQpBZnRlciB0aGUgZmlyc3QgcnVuIHdlIGxlYXJuZWQgdGhhdCBuZWl0aGVyIHJlZ2lvbiBub3IgdWZvMjAxMCBpcyBzaWduaWZpY2FudCBhdCBhIDUlIHNpZyBsZXZlbA0KDQpOb3RlczogcmVnaW9uIGlzIGNhdGVnb3JpY2FsIChlYXN0LHdlc3QsY2VudHJhbClhbmQgdWZvIGlzIG51bWVyaWNhbA0KDQpOdW1iZXJfaW5mZWN0aW9ucz1pbnRlcmNlcHQraW5jb21lK3BvcHVsYXRpb24rZQ0KDQpXZSB0aGVuIGxlYXJuZWQgdGhhdCB0aGUgYWRqdXN0ZWQgUiBzcXVhcmUgb2YgdGhlIGZpcnN0IG1vZGVsIGlzIGhpZ2hlciB0aGFuIHRoZSBvbmUgZnJvbSBtb2RlbCAyLg0KDQpBIHBvdGVudGlhbCBzb2x1dGlvbiBtaWdodCBiZSBjcmVhdGluZyBhbiBpbnRlcmFjdGlvbiB0ZXJtDQoNCnBvcF91Zm89cG9wdWxhdGlvbip1Zm8yMDEwDQoNCg0KTnVtYmVyX2luZmVjdGlvbnM9aW50ZXJjZXB0K2luY29tZStwb3BfdWZvK2UNCg0KTm90ZTogV2UganVzdCBjcmVhdGVkIGFuIGludGVyYWN0aW9uIHRlcm0gKG51bWVyaWMpDQoNCldlIHRoZW4ganVzdCBsZWFybmVkIHRoYXQgbXkgQWRqdXN0ZWQgUi1zcXVhcmVkIGJhcmVseSB3ZW50IHVwLiBNeSB0ZWFtIGJlbGlldmVzIHRoYXQgdGhlIHZhcmlhYmxlIHRvIGJlIGNvbnNpZGVyZWQgc2hvdWxkIGJlIHJlZ2lvbi4uLg0KDQoNCkxldCB1cyBjcmVhdGUgYSBuZXcgaW50ZXJhY3Rpb24gdGVybQ0KDQpwb3BfcmVnaW9uPXBvcCpyZWdpb24NCg0KDQo0LiBXaGF0IGtpbmQgb2YgcmVzcG9uc2UgdmFyaWFibGUgaGF2ZSB5b3UgZ290OiBpcyBpdCBhIGNvbnRpbnVvdXMgbWVhc3VyZW1lbnQsIGEgY291bnQsIGEgcHJvcG9ydGlvbiwgYSB0aW1lLWF0LWRlYXRoIG9yIGEgY2F0ZWdvcnkgPyANCg0KV2UgY2FuIGhhdmUgYWxsIG9mIHRoZW0NCg0KIyMgRXN0aW1hdGluZyBQYXJhbWV0ZXJzIGZyb20gRGF0YSANCg0KRGF0YSBoYXZlIGEgbnVtYmVyIG9mIGltcG9ydGFudCBwcm9wZXJ0aWVzLCBhbmQgaXQgaXMgdXNlZnVsIHRvIGJlIGFibGUgdG8gcXVhbnRpZnkgdGhlIGZvbGxvd2luZyBhdHRyaWJ1dGVzOiANCg0KIyMjIFNhbXBsZSBTaXplIA0KSW4gUiwgeW91IGZpbmQgdGhlIHNpemUgb2YgYSB2ZWN0b3IgdXNpbmcgYGxlbmd0aChuYW1lKWAuICBUaGUgbnVtYmVyIG9mIG1lYXN1cmVtZW50cyBvZiB0aGUgcmVzcG9uc2UgdmFyaWFibGUgaXMga25vd24gdW5pdmVyc2FsbHkgYXMgJG4kLg0KDQojIyMgQ2VudHJhbCBUZW5kZW5jeSANCkF2ZXJhZ2VzIGZyb20gcmVwZWF0ZWQgYm91dHMgb2Ygc2FtcGxpbmcgc2hvdyBhIHJlbWFya2FibGUgdGVuZGVuY3kgdG8gY2x1c3RlciBhcm91bmQgdGhlIGFyaXRobWV0aWMgbWVhbiAoY2VudHJhbCBsaW1pdCB0aGVvcmVtKS4NCg0KVGhlIF9tb2RlXyBpcyB0aGUgbW9zdCBmcmVxdWVudGx5IHJlcHJlc2VudGVkIGNsYXNzIG9mIGRhdGEuIFRoZSBfbWVkaWFuXyBpcyB0aGUgdmFsdWUgb2YgdGhlIHJlc3BvbnNlIHZhcmlhYmxlIHRoYXQgbGllcyBpbiB0aGUgbWlkZGxlIG9mIHRoZSByYW5rZWQgc2V0IG9mICR5JCB2YWx1ZXMuICBJdCBoYXMgdGhlIGdyZWF0IGFkdmFudGFnZSBvZiBub3QgYmVpbmcgc2Vuc2l0aXZlIHRvIG91dGxpZXJzLg0KVGhlIChhcml0aG1ldGljKSBfbWVhbl8gaXMgdGhlIHN1bSBvZiB0aGUgb2JzZXJ2YXRpb25zIGRpdmlkZWQgYnkgdGhlIHNhbXBsZSBzaXplLg0KDQoNCiMjIyBNZWFzdXJpbmcgVmFyaWF0aW9uDQoNCkEgbWVhc3VyZSBvZiB2YXJpYWJpbGl0eSBpcyBwZXJoYXBzIHRoZSBtb3N0IGltcG9ydGFudCBxdWFudGl0eSBpbiBzdGF0aXN0aWNhbCBhbmFseXNpcy4gVGhlIGdyZWF0ZXIgdGhlIHZhcmlhYmlsaXR5IGluIHRoZSBkYXRhLCB0aGUgZ3JlYXRlciB3aWxsIGJlIG91ciBfdW5jZXJ0YWludHlfIGluIHRoZSB2YWx1ZXMgb2YgcGFyYW1ldGVycyBlc3RpbWF0ZWQgZnJvbSB0aGUgZGF0YSwgYW5kIHRoZSBsb3dlciB3aWxsIGJlIG91ciBhYmlsaXR5IHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gY29tcGV0aW5nIGh5cG90aGVzZXMgYWJvdXQgdGhlIGRhdGEuIA0KDQpDb25zaWRlciB0aGUgZm9sbG93aW5nIGRhdGEsIGB5YCwgd2hpY2ggYXJlIHNpbXBseSBwbG90dGVkIGluIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IHdlcmUgbWVhc3VyZWQ6IA0KDQpgYGB7cn0NCnkgPC0gYygxMyw3LDUsMTIsOSwxNSw2LDEsOSw3LDEyKQ0KIyBQbG90IGRhdGEgDQpwbG90KHksIHlsaW0gPSBjKDAsMTgpKSANCmBgYA0KDQoNClZpc3VhbCBpbnNwZWN0aW9uIGluZGljYXRlcyBzdWJzdGFudGlhbCB2YXJpYXRpb24gaW4gYHlgLiBCdXQgaG93IHRvIG1lYXN1cmUgaXQ/IE9uZSB3YXkgd291bGQgYmUgdG8gc3BlY2lmeSB0aGUgcmFuZ2Ugb2YgYHlgIHZhbHVlcy4gDQoNCmBgYHtyfQ0KcmFuZ2UoeSkgDQpgYGANCg0KVGhlIG1pbmltdW0gdmFsdWUgb2YgYHlgIGlzIDEgYW5kIHRoZSBtYXhpbXVtIGlzIDE1LiBUaGUgdmFyaWFiaWxpdHkgaXMgY29udGFpbmVkIHdpdGhpbiB0aGUgcmFuZ2UsIGFuZCB0byB0aGF0IGV4dGVudCBpdCBpcyBhIHZlcnkgdXNlZnVsIG1lYXN1cmUuIEJ1dCBpdCBpcyBub3QgaWRlYWwgZm9yIGdlbmVyYWwgcHVycG9zZXMuIEZvciBvbmUgdGhpbmcsIGl0IGlzIHRvdGFsbHkgZGV0ZXJtaW5lZCBieSBvdXRsaWVycywgYW5kIGdpdmVzIHVzIG5vIGluZGljYXRpb24gb2YgbW9yZSB0eXBpY2FsIGxldmVscyBvZiB2YXJpYXRpb24uDQoNCg0KSG93IGFib3V0IGZpdHRpbmcgdGhlIGF2ZXJhZ2UgdmFsdWUgb2YgYHlgIHRocm91Z2ggdGhlIGRhdGEgYW5kIG1lYXN1cmluZyBfaG93IGZhcl8gZWFjaCBpbmRpdmlkdWFsIGB5YCB2YWx1ZSBkZXBhcnRzIGZyb20gdGhlIG1lYW4/IA0KDQpgYGB7cn0NCnBsb3QoeSwgeWxpbSA9IGMoMCwxOCkpIA0KIyAybmQgcGFyYW1ldGVyIHNheXMgdGhlIHNsb3BlIG9mIHRoZSBmaXR0ZWQgbGluZSBpcyAwDQphYmxpbmUobWVhbih5KSwwKQ0KYGBgDQoNClRoaXMgZGl2aWRlcyB0aGUgZGF0YSBpbnRvIDUgcG9pbnRzIHRoYXQgYXJlIGxhcmdlciB0aGFuIHRoZSBtZWFuIGFuZCA3IHBvaW50cyB0aGF0IGFyZSBzbWFsbGVyIHRoYW4gdGhlIG1lYW4uIA0KIA0KDQoNClRoZSBfc3VtIG9mIHNxdWFyZXNfIChkaWZmZXJlbmNlcykgaXMgdGhlIGJhc2lzIG9mIGFsbCB0aGUgbWVhc3VyZXMgb2YgdmFyaWFiaWxpdHkgdXNlZCBpbiBsaW5lYXIgc3RhdGlzdGljYWwgYW5hbHlzaXM6DQoNCiQkDQpcc3VtIGReIDIgPSBcc3VtICh5IC0gXGJhcnt5fSleMg0KJCQNCg0KDQpXZSBjb3VsZCBub3QgY2FsY3VsYXRlICRcc3VtIGReMiQgX2JlZm9yZV8gd2Uga25ldyB0aGUgdmFsdWUgb2YgdGhlIG1lYW4gJFxiYXJ7eX0kLiBBbmQgaG93IGRpZCB3ZSBrbm93IHRoZSB2YWx1ZSBvZiAkXGJhcnt5fSQ/IFdlbGwgd2UgZGlkIG5vdCBrbm93IHRoZSB2YWx1ZSwgd2UgZXN0aW1hdGVkIGl0IGZyb20gdGhlIGRhdGEuIFRoaXMgbGVhZHMgdXMgaW50byBhIHZlcnkgaW1wb3J0YW50IGNvbmNlcHQ6IGRlZ3JlZXMgb2YgZnJlZWRvbS4NCg0KDQoqKkRlZ3JlZXMgb2YgRnJlZWRvbSoqOiBkZWdyZWVzIG9mIGZyZWVkb20gKGQuby5mKSBpcyB0aGUgc2FtcGxlIHNpemUsICRuJCwgbWludXMgdGhlIG51bWJlciBvZiBwYXJhbWV0ZXJzLCAkcCQsIGVzdGltYXRlZCBmcm9tIHRoZSBkYXRhLiANCg0KSW4gYSBfbGluZWFyIHJlZ3Jlc3Npb25fIHdlIGVzdGltYXRlIHR3byBwYXJhbWV0ZXJzIGZyb20gdGhlIGRhdGEgd2hlbiB3ZSBmaXQgdGhlIG1vZGVsOg0KJHkgPSBteCArIGIkDQoNCnRoZSBpbnRlcmNlcHQsICRiJCwgYW5kIHRoZSBzbG9wZSAkbSQuIEJlY2F1c2Ugd2UgaGF2ZSBlc3RpbWF0ZWQgMiBwYXJhbWV0ZXJzLCB3ZSBoYXZlICRuLTIkIGQuby5mDQoNCkluIGEgb25lIHdheSBfYW5hbHlzaXMgb2YgdmFyaWFuY2VfIHdpdGggNSBnZW5vdHlwZXMsIHdlIGVzdGltYXRlIDUgbWVhbnMgZnJvbQ0KdGhlIGRhdGEgKG9uZSBmb3IgZWFjaCBnZW5vdHlwZSkgc28gd2UgaGF2ZSAkbi01JCBkLm8uZi4gQW5kIHNvIG9uLiAgDQoNCg0KDQoqKlZhcmlhbmNlKioNCg0KVmFyaWFuY2UsIGRlbm90ZWQgYnkgJHNeMiQsIGlzIGRlZmluZWQgYXMgdGhlIF9zdW0gb2Ygc3F1YXJlc18gZGl2aWRlZCBieSB0aGUgbnVtYmVyIG9mIF9kZWdyZWVzIG9mIGZyZWVkb21fOg0KDQokJA0Kc14yID0gXGZyYWN7XHN1bSAoeSAtIFxiYXJ7eX0pXjJ9e24tMX0NCiQkDQoNCg0KKipfRXhhbXBsZV8qKg0KDQpUaGUgZGF0YSBpbiB0aGUgZm9sbG93aW5nIHRhYmxlIGNvbWUgZnJvbSAzIG1hcmtldCBnYXJkZW5zLiBUaGUgZGF0YSBzaG93IHRoZSBfb3pvbmUgY29uY2VudHJhdGlvbnNfIGluIHBhcnRzIHBlciBodW5kcmVkIG1pbGxpb24gKGBwcGhtYCkgb24gdGVuIHN1bW1lciBkYXlzLiAoaGludDpDcmVhdGUgYSBjc3YgZmlsZSB3aXRoIHRoZSBpbmZvcm1hdGlvbiBsaXN0ZWQgaW4gdGhlIHRhYmxlKQ0KDQpHYXJkZW4gQSAgfCBHYXJkZW4gQiAgfCBHYXJkZW4gQw0KLS0tLS0tLS0tLXwtLS0tLS0tLS0tLXwtLS0tLS0tLS0tDQozICAgICAgICAgfCA1ICAgICAgICAgfCAzDQo0ICAgICAgICAgfCA1ICAgICAgICAgfCAzDQo0ICAgICAgICAgfCA2ICAgICAgICAgfCAyDQozICAgICAgICAgfCA3ICAgICAgICAgfCAxDQoyICAgICAgICAgfCA0ICAgICAgICAgfCAxMA0KMyAgICAgICAgIHwgNCAgICAgICAgIHwgNA0KMSAgICAgICAgIHwgMyAgICAgICAgIHwgMw0KMyAgICAgICAgIHwgNSAgICAgICAgIHwgMTENCjUgICAgICAgICB8IDYgICAgICAgICB8IDMNCjIgICAgICAgICB8IDUgICAgICAgICB8IDEwDQoNCldlIHdhbnQgdG8gY2FsY3VsYXRlIHRoZSBfdmFyaWFuY2UgaW4gb3pvbmUgY29uY2VudHJhdGlvbiBmb3IgZWFjaCBnYXJkZW5fDQoNCg0KDQpgYGB7cn0NCiMgR2FyZGVuIEENCkEgPC0gYygzLDQsNCwzLDIsMywxLDMsNSwyKSANCiMgR2FyZGVuIEINCkIgPC0gYyg1LDUsNiw3LDQsNCwzLDUsNiw1KSANCiMgR2FyZGVuIEMNCkMgPC0gYygzLDMsMiwxLDEwLDQsMywxMSwzLDEwKSANCmBgYA0KDQoNCldlIGNhbiB1c2UgdGhlIGZ1bmN0aW9uIGB2YXIoKWAgdG8gZmluZCB0aGUgdmFyaWFuY2U6DQoNCmBgYHtyfQ0KczJBIDwtIHZhcihBKQ0KczJCIDwtIHZhcihCKQ0KczJDIDwtIHZhcihDKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCiMgcHJpbnQgdGhlIHZhcmlhbmNlcw0KYyhzMkEsIHMyQiwgczJDKQ0KIyBwcmludCB0aGUgbWVhbnMNCm1lYW4oQSkNCm1lYW4oQikNCm1lYW4oQykNCmBgYA0KDQoNClRoZXJlIGFyZSB0aHJlZSBpbXBvcnRhbnQgcG9pbnRzIHRvIGJlIG1hZGUgZnJvbSB0aGlzIGV4YW1wbGU6DQoNCi0gdHdvIHBvcHVsYXRpb25zIGNhbiBoYXZlIF9kaWZmZXJlbnQgbWVhbnMgYnV0IHRoZSBzYW1lIHZhcmlhbmNlXyAoR2FyZGVucyBBICYgQikNCg0KLSB0d28gcG9wdWxhdGlvbnMgY2FuIGhhdmUgdGhlIF9zYW1lIG1lYW4gYnV0IGRpZmZlcmVudCB2YXJpYW5jZXNfIChHYXJkZW5zIEIgJiBDKQ0KDQpJcyBpdCBhIGJhZCBpZGVhIGNvbXBhcmluZyBtZWFucyB3aGVuIHRoZSB2YXJpYW5jZXMgYXJlIGRpZmZlcmVudD9FeHBsYWluLg0KDQoNCmBgYHtyfQ0KcmF0aW9fQ0IgPC0gczJDL3MyQg0KIyBpcyBpdCBiaWdnZXIgdGhhbiA0IHRpbWVzIHRoZSBzbWFsbGVyIHZhcmlhbmNlPw0KcmF0aW9fQ0IgPiA0KnMyQg0KYGBgDQoNCg0KIyMgVXNpbmcgVmFyaWFuY2UNCg0KV2UgY2FuIHVzZSB2YXJpYW5jZSBpbiB0d28gbWFpbiB3YXlzOg0KDQotIGZvciBlc3RhYmxpc2hpbmcgbWVhc3VyZXMgb2YgdW5yZWxpYWJpbGl0eQ0KLSBmb3IgdGVzdGluZyBoeXBvdGhlc2VzIA0KDQoNCkNvbnNpZGVyIHRoZSBwcm9wZXJ0aWVzIHRoYXQgeW91IHdvdWxkIGxpa2UgYSBtZWFzdXJlIG9mIHVucmVsaWFiaWxpdHkgdG8gcG9zc2Vzcy4gDQotIEFzIHRoZSB2YXJpYW5jZSBvZiB0aGUgZGF0YSBpbmNyZWFzZXMgd2hhdCB3b3VsZCBoYXBwZW4gdG8gdW5yZWxpYWJpbGl0eSBvZiBlc3RpbWF0ZWQgcGFyYW1ldGVycyA/IA0KLSBXb3VsZCBpdCBnbyB1cCBvciBkb3duID8gDQotIFVucmVsaWFiaWxpdHkgd291bGQgZ28gdXAgYXMgdmFyaWFuY2UgaW5jcmVhc2VkLCBzbyB3ZSB3b3VsZCB3YW50IHRvIGhhdmUgdGhlIHZhcmlhbmNlIG9uIHRoZSB0b3Agb2YgYW55IGRpdmlzaW9ucyBpbiBvdXIgZm9ybXVsYSBmb3IgdW5yZWxpYWJpbGl0eSAoaS5lLiBpbiB0aGUgbnVtZXJhdG9yKS4gDQoNCiR1bnJlbGlhYmlsaXR5IFxwcm9wdG8gc14yJA0KDQoNCldoYXQgYWJvdXQgX3NhbXBsZSBzaXplXz8gDQotIFdvdWxkIHlvdSB3YW50IHlvdXIgZXN0aW1hdGUgb2YgdW5yZWxpYWJpbGl0eSB0byBnbyB1cCBvcg0KZG93biBhcyBzYW1wbGUgc2l6ZSwgJG4kLCBpbmNyZWFzZWQgPyANCi0gWW91IHdvdWxkIHdhbnQgdW5yZWxpYWJpbGl0eSB0byBnbyBkb3duIGFzIHNhbXBsZSBzaXplIHdlbnQgdXAsIHNvIHlvdSB3b3VsZCBwdXQgc2FtcGxlIHNpemUgb24gdGhlIGJvdHRvbSBvZiB0aGUgZm9ybXVsYSBmb3INCnVucmVsaWFiaWxpdHkgKGkuZS4gaW4gdGhlIGRlbm9taW5hdG9yKQ0KDQokdW5yZWxpYWJpbGl0eSBccHJvcHRvIFxmcmFje3NeMn17bn0kDQoNCg0KDQoNCk5vdyBjb25zaWRlciB0aGUgdW5pdHMgaW4gd2hpY2ggdW5yZWxpYWJpbGl0eSBpcyBtZWFzdXJlZC4NCldoYXQgYXJlIHRoZSB1bml0cyBpbiB3aGljaCBvdXIgY3VycmVudCBtZWFzdXJlIGFyZSBleHByZXNzZWQ/IFNhbXBsZSBzaXplIGlzIGRpbWVuc2lvbmxlc3MsIGJ1dCB2YXJpYW5jZSBoYXMgZGltZW5zaW9ucyBvZiBtZWFuIHNxdWFyZWQuIFNvIGlmIHRoZSBtZWFuIHdhcyBhIGxlbmd0aCBpbiAkY20kIHRoZSB2YXJpYW5jZSB3b3VsZCBiZSBhbiBhcmVhIGluICRjbV4yJC4gDQoNCkl0IHdvdWxkIG1ha2UgZ29vZCBzZW5zZSB0byBoYXZlIHRoZSBkaW1lbnNpb25zIG9mIHRoZSB1bnJlbGlhYmlsaXR5IG1lYXN1cmUgYW5kIHRoZSBwYXJhbWV0ZXIgd2hvc2UgdW5yZWxpYWJpbGl0eSBpdCBpcyBtZWFzdXJpbmcgdG8gYmUgdGhlDQpzYW1lOiANCg0KDQokJA0KU0Vfe1xiYXJ7eX19ID0gXHNxcnR7XGZyYWN7c14yfXtufX0NCiQkDQoNClVucmVsaWFiaWxpdHkgbWVhc3VyZXMgYXJlIGNhbGxlZCBfc3RhbmRhcmQgZXJyb3JzXy4gV2hhdCB3ZSBoYXZlIGp1c3QgY2FsY3VsYXRlZCBpcyB0aGUgc3RhbmRhcmQgZXJyb3Igb2YgdGhlIG1lYW4uDQoNCldlIGNhbiBlYXNpbHkgY2FsY3VsYXRlICBjYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGVycm9ycyBvZiBlYWNoIG9mIG91ciBtYXJrZXQgZ2FyZGVuIG1lYW5zOiANCg0KYGBge3J9DQpzcXJ0KHMyQS8xMCkgDQpzcXJ0KHMyQi8xMCkgDQpzcXJ0KHMyQy8xMCkgDQpgYGANCg0KDQoNCg0KSW4gd3JpdHRlbiB3b3JrIG9uZSBzaG93cyB0aGUgdW5yZWxpYWJpbGl0eSBvZiBhbnkgZXN0aW1hdGVkIHBhcmFtZXRlciBpbiBhIGZvcm1hbCwgc3RydWN0dXJlZCB3YXkgbGlrZSB0aGlzOg0KDQpUaGUgbWVhbiBvem9uZSBjb25jZW50cmF0aW9uIGluIEdhcmRlbiBBIHdhcyAkMy4wIFxwbSAwLjM2NSQgKDEgcy5lLiwgJG4gPSAxMCQpDQoNCllvdSB3cml0ZSBwbHVzIG9yIG1pbnVzLCB0aGVuIHRoZSB1bnJlbGlhYmlsaXR5IG1lYXN1cmUgdGhlbiwgaW4gYnJhY2tldHMsIHRlbGwgdGhlIHJlYWRlciB3aGF0IHRoZSB1bnJlbGlhYmlsaXR5IG1lYXN1cmUgaXMgKGluIHRoaXMgY2FzZSBvbmUgc3RhbmRhcmQgZXJyb3IpIGFuZCB0aGUgc2l6ZSBvZiB0aGUgc2FtcGxlIG9uIHdoaWNoIHRoZSBwYXJhbWV0ZXIgZXN0aW1hdGUgd2FzIGJhc2VkIChpbiB0aGlzIGNhc2UsIDEwKSkuIA0KDQoNCg0KQSAqKmNvbmZpZGVuY2UgaW50ZXJ2YWwqKiBzaG93cyB0aGUgX2xpa2VseSByYW5nZV8gaW4gd2hpY2ggdGhlIG1lYW4gd291bGQgZmFsbCBpZiB0aGUgc2FtcGxpbmcgZXhlcmNpc2Ugd2VyZSB0byBiZSByZXBlYXRlZC4gSXQgaXMgcHJldHR5IGNsZWFyIHRoYXQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgd2lsbCBnZXQgd2lkZXIgYXMgdGhlIHVucmVsaWFiaWxpdHkgZ29lcyB1cCwgc28NCg0KY29uZmlkZW5jZSBpbnRlcnZhbCAkXHByb3B0byBcc3FydCBcZnJhY3tzXjJ9e259JA0KDQoNCkJ1dCB3aGF0IGRvIHdlIG1lYW4gYnkgX2NvbmZpZGVuY2VfID8gDQpBc2sgeW91cnNlbGYgdGhpcyBxdWVzdGlvbjogd291bGQgdGhlIGludGVydmFsIGJlIHdpZGVyIG9yIG5hcnJvd2VyIGlmIHdlIHdhbnRlZCB0byBiZSBtb3JlIGNvbmZpZGVudCB0aGF0IG91ciByZXBlYXQgc2FtcGxlIG1lYW4gZmFsbHMgaW5zaWRlIHRoZSBpbnRlcnZhbD8NCg0KWW91IHNob3VsZCBiZSBhYmxlIHRvIGNvbnZpbmNlIHlvdXJzZWxmIHRoYXQgdGhlIG1vcmUgY29uZmlkZW50IHlvdSB3YW50IHRvIGJlLCB0aGUgd2lkZXIgdGhlIGludGVydmFsIHdpbGwgbmVlZCB0byBiZS4gWW91IGNhbiBzZWUgdGhpcyBjbGVhcmx5IGJ5IGNvbnNpZGVyaW5nIHRoZSBsaW1pdGluZyBjYXNlIG9mIGNvbXBsZXRlIGFuZCBhYnNvbHV0ZSBjZXJ0YWludHkuIE5vdGhpbmcgaXMgY2VydGFpbiBpbiBzdGF0aXN0aWNhbCBzY2llbmNlLCBzbyB0aGUgaW50ZXJ2YWwgd291bGQgaGF2ZSB0byBiZSBpbmZpbml0ZWx5IHdpZGUuIFdlIGNhbiBwcm9kdWNlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIG9mIGRpZmZlcmVudCB3aWR0aHMgYnkgc3BlY2lmeWluZyBkaWZmZXJlbnQgX2xldmVscyBvZiBjb25maWRlbmNlXy4gVGhlIGhpZ2hlciB0aGUgY29uZmlkZW5jZSwgdGhlIHdpZGVyIHRoZSBpbnRlcnZhbC4gDQoNCg0KSG93IGV4YWN0bHkgZG9lcyB0aGlzIHdvcms/IEhvdyBkbyB3ZSB0dXJuIHRoZSBwcm9wb3J0aW9uYWxpdHkgaW4gdGhlIGVxdWF0aW9uIGFib3ZlIGludG8gZXF1YWxpdHk/IA0KDQpUaGUgYW5zd2VyIGlzIGJ5IHJlc29ydGluZyB0byBhbiBhcHByb3ByaWF0ZSB0aGVvcmV0aWNhbCBfZGlzdHJpYnV0aW9uXy4gU3VwcG9zZSBvdXIgc2FtcGxlIHNpemUgaXMgdG9vIHNtYWxsIHRvIHVzZSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiAoJG4gPCAzMCQsIGFzIGhlcmUpLCB0aGVuIHdlIHRyYWRpdGlvbmFsbHkgdXNlIFN0dWRlbnQncyAkdCQgW2Rpc3RyaWJ1dGlvbl0oaHR0cDovL21hdGh3b3JsZC53b2xmcmFtLmNvbS9TdHVkZW50c3QtRGlzdHJpYnV0aW9uLmh0bWwpLiANCg0KVGhlIHZhbHVlcyBvZiBTdHVkZW50J3MgJHQkIGFzc29jaWF0ZWQgd2l0aCBkaWZmZXJlbnQgbGV2ZWxzIG9mIGNvbmZpZGVuY2UgYXJlIHRhYnVsYXRlZCBidXQgYWxzbyBhdmFpbGFibGUgaW4gdGhlIGZ1bmN0aW9uIGBxdGAsIHdoaWNoIGdpdmVzIHRoZSAqKnF1YW50aWxlcyoqIG9mIHRoZSAkdCQgZGlzdHJpYnV0aW9uLiANCg0KQ29uZmlkZW5jZSBpbnRlcnZhbHMgYXJlIDItdGFpbGVkOyB0aGUgcGFyYW1ldGVyIG1heSBiZSBsYXJnZXIgb3Igc21hbGxlciB0aGFuIG91ciBlc3RpbWF0ZSBvZiBpdC4gVGh1cywgaWYgd2Ugd2FudCB0byBlc3RhYmxpc2ggYSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCB3ZSBuZWVkIHRvIGNhbGN1bGF0ZSBTdHVkZW50J3MgJHQkIGFzc29jaWF0ZWQgd2l0aCAkXGFscGhhID0gMC4wMjUkLCB0aGF0IGlzLCB3aXRoICQwLjAxIFx0aW1lcyBcZnJhY3soMTAwLTk1KX17Mn0kDQoNCg0KDQpUaGUgdmFsdWUgaXMgZm91bmQgbGlrZSB0aGlzIGZvciB0aGUgbGVmdCAoMC4wMjUpIGFuZCByaWdodCAoMC45NzUpIGhhbmQgdGFpbHM6IA0KDQpgYGB7cn0NCnF0KDAuMDI1LDkpDQpxdCgwLjk3NSw5KQ0KP3F0DQpgYGANCg0KDQoNCg0KVGhlIGZpcnN0IGFyZ3VtZW50IGlzIHRoZSBwcm9iYWJpbGl0eSBhbmQgdGhlIHNlY29uZCBpcyB0aGUgZGVncmVlcyBvZiBmcmVlZG9tLiBUaGlzIHNheXMgdGhhdCB2YWx1ZXMgYXMgc21hbGwgYXMgJC0yLjI2MiQgc3RhbmRhcmQgZXJyb3JzIGJlbG93IHRoZSBtZWFuIGFyZSB0byBiZSBleHBlY3RlZCBpbiAyLjUlIG9mIGNhc2VzICgkcD0wLjAyNSQpLCBhbmQgdmFsdWVzIGFzIGxhcmdlIGFzICQrMi4yNjIkIHN0YW5kYXJkIGVycm9yIGFib3ZlIHRoZSBtZWFuIHdpdGggc2ltaWxhciBwcm9iYWJpbGl0eSAoJHA9MC45NzUkKQ0KDQoNCg0KVmFsdWVzIG9mIFN0dWRlbnQncyAkdCQgYXJlIG51bWJlcnMgb2Ygc3RhbmRhcmQgZXJyb3JzIHRvIGJlIGV4cGVjdGVkIHdpdGggc3BlY2lmaWVkIHByb2JhYmlsaXR5IGFuZCBmb3IgYSBnaXZlbiBudW1iZXIgb2YgZGVncmVlcyBvZiBmcmVlZG9tLiBUaGUgdmFsdWVzIG9mICR0JCBmb3IgOTklIGFyZSBiaWdnZXIgdGhhbiB0aGVzZSAoMC4wMDUgaW4gZWFjaCB0YWlsKTogDQoNCmBgYHtyfQ0KcXQoMC45OTUsIDkpDQpgYGANCg0KDQphbmQgdGhlIHZhbHVlIGZvciA5OS41JSBiaWdnZXIgc3RpbGwgKDAuMDAyNSBpbiBlYWNoIHRhaWwpOiANCg0KYGBge3J9DQpxdCgwLjk5NzUsIDkpDQpgYGANCg0KDQpWYWx1ZXMgb2YgU3R1ZGVudCdzICR0JCBsaWtlIHRoZXNlIGFwcGVhciBpbiB0aGUgZm9ybXVsYSBmb3IgY2FsY3VsYXRpbmcgdGhlIHdpZHRoIG9mIHRoZSBjb25maWRlbmNlIGludGVydmFsLCBhbmQgdGhlaXIgaW5jbHVzaW9uIGlzIHRoZSByZWFzb24gd2h5IHRoZSB3aWR0aCBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBnb2VzIHVwIGFzIG91ciBkZWdyZWUgb2YgY29uZmlkZW5jZSBpcyBpbmNyZWFzZWQuIFRoZSBvdGhlciBjb21wb25lbnQgb2YgdGhlIGZvcm11bGEsIHRoZSBzdGFuZGFyZCBlcnJvciwgaXMgbm90IGFmZmVjdGVkIGJ5IG91ciBjaG9pY2Ugb2YgY29uZmlkZW5jZSBsZXZlbC4gU28sIGZpbmFsbHksIHdlIGNhbiB3cml0ZSBkb3duIHRoZSBmb3JtdWxhIGZvciB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBvZiBhIG1lYW4gYmFzZWQgb24NCmEgc21hbGwgc2FtcGxlICgkbiA8IDMwJCk6DQoNCiQkDQpDSV97OTVcJX0gPSB0X3soXGFscGhhID0gMC4wMjUsIGQuby5mID0gbi0xKX0gXHRpbWVzIFxzcXJ0IFxmcmFje3NeMn17bn0NCiQkDQoNCkZvciBHYXJkZW4gQiwgdGhlcmVmb3JlLCB3ZSBjb3VsZCB3cml0ZSANCg0KYGBge3J9DQpxdCgwLjk3NSw5KSpzcXJ0KDEuMzMzMzMvMTApIA0KYGBgDQoNCg0KVGhlIG1lYW4gb3pvbmUgY29uY2VudHJhdGlvbiBpbiBHYXJkZW4gQiB3YXMgJDUuMCBccG0gMC44MjYkICg5NSUgQy5JLiwgJG4gPSAxMCQpLiANCg0KDQojIyBRdWFudGlsZXMNCg0KUXVhbnRpbGVzIGFyZSBpbXBvcnRhbnQgc3VtbWFyeSBzdGF0aXN0aWNzLiBUaGV5IHNob3cgdGhlIHZhbHVlcyBvZiAkeSQgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIHNwZWNpZmllZCBwZXJjZW50YWdlIHBvaW50cyBvZiB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSAkeSQgdmFsdWVzLiBGb3IgaW5zdGFuY2UsIHRoZSA1MCUgcXVhbnRpbGUgaXMgdGhlIHNhbWUgdGhpbmcgYXMgdGhlIG1lZGlhbi4gDQoNClRoZSBtb3N0IGNvbW1vbmx5IHVzZWQgcXVhbnRpbGVzIGFyZSBhaW1lZCBhdCBzcGVjaWZ5aW5nIHRoZSBtaWRkbGUgb2YgYSBkYXRhIHNldCBhbmQgdGhlIHRhaWxzIG9mIGEgZGF0YSBzZXQuIEJ5IHRoZSBtaWRkbGUgb2YgYSBkYXRhIHNldCB3ZSBtZWFuIHRoZSB2YWx1ZXMgb2YgJHkkIGJldHdlZW4gd2hpY2ggdGhlIG1pZGRsZSA1MCUgb2YgdGhlIG51bWJlcnMgbGllLiBUaGF0IGlzIHRvIHNheSwgdGhlIHZhbHVlcyBvZiAkeSQgdGhhdCBsaWUgYmV0d2VlbiB0aGUgMjUlIGFuZCA3NSUgcXVhbnRpbGVzLiBCeSB0aGUgdGFpbHMgb2YgYSBkaXN0cmlidXRpb24gd2UgbWVhbiB0aGUgZXh0cmVtZSB2YWx1ZXMgb2YgJHkkOiBmb3IgZXhhbXBsZSwgd2UgbWlnaHQgZGVmaW5lIHRoZSB0YWlscyBvZiBhIGRpc3RyaWJ1dGlvbiBhcyB0aGUgdmFsdWVzIHRoYXQgYXJlIHNtYWxsZXIgdGhhbiB0aGUgMi41JSBxdWFudGlsZSBvciBsYXJnZXIgdGhhbiB0aGUgOTcuNSUgcXVhbnRpbGUuDQoNCg0KVG8gc2VlIHRoaXMsIHdlIGNhbiBnZW5lcmF0ZSBhIHZlY3RvciBjYWxsZWQgYHpgIGNvbnRhaW5pbmcgMzAwMCByYW5kb20gbnVtYmVycyBkcmF3biBmcm9tIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiB1c2luZyB0aGUgZnVuY3Rpb24gYHJub3JtKClgIHdpdGggYSBtZWFuIG9mIDAgYW5kIGEgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDEgKGkuZS4gdGhlIF9zdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uXykNCg0KYGBge3J9DQp6IDwtcm5vcm0oMzAwMCkNCmBgYA0KDQpXZSBjYW4gc2VlIGhvdyBjbG9zZSB0aGUgbWVhbiByZWFsbHkgaXMgdG8gMA0KDQpgYGB7cn0NCm1lYW4oeikNCmBgYA0KDQpCdXQgd2hhdCBhYm91dCB0aGUgdGFpbHMgb2YgdGhlIGRpc3RyaWJ1dGlvbj8gV2Uga25vdyB0aGF0IGZvciBhbiBpbmZpbml0ZWx5IGxhcmdlIHNhbXBsZSwgdGhlIFtzdGFuZGFyZCBub3JtYWxdKGh0dHBzOi8vd3d3Lm1hdGhzaXNmdW4uY29tL2RhdGEvc3RhbmRhcmQtbm9ybWFsLWRpc3RyaWJ1dGlvbi10YWJsZS5odG1sKSBzaG91bGQgaGF2ZSAyLjUlIG9mIGl0cyBgemAgdmFsdWVzIGxlc3MgdGhhbiAtMS45NiwgYW5kIDk3LjUlIG9mIGl0cyB2YWx1ZXMgbGVzcyB0aGFuICsxLjk2DQoNCg0KU28gd2hhdCBpcyB0aGlzIHNhbXBsZSBvZiAzMDAwIHBvaW50cyBsaWtlPyBXZSBjb25jYXRlbmF0ZSB0aGUgdHdvIGZyYWN0aW9ucyAwLjAyNSBhbmQgMC45NzUgdG8gbWFrZSB0aGUgc2Vjb25kIGFyZ3VtZW50IG9mIHF1YW50aWxlDQoNCmBgYHtyfQ0KcXVhbnRpbGUoeixjKDAuMDI1LDAuOTc1KSkgDQpgYGANCg0KV2hhdCBpZiB3ZSB0cnkgd2l0aCAxMCwwMDAgbnVtYmVycz8NCg0KYGBge3J9DQp6IDwtIHJub3JtKDEwMDAwKQ0KcXVhbnRpbGUoeixjKC4wMjUsLjk3NSkpDQo=