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:
- Which of your variables is the response variable?
A dependent variable
- Which are the explanatory variables?
Variables that explain a model or a response variable e.g years_educ
explaining salary.
- 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
- 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)
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:
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:
- for establishing measures of unreliability
- for testing hypotheses
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=