Parametric vs. Non-Parametric
- Parametric tests: the tests we have studied so far (z, t, F) have
been used to describe a populations distribution (parameters).
- Require interval or ratio data
- Non-Parametric tests: describe relationships about that exist in
populations but make relaxed (or different) assumptions about
populations distributions.
- These tests can compare qualitative data (e.g., chi-squared)
- Non-parametric tests are more likely to commit type II errors
- Typically are used with ordinal or nominal data, but can also be
used with interval or ratio data when parametric assumptions are not met
(e.g., when variance or distribution presents a problem).
- These tests do not use the mean and standard deviation since they
are often meaningless in ordinal data.
- These tests rank scores to see how different groups compare
to each other.
One-Way Pearson’s Chi-Squared [Goodness of Fit]
Have you been told: “Stay with your first answer on a multiple-choice
test.” So is changing answers more likely to be harmful?
Best (1979) studied the responses of 261 students in an introductory
psychology course. He recorded the number of right-to-wrong (27),
wrong-to-right (195), and wrong-to-wrong (39) answer changes for each
student. Note: We will ignore wrong-to-wrong as he did in his first
analysis.
Total of 222 observations
We will use the One-Way Chi-Squared [Goodness of
fit]. It asks whether the relative frequencies observed in the
categories of a sample frequency distribution are in agreement with the
relative frequencies hypothesized to be true in the population.
Hypothesis for Goodness of fit
There are two versions:
- No preference: there will be no preference between different
categories (e.g., do people prefer Coke or Pepsi)
- No difference from a known population: This type hypothesis compares
two populations (or representative samples)
If people were making chance guesses from a population of people who
don’t have any knowledge about material on the test (version 2 of the
hypothesis):
- \(H_0: P_{right-to-wrong} = .5,
P_{wrong-to-right} = .5\)
- \(H_1: H_0\) is False
Note: The probability you set can be whatever you want, but
across all cells, they must add to 1. When you do not know what
probability should be from a theoretical standpoint, you can simply do
1/Number of cells.
Find Expected Frequencies
If we expect by chance people would have gotten p = .50 on
wrong-to-right and right to wrong, \(f_e =
pn\)
\(E_{right-to-wrong}= .5*222=111\)
\(E_{wrong-to-right}= .5*222=111\)
Observed |
27 |
195 |
Expected |
111 |
111 |
Note: These tables are often shown in papers (sometimes as
proportions).
Goodness of Fit Calculation by Hand
\[\chi^2 = \sum
\frac{(f_o-f_e)^2}{f_e}\]
\(\chi^2 =
\frac{(27-111)^2}{111}+\frac{(195-111)^2}{111} = 127.14\)
Note: Never enter proportions into the chi-square. You must
work with frequencies.
Test Against Distribution
The chi-square distribution is a non-parametric distribution [not
normal] (see handout). Like the F-test, it has no tails. The
distribution changes as a function of the degrees of freedom [\(df\) is the number of cells - 1]
Just like the F-test we ask where is our chi-square value relative to
this chance distribution given our \(df =
1\). We calculated 127.14, and that is in the tail. We can use R
or a table to get the critical values for alpha =.05
Crit.MCQ=qchisq(.05, df=1, lower.tail = FALSE)
We get the crit = 3.8414588 < 124.14, so we reject the null.
Impact of higher DF
Just like in F-tests the shape of chance distribution changes as we
have more df.
As you can see the distribution gets more spread out. So with larger
DF our critical value increases
ChiCrit<-qchisq(.05, 1:8, lower.tail = FALSE)
plot(ChiCrit, main="Chi-Square Critical Values: alpha = .05",
xlab="df", ylab="Critical Value", xlim=c(1,8), ylim=c(0,25))
Goodness of Fit Calculation by Code
Step 1: Build your Table
MCQ.Study <- as.table(rbind(c(27, 195)))
dimnames(MCQ.Study) <- list(Freq = c("Observed"),
Action = c("RtoW", "WtoR"))
MCQ.Study
## Action
## Freq RtoW WtoR
## Observed 27 195
Step 2: Calculate Chi-squared
(MCQ.chi <- chisq.test(MCQ.Study, p=c(.5, .5)))
##
## Chi-squared test for given probabilities
##
## data: MCQ.Study
## X-squared = 127.14, df = 1, p-value < 2.2e-16
Step 2a: Calculate chi-square via Monte Carlo simulation
In the goodness-of-fit simulation is done by random sampling from the
discrete distribution specified by p, each sample being the total number
of observations (see ?chisq.test for more details on the simulation
process)
(MCQ.chi <- chisq.test(MCQ.Study, p=c(.5, .5), simulate.p.value = TRUE, B = 10000))
##
## Chi-squared test for given probabilities with simulated p-value (based
## on 10000 replicates)
##
## data: MCQ.Study
## X-squared = 127.14, df = NA, p-value = 9.999e-05
Step 3: Report in APA
\(\chi^2(df,N) = X.XX, p < |=
.XXX\)
Since our result was p-value < 2.2e-16
\(\chi^2(1,N = 222) = 124.14, p <
.0001\)
There is a difference how people change their items, and we can see
from the frequencies that should change their answers if they are
unsure.
Two-Way Pearson’s Chi-Squared [Test of Independence]
“Maybe we should only change our answers on easy items, but on hard
items, we should trust ourselves.”
Best (1979) also examined the 1670 total number of responses across
the 261 students and divided the items into easy/difficult in an
introductory psychology course. He recorded the number of
right-to-wrong, wrong-to-right, and wrong-to-wrong (39) answer changes
for each student. Again we will ignore wrong-to-wrong (17% of the
responses) for simplicity.
Easy |
97 |
411 |
Difficult |
251 |
620 |
We need to do a Two-Way Chi-Square [Test of Independence]. It asks
whether observed frequencies reflect the independence of two qualitative
variables. Compares the actual observed frequencies of some phenomenon
(in our sample) with the frequencies we would expect if there were no
relationship at all between the two variables in the larger (sampled)
population. We ask if the two variables are independent: knowledge of
the value of one variable provides no information about the value of
another variable.
Hypothesis for Test of Independence
The null hypothesis is that for each, the value obtained for one
variable is not related to or influenced by the second variable. This
idea can be expressed in two versions:
- Version 1: A single sample is measured on two separate variables.
For example, knowing your personality will help predict your color
preference (alternative). Knowing your personality will NOT help you
predict your color preference (null) [Personality and color preference
are measured per person]
- Null: The variables are not related.
- Alternative: The variables are related.
- Version 2: Two (or more) samples are measured and compared to see if
there are differences. For example, the same proportions of extroverts
(group 1) and introverts (group 2) prefer the same color (null). If the
proportions are different for the two groups, then you have the
alternative hypothesis
- Null: The samples are independent
- Alternative: The samples are not independent
Here we are working with Version 1 (one group taking two types of
items)
- \(H_0:\) The item difficulty is not
related to how a person changes their answer
- \(H_1:\) The item difficulty is
related to how a person changes their answer
Find Expected Frequencies
This is little more complex than the goodness of fit test
Step 1: Find row/col sums
Easy |
97 |
411 |
508 |
Difficult |
251 |
620 |
871 |
Sum |
348 |
1031 |
1379 |
Step 2: Expected frequencies per cell
\[f_e =
\frac{col\,total*row\,total}{overall\,total}\]
Easy |
97 (128.1972) |
411 (379.8028) |
508 |
Difficult |
251 (219.8028) |
620 (651.1972) |
871 |
Sum |
348 |
1031 |
1379 |
Test of Independence Calculation by Hand
\[\chi^2 = \sum
\frac{(f_o-f_e)^2}{f_e}\]
\(\chi^2 = \frac{(97-128.1972)^2}{128.1972}
+ \frac{(411-379.8028)^2}{379.8028}
+\frac{(251-219.8028)^2}{219.8028}+\frac{(620-651.1972)^2}{651.1972}\)
\(\chi^2 = 16.08\)
Test Against Distribution
\(df = (Row-1)(Col-1)\) \(df = (2-1)(2-1) = 1\)
Given our \(df = 1\). We calculated
16.08 we can use R or a table to get the critical values for alpha =
.05
Crit.MCQ=qchisq(.05, df=1, lower.tail = FALSE)
We get the crit = 3.8414588 < 16.08, so we reject the null.
Test of Independence Calculation by Code
Step 1: Build Your table
MCQ.Study.2 <- as.table(rbind(c(97, 411), c(251, 620)))
dimnames(MCQ.Study.2) <- list(Social = c("Easy","Diff"),
Change = c("RtoW", "WtoR"))
MCQ.Study.2
## Change
## Social RtoW WtoR
## Easy 97 411
## Diff 251 620
Step 2: Calculate chi-square
In tests of independence, it will calculate the expected frequencies
for you. Also, you can apply a correction called the Yates’ continuity
correction which reduced the error of when looking up discrete values on
the continuous chi-square distribution. You should always use this
version of the formula as it will be more conservative. You would simply
write Yates corrected chi-square tests in your method section (no one
uses the subscript as I wrote below).
\[\chi^2_{Yates} = \sum \frac{(|f_o-f_e| -
.5)^2}{f_e}\]
Note: you can view observed and expected frequencies. Also,
you can simulate the results as we did before.
(MCQ.chi.2 <- chisq.test(MCQ.Study.2,correct = TRUE))
MCQ.chi.2$observed # observed counts (same as M)
MCQ.chi.2$expected # expected counts under the null
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: MCQ.Study.2
## X-squared = 15.566, df = 1, p-value = 7.968e-05
##
## Change
## Social RtoW WtoR
## Easy 97 411
## Diff 251 620
## Change
## Social RtoW WtoR
## Easy 128.1972 379.8028
## Diff 219.8028 651.1972
Step 3: Effect size
Biased calculation phi (\(\varphi\))
and cohen’s w can be estimated using this same formula (which is needed
for power analysis). These are basically correlation coefficients when
you have a 2x2 contingency table.
\[\varphi =
\sqrt\frac{\chi^2}{N}\]
Cramer’s V, which is similar (\(\varphi\)), but used for when you have
large than 2x2 tables.
\[V = \sqrt\frac{\chi^2}{N*min(C-1,
R-1)}\]
\(V = \sqrt\frac{15.566}{1379*1} =
0.106283\)
1 |
0.10 |
0.30 |
0.50 |
2 |
0.07 |
0.21 |
0.35 |
3 |
0.06 |
0.17 |
0.29 |
4 |
0.05 |
0.15 |
0.25 |
5 |
0.04 |
0.13 |
0.22 |
Odd-Ratio (OR) as Effect size
Some people (mostly in the clinical) prefer odds ratios, but they can
only work when you have a r X 2 table
Odds Ratio (OR) is a measure of association between exposure and an
outcome.
Easy |
97 (A) |
411 (B) |
Difficult |
251 (C) |
620 (D) |
Conceptually:
\[OR = \frac{AD}{BC}\]
\(OR = \frac{97*620}{411*251} =
0.58\)
So, people are .58 times more likely to switch from
right-to-wrong/wrong-to-right based on the difficulty of the item. (OR
< 1, so it’s less likely to happen). The item difficulty is
significant as we already saw, but the difficulty has minimal
impact.
In practice, we can use a package, which has other versions which can
apply corrections and give us CIs around OR.
library(epitools)
# Regular
oddsratio.wald(MCQ.Study.2, correction=TRUE)$measure
# Small samples
oddsratio.small(MCQ.Study.2, correction=TRUE)$measure
## odds ratio with 95% C.I.
## Social estimate lower upper
## Easy 1.0000000 NA NA
## Diff 0.5829722 0.4470703 0.7601862
## odds ratio with 95% C.I.
## Social estimate lower upper
## Easy 1.0000000 NA NA
## Diff 0.5792495 0.4485089 0.7619142
Step 4: Report in APA
\(\chi^2(df,N) = X.XX, p < |= .XXX, V =
.XX | OR = X.XX\)
Since our result was p-value < 7.968e-05
The item difficulty is related to how a person changes their answer,
\(\chi^2(1,1379) = 15.57, p < .0001, V =
.11\). [That is all we can say statistically. Normally people
present a table in percentages to unpack this result,
but You have to decide if you want to do row or column
percentages. People do not present both]. I think the row percent make
more sense in this case we want to compare across item difficulty.
Row Proportion Code
prop.table(MCQ.Study.2,1)
Easy |
19.1% |
80.9% |
100% |
Difficult |
28.8% |
71.2% |
100% |
Col Total |
25.2% |
74.8% |
100% |
Col Proportion Code
prop.table(MCQ.Study.2,2)
Easy |
27.9% |
39.9% |
36.8% |
Difficult |
72.1% |
60.1% |
63.2% |
% |
100% |
100% |
100% |
Chi-Square Issues
- We must have at least five responses per cell (it will calculate but
its an assumption of the test)
- Chi-squared cannot be negative because all discrepancies are
squared.
- Chi-squared can be zero, but only in the unusual event that each
observed frequency exactly equals the corresponding expected
frequency.
- Other things being equal, the larger the discrepancy between the
expected frequencies and their corresponding observed frequencies, the
larger the observed value of chi-square.
- It is not the size of the discrepancy alone that accounts for a
contribution to the value of chi-square, but the size of the discrepancy
relative to the magnitude of the expected frequency.
- The value of chi-square depends on the number of discrepancies
involved in its calculation.
- There is no follow-up method, so we can remove conditions
and re-test our chi-square (or one one-way chi-square), but you will
need to Bonferroni correct the pvalues by hand (pvalue X number of tests
conducted).
- High rate of Type II error
Power in Chi-Squared
Let’s use our use the V we got in the study above to substitute for
Cohen’s W. Let’s use the power package to solve for N (total # of
observations needed)
library(pwr)
pwr.chisq.test(w = 0.106283, N = NULL, df = 1, sig.level = 0.05, power = .80)
##
## Chi squared power calculation
##
## w = 0.106283
## N = 694.8307
## df = 1
## sig.level = 0.05
## power = 0.8
##
## NOTE: N is the number of observations
Other Classical Non-Parametric Tests
Nominal Data:
- Chi-square test is the non-parametric equivalent to z, t, or F
tests, but for nominal data only!
- Binomial/sign test is a special case of the Chi-squared
- Another older alternative is Fisher’s Exact test
Fisher’s Exact test
Fisher’s Exact test is like a chi-square, but its calculated
differently and can be more conservative than Pearson’s chi-square. Its
often used when you have small cell sizes.
fisher.test(MCQ.Study.2, simulate.p.value = TRUE, B = 1e5)
##
## Fisher's Exact Test for Count Data
##
## data: MCQ.Study.2
## p-value = 6.496e-05
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
## 0.4421001 0.7654197
## sample estimates:
## odds ratio
## 0.5831962
Binominal Data
The binomial distribution approaches a normal distribution as you add
more trials (for example, the more coin flips you have the more normal
the distribution looks; where p=prob of head, and q=prob of tails, n =
coin flips). Generally, when the values of pn and qn are both equal to
10, the distribution approaches normal. Note: \(\mu=pn\), \(\sigma = \sqrt{npq}\). Note this test is an
old test useful when people tended to do stats by hand.
\[Z = \frac{X-\mu}{\sigma} =
\frac{X-pn}{\sqrt{npq}}\]
We can use our Zcrit table again (remember \(\alpha=.05\) yields \(Z_{crit} = 1.96\))
Let’s use our goodness of fit data again:
Binomial by hand
We just need to call one of the conditions a “success” (we will pick
Wrong-to-Right; \(X = 195\)). So \(p = .5\), \(q =
.5\), Our \(n = 195+27 =
222\)
\(Z = \frac{195-.5*222}{\sqrt{222*.5*.5}} =
11.27542\)
\(Z = 11.28, p < .05\)
Note: \(Z^2 = \chi^2\) = 11.27542^2
= 127.14 (the one-way \(\chi^2\) value
we got above!)
Binomial by R function
binom.test(195, 222, p = 0.5,
conf.level = 0.95)
##
## Exact binomial test
##
## data: 195 and 222
## number of successes = 195, number of trials = 222, p-value < 2.2e-16
## alternative hypothesis: true probability of success is not equal to 0.5
## 95 percent confidence interval:
## 0.8279981 0.9182995
## sample estimates:
## probability of success
## 0.8783784
Sign test
- Sign test is a special case of the binomial test
- A sign test compares the number of times a treatment results one
direction over another.
- Example, let’s say that you were a therapist charting several of
your patient’s improvement to a new type of therapy you were using. You
cannot measure the magnitude of the improvement, but you can record if
you see if they improve or get worse.
Sign tests:
- Are used when you have the direction of change from an
experiment
- Can be used as a pilot test to see if you should move forward in an
experiment
- Can support a hypothesis when all other tests fail
- Are not as sensitive as parametric tests
- Use the same calculation as the binomial test; you just count the
number of pluses and minuses
Ordinal Data
Wilcoxon rank sum test
Non-parametric equivalent to the t-test. This test compares ranks and
not the means. It comes in two flavors (paired-sample and independent
sample [also called the Mann-Whitney U-test])
Wilcoxon rank sum test for independent sample
\(H_0:\) There is no difference
between the two treatments.
- Therefore, there is no tendency for the ranks of one treatment
condition to be systematically higher or lower than the ranks for the
other treatment.
\(H_1:\) There is a difference
between the two treatments.
- Therefore, the ranks in one treatment condition are systematically
higher or lower than the ranks in another treatment.
41 |
10 |
39 |
14 |
37 |
9 |
44 |
17 |
40 |
12 |
45 |
8 |
46 |
104 |
Data frame in R
data.W<-data.frame(IV=c(rep("G1",7),rep("G2",7)),
DV =c(41,39,37,44,40,45,46,10,14,9,13,12,8,104))
Independent t-test
library(dplyr)
data.W %>% group_by(IV) %>% summarise(Mean=mean(DV), SD=sd(DV))
t.test(DV~IV,data=data.W, paired=FALSE)
## # A tibble: 2 × 3
## IV Mean SD
## <chr> <dbl> <dbl>
## 1 G1 41.7 3.35
## 2 G2 24.3 35.2
##
## Welch Two Sample t-test
##
## data: DV by IV
## t = 1.3035, df = 6.1087, p-value = 0.2394
## alternative hypothesis: true difference in means between group G1 and group G2 is not equal to 0
## 95 percent confidence interval:
## -15.14833 50.00547
## sample estimates:
## mean in group G1 mean in group G2
## 41.71429 24.28571
Independent W-test
wilcox.test(DV~IV,data=data.W, paired=FALSE)
##
## Wilcoxon rank sum exact test
##
## data: DV by IV
## W = 42, p-value = 0.02622
## alternative hypothesis: true location shift is not equal to 0
In this case, by comparing ranks and not raw scores, we can see the
non-parametric test gives a significant result (as we are comparing
ranks the variance difference between the groups goes away)
Note: If the data is paired sample, you simply have to say
paired=TRUE
Paired W-test
t.test(DV~IV,data=data.W, paired=TRUE)
wilcox.test(DV~IV,data=data.W, paired=TRUE, alternative =("two.sided"))
##
## Paired t-test
##
## data: DV by IV
## t = 1.3777, df = 6, p-value = 0.2175
## alternative hypothesis: true mean difference is not equal to 0
## 95 percent confidence interval:
## -13.52663 48.38378
## sample estimates:
## mean difference
## 17.42857
##
##
## Wilcoxon signed rank test with continuity correction
##
## data: DV by IV
## V = 21, p-value = 0.2702
## alternative hypothesis: true location shift is not equal to 0
Kruskal-Wallis Test
The non-parametric equivalent to the independent measures one-way
ANOVA. It compares three or more separate groups and is tested against
the chi-square distribution.
Like the W test, you would convert the data into ranks and calculate
the H value.
14 |
2 |
26 |
3 |
14 |
8 |
2 |
9 |
14 |
5 |
12 |
19 |
8 |
5 |
20 |
Data frame in R
data.H<-data.frame(IV=c(rep("G1",5),rep("G2",5),rep("G3",5)),
DV =c(14,3,2,5,8,
2,14,9,12,5,
26,8,14,19,20))
Kruskal-Wallis Test in R
kruskal.test(DV~IV, data=data.H)
##
## Kruskal-Wallis rank sum test
##
## data: DV by IV
## Kruskal-Wallis chi-squared = 6.0608, df = 2, p-value = 0.0483
You can follow up this analysis with the W test above
Friedman Test
Non-parametric one-way RM ANOVA. For this test you must have a
“block”. You block will be your ID variable. You can follow up this test
with Wilcoxon rank sum test (paired=TRUE).
1 |
14 |
2 |
26 |
2 |
3 |
14 |
8 |
3 |
2 |
9 |
14 |
4 |
5 |
12 |
19 |
5 |
8 |
5 |
20 |
Data frame in R
data.F<-data.frame(ID=rep(1:5,3),
IV=c(rep("G1",5),rep("G2",5),rep("G3",5)),
DV =c(14,3,2,5,8,
2,14,9,12,5,
26,8,14,19,20))
Friedman Test in R
friedman.test(DV~IV|ID, data=data.F)
##
## Friedman rank sum test
##
## data: DV and IV and ID
## Friedman chi-squared = 5.2, df = 2, p-value = 0.07427
You can follow up this analysis with the W test above
Pros and Cons
Classical non-parametrics are easy to run by hand and are often
useful if parametric tests fail (especially if you have large variance
or suspect your assumptions are not being met). However, they have a
high rate of Type II Error.
References
Best, J, B. (1979). Item difficulty and answer changing. Teaching
of Psychology, 6, 228-230
LS0tDQp0aXRsZTogIlBlYXJzb24ncyBDaGktU3F1YXJlIGFuZCBPdGhlciBVc2VmdWwgTm9uLVBhcmFtZXRyaWNzIg0KaGVhZGVyLWluY2x1ZGVzOg0KLSBcdXNlcGFja2FnZXthbXNtYXRofQ0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGZvbnRzaXplOiA4cHQNCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRoZW1lOiBmbGF0bHkNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogbm8NCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChjYWNoZT1UUlVFKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2UgPSBGQUxTRSkNCmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gIEZBTFNFKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aD00LjI1KQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5oZWlnaHQ9NC4wKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5hbGlnbj0nY2VudGVyJykgDQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLnBvcyA9ICdIJykNCmtuaXRyOjpvcHRzX2NodW5rJHNldChyZXN1bHRzPSdob2xkJykgDQpgYGANCg0KXHBhZ2VicmVhaw0KDQojIFBhcmFtZXRyaWMgdnMuIE5vbi1QYXJhbWV0cmljDQotIFBhcmFtZXRyaWMgdGVzdHM6IHRoZSB0ZXN0cyB3ZSBoYXZlIHN0dWRpZWQgc28gZmFyICh6LCB0LCBGKSBoYXZlIGJlZW4gdXNlZCB0byBkZXNjcmliZSBhIHBvcHVsYXRpb25zIGRpc3RyaWJ1dGlvbiAocGFyYW1ldGVycykuIA0KICAgIC0gUmVxdWlyZSBpbnRlcnZhbCBvciByYXRpbyBkYXRhIA0KLSBOb24tUGFyYW1ldHJpYyB0ZXN0czogZGVzY3JpYmUgcmVsYXRpb25zaGlwcyBhYm91dCB0aGF0IGV4aXN0IGluIHBvcHVsYXRpb25zIGJ1dCBtYWtlIHJlbGF4ZWQgKG9yIGRpZmZlcmVudCkgYXNzdW1wdGlvbnMgYWJvdXQgcG9wdWxhdGlvbnMgZGlzdHJpYnV0aW9ucy4gIA0KICAgIC0gVGhlc2UgdGVzdHMgY2FuIGNvbXBhcmUgcXVhbGl0YXRpdmUgZGF0YSAoZS5nLiwgY2hpLXNxdWFyZWQpDQogICAgLSBOb24tcGFyYW1ldHJpYyB0ZXN0cyBhcmUgbW9yZSBsaWtlbHkgdG8gY29tbWl0IHR5cGUgSUkgZXJyb3JzDQogICAgLSBUeXBpY2FsbHkgYXJlIHVzZWQgd2l0aCBvcmRpbmFsIG9yIG5vbWluYWwgZGF0YSwgYnV0IGNhbiBhbHNvIGJlIHVzZWQgd2l0aCBpbnRlcnZhbCBvciByYXRpbyBkYXRhIHdoZW4gcGFyYW1ldHJpYyBhc3N1bXB0aW9ucyBhcmUgbm90IG1ldCAoZS5nLiwgd2hlbiB2YXJpYW5jZSBvciBkaXN0cmlidXRpb24gcHJlc2VudHMgYSBwcm9ibGVtKS4NCiAgICAgICAgLSBUaGVzZSB0ZXN0cyBkbyBub3QgdXNlIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gc2luY2UgdGhleSBhcmUgb2Z0ZW4gbWVhbmluZ2xlc3MgaW4gb3JkaW5hbCBkYXRhLiANCiAgICAgICAgLSAqKlRoZXNlIHRlc3RzIHJhbmsgc2NvcmVzIHRvIHNlZSBob3cgZGlmZmVyZW50IGdyb3VwcyBjb21wYXJlIHRvIGVhY2ggb3RoZXIuKioNCg0KIyBPbmUtV2F5IFBlYXJzb24ncyBDaGktU3F1YXJlZCBbR29vZG5lc3Mgb2YgRml0XQ0KSGF2ZSB5b3UgYmVlbiB0b2xkOiAiU3RheSB3aXRoIHlvdXIgZmlyc3QgYW5zd2VyIG9uIGEgbXVsdGlwbGUtY2hvaWNlIHRlc3QuIiAgKlNvIGlzIGNoYW5naW5nIGFuc3dlcnMgbW9yZSBsaWtlbHkgdG8gYmUgaGFybWZ1bD8qDQoNCj4gQmVzdCAoMTk3OSkgc3R1ZGllZCB0aGUgcmVzcG9uc2VzIG9mIDI2MSBzdHVkZW50cyBpbiBhbiBpbnRyb2R1Y3RvcnkgcHN5Y2hvbG9neSBjb3Vyc2UuICBIZSByZWNvcmRlZCB0aGUgbnVtYmVyIG9mIHJpZ2h0LXRvLXdyb25nICgyNyksIHdyb25nLXRvLXJpZ2h0ICgxOTUpLCBhbmQgd3JvbmctdG8td3JvbmcgKDM5KSBhbnN3ZXIgY2hhbmdlcyBmb3IgZWFjaCBzdHVkZW50LiBOb3RlOiBXZSB3aWxsIGlnbm9yZSB3cm9uZy10by13cm9uZyBhcyBoZSBkaWQgaW4gaGlzIGZpcnN0IGFuYWx5c2lzLiAgDQoNCkZyZXF1ZW5jeSB8IFJpZ2h0LXRvLVdyb25nIHwgV3JvbmctdG8tUmlnaHQNCjotLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tLTogDQpPYnNlcnZlZCAgfCAgMjcgICAgICAgICAgICB8IDE5NQ0KDQpUb3RhbCBvZiAyMjIgb2JzZXJ2YXRpb25zDQoNCldlIHdpbGwgdXNlIHRoZSAqKk9uZS1XYXkgQ2hpLVNxdWFyZWQqKiBbR29vZG5lc3Mgb2YgZml0XS4gSXQgYXNrcyB3aGV0aGVyIHRoZSByZWxhdGl2ZSBmcmVxdWVuY2llcyBvYnNlcnZlZCBpbiB0aGUgY2F0ZWdvcmllcyBvZiBhIHNhbXBsZSBmcmVxdWVuY3kgZGlzdHJpYnV0aW9uIGFyZSBpbiBhZ3JlZW1lbnQgd2l0aCB0aGUgcmVsYXRpdmUgZnJlcXVlbmNpZXMgaHlwb3RoZXNpemVkIHRvIGJlIHRydWUgaW4gdGhlIHBvcHVsYXRpb24uDQoNCiMjIEh5cG90aGVzaXMgZm9yIEdvb2RuZXNzIG9mIGZpdA0KVGhlcmUgYXJlIHR3byB2ZXJzaW9uczogDQoNCi0gTm8gcHJlZmVyZW5jZTogdGhlcmUgd2lsbCBiZSBubyBwcmVmZXJlbmNlIGJldHdlZW4gZGlmZmVyZW50IGNhdGVnb3JpZXMgKGUuZy4sIGRvIHBlb3BsZSBwcmVmZXIgQ29rZSBvciBQZXBzaSkNCi0JTm8gZGlmZmVyZW5jZSBmcm9tIGEga25vd24gcG9wdWxhdGlvbjogVGhpcyB0eXBlIGh5cG90aGVzaXMgY29tcGFyZXMgdHdvIHBvcHVsYXRpb25zIChvciByZXByZXNlbnRhdGl2ZSBzYW1wbGVzKQ0KDQpJZiBwZW9wbGUgd2VyZSBtYWtpbmcgY2hhbmNlIGd1ZXNzZXMgZnJvbSBhIHBvcHVsYXRpb24gb2YgcGVvcGxlIHdobyBkb24ndCBoYXZlIGFueSBrbm93bGVkZ2UgYWJvdXQgbWF0ZXJpYWwgb24gdGhlIHRlc3QgKHZlcnNpb24gMiBvZiB0aGUgaHlwb3RoZXNpcyk6DQoNCi0gJEhfMDogUF97cmlnaHQtdG8td3Jvbmd9ID0gLjUsIFBfe3dyb25nLXRvLXJpZ2h0fSA9IC41JCANCi0gJEhfMTogSF8wJCBpcyBGYWxzZSANCg0KKk5vdGU6KiBUaGUgcHJvYmFiaWxpdHkgeW91IHNldCBjYW4gYmUgd2hhdGV2ZXIgeW91IHdhbnQsIGJ1dCBhY3Jvc3MgYWxsIGNlbGxzLCB0aGV5IG11c3QgYWRkIHRvIDEuIFdoZW4geW91IGRvIG5vdCBrbm93IHdoYXQgcHJvYmFiaWxpdHkgc2hvdWxkIGJlIGZyb20gYSB0aGVvcmV0aWNhbCBzdGFuZHBvaW50LCB5b3UgY2FuIHNpbXBseSBkbyAxL051bWJlciBvZiBjZWxscy4gDQoNCiMjIyBGaW5kIEV4cGVjdGVkIEZyZXF1ZW5jaWVzDQoNCklmIHdlIGV4cGVjdCBieSBjaGFuY2UgcGVvcGxlIHdvdWxkIGhhdmUgZ290dGVuIHAgPSAuNTAgb24gd3JvbmctdG8tcmlnaHQgYW5kIHJpZ2h0IHRvIHdyb25nLCAkZl9lID0gcG4kICANCg0KJEVfe3JpZ2h0LXRvLXdyb25nfT0gLjUqMjIyPTExMSQNCiRFX3t3cm9uZy10by1yaWdodH09IC41KjIyMj0xMTEkDQoNCkZyZXF1ZW5jeSB8IFJpZ2h0LXRvLVdyb25nIHwgV3JvbmctdG8tUmlnaHQNCjotLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tOnw6LS0tLS0tLS0tLS0tLTogDQpPYnNlcnZlZCAgfCAgMjcgICAgICAgICAgICB8IDE5NQ0KRXhwZWN0ZWQgIHwgIDExMSAgICAgICAgICAgfCAxMTENCg0KKk5vdGU6KiBUaGVzZSB0YWJsZXMgYXJlIG9mdGVuIHNob3duIGluIHBhcGVycyAoc29tZXRpbWVzIGFzIHByb3BvcnRpb25zKS4NCg0KIyMgR29vZG5lc3Mgb2YgRml0IENhbGN1bGF0aW9uIGJ5IEhhbmQNCg0KJCRcY2hpXjIgPSBcc3VtIFxmcmFjeyhmX28tZl9lKV4yfXtmX2V9JCQNCg0KJFxjaGleMiA9IFxmcmFjeygyNy0xMTEpXjJ9ezExMX0rXGZyYWN7KDE5NS0xMTEpXjJ9ezExMX0gPSAxMjcuMTQkDQoNCipOb3RlOiogTmV2ZXIgZW50ZXIgcHJvcG9ydGlvbnMgaW50byB0aGUgY2hpLXNxdWFyZS4gWW91IG11c3Qgd29yayB3aXRoIGZyZXF1ZW5jaWVzLg0KDQojIyMgVGVzdCBBZ2FpbnN0IERpc3RyaWJ1dGlvbg0KVGhlIGNoaS1zcXVhcmUgZGlzdHJpYnV0aW9uIGlzIGEgbm9uLXBhcmFtZXRyaWMgZGlzdHJpYnV0aW9uIFtub3Qgbm9ybWFsXSAoc2VlIGhhbmRvdXQpLiBMaWtlIHRoZSBGLXRlc3QsIGl0IGhhcyBubyB0YWlscy4gVGhlIGRpc3RyaWJ1dGlvbiBjaGFuZ2VzIGFzIGEgZnVuY3Rpb24gb2YgdGhlIGRlZ3JlZXMgb2YgZnJlZWRvbSBbJGRmJCBpcyB0aGUgbnVtYmVyIG9mIGNlbGxzIC0gMV0NCg0KYGBge3IsIGVjaG89RkFMU0V9DQp4IDwtIHJjaGlzcSgxZTYsIDEpDQpoaXN0KHgsIHByb2I9VFJVRSwgbWFpbj0iQ2hpLVNxdWFyZSBIaXN0b2dyYW0vRGVuc2l0eSBQbG90OiBkZiA9IDEiLA0KICB4bGFiPSJDaGktc3F1YXJlIHZhbHVlIiwgeWxhYj0iUHJvYmFiaWxpdHkgRGVuc2l0eSIsIHhsaW09YygwLDIwKSwgeWxpbT1jKDAsMS4xKSkNCmxpbmVzKGRlbnNpdHkoeCksIGNvbD0ncmVkJykNCmBgYA0KDQoNCkp1c3QgbGlrZSB0aGUgRi10ZXN0IHdlIGFzayB3aGVyZSBpcyBvdXIgY2hpLXNxdWFyZSB2YWx1ZSByZWxhdGl2ZSB0byB0aGlzIGNoYW5jZSBkaXN0cmlidXRpb24gZ2l2ZW4gb3VyICRkZiA9IDEkLiAgV2UgY2FsY3VsYXRlZCAxMjcuMTQsIGFuZCB0aGF0IGlzIGluIHRoZSB0YWlsLiBXZSBjYW4gdXNlIFIgb3IgYSB0YWJsZSB0byBnZXQgdGhlIGNyaXRpY2FsIHZhbHVlcyBmb3IgYWxwaGEgPS4wNSANCg0KYGBge3J9DQpDcml0Lk1DUT1xY2hpc3EoLjA1LCBkZj0xLCBsb3dlci50YWlsID0gRkFMU0UpDQpgYGANCg0KV2UgZ2V0IHRoZSBjcml0ID0gYHIgQ3JpdC5NQ1FgIDwgMTI0LjE0LCBzbyB3ZSByZWplY3QgdGhlIG51bGwuICAgDQoNCiMjIyMgSW1wYWN0IG9mIGhpZ2hlciBERg0KSnVzdCBsaWtlIGluIEYtdGVzdHMgdGhlIHNoYXBlIG9mIGNoYW5jZSBkaXN0cmlidXRpb24gY2hhbmdlcyBhcyB3ZSBoYXZlIG1vcmUgZGYuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KeCA8LSByY2hpc3EoMWU2LCA0KQ0KaGlzdCh4LCBwcm9iPVRSVUUsIG1haW49IkNoaS1TcXVhcmUgSGlzdG9ncmFtL0RlbnNpdHkgUGxvdDogZGYgPSA0IiwNCiAgeGxhYj0iQ2hpLXNxdWFyZSB2YWx1ZSIsIHlsYWI9IlByb2JhYmlsaXR5IERlbnNpdHkiLCB4bGltPWMoMCwyMCksIHlsaW09YygwLC4yKSkNCmxpbmVzKGRlbnNpdHkoeCksIGNvbD0ncmVkJykNCmBgYA0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KeCA8LSByY2hpc3EoMWU2LCA4KQ0KaGlzdCh4LCBwcm9iPVRSVUUsIG1haW49IkNoaS1TcXVhcmUgSGlzdG9ncmFtL0RlbnNpdHkgUGxvdDogZGYgPSA4IiwNCiAgeGxhYj0iQ2hpLXNxdWFyZSB2YWx1ZSIsIHlsYWI9IlByb2JhYmlsaXR5IERlbnNpdHkiLCB4bGltPWMoMCwyMCksIHlsaW09YygwLC4yKSkNCmxpbmVzKGRlbnNpdHkoeCksIGNvbD0ncmVkJykNCmBgYA0KDQpBcyB5b3UgY2FuIHNlZSB0aGUgZGlzdHJpYnV0aW9uIGdldHMgbW9yZSBzcHJlYWQgb3V0LiBTbyB3aXRoIGxhcmdlciBERiBvdXIgY3JpdGljYWwgdmFsdWUgaW5jcmVhc2VzDQoNCmBgYHtyfQ0KQ2hpQ3JpdDwtcWNoaXNxKC4wNSwgMTo4LCBsb3dlci50YWlsID0gRkFMU0UpDQpwbG90KENoaUNyaXQsIG1haW49IkNoaS1TcXVhcmUgQ3JpdGljYWwgVmFsdWVzOiBhbHBoYSA9IC4wNSIsDQogIHhsYWI9ImRmIiwgeWxhYj0iQ3JpdGljYWwgVmFsdWUiLCB4bGltPWMoMSw4KSwgeWxpbT1jKDAsMjUpKQ0KYGBgDQoNCg0KDQojIyBHb29kbmVzcyBvZiBGaXQgQ2FsY3VsYXRpb24gYnkgQ29kZQ0KDQojIyMgU3RlcCAxOiBCdWlsZCB5b3VyIFRhYmxlDQoNCmBgYHtyfQ0KTUNRLlN0dWR5IDwtIGFzLnRhYmxlKHJiaW5kKGMoMjcsIDE5NSkpKQ0KZGltbmFtZXMoTUNRLlN0dWR5KSA8LSBsaXN0KEZyZXEgPSBjKCJPYnNlcnZlZCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgQWN0aW9uID0gYygiUnRvVyIsICJXdG9SIikpDQpNQ1EuU3R1ZHkNCmBgYA0KDQojIyMgU3RlcCAyOiBDYWxjdWxhdGUgQ2hpLXNxdWFyZWQNCg0KYGBge3J9DQooTUNRLmNoaSA8LSBjaGlzcS50ZXN0KE1DUS5TdHVkeSwgcD1jKC41LCAuNSkpKQ0KYGBgDQoNCiMjIyMgU3RlcCAyYTogQ2FsY3VsYXRlIGNoaS1zcXVhcmUgdmlhIE1vbnRlIENhcmxvIHNpbXVsYXRpb24NCkluIHRoZSBnb29kbmVzcy1vZi1maXQgc2ltdWxhdGlvbiBpcyBkb25lIGJ5IHJhbmRvbSBzYW1wbGluZyBmcm9tIHRoZSBkaXNjcmV0ZSBkaXN0cmlidXRpb24gc3BlY2lmaWVkIGJ5IHAsIGVhY2ggc2FtcGxlIGJlaW5nIHRoZSB0b3RhbCBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIChzZWUgP2NoaXNxLnRlc3QgZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgc2ltdWxhdGlvbiBwcm9jZXNzKQ0KDQpgYGB7cn0NCihNQ1EuY2hpIDwtIGNoaXNxLnRlc3QoTUNRLlN0dWR5LCBwPWMoLjUsIC41KSwgc2ltdWxhdGUucC52YWx1ZSA9IFRSVUUsIEIgPSAxMDAwMCkpDQpgYGANCg0KIyMjIFN0ZXAgMzogUmVwb3J0IGluIEFQQQ0KDQokXGNoaV4yKGRmLE4pID0gWC5YWCwgcCA8IHw9IC5YWFgkDQoNClNpbmNlIG91ciByZXN1bHQgd2FzIHAtdmFsdWUgPCAyLjJlLTE2DQoNCiRcY2hpXjIoMSxOID0gMjIyKSA9IDEyNC4xNCwgcCA8IC4wMDAxJA0KDQpUaGVyZSBpcyBhIGRpZmZlcmVuY2UgaG93IHBlb3BsZSBjaGFuZ2UgdGhlaXIgaXRlbXMsIGFuZCB3ZSBjYW4gc2VlIGZyb20gdGhlIGZyZXF1ZW5jaWVzIHRoYXQgc2hvdWxkIGNoYW5nZSB0aGVpciBhbnN3ZXJzIGlmIHRoZXkgYXJlIHVuc3VyZS4gDQoNClxwYWdlYnJlYWsNCg0KIyBUd28tV2F5IFBlYXJzb24ncyBDaGktU3F1YXJlZCBbVGVzdCBvZiBJbmRlcGVuZGVuY2VdIA0KIk1heWJlIHdlIHNob3VsZCBvbmx5IGNoYW5nZSBvdXIgYW5zd2VycyBvbiBlYXN5IGl0ZW1zLCBidXQgb24gaGFyZCBpdGVtcywgd2Ugc2hvdWxkIHRydXN0IG91cnNlbHZlcy4iDQoNCj4gQmVzdCAoMTk3OSkgYWxzbyBleGFtaW5lZCB0aGUgMTY3MCB0b3RhbCBudW1iZXIgb2YgcmVzcG9uc2VzIGFjcm9zcyB0aGUgMjYxIHN0dWRlbnRzIGFuZCBkaXZpZGVkIHRoZSBpdGVtcyBpbnRvIGVhc3kvZGlmZmljdWx0IGluIGFuIGludHJvZHVjdG9yeSBwc3ljaG9sb2d5IGNvdXJzZS4gIEhlIHJlY29yZGVkIHRoZSBudW1iZXIgb2YgcmlnaHQtdG8td3JvbmcsIHdyb25nLXRvLXJpZ2h0LCBhbmQgd3JvbmctdG8td3JvbmcgKDM5KSBhbnN3ZXIgY2hhbmdlcyBmb3IgZWFjaCBzdHVkZW50LiBBZ2FpbiB3ZSB3aWxsIGlnbm9yZSB3cm9uZy10by13cm9uZyAoMTclIG9mIHRoZSByZXNwb25zZXMpIGZvciBzaW1wbGljaXR5Lg0KDQpGcmVxdWVuY3kgfCBSaWdodCB0byBXcm9uZyB8IFdyb25nIHRvIFJpZ2h0IA0KLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLQ0KRWFzeSAgICAgfCAgOTcgICAgICAgICAgICB8IDQxMQ0KRGlmZmljdWx0fCAgMjUxICAgICAgICAgICB8IDYyMA0KDQpXZSBuZWVkIHRvIGRvIGEgVHdvLVdheSBDaGktU3F1YXJlIFtUZXN0IG9mIEluZGVwZW5kZW5jZV0uIEl0IGFza3Mgd2hldGhlciBvYnNlcnZlZCBmcmVxdWVuY2llcyByZWZsZWN0IHRoZSBpbmRlcGVuZGVuY2Ugb2YgdHdvIHF1YWxpdGF0aXZlIHZhcmlhYmxlcy4gQ29tcGFyZXMgdGhlIGFjdHVhbCBvYnNlcnZlZCBmcmVxdWVuY2llcyBvZiBzb21lIHBoZW5vbWVub24gKGluIG91ciBzYW1wbGUpIHdpdGggdGhlIGZyZXF1ZW5jaWVzIHdlIHdvdWxkIGV4cGVjdCBpZiB0aGVyZSB3ZXJlIG5vIHJlbGF0aW9uc2hpcCBhdCBhbGwgYmV0d2VlbiB0aGUgdHdvIHZhcmlhYmxlcyBpbiB0aGUgbGFyZ2VyIChzYW1wbGVkKSBwb3B1bGF0aW9uLiBXZSBhc2sgaWYgdGhlIHR3byB2YXJpYWJsZXMgYXJlIGluZGVwZW5kZW50OiBrbm93bGVkZ2Ugb2YgdGhlIHZhbHVlIG9mIG9uZSB2YXJpYWJsZSBwcm92aWRlcyBubyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdmFsdWUgb2YgYW5vdGhlciB2YXJpYWJsZS4NCg0KIyMgSHlwb3RoZXNpcyBmb3IgVGVzdCBvZiBJbmRlcGVuZGVuY2UNCg0KVGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0aGF0IGZvciBlYWNoLCB0aGUgdmFsdWUgb2J0YWluZWQgZm9yIG9uZSB2YXJpYWJsZSBpcyBub3QgcmVsYXRlZCB0byBvciBpbmZsdWVuY2VkIGJ5IHRoZSBzZWNvbmQgdmFyaWFibGUuICBUaGlzIGlkZWEgY2FuIGJlIGV4cHJlc3NlZCBpbiB0d28gdmVyc2lvbnM6DQoNCi0gVmVyc2lvbiAxOiBBIHNpbmdsZSBzYW1wbGUgaXMgbWVhc3VyZWQgb24gdHdvIHNlcGFyYXRlIHZhcmlhYmxlcy4gRm9yIGV4YW1wbGUsIGtub3dpbmcgeW91ciBwZXJzb25hbGl0eSB3aWxsIGhlbHAgcHJlZGljdCB5b3VyIGNvbG9yIHByZWZlcmVuY2UgKGFsdGVybmF0aXZlKS4gS25vd2luZyB5b3VyIHBlcnNvbmFsaXR5IHdpbGwgTk9UIGhlbHAgeW91IHByZWRpY3QgeW91ciBjb2xvciBwcmVmZXJlbmNlIChudWxsKSBbUGVyc29uYWxpdHkgYW5kIGNvbG9yIHByZWZlcmVuY2UgYXJlIG1lYXN1cmVkIHBlciBwZXJzb25dDQogICAgLQlOdWxsOiBUaGUgdmFyaWFibGVzIGFyZSBub3QgcmVsYXRlZC4gDQogICAgLQlBbHRlcm5hdGl2ZTogVGhlIHZhcmlhYmxlcyBhcmUgcmVsYXRlZC4gDQoNCi0gVmVyc2lvbiAyOiBUd28gKG9yIG1vcmUpIHNhbXBsZXMgYXJlIG1lYXN1cmVkIGFuZCBjb21wYXJlZCB0byBzZWUgaWYgdGhlcmUgYXJlIGRpZmZlcmVuY2VzLiBGb3IgZXhhbXBsZSwgdGhlIHNhbWUgcHJvcG9ydGlvbnMgb2YgZXh0cm92ZXJ0cyAoZ3JvdXAgMSkgYW5kIGludHJvdmVydHMgKGdyb3VwIDIpIHByZWZlciB0aGUgc2FtZSBjb2xvciAobnVsbCkuICBJZiB0aGUgcHJvcG9ydGlvbnMgYXJlIGRpZmZlcmVudCBmb3IgdGhlIHR3byBncm91cHMsIHRoZW4geW91IGhhdmUgdGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMNCiAgICAtCU51bGw6IFRoZSBzYW1wbGVzIGFyZSBpbmRlcGVuZGVudCANCiAgICAtCUFsdGVybmF0aXZlOiBUaGUgc2FtcGxlcyBhcmUgbm90IGluZGVwZW5kZW50DQoNCkhlcmUgd2UgYXJlIHdvcmtpbmcgd2l0aCBWZXJzaW9uIDEgKG9uZSBncm91cCB0YWtpbmcgdHdvIHR5cGVzIG9mIGl0ZW1zKQ0KDQotICRIXzA6JCBUaGUgaXRlbSBkaWZmaWN1bHR5IGlzIG5vdCByZWxhdGVkIHRvIGhvdyBhIHBlcnNvbiBjaGFuZ2VzIHRoZWlyIGFuc3dlciANCi0gJEhfMTokIFRoZSBpdGVtIGRpZmZpY3VsdHkgaXMgcmVsYXRlZCB0byBob3cgYSBwZXJzb24gY2hhbmdlcyB0aGVpciBhbnN3ZXIgDQoNCiMjIEZpbmQgRXhwZWN0ZWQgRnJlcXVlbmNpZXMNClRoaXMgaXMgbGl0dGxlIG1vcmUgY29tcGxleCB0aGFuIHRoZSBnb29kbmVzcyBvZiBmaXQgdGVzdA0KDQojIyMgU3RlcCAxOiBGaW5kIHJvdy9jb2wgc3Vtcw0KDQpGcmVxdWVuY3kgfCBSaWdodCB0byBXcm9uZyB8IFdyb25nIHRvIFJpZ2h0IHwgU3VtDQotLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfC0tLS0NCkVhc3kgICAgIHwgIDk3ICAgICAgICAgICAgfCA0MTEgICAgICAgICAgICB8ICoqNTA4KioNCkRpZmZpY3VsdHwgIDI1MSAgICAgICAgICAgfCA2MjAgICAgICAgICAgICB8ICoqODcxKioNClN1bSAgICAgIHwgICoqMzQ4KiogICAgICAgfCAqKjEwMzEqKiAgICAgICB8ICoqMTM3OSoqIA0KDQojIyMgU3RlcCAyOiBFeHBlY3RlZCBmcmVxdWVuY2llcyBwZXIgY2VsbA0KDQokJGZfZSA9IFxmcmFje2NvbFwsdG90YWwqcm93XCx0b3RhbH17b3ZlcmFsbFwsdG90YWx9JCQNCg0KDQpGcmVxdWVuY3kgfCBSaWdodCB0byBXcm9uZyB8IFdyb25nIHRvIFJpZ2h0IHwgU3VtDQotLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfC0tLS0NCkVhc3kgICAgIHwgIDk3ICgxMjguMTk3MikgfCA0MTEgKDM3OS44MDI4KSB8ICoqNTA4KioNCkRpZmZpY3VsdHwgIDI1MSAoMjE5LjgwMjgpfCA2MjAgKDY1MS4xOTcyKSB8ICoqODcxKioNClN1bSAgICAgIHwgICoqMzQ4KiogICAgICAgfCAqKjEwMzEqKiAgICAgICB8ICoqMTM3OSoqIA0KDQoNCiMjIFRlc3Qgb2YgSW5kZXBlbmRlbmNlIENhbGN1bGF0aW9uIGJ5IEhhbmQNCg0KJCRcY2hpXjIgPSBcc3VtIFxmcmFjeyhmX28tZl9lKV4yfXtmX2V9JCQNCg0KJFxjaGleMiA9IFxmcmFjeyg5Ny0xMjguMTk3MileMn17MTI4LjE5NzJ9ICsgXGZyYWN7KDQxMS0zNzkuODAyOCleMn17Mzc5LjgwMjh9ICtcZnJhY3soMjUxLTIxOS44MDI4KV4yfXsyMTkuODAyOH0rXGZyYWN7KDYyMC02NTEuMTk3MileMn17NjUxLjE5NzJ9JA0KDQokXGNoaV4yID0gMTYuMDgkDQoNCiMjIyBUZXN0IEFnYWluc3QgRGlzdHJpYnV0aW9uDQokZGYgPSAoUm93LTEpKENvbC0xKSQNCiRkZiA9ICgyLTEpKDItMSkgPSAxJA0KDQpHaXZlbiBvdXIgJGRmID0gMSQuICBXZSBjYWxjdWxhdGVkIDE2LjA4IHdlIGNhbiB1c2UgUiBvciBhIHRhYmxlIHRvIGdldCB0aGUgY3JpdGljYWwgdmFsdWVzIGZvciBhbHBoYSA9IC4wNSANCg0KDQpgYGB7cn0NCkNyaXQuTUNRPXFjaGlzcSguMDUsIGRmPTEsIGxvd2VyLnRhaWwgPSBGQUxTRSkNCmBgYA0KDQpXZSBnZXQgdGhlIGNyaXQgPSBgciBDcml0Lk1DUWAgPCAxNi4wOCwgc28gd2UgcmVqZWN0IHRoZSBudWxsLiAgIA0KDQoNCiMjIFRlc3Qgb2YgSW5kZXBlbmRlbmNlIENhbGN1bGF0aW9uIGJ5IENvZGUNCg0KIyMjIFN0ZXAgMTogQnVpbGQgWW91ciB0YWJsZQ0KDQpgYGB7cn0NCk1DUS5TdHVkeS4yIDwtIGFzLnRhYmxlKHJiaW5kKGMoOTcsIDQxMSksIGMoMjUxLCA2MjApKSkNCmRpbW5hbWVzKE1DUS5TdHVkeS4yKSA8LSBsaXN0KFNvY2lhbCA9IGMoIkVhc3kiLCJEaWZmIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDaGFuZ2UgPSBjKCJSdG9XIiwgIld0b1IiKSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpNQ1EuU3R1ZHkuMg0KYGBgDQoNCiMjIyBTdGVwIDI6IENhbGN1bGF0ZSBjaGktc3F1YXJlDQpJbiB0ZXN0cyBvZiBpbmRlcGVuZGVuY2UsIGl0IHdpbGwgY2FsY3VsYXRlIHRoZSBleHBlY3RlZCBmcmVxdWVuY2llcyBmb3IgeW91LiBBbHNvLCB5b3UgY2FuIGFwcGx5IGEgY29ycmVjdGlvbiBjYWxsZWQgdGhlIFlhdGVzJyBjb250aW51aXR5IGNvcnJlY3Rpb24gd2hpY2ggcmVkdWNlZCB0aGUgZXJyb3Igb2Ygd2hlbiBsb29raW5nIHVwIGRpc2NyZXRlIHZhbHVlcyBvbiB0aGUgY29udGludW91cyBjaGktc3F1YXJlIGRpc3RyaWJ1dGlvbi4gWW91IHNob3VsZCBhbHdheXMgdXNlIHRoaXMgdmVyc2lvbiBvZiB0aGUgZm9ybXVsYSBhcyBpdCB3aWxsIGJlIG1vcmUgY29uc2VydmF0aXZlLiBZb3Ugd291bGQgc2ltcGx5IHdyaXRlIFlhdGVzIGNvcnJlY3RlZCBjaGktc3F1YXJlIHRlc3RzIGluIHlvdXIgbWV0aG9kIHNlY3Rpb24gKG5vIG9uZSB1c2VzIHRoZSBzdWJzY3JpcHQgYXMgSSB3cm90ZSBiZWxvdykuDQoNCiQkXGNoaV4yX3tZYXRlc30gPSBcc3VtIFxmcmFjeyh8Zl9vLWZfZXwgLSAuNSleMn17Zl9lfSQkDQoNCipOb3RlKjogeW91IGNhbiB2aWV3IG9ic2VydmVkIGFuZCBleHBlY3RlZCBmcmVxdWVuY2llcy4gQWxzbywgeW91IGNhbiBzaW11bGF0ZSB0aGUgcmVzdWx0cyBhcyB3ZSBkaWQgYmVmb3JlLiANCg0KYGBge3J9DQooTUNRLmNoaS4yIDwtIGNoaXNxLnRlc3QoTUNRLlN0dWR5LjIsY29ycmVjdCA9IFRSVUUpKQ0KTUNRLmNoaS4yJG9ic2VydmVkICAgIyBvYnNlcnZlZCBjb3VudHMgKHNhbWUgYXMgTSkNCk1DUS5jaGkuMiRleHBlY3RlZCAgICMgZXhwZWN0ZWQgY291bnRzIHVuZGVyIHRoZSBudWxsDQpgYGANCg0KDQojIyMgU3RlcCAzOiBFZmZlY3Qgc2l6ZQ0KQmlhc2VkIGNhbGN1bGF0aW9uIHBoaSAoJFx2YXJwaGkkKSBhbmQgY29oZW4ncyB3IGNhbiBiZSBlc3RpbWF0ZWQgdXNpbmcgdGhpcyBzYW1lIGZvcm11bGEgKHdoaWNoIGlzIG5lZWRlZCBmb3IgcG93ZXIgYW5hbHlzaXMpLiBUaGVzZSBhcmUgYmFzaWNhbGx5IGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyB3aGVuIHlvdSBoYXZlIGEgMngyIGNvbnRpbmdlbmN5IHRhYmxlLiANCg0KJCRcdmFycGhpID0gXHNxcnRcZnJhY3tcY2hpXjJ9e059JCQNCg0KQ3JhbWVyJ3MgViwgd2hpY2ggaXMgc2ltaWxhciAoJFx2YXJwaGkkKSwgYnV0IHVzZWQgZm9yIHdoZW4geW91IGhhdmUgbGFyZ2UgdGhhbiAyeDIgdGFibGVzLg0KDQokJFYgPSBcc3FydFxmcmFje1xjaGleMn17TiptaW4oQy0xLCBSLTEpfSQkDQoNCiRWID0gXHNxcnRcZnJhY3sxNS41NjZ9ezEzNzkqMX0gPSAwLjEwNjI4MyQNCg0KDQp8IGRmICB8IFNtYWxsIHwgTWVkaXVtIHwgTGFyZ2UgfA0KfCA6LS0gfCA6LS0tLSB8IDotLS0tLSB8IDotLS0tIHwNCnwgMSAgIHwgMC4xMCAgfCAwLjMwICAgfCAwLjUwICB8DQp8IDIgICB8IDAuMDcgIHwgMC4yMSAgIHwgMC4zNSAgfA0KfCAzICAgfCAwLjA2ICB8IDAuMTcgICB8IDAuMjkgIHwNCnwgNCAgIHwgMC4wNSAgfCAwLjE1ICAgfCAwLjI1ICB8DQp8IDUgICB8IDAuMDQgIHwgMC4xMyAgIHwgMC4yMiAgfA0KDQojIyMjIE9kZC1SYXRpbyAoT1IpIGFzIEVmZmVjdCBzaXplDQpTb21lIHBlb3BsZSAobW9zdGx5IGluIHRoZSBjbGluaWNhbCkgcHJlZmVyIG9kZHMgcmF0aW9zLCBidXQgdGhleSBjYW4gb25seSB3b3JrIHdoZW4geW91IGhhdmUgYSByIFggMiB0YWJsZQ0KDQpPZGRzIFJhdGlvIChPUikgaXMgYSBtZWFzdXJlIG9mIGFzc29jaWF0aW9uIGJldHdlZW4gZXhwb3N1cmUgYW5kIGFuIG91dGNvbWUuIA0KDQpGcmVxdWVuY3kgfCBSaWdodCB0byBXcm9uZyB8IFdyb25nIHRvIFJpZ2h0IA0KLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLQ0KRWFzeSAgICAgfCAgOTcgIChBKSAgICAgICB8IDQxMSAoQikgICAgICAgICANCkRpZmZpY3VsdHwgIDI1MSAoQykgICAgICAgfCA2MjAgKEQpICAgICAgICAgDQoNCg0KQ29uY2VwdHVhbGx5OiANCg0KJCRPUiA9IFxmcmFje0FEfXtCQ30kJA0KDQokT1IgPSBcZnJhY3s5Nyo2MjB9ezQxMSoyNTF9ID0gMC41OCQNCg0KU28sIHBlb3BsZSBhcmUgLjU4IHRpbWVzIG1vcmUgbGlrZWx5IHRvIHN3aXRjaCBmcm9tIHJpZ2h0LXRvLXdyb25nL3dyb25nLXRvLXJpZ2h0IGJhc2VkIG9uIHRoZSBkaWZmaWN1bHR5IG9mIHRoZSBpdGVtLiAoT1IgPCAxLCBzbyBpdCdzIGxlc3MgbGlrZWx5IHRvIGhhcHBlbikuIFRoZSBpdGVtIGRpZmZpY3VsdHkgaXMgc2lnbmlmaWNhbnQgYXMgd2UgYWxyZWFkeSBzYXcsIGJ1dCB0aGUgZGlmZmljdWx0eSBoYXMgbWluaW1hbCBpbXBhY3QuIA0KDQpJbiBwcmFjdGljZSwgd2UgY2FuIHVzZSBhIHBhY2thZ2UsIHdoaWNoIGhhcyBvdGhlciB2ZXJzaW9ucyB3aGljaCBjYW4gYXBwbHkgY29ycmVjdGlvbnMgYW5kIGdpdmUgdXMgQ0lzIGFyb3VuZCBPUi4gDQoNCmBgYHtyfQ0KbGlicmFyeShlcGl0b29scykNCiMgUmVndWxhcg0Kb2Rkc3JhdGlvLndhbGQoTUNRLlN0dWR5LjIsIGNvcnJlY3Rpb249VFJVRSkkbWVhc3VyZQ0KIyBTbWFsbCBzYW1wbGVzDQpvZGRzcmF0aW8uc21hbGwoTUNRLlN0dWR5LjIsIGNvcnJlY3Rpb249VFJVRSkkbWVhc3VyZQ0KYGBgDQoNCg0KIyMjIFN0ZXAgNDogUmVwb3J0IGluIEFQQQ0KDQokXGNoaV4yKGRmLE4pID0gWC5YWCwgcCA8IHw9IC5YWFgsIFYgPSAuWFggfCBPUiA9IFguWFgkDQoNClNpbmNlIG91ciByZXN1bHQgd2FzIHAtdmFsdWUgPCA3Ljk2OGUtMDUNCg0KVGhlIGl0ZW0gZGlmZmljdWx0eSBpcyByZWxhdGVkIHRvIGhvdyBhIHBlcnNvbiBjaGFuZ2VzIHRoZWlyIGFuc3dlciwgJFxjaGleMigxLDEzNzkpID0gMTUuNTcsIHAgPCAuMDAwMSwgViA9IC4xMSQuIFtUaGF0IGlzIGFsbCB3ZSBjYW4gc2F5IHN0YXRpc3RpY2FsbHkuICBOb3JtYWxseSBwZW9wbGUgcHJlc2VudCBhIHRhYmxlIGluIHBlcmNlbnRhZ2VzIHRvIHVucGFjayB0aGlzIHJlc3VsdCwgKipidXQqKiBZb3UgaGF2ZSB0byBkZWNpZGUgaWYgeW91IHdhbnQgdG8gZG8gcm93IG9yIGNvbHVtbiBwZXJjZW50YWdlcy4gUGVvcGxlIGRvIG5vdCBwcmVzZW50IGJvdGhdLiBJIHRoaW5rIHRoZSByb3cgcGVyY2VudCBtYWtlIG1vcmUgc2Vuc2UgaW4gdGhpcyBjYXNlIHdlIHdhbnQgdG8gY29tcGFyZSBhY3Jvc3MgaXRlbSBkaWZmaWN1bHR5LiANCg0KIyMjIyBSb3cgUHJvcG9ydGlvbiBDb2RlDQpgYGB7ciwgZXZhbD1GQUxTRX0NCnByb3AudGFibGUoTUNRLlN0dWR5LjIsMSkNCmBgYA0KDQoNCiUgUm93ICAgIHwgUmlnaHQgdG8gV3JvbmcgfCBXcm9uZyB0byBSaWdodCB8ICUNCi0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS18LS0tLQ0KRWFzeSAgICAgfCAgMTkuMSUgICAgICAgICB8ICA4MC45JSAgICAgICAgIHwgMTAwJQ0KRGlmZmljdWx0fCAgMjguOCUgICAgICAgICB8ICA3MS4yJSAgICAgICAgIHwgMTAwJQ0KQ29sIFRvdGFsfCAgMjUuMiUgICAgICAgICB8ICA3NC44JSAgICAgICAgIHwgMTAwJSANCg0KDQojIyMjIENvbCBQcm9wb3J0aW9uIENvZGUNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcHJvcC50YWJsZShNQ1EuU3R1ZHkuMiwyKQ0KYGBgDQoNCiUgQ29sICAgIHwgUmlnaHQgdG8gV3JvbmcgfCBXcm9uZyB0byBSaWdodCB8IFJvdyBUb3RhbA0KLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLXwtLS0tDQpFYXN5ICAgICB8ICAyNy45JSAgICAgICAgIHwgIDM5LjklICAgICAgICAgfCAzNi44JQ0KRGlmZmljdWx0fCAgNzIuMSUgICAgICAgICB8ICA2MC4xJSAgICAgICAgIHwgNjMuMiUNCiUgICAgICAgIHwgIDEwMCUgICAgICAgICAgfCAgMTAwJSAgICAgICAgICB8IDEwMCUgDQoNCiMjIENoaS1TcXVhcmUgSXNzdWVzDQotIFdlIG11c3QgaGF2ZSBhdCBsZWFzdCBmaXZlIHJlc3BvbnNlcyBwZXIgY2VsbCAoaXQgd2lsbCBjYWxjdWxhdGUgYnV0IGl0cyBhbiBhc3N1bXB0aW9uIG9mIHRoZSB0ZXN0KQ0KLSBDaGktc3F1YXJlZCBjYW5ub3QgYmUgbmVnYXRpdmUgYmVjYXVzZSBhbGwgZGlzY3JlcGFuY2llcyBhcmUgc3F1YXJlZC4NCi0gQ2hpLXNxdWFyZWQgY2FuIGJlIHplcm8sIGJ1dCBvbmx5IGluIHRoZSB1bnVzdWFsIGV2ZW50IHRoYXQgZWFjaCBvYnNlcnZlZCBmcmVxdWVuY3kgZXhhY3RseSBlcXVhbHMgdGhlIGNvcnJlc3BvbmRpbmcgZXhwZWN0ZWQgZnJlcXVlbmN5Lg0KLSBPdGhlciB0aGluZ3MgYmVpbmcgZXF1YWwsIHRoZSBsYXJnZXIgdGhlIGRpc2NyZXBhbmN5IGJldHdlZW4gdGhlIGV4cGVjdGVkIGZyZXF1ZW5jaWVzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIG9ic2VydmVkIGZyZXF1ZW5jaWVzLCB0aGUgbGFyZ2VyIHRoZSBvYnNlcnZlZCB2YWx1ZSBvZiBjaGktc3F1YXJlLg0KLSBJdCBpcyBub3QgdGhlIHNpemUgb2YgdGhlIGRpc2NyZXBhbmN5IGFsb25lIHRoYXQgYWNjb3VudHMgZm9yIGEgY29udHJpYnV0aW9uIHRvIHRoZSB2YWx1ZSBvZiBjaGktc3F1YXJlLCBidXQgdGhlIHNpemUgb2YgdGhlIGRpc2NyZXBhbmN5IHJlbGF0aXZlIHRvIHRoZSBtYWduaXR1ZGUgb2YgdGhlIGV4cGVjdGVkIGZyZXF1ZW5jeS4NCi0gVGhlIHZhbHVlIG9mIGNoaS1zcXVhcmUgZGVwZW5kcyBvbiB0aGUgbnVtYmVyIG9mIGRpc2NyZXBhbmNpZXMgaW52b2x2ZWQgaW4gaXRzIGNhbGN1bGF0aW9uLg0KLSAqKlRoZXJlIGlzIG5vIGZvbGxvdy11cCBtZXRob2QsIHNvIHdlIGNhbiByZW1vdmUgY29uZGl0aW9ucyBhbmQgcmUtdGVzdCBvdXIgY2hpLXNxdWFyZSAob3Igb25lIG9uZS13YXkgY2hpLXNxdWFyZSksIGJ1dCB5b3Ugd2lsbCBuZWVkIHRvIEJvbmZlcnJvbmkgY29ycmVjdCB0aGUgcHZhbHVlcyBieSBoYW5kIChwdmFsdWUgWCBudW1iZXIgb2YgdGVzdHMgY29uZHVjdGVkKS4qKg0KLSBIaWdoIHJhdGUgb2YgVHlwZSBJSSBlcnJvcg0KDQojIFBvd2VyIGluIENoaS1TcXVhcmVkDQoNCkxldCdzIHVzZSBvdXIgdXNlIHRoZSBWIHdlIGdvdCBpbiB0aGUgc3R1ZHkgYWJvdmUgdG8gc3Vic3RpdHV0ZSBmb3IgQ29oZW4ncyBXLiBMZXQncyB1c2UgdGhlIHBvd2VyIHBhY2thZ2UgdG8gc29sdmUgZm9yIE4gKHRvdGFsICMgb2Ygb2JzZXJ2YXRpb25zIG5lZWRlZCkNCg0KYGBge3J9DQpsaWJyYXJ5KHB3cikNCnB3ci5jaGlzcS50ZXN0KHcgPSAwLjEwNjI4MywgTiA9IE5VTEwsIGRmID0gMSwgc2lnLmxldmVsID0gMC4wNSwgcG93ZXIgPSAuODApDQpgYGANCg0KDQpccGFnZWJyZWFrDQoNCiMgT3RoZXIgQ2xhc3NpY2FsIE5vbi1QYXJhbWV0cmljIFRlc3RzDQoNCiMjIE5vbWluYWwgRGF0YToNCi0gQ2hpLXNxdWFyZSB0ZXN0IGlzIHRoZSBub24tcGFyYW1ldHJpYyBlcXVpdmFsZW50IHRvIHosIHQsIG9yIEYgdGVzdHMsIGJ1dCBmb3Igbm9taW5hbCBkYXRhIG9ubHkhIAkNCiAgICAtIEJpbm9taWFsL3NpZ24gdGVzdCBpcyBhIHNwZWNpYWwgY2FzZSBvZiB0aGUgQ2hpLXNxdWFyZWQNCiAgICAtIEFub3RoZXIgb2xkZXIgYWx0ZXJuYXRpdmUgaXMgRmlzaGVyJ3MgRXhhY3QgdGVzdA0KDQojIyMgRmlzaGVyJ3MgRXhhY3QgdGVzdCANCkZpc2hlcidzIEV4YWN0IHRlc3QgaXMgbGlrZSBhIGNoaS1zcXVhcmUsIGJ1dCBpdHMgY2FsY3VsYXRlZCBkaWZmZXJlbnRseSBhbmQgY2FuIGJlIG1vcmUgY29uc2VydmF0aXZlIHRoYW4gUGVhcnNvbidzIGNoaS1zcXVhcmUuIEl0cyBvZnRlbiB1c2VkIHdoZW4geW91IGhhdmUgc21hbGwgY2VsbCBzaXplcy4NCg0KYGBge3J9DQpmaXNoZXIudGVzdChNQ1EuU3R1ZHkuMiwgc2ltdWxhdGUucC52YWx1ZSA9IFRSVUUsIEIgPSAxZTUpDQpgYGANCg0KIyMjIEJpbm9taW5hbCBEYXRhDQpUaGUgYmlub21pYWwgZGlzdHJpYnV0aW9uIGFwcHJvYWNoZXMgYSBub3JtYWwgZGlzdHJpYnV0aW9uIGFzIHlvdSBhZGQgbW9yZSB0cmlhbHMgKGZvciBleGFtcGxlLCB0aGUgbW9yZSBjb2luIGZsaXBzIHlvdSBoYXZlIHRoZSBtb3JlIG5vcm1hbCB0aGUgZGlzdHJpYnV0aW9uIGxvb2tzOyB3aGVyZSBwPXByb2Igb2YgaGVhZCwgYW5kIHE9cHJvYiBvZiB0YWlscywgbiA9IGNvaW4gZmxpcHMpLiAgR2VuZXJhbGx5LCB3aGVuIHRoZSB2YWx1ZXMgb2YgcG4gYW5kIHFuIGFyZSBib3RoIGVxdWFsIHRvIDEwLCB0aGUgZGlzdHJpYnV0aW9uIGFwcHJvYWNoZXMgbm9ybWFsLiAgTm90ZTogJFxtdT1wbiQsICRcc2lnbWEgPSBcc3FydHtucHF9JC4gTm90ZSB0aGlzIHRlc3QgaXMgYW4gb2xkIHRlc3QgdXNlZnVsIHdoZW4gcGVvcGxlIHRlbmRlZCB0byBkbyBzdGF0cyBieSBoYW5kLiAgDQoNCiQkWiA9IFxmcmFje1gtXG11fXtcc2lnbWF9ID0gXGZyYWN7WC1wbn17XHNxcnR7bnBxfX0kJA0KDQpXZSBjYW4gdXNlIG91ciBaY3JpdCB0YWJsZSBhZ2FpbiAocmVtZW1iZXIgJFxhbHBoYT0uMDUkIHlpZWxkcyAkWl97Y3JpdH0gPSAxLjk2JCkNCg0KTGV0J3MgdXNlIG91ciBnb29kbmVzcyBvZiBmaXQgZGF0YSBhZ2FpbjoNCg0KRnJlcXVlbmN5IHwgUmlnaHQgdG8gV3JvbmcgfCBXcm9uZyB0byBSaWdodA0KOi0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLToNCk9ic2VydmVkICB8ICAyNyAgICAgICAgICAgIHwgMTk1DQoNCiMjIyMgQmlub21pYWwgYnkgaGFuZA0KDQpXZSBqdXN0IG5lZWQgdG8gY2FsbCBvbmUgb2YgdGhlIGNvbmRpdGlvbnMgYSAic3VjY2VzcyIgKHdlIHdpbGwgcGljayBXcm9uZy10by1SaWdodDsgJFggPSAxOTUkKS4gU28gJHAgPSAuNSQsICRxID0gLjUkLCBPdXIgJG4gPSAxOTUrMjcgPSAyMjIkDQoNCiRaID0gXGZyYWN7MTk1LS41KjIyMn17XHNxcnR7MjIyKi41Ki41fX0gPSAxMS4yNzU0MiQNCg0KJFogPSAxMS4yOCwgcCA8IC4wNSQNCg0KTm90ZTogJFpeMiA9IFxjaGleMiQgPSAxMS4yNzU0Ml4yID0gMTI3LjE0ICh0aGUgb25lLXdheSAkXGNoaV4yJCB2YWx1ZSB3ZSBnb3QgYWJvdmUhKQ0KDQoNCiMjIyMgQmlub21pYWwgYnkgUiBmdW5jdGlvbg0KDQpgYGB7cn0NCmJpbm9tLnRlc3QoMTk1LCAyMjIsIHAgPSAwLjUsDQogICAgICAgICAgIGNvbmYubGV2ZWwgPSAwLjk1KQ0KYGBgDQoNCiMjIyBTaWduIHRlc3QNCi0gU2lnbiB0ZXN0IGlzIGEgc3BlY2lhbCBjYXNlIG9mIHRoZSBiaW5vbWlhbCB0ZXN0DQotIEEgc2lnbiB0ZXN0IGNvbXBhcmVzIHRoZSBudW1iZXIgb2YgdGltZXMgYSB0cmVhdG1lbnQgcmVzdWx0cyBvbmUgZGlyZWN0aW9uIG92ZXIgYW5vdGhlci4gDQogICAgLSBFeGFtcGxlLCBsZXQncyBzYXkgdGhhdCB5b3Ugd2VyZSBhIHRoZXJhcGlzdCBjaGFydGluZyBzZXZlcmFsIG9mIHlvdXIgcGF0aWVudCdzIGltcHJvdmVtZW50IHRvIGEgbmV3IHR5cGUgb2YgdGhlcmFweSB5b3Ugd2VyZSB1c2luZy4gIFlvdSBjYW5ub3QgbWVhc3VyZSB0aGUgbWFnbml0dWRlIG9mIHRoZSBpbXByb3ZlbWVudCwgYnV0IHlvdSBjYW4gcmVjb3JkIGlmIHlvdSBzZWUgaWYgdGhleSBpbXByb3ZlIG9yIGdldCB3b3JzZS4gICANClNpZ24gdGVzdHM6IA0KLSBBcmUgdXNlZCB3aGVuIHlvdSBoYXZlIHRoZSBkaXJlY3Rpb24gb2YgY2hhbmdlIGZyb20gYW4gZXhwZXJpbWVudA0KLSBDYW4gYmUgdXNlZCBhcyBhIHBpbG90IHRlc3QgdG8gc2VlIGlmIHlvdSBzaG91bGQgbW92ZSBmb3J3YXJkIGluIGFuIGV4cGVyaW1lbnQNCi0gQ2FuIHN1cHBvcnQgYSBoeXBvdGhlc2lzIHdoZW4gYWxsIG90aGVyIHRlc3RzIGZhaWwNCi0gQXJlIG5vdCBhcyBzZW5zaXRpdmUgYXMgcGFyYW1ldHJpYyB0ZXN0cw0KLSBVc2UgdGhlIHNhbWUgY2FsY3VsYXRpb24gYXMgdGhlIGJpbm9taWFsIHRlc3Q7IHlvdSBqdXN0IGNvdW50IHRoZSBudW1iZXIgb2YgcGx1c2VzIGFuZCBtaW51c2VzDQoNCg0KIyMgT3JkaW5hbCBEYXRhDQoNCiMjIyBXaWxjb3hvbiByYW5rIHN1bSB0ZXN0IA0KDQpOb24tcGFyYW1ldHJpYyBlcXVpdmFsZW50IHRvIHRoZSB0LXRlc3QuIFRoaXMgdGVzdCBjb21wYXJlcyByYW5rcyBhbmQgbm90IHRoZSBtZWFucy4gSXQgY29tZXMgaW4gdHdvIGZsYXZvcnMgKHBhaXJlZC1zYW1wbGUgYW5kIGluZGVwZW5kZW50IHNhbXBsZSBbYWxzbyBjYWxsZWQgdGhlIE1hbm4tV2hpdG5leSBVLXRlc3RdKQ0KDQojIyMjIFdpbGNveG9uIHJhbmsgc3VtIHRlc3QgZm9yIGluZGVwZW5kZW50IHNhbXBsZSANCg0KJEhfMDokICBUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byB0cmVhdG1lbnRzLg0KDQotIFRoZXJlZm9yZSwgdGhlcmUgaXMgbm8gdGVuZGVuY3kgZm9yIHRoZSByYW5rcyBvZiBvbmUgdHJlYXRtZW50IGNvbmRpdGlvbiB0byBiZSBzeXN0ZW1hdGljYWxseSBoaWdoZXIgb3IgbG93ZXIgdGhhbiB0aGUgcmFua3MgZm9yIHRoZSBvdGhlciB0cmVhdG1lbnQuIA0KDQokSF8xOiQgIFRoZXJlIGlzIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gdHJlYXRtZW50cy4gDQoNCi0gVGhlcmVmb3JlLCB0aGUgcmFua3MgaW4gb25lIHRyZWF0bWVudCBjb25kaXRpb24gYXJlIHN5c3RlbWF0aWNhbGx5IGhpZ2hlciBvciBsb3dlciB0aGFuIHRoZSByYW5rcyBpbiBhbm90aGVyIHRyZWF0bWVudC4gDQoNCnwgR3JvdXAgMSB8IEdyb3VwIDIgfA0KfCA6LS0gfCA6LS0gfA0KfCA0MSAgfCAxMCAgfA0KfCAzOSAgfCAxNCAgfA0KfCAzNyAgfCA5ICAgfA0KfCA0NCAgfCAxNyAgfA0KfCA0MCAgfCAxMiAgfA0KfCA0NSAgfCA4ICAgfA0KfCA0NiAgfCAxMDQgfA0KDQpEYXRhIGZyYW1lIGluIFINCmBgYHtyfQ0KZGF0YS5XPC1kYXRhLmZyYW1lKElWPWMocmVwKCJHMSIsNykscmVwKCJHMiIsNykpLA0KICAgICAgICAgICAgICAgICAgICAgICAgRFYgPWMoNDEsMzksMzcsNDQsNDAsNDUsNDYsMTAsMTQsOSwxMywxMiw4LDEwNCkpDQpgYGANCg0KDQojIyMjIEluZGVwZW5kZW50IHQtdGVzdCANCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmRhdGEuVyAlPiUgZ3JvdXBfYnkoSVYpICU+JSBzdW1tYXJpc2UoTWVhbj1tZWFuKERWKSwgU0Q9c2QoRFYpKQ0KdC50ZXN0KERWfklWLGRhdGE9ZGF0YS5XLCBwYWlyZWQ9RkFMU0UpDQpgYGANCg0KIyMjIyBJbmRlcGVuZGVudCBXLXRlc3QNCg0KYGBge3J9DQp3aWxjb3gudGVzdChEVn5JVixkYXRhPWRhdGEuVywgcGFpcmVkPUZBTFNFKQ0KYGBgDQoNCg0KSW4gdGhpcyBjYXNlLCBieSBjb21wYXJpbmcgcmFua3MgYW5kIG5vdCByYXcgc2NvcmVzLCB3ZSBjYW4gc2VlIHRoZSBub24tcGFyYW1ldHJpYyB0ZXN0IGdpdmVzIGEgc2lnbmlmaWNhbnQgcmVzdWx0IChhcyB3ZSBhcmUgY29tcGFyaW5nIHJhbmtzIHRoZSB2YXJpYW5jZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGdyb3VwcyBnb2VzIGF3YXkpIA0KDQoqTm90ZToqIElmIHRoZSBkYXRhIGlzIHBhaXJlZCBzYW1wbGUsIHlvdSBzaW1wbHkgaGF2ZSB0byBzYXkgcGFpcmVkPVRSVUUNCg0KIyMjIyBQYWlyZWQgVy10ZXN0DQoNCmBgYHtyfQ0KdC50ZXN0KERWfklWLGRhdGE9ZGF0YS5XLCBwYWlyZWQ9VFJVRSkNCndpbGNveC50ZXN0KERWfklWLGRhdGE9ZGF0YS5XLCBwYWlyZWQ9VFJVRSwgYWx0ZXJuYXRpdmUgPSgidHdvLnNpZGVkIikpDQpgYGANCg0KIyMjIEtydXNrYWwtV2FsbGlzIFRlc3QNClRoZSBub24tcGFyYW1ldHJpYyBlcXVpdmFsZW50IHRvIHRoZSBpbmRlcGVuZGVudCBtZWFzdXJlcyBvbmUtd2F5IEFOT1ZBLiAgSXQgY29tcGFyZXMgdGhyZWUgb3IgbW9yZSBzZXBhcmF0ZSBncm91cHMgYW5kIGlzIHRlc3RlZCBhZ2FpbnN0IHRoZSBjaGktc3F1YXJlIGRpc3RyaWJ1dGlvbi4gDQoNCg0KTGlrZSB0aGUgVyB0ZXN0LCB5b3Ugd291bGQgY29udmVydCB0aGUgZGF0YSBpbnRvIHJhbmtzIGFuZCBjYWxjdWxhdGUgdGhlIEggdmFsdWUuDQoNCg0KfCBHcm91cCAxIHwgR3JvdXAgMiB8IEdyb3VwIDMgfA0KfCA6LS0tLS0tIHwgOi0tLS0tLSB8IDotLS0tLS0gfA0KfCAxNCAgICAgIHwgMiAgICAgICB8IDI2ICAgICAgfA0KfCAzICAgICAgIHwgMTQgICAgICB8IDggICAgICAgfA0KfCAyICAgICAgIHwgOSAgICAgICB8IDE0ICAgICAgfA0KfCA1ICAgICAgIHwgMTIgICAgICB8IDE5ICAgICAgfA0KfCA4ICAgICAgIHwgNSAgICAgICB8IDIwICAgICAgfA0KDQoNCkRhdGEgZnJhbWUgaW4gUg0KYGBge3J9DQpkYXRhLkg8LWRhdGEuZnJhbWUoSVY9YyhyZXAoIkcxIiw1KSxyZXAoIkcyIiw1KSxyZXAoIkczIiw1KSksDQogICAgICAgICAgICAgICAgICAgICAgICBEViA9YygxNCwzLDIsNSw4LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiwxNCw5LDEyLDUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyNiw4LDE0LDE5LDIwKSkNCmBgYA0KDQoNCiMjIyMgS3J1c2thbC1XYWxsaXMgVGVzdCBpbiBSDQoNCmBgYHtyfQ0Ka3J1c2thbC50ZXN0KERWfklWLCBkYXRhPWRhdGEuSCkgDQpgYGANCg0KWW91IGNhbiBmb2xsb3cgdXAgdGhpcyBhbmFseXNpcyB3aXRoIHRoZSBXIHRlc3QgYWJvdmUNCg0KDQojIyMgRnJpZWRtYW4gVGVzdA0KTm9uLXBhcmFtZXRyaWMgb25lLXdheSBSTSBBTk9WQS4gRm9yIHRoaXMgdGVzdCB5b3UgbXVzdCBoYXZlIGEgImJsb2NrIi4gWW91IGJsb2NrIHdpbGwgYmUgeW91ciBJRCB2YXJpYWJsZS4gWW91IGNhbiBmb2xsb3cgdXAgdGhpcyB0ZXN0IHdpdGggV2lsY294b24gcmFuayBzdW0gdGVzdCAocGFpcmVkPVRSVUUpLg0KDQoNCklEIHwgR3JvdXAgMSB8IEdyb3VwIDIgfCBHcm91cCAzIHwNCjotLXwgOi0tLS0tLSB8IDotLS0tLS0gfCA6LS0tLS0tIHwNCjEgIHwgMTQgICAgICB8IDIgICAgICAgfCAyNiAgICAgIHwNCjIgIHwgMyAgICAgICB8IDE0ICAgICAgfCA4ICAgICAgIHwNCjMgIHwgMiAgICAgICB8IDkgICAgICAgfCAxNCAgICAgIHwNCjQgIHwgNSAgICAgICB8IDEyICAgICAgfCAxOSAgICAgIHwNCjUgIHwgOCAgICAgICB8IDUgICAgICAgfCAyMCAgICAgIHwNCg0KRGF0YSBmcmFtZSBpbiBSDQpgYGB7cn0NCmRhdGEuRjwtZGF0YS5mcmFtZShJRD1yZXAoMTo1LDMpLA0KICAgICAgICAgICAgICAgICAgIElWPWMocmVwKCJHMSIsNSkscmVwKCJHMiIsNSkscmVwKCJHMyIsNSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgRFYgPWMoMTQsMywyLDUsOCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIsMTQsOSwxMiw1LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjYsOCwxNCwxOSwyMCkpDQpgYGANCg0KIyMjIyBGcmllZG1hbiBUZXN0IGluIFINCmBgYHtyfQ0KZnJpZWRtYW4udGVzdChEVn5JVnxJRCwgZGF0YT1kYXRhLkYpIA0KYGBgDQoNCllvdSBjYW4gZm9sbG93IHVwIHRoaXMgYW5hbHlzaXMgd2l0aCB0aGUgVyB0ZXN0IGFib3ZlDQoNCg0KIyBQcm9zIGFuZCBDb25zDQpDbGFzc2ljYWwgbm9uLXBhcmFtZXRyaWNzIGFyZSBlYXN5IHRvIHJ1biBieSBoYW5kIGFuZCBhcmUgb2Z0ZW4gdXNlZnVsIGlmIHBhcmFtZXRyaWMgdGVzdHMgZmFpbCAoZXNwZWNpYWxseSBpZiB5b3UgaGF2ZSBsYXJnZSB2YXJpYW5jZSBvciBzdXNwZWN0IHlvdXIgYXNzdW1wdGlvbnMgYXJlIG5vdCBiZWluZyBtZXQpLiBIb3dldmVyLCB0aGV5IGhhdmUgYSBoaWdoIHJhdGUgb2YgVHlwZSBJSSBFcnJvci4NCg0KDQoNCiMgUmVmZXJlbmNlcw0KQmVzdCwgSiwgQi4gKDE5NzkpLiBJdGVtIGRpZmZpY3VsdHkgYW5kIGFuc3dlciBjaGFuZ2luZy4gKlRlYWNoaW5nIG9mIFBzeWNob2xvZ3kqLCA2LCAyMjgtMjMwDQoNCg==