Introduction to Hypothesis testing
1 Data downloading
Using the getSymbols function, download monthly data for Apple (AAPL) and Microsoft (MSFT) from 2016 to date.
library(quantmod)
Loading required package: xts
Loading required package: zoo
Attaching package: ‘zoo’
The following objects are masked from ‘package:base’:
as.Date, as.Date.numeric
Loading required package: TTR
Registered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
getSymbols(c("AAPL", "MSFT"), from="2016-01-01", periodicity="monthly", src="yahoo")
‘getSymbols’ currently uses auto.assign=TRUE by default, but will
use auto.assign=FALSE in 0.5-0. You will still be able to use
‘loadSymbols’ to automatically load data. getOption("getSymbols.env")
and getOption("getSymbols.auto.assign") will still be checked for
alternate defaults.
This message is shown once per session and may be disabled by setting
options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
[1] "AAPL" "MSFT"
2 Return Calculation
Calculate the continuously compounded returns for each stock. Remember that the cc returns can be calculate as the first difference of the log of adjusted prices
r_AAPL <- diff(log(Ad(AAPL)))
r_MSFT <- diff(log(Ad(MSFT)))
head(r_AAPL, 5)
AAPL.Adjusted
2016-01-01 NA
2016-02-01 -0.006699996
2016-03-01 0.125157717
2016-04-01 -0.150731161
2016-05-01 0.063244216
head(r_MSFT, 5)
MSFT.Adjusted
2016-01-01 NA
2016-02-01 -0.07949864
2016-03-01 0.08919059
2016-04-01 -0.10208674
2016-05-01 0.06087242
r_AAPL = na.omit(r_AAPL)
r_MSFT = na.omit(r_MSFT)
3 Hypothesis test for one-sample mean
Run a t-test to compare whether the mean return of a stock is different than zero. To do a hypothesis test, we usually do the following steps:
- DEFINE THE VARIABLE OF analysis
- WRITE THE NULL AND THE ALTERNATIVE HYPOTHESIS.
- CALCULATE THE STANDARD ERROR, WHICH IS THE STANDARD DEVIATION OF THE VARIABLE OF STUDY.
- CALCULATE THE t-statistic (t-value). EXPLAIN/INTERPRET THE t-statistic.
- WRITE YOUR CONCLUSION OF THE t-TEST
We will do these steps for the case of Apple return
Defining the variable of analysis In this case, the variable of analysis is the mean return of Apple. We want to test whether the mean return of Apple is greater than zero. We start believing that the mean return of Apple is greater than zero.
Writing the null and alternative hypotheses The alternative hypothesis is always our belief, and the null hypothesis is the opposite of our belief. The null hypothesis is usually named H0, while the alternative hypothesis is named Ha. Then we define the hypotheses as follows.
H0: mean(r_AAPL) = 0
Ha: mean(r_AAPL) > 0
In any hypothesis test we assume that the null hypothesis is true. The alternative hypothesis is our belief that we want to provide evidence for. In other words, we start being very skeptic about our belief, so we start assuming that we are wrong and that the null hypothesis is true. Then, the purpose of any hypothesis test is provide strong evidence against the null hypothesis, so we can say with certain confidence (level of probability) that our alternative hypothesis might be true. Then, how we provide this evidence against the null hypothesis? We start assuming that H0 is true, then we collect a sample data, calculate the variable of analysis with the data, and then calculate the t-statistic of the test. Then, what is the t statistic? The t-statistic or t-value is the standardized distance between the variable of analysis (calculated with the data) and the value stated in the null hypothesis. This standardized distance is measured in number of standard deviations of the variable of analysis. For the case of this example, I can re-write the definition of the t-statistic as follows: The t-statistic or t-value is the standardized distance between the mean return of Apple (calculated with historical returns) and zero (the value of the H0). This standardized distance is measured in number of standard deviations of the Apple mean returns. The standard deviation of the variable of analysis is usually named as standard error of the test. Then, we need to first calculate the standard error of the test, and then the t-statistic.
- Calculate the standard error of the test The standard error of the test is the standard deviation of the variable of analysis. For the case of Apple returns, the standard error is the standard deviation of the mean returns of Apple. Check that it is not the same the standard deviation of Apple returns vs the standard deviation of the Apple **mean returns*. From the Central Limit Theorem we learned that the standard deviation of the mean of a group is significantly reduced compared with the standard deviation of the individuals. In this case, the standard deviation of Apple mean returns (the mean of a group of returns) must be much less than the standard deviation of Apple historical individual returns. Then, how we can calculate the standard error, which is the standard deviation of the mean of a group? Remember what we learned from the Central Limit Theorem. The standard deviation of the mean of a group is equal to the standard deviation of the individuals divided by the squared root of N (N=the number of elements in the group). Then, for the case of Apple mean return, the standard error is equal to the standard deviation of Apple historical returns divided by the squared root of the number of historical periods. Then, we can manually calculate the standard error as follows:
1.- I set N equal to the # of rows of the historical return dataset: 2.- I calculate the standard error: 3.- Note that sd is a function to calculate the standard deviation of a variable
N = nrow(r_AAPL)
se_AAPL <- sd(r_AAPL) / sqrt(N)
se_AAPL
[1] 0.01011031
We got a standard error equal to 0.0101059, which is much less that the original standard deviation of the monthly Apple returns, which is equal to 0.0827202.
- Calculation of the t-statistic (also called t-value) We will calculate the t-statistic a) by hand (manually calculated), and b) using the t.test function. We start doing the manual calculation to better understand what is the t-statistic: Since the t-statistic is the standardized distance from the real value of the variable of analysis and the null value stated in the null hypothesis, then:
t_val <- (mean(r_AAPL) - 0) / se_AAPL
t_val
[1] 2.832736
The numerator of t_val is the distance between the Apple mean return and the hypothetical value of Apple mean return (stated in H0), which is zero. To measure this distance in number of standard deviations of Apple mean returns, we divide this distance by its standard error. By doing this division we get a standardized distance from the actual (real) Apple mean returns and zero, the hypothetical Apple mean return stated in the null hypothesis H0.
Now calculate the t-statistic using the t.test function:
ttest_AAPL <- t.test(as.numeric(r_AAPL), alternative = "greater")
ttest_AAPL
One Sample t-test
data: as.numeric(r_AAPL)
t = 2.8327, df = 66, p-value = 0.003057
alternative hypothesis: true mean is greater than 0
95 percent confidence interval:
0.01177311 Inf
sample estimates:
mean of x
0.02863983
We can display only the t-value and the corresponding p-value of the test:
cat("t-vale from t.test =", ttest_AAPL$statistic,"\n")
t-vale from t.test = 2.832736
cat("p-value = ", ttest_AAPL$p.value)
p-value = 0.003057268
WE GOT THE SAME t-VALUE USING THE t.test FUNCTION compared with our MANUAL CALCULATION!
d.1. Interpretation of the t-statistic The t-value of the test is 2.7998249.
As we mentioned, the t-value or t-statistic is a measure of standardized distance between the real actual value of the variable of analysis and the hypothetical value stated in the null hypothesis. In this case we can say that the real Apple mean return is 2.7998249 standard deviations away from zero, the hypothetical Apple mean return stated in H0. When the t-value is bigger than 2, we have strong statistical evidence (at least at the 95% confidence level) to reject the null hypothesis H0. Why this is the case? Let’s quickly review what is the t-Student distribution vs the z normal distribution. In any hypothesis testing we assume that the variable of analysis behaves like a t-Student distribution. The t-Student distribution is a probability distribution that is very similar to the normal probability distribution. The main difference is that the t-Student distribution better models extreme values for small samples, and real financial returns usually have more extreme values compared to the normal distribution. When the sample size is bigger than 30, the normal z distribution behaves almost the same as the t Student distribution. Since the variable of analysis is supposed to behave like a t-Student distribution, then when the t-statistic is greater than 2 this means that the hypothetical distribution with mean zero is very far away from the real distribution of the data. When this distance is 2, then, both distributions will overlap only in about 2.5%! This means that if we assume that the hypothetical distribution with mean=0 is true, then it will be very unlikely that we got a mean that is 2 standard deviations away from the tru value!! Then, we can say that we have strong evidence to reject the null hypothesis when the t-value is 2 or greater!
- Conclusion of the test Since the t-value of the test is greater than 2, then we have strong statistical evidence to reject the null hypothesis that states that Apple mean return is zero. Therefore, AAPL mean return is statistically greater than 0. Another more detailed interpretation using the p-value and the confidence level of the test is the following: Since the t-value of the mean return of AAPL is greater than 2 and the corresponding p-value is less than 0.05, we can reject the null hypothesis at the 99.6650538% confidence (1-pvalue). Therefore, AAPL mean return is statistically greater than 0 with a confidence level of 99.6650538%.
Hypothesis test for comparing 2 sample means
Do a hypothesis test to check whether the Apple mean monthly return is greater than the Microsoft mean monthly return. We follow the same steps of hypothesis testing we described in the previous example:
3.4.1 Defining the variable of analysis In this case, the variable of analysis is the difference of two mean returns. More specifically, the variable of analysis is the difference between Apple mean returns and Microsoft mean returns. If this difference is bigger than zero, then we say that Apple mean returns is greater than Microsoft mean returns. We start calculating the mean of returns for both stocks:
mean_AAPL_r <- mean(r_AAPL)
mean_MSFT_r <- mean(r_MSFT)
print(mean_AAPL_r)
[1] 0.02863983
print(mean_MSFT_r)
[1] 0.02690819
3.4.2 Writing the null and alternative hypotheses
Remember that the alternative hypothesis (Ha) is always our belief, and the null hypothesis (H0) is the opposite of our belief. Then we define the hypotheses as follows. Since the mean return of Apple is higher than the mean return of Microsoft we start believing that Apple is significantly offering higher average monthly returns compared to Microsoft. Then:
H0: mean(r_AAPL) = mean(r_MSFT)
Ha: mean(r_AAPL) > mean(r_MSFT)
However, the null hypothesis always has to be stated with a variable that is equal to a specific value. Remember that our variable of study is the difference of both means. Then, we can re-arrange the equality to leave a number to the right:
H0: mean(r_AAPL) - mean(r_MSFT) = 0
Ha: mean(r_AAPL) - mean(r_MSFT) <>0
We can define our variable of study as meandif:
meandif = mean(r_AAPL) - mean(r_MSFT)
Then, the final setup of the hypotheses is:
H0: meandif = 0
Ha: meandif > 0
In this case, the variable of study of this test is meandif, which is the difference of 2 means. The mean return of AAPL and MSFT are random variables, so the variable of this test is also a random variable. To calculate the t value of this test, we have estimate the standar error, which is the standard deviation of meandif.
3.4.3 Calculate the standard error of the test In this case the standard error is the standard deviation of the difference of both means (meandiff). Remember that the means of return of each stock are random variables. From basic probability theory, if both random variables (Apple mean returns and Microsoft mean returns) are independent, then the variance of the difference of 2 random variables is the SUM of the variances! This sounds counter-intuitive.
WHY THE VARIANCE OF THE DIFFERENCE OF 2 RANDOM VARIABLES IS THE SUM OF THE 2 VARIANCES INSTEAD OF BEING THE DIFFERENCE OF BOTH VARIANCES? DO YOUR OWN RESEARCH AND BRIEFLY EXPLAIN. EVERY TIME SOMETHING HAPPENS AT RANDOM, WHETHER IT ADDS TO THE PILE OR SUBTRACTS FROM IT,UNCERTAINTY (VARIANCE) INCREASES.
RESEARCH XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PERSONAL NOTES This is an excerpt I found to be extremely useful. “The Pythagorean Theorem of Statistics Quick. What’s the most important theorem in statistics? That’s easy. It’s the central limit theorem (CLT), hands down. Okay, how about the second most important theorem? I say it’s the fact that for the sum or difference of independent random variables, variances add:”
VAR(X+-y)=VAR(X)+var(Y)
“I like to refer to this statement as the Pythagorean theorem of statistics for several reasons: When written in terms of standard deviations, it looks like the Pythagorean theorem:”
“Just as the Pythagorean theorem applies only to right triangles, this relationship applies only to independent random variables. The name helps students remember both the relationship and the restriction. As you may suspect, this analogy is more than a mere coincidence. There’s a nice geometric model that represents random variables as vectors whose lengths correspond to their standard deviations. When the variables are independent, the vectors are orthogonal. Then the standard deviation of the sum or difference of the variables is the hypotenuse of a right triangle.”
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3.4.4 Calculation of the t-statistic of the test Here we do the calculation of t-value manually in R:
N <- nrow(r_AAPL)
t <- (mean_AAPL_r - mean_MSFT_r - 0) / sqrt( (1/N) * (var(r_AAPL) + var(r_MSFT) ))
t
AAPL.Adjusted
AAPL.Adjusted 0.1464527
ttest <- t.test(as.numeric(r_AAPL), as.numeric(r_MSFT), paired = FALSE, var.equal = FALSE)
ttest
Welch Two Sample t-test
data: as.numeric(r_AAPL) and as.numeric(r_MSFT)
t = 0.14645, df = 108.76, p-value = 0.8838
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-0.02170352 0.02516680
sample estimates:
mean of x mean of y
0.02863983 0.02690819
We can also display only the t-value and the corresponding p-value:
cat("t-vale from t.test =", ttest$statistic,"\n")
t-vale from t.test = 0.1464527
cat("p-value = ", ttest$p.value)
p-value = 0.8838352
We got the same t value than the manual calculation.
4.5 Interpretation of the t-statistic/t-value We got a t-value= 0.1213646. This means that the distance between the difference of both mean returns from zero is only 0.1213646. Then, the real distribution of our variable of analysis is not too far away from the hypothetical distribution with a difference=0 to say that there is a significant distance to reject the null hypothesis.
3.4.6 Conclusion of the test Since the t-value of the test is less than 2 and the p-value is greater than 0.05, then the null hypothesis (H0) cannot be rejected. Therefore, we conclude that there is no significant difference between the average monthly returns of AAPL and MSFT over time; they are statistically equal.
Reading
Regression Analysis is perhaps the single most important Business Statistics tool used in the industry. Regression is the engine behind a multitude of data analytics applications used for many forms of forecasting and prediction.
LS0tCnRpdGxlOiAiV29ya3Nob3AgMyAtIEZpbmFuY2lhbCBFY29ub21ldHJpY3MgMSIKYXV0aG9yOiBTdGVmYW4gU2Nod2VpdHplciBBMDEyMDk3NTUKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQojIyBJbnRyb2R1Y3Rpb24gdG8gSHlwb3RoZXNpcyB0ZXN0aW5nCgoKMSBEYXRhIGRvd25sb2FkaW5nCgpVc2luZyB0aGUgZ2V0U3ltYm9scyBmdW5jdGlvbiwgZG93bmxvYWQgbW9udGhseSBkYXRhIGZvciBBcHBsZSAoQUFQTCkgYW5kIE1pY3Jvc29mdCAoTVNGVCkgZnJvbSAyMDE2IHRvIGRhdGUuCmBgYHtyfQpsaWJyYXJ5KHF1YW50bW9kKQpnZXRTeW1ib2xzKGMoIkFBUEwiLCAiTVNGVCIpLCBmcm9tPSIyMDE2LTAxLTAxIiwgcGVyaW9kaWNpdHk9Im1vbnRobHkiLCBzcmM9InlhaG9vIikKYGBgCgoyIFJldHVybiBDYWxjdWxhdGlvbgoKQ2FsY3VsYXRlIHRoZSBjb250aW51b3VzbHkgY29tcG91bmRlZCByZXR1cm5zIGZvciBlYWNoIHN0b2NrLiBSZW1lbWJlciB0aGF0IHRoZSBjYyByZXR1cm5zIGNhbiBiZSBjYWxjdWxhdGUgYXMgdGhlIGZpcnN0IGRpZmZlcmVuY2Ugb2YgdGhlIGxvZyBvZiBhZGp1c3RlZCBwcmljZXMKYGBge3J9CnJfQUFQTCA8LSBkaWZmKGxvZyhBZChBQVBMKSkpCnJfTVNGVCA8LSBkaWZmKGxvZyhBZChNU0ZUKSkpCgpoZWFkKHJfQUFQTCwgNSkKYGBgCmBgYHtyfQpoZWFkKHJfTVNGVCwgNSkKYGBgCmBgYHtyfQpyX0FBUEwgPSBuYS5vbWl0KHJfQUFQTCkKcl9NU0ZUID0gbmEub21pdChyX01TRlQpCmBgYAoKMyBIeXBvdGhlc2lzIHRlc3QgZm9yIG9uZS1zYW1wbGUgbWVhbgoKUnVuIGEgdC10ZXN0IHRvIGNvbXBhcmUgd2hldGhlciB0aGUgbWVhbiByZXR1cm4gb2YgYSBzdG9jayBpcyBkaWZmZXJlbnQgdGhhbiB6ZXJvLgpUbyBkbyBhIGh5cG90aGVzaXMgdGVzdCwgd2UgdXN1YWxseSBkbyB0aGUgZm9sbG93aW5nIHN0ZXBzOgoKYS4gREVGSU5FIFRIRSBWQVJJQUJMRSBPRiBhbmFseXNpcwpiLiBXUklURSBUSEUgTlVMTCBBTkQgVEhFIEFMVEVSTkFUSVZFIEhZUE9USEVTSVMuCmMuIENBTENVTEFURSBUSEUgU1RBTkRBUkQgRVJST1IsIFdISUNIIElTIFRIRSBTVEFOREFSRCBERVZJQVRJT04gT0YgVEhFIFZBUklBQkxFIE9GIFNUVURZLgpkLiBDQUxDVUxBVEUgVEhFIHQtc3RhdGlzdGljICh0LXZhbHVlKS4gRVhQTEFJTi9JTlRFUlBSRVQgVEhFIHQtc3RhdGlzdGljLgplLiBXUklURSBZT1VSIENPTkNMVVNJT04gT0YgVEhFIHQtVEVTVAoKV2Ugd2lsbCBkbyB0aGVzZSBzdGVwcyBmb3IgdGhlIGNhc2Ugb2YgQXBwbGUgcmV0dXJuCgphLiBEZWZpbmluZyB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMKSW4gdGhpcyBjYXNlLCB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMgaXMgdGhlIG1lYW4gcmV0dXJuIG9mIEFwcGxlLiBXZSB3YW50IHRvIHRlc3Qgd2hldGhlciB0aGUgbWVhbiByZXR1cm4gb2YgQXBwbGUgaXMgZ3JlYXRlciB0aGFuIHplcm8uIFdlIHN0YXJ0IGJlbGlldmluZyB0aGF0IHRoZSBtZWFuIHJldHVybiBvZiBBcHBsZSBpcyBncmVhdGVyIHRoYW4gemVyby4KCmIuIFdyaXRpbmcgdGhlIG51bGwgYW5kIGFsdGVybmF0aXZlIGh5cG90aGVzZXMKVGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgaXMgYWx3YXlzIG91ciBiZWxpZWYsIGFuZCB0aGUgbnVsbCBoeXBvdGhlc2lzIGlzIHRoZSBvcHBvc2l0ZSBvZiBvdXIgYmVsaWVmLiBUaGUgbnVsbCBoeXBvdGhlc2lzIGlzIHVzdWFsbHkgbmFtZWQgSDAsIHdoaWxlIHRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIGlzIG5hbWVkIEhhLiBUaGVuIHdlIGRlZmluZSB0aGUgaHlwb3RoZXNlcyBhcyBmb2xsb3dzLgoKSDA6IG1lYW4ocl9BQVBMKSA9IDAKCkhhOiBtZWFuKHJfQUFQTCkgPiAwCgpJbiBhbnkgaHlwb3RoZXNpcyB0ZXN0IHdlIGFzc3VtZSB0aGF0IHRoZSBudWxsIGh5cG90aGVzaXMgaXMgdHJ1ZS4gVGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgaXMgb3VyIGJlbGllZiB0aGF0IHdlIHdhbnQgdG8gcHJvdmlkZSBldmlkZW5jZSBmb3IuCkluIG90aGVyIHdvcmRzLCB3ZSBzdGFydCBiZWluZyB2ZXJ5IHNrZXB0aWMgYWJvdXQgb3VyIGJlbGllZiwgc28gd2Ugc3RhcnQgYXNzdW1pbmcgdGhhdCB3ZSBhcmUgd3JvbmcgYW5kIHRoYXQgdGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0cnVlLgpUaGVuLCB0aGUgcHVycG9zZSBvZiBhbnkgaHlwb3RoZXNpcyB0ZXN0IGlzIHByb3ZpZGUgc3Ryb25nIGV2aWRlbmNlIGFnYWluc3QgdGhlIG51bGwgaHlwb3RoZXNpcywgc28gd2UgY2FuIHNheSB3aXRoIGNlcnRhaW4gY29uZmlkZW5jZSAobGV2ZWwgb2YgcHJvYmFiaWxpdHkpIHRoYXQgb3VyIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgbWlnaHQgYmUgdHJ1ZS4KVGhlbiwgaG93IHdlIHByb3ZpZGUgdGhpcyBldmlkZW5jZSBhZ2FpbnN0IHRoZSBudWxsIGh5cG90aGVzaXM/CldlIHN0YXJ0IGFzc3VtaW5nIHRoYXQgSDAgaXMgdHJ1ZSwgdGhlbiB3ZSBjb2xsZWN0IGEgc2FtcGxlIGRhdGEsIGNhbGN1bGF0ZSB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMgd2l0aCB0aGUgZGF0YSwgYW5kIHRoZW4gY2FsY3VsYXRlIHRoZSB0LXN0YXRpc3RpYyBvZiB0aGUgdGVzdC4gVGhlbiwgd2hhdCBpcyB0aGUgdCBzdGF0aXN0aWM/ClRoZSB0LXN0YXRpc3RpYyBvciB0LXZhbHVlIGlzIHRoZSBzdGFuZGFyZGl6ZWQgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMgKGNhbGN1bGF0ZWQgd2l0aCB0aGUgZGF0YSkgYW5kIHRoZSB2YWx1ZSBzdGF0ZWQgaW4gdGhlIG51bGwgaHlwb3RoZXNpcy4gVGhpcyBzdGFuZGFyZGl6ZWQgZGlzdGFuY2UgaXMgbWVhc3VyZWQgaW4gbnVtYmVyIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgdGhlIHZhcmlhYmxlIG9mIGFuYWx5c2lzLgpGb3IgdGhlIGNhc2Ugb2YgdGhpcyBleGFtcGxlLCBJIGNhbiByZS13cml0ZSB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgdC1zdGF0aXN0aWMgYXMgZm9sbG93czoKVGhlIHQtc3RhdGlzdGljIG9yIHQtdmFsdWUgaXMgdGhlIHN0YW5kYXJkaXplZCBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBtZWFuIHJldHVybiBvZiBBcHBsZSAoY2FsY3VsYXRlZCB3aXRoIGhpc3RvcmljYWwgcmV0dXJucykgYW5kIHplcm8gKHRoZSB2YWx1ZSBvZiB0aGUgSDApLiBUaGlzIHN0YW5kYXJkaXplZCBkaXN0YW5jZSBpcyBtZWFzdXJlZCBpbiBudW1iZXIgb2Ygc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiB0aGUgQXBwbGUgbWVhbiByZXR1cm5zLgpUaGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSB2YXJpYWJsZSBvZiBhbmFseXNpcyBpcyB1c3VhbGx5IG5hbWVkIGFzIHN0YW5kYXJkIGVycm9yIG9mIHRoZSB0ZXN0LgpUaGVuLCB3ZSBuZWVkIHRvIGZpcnN0IGNhbGN1bGF0ZSB0aGUgc3RhbmRhcmQgZXJyb3Igb2YgdGhlIHRlc3QsIGFuZCB0aGVuIHRoZSB0LXN0YXRpc3RpYy4KCmMuICBDYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGVycm9yIG9mIHRoZSB0ZXN0ClRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgdGVzdCBpcyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSB2YXJpYWJsZSBvZiBhbmFseXNpcy4KRm9yIHRoZSBjYXNlIG9mIEFwcGxlIHJldHVybnMsIHRoZSBzdGFuZGFyZCBlcnJvciBpcyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBtZWFuIHJldHVybnMgb2YgQXBwbGUuIENoZWNrIHRoYXQgaXQgaXMgbm90IHRoZSBzYW1lIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgQXBwbGUgcmV0dXJucyB2cyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBBcHBsZSAqKm1lYW4gcmV0dXJucyouCkZyb20gdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSB3ZSBsZWFybmVkIHRoYXQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgbWVhbiBvZiBhIGdyb3VwIGlzIHNpZ25pZmljYW50bHkgcmVkdWNlZCBjb21wYXJlZCB3aXRoIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIGluZGl2aWR1YWxzLgpJbiB0aGlzIGNhc2UsIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgQXBwbGUgbWVhbiByZXR1cm5zICh0aGUgbWVhbiBvZiBhIGdyb3VwIG9mIHJldHVybnMpIG11c3QgYmUgbXVjaCBsZXNzIHRoYW4gdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBBcHBsZSBoaXN0b3JpY2FsIGluZGl2aWR1YWwgcmV0dXJucy4KVGhlbiwgaG93IHdlIGNhbiBjYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGVycm9yLCB3aGljaCBpcyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBtZWFuIG9mIGEgZ3JvdXA/IFJlbWVtYmVyIHdoYXQgd2UgbGVhcm5lZCBmcm9tIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0uIFRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIG1lYW4gb2YgYSBncm91cCBpcyBlcXVhbCB0byB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBpbmRpdmlkdWFscyBkaXZpZGVkIGJ5IHRoZSBzcXVhcmVkIHJvb3Qgb2YgTiAoTj10aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBncm91cCkuClRoZW4sIGZvciB0aGUgY2FzZSBvZiBBcHBsZSBtZWFuIHJldHVybiwgdGhlIHN0YW5kYXJkIGVycm9yIGlzIGVxdWFsIHRvIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgQXBwbGUgaGlzdG9yaWNhbCByZXR1cm5zIGRpdmlkZWQgYnkgdGhlIHNxdWFyZWQgcm9vdCBvZiB0aGUgbnVtYmVyIG9mIGhpc3RvcmljYWwgcGVyaW9kcy4gVGhlbiwgd2UgY2FuIG1hbnVhbGx5IGNhbGN1bGF0ZSB0aGUgc3RhbmRhcmQgZXJyb3IgYXMgZm9sbG93czoKCjEuLSBJIHNldCBOIGVxdWFsIHRvIHRoZSAjIG9mIHJvd3Mgb2YgdGhlIGhpc3RvcmljYWwgcmV0dXJuIGRhdGFzZXQ6CjIuLSBJIGNhbGN1bGF0ZSB0aGUgc3RhbmRhcmQgZXJyb3I6CjMuLSBOb3RlIHRoYXQgc2QgaXMgYSBmdW5jdGlvbiB0byBjYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBhIHZhcmlhYmxlCmBgYHtyfQpOID0gbnJvdyhyX0FBUEwpCnNlX0FBUEwgPC0gc2Qocl9BQVBMKSAvIHNxcnQoTikKc2VfQUFQTApgYGAKV2UgZ290IGEgc3RhbmRhcmQgZXJyb3IgZXF1YWwgdG8gMC4wMTAxMDU5LCB3aGljaCBpcyBtdWNoIGxlc3MgdGhhdCB0aGUgb3JpZ2luYWwgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHRoZSBtb250aGx5IEFwcGxlIHJldHVybnMsIHdoaWNoIGlzIGVxdWFsIHRvIDAuMDgyNzIwMi4KCmQuIENhbGN1bGF0aW9uIG9mIHRoZSB0LXN0YXRpc3RpYyAoYWxzbyBjYWxsZWQgdC12YWx1ZSkKV2Ugd2lsbCBjYWxjdWxhdGUgdGhlIHQtc3RhdGlzdGljIGEpIGJ5IGhhbmQgKG1hbnVhbGx5IGNhbGN1bGF0ZWQpLCBhbmQgYikgdXNpbmcgdGhlIHQudGVzdCBmdW5jdGlvbi4KV2Ugc3RhcnQgZG9pbmcgdGhlIG1hbnVhbCBjYWxjdWxhdGlvbiB0byBiZXR0ZXIgdW5kZXJzdGFuZCB3aGF0IGlzIHRoZSB0LXN0YXRpc3RpYzoKU2luY2UgdGhlIHQtc3RhdGlzdGljIGlzIHRoZSBzdGFuZGFyZGl6ZWQgZGlzdGFuY2UgZnJvbSB0aGUgcmVhbCB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMgYW5kIHRoZSBudWxsIHZhbHVlIHN0YXRlZCBpbiB0aGUgbnVsbCBoeXBvdGhlc2lzLCB0aGVuOgoKYGBge3J9CnRfdmFsIDwtIChtZWFuKHJfQUFQTCkgLSAwKSAvIHNlX0FBUEwKdF92YWwKYGBgClRoZSBudW1lcmF0b3Igb2YgdF92YWwgaXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIEFwcGxlIG1lYW4gcmV0dXJuIGFuZCB0aGUgaHlwb3RoZXRpY2FsIHZhbHVlIG9mIEFwcGxlIG1lYW4gcmV0dXJuIChzdGF0ZWQgaW4gSDApLCB3aGljaCBpcyB6ZXJvLiBUbyBtZWFzdXJlIHRoaXMgZGlzdGFuY2UgaW4gbnVtYmVyIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgQXBwbGUgbWVhbiByZXR1cm5zLCB3ZSBkaXZpZGUgdGhpcyBkaXN0YW5jZSBieSBpdHMgc3RhbmRhcmQgZXJyb3IuIEJ5IGRvaW5nIHRoaXMgZGl2aXNpb24gd2UgZ2V0IGEgc3RhbmRhcmRpemVkIGRpc3RhbmNlIGZyb20gdGhlIGFjdHVhbCAocmVhbCkgQXBwbGUgbWVhbiByZXR1cm5zIGFuZCB6ZXJvLCB0aGUgaHlwb3RoZXRpY2FsIEFwcGxlIG1lYW4gcmV0dXJuIHN0YXRlZCBpbiB0aGUgbnVsbCBoeXBvdGhlc2lzIEgwLgoKTm93IGNhbGN1bGF0ZSB0aGUgdC1zdGF0aXN0aWMgdXNpbmcgdGhlIHQudGVzdCBmdW5jdGlvbjoKYGBge3J9CnR0ZXN0X0FBUEwgPC0gdC50ZXN0KGFzLm51bWVyaWMocl9BQVBMKSwgYWx0ZXJuYXRpdmUgPSAiZ3JlYXRlciIpCnR0ZXN0X0FBUEwKYGBgCldlIGNhbiBkaXNwbGF5IG9ubHkgdGhlIHQtdmFsdWUgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHAtdmFsdWUgb2YgdGhlIHRlc3Q6CmBgYHtyfQpjYXQoInQtdmFsZSBmcm9tIHQudGVzdCA9IiwgdHRlc3RfQUFQTCRzdGF0aXN0aWMsIlxuIikKYGBgCmBgYHtyfQpjYXQoInAtdmFsdWUgPSAiLCB0dGVzdF9BQVBMJHAudmFsdWUpCmBgYApXRSBHT1QgVEhFIFNBTUUgdC1WQUxVRSBVU0lORyBUSEUgdC50ZXN0IEZVTkNUSU9OIGNvbXBhcmVkIHdpdGggb3VyIE1BTlVBTCBDQUxDVUxBVElPTiEKCmQuMS4gSW50ZXJwcmV0YXRpb24gb2YgdGhlIHQtc3RhdGlzdGljClRoZSB0LXZhbHVlIG9mIHRoZSB0ZXN0IGlzIDIuNzk5ODI0OS4KCkFzIHdlIG1lbnRpb25lZCwgdGhlIHQtdmFsdWUgb3IgdC1zdGF0aXN0aWMgaXMgYSBtZWFzdXJlIG9mIHN0YW5kYXJkaXplZCBkaXN0YW5jZSBiZXR3ZWVuIHRoZSByZWFsIGFjdHVhbCB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMgYW5kIHRoZSBoeXBvdGhldGljYWwgdmFsdWUgc3RhdGVkIGluIHRoZSBudWxsIGh5cG90aGVzaXMuCkluIHRoaXMgY2FzZSB3ZSBjYW4gc2F5IHRoYXQgdGhlIHJlYWwgQXBwbGUgbWVhbiByZXR1cm4gaXMgMi43OTk4MjQ5IHN0YW5kYXJkIGRldmlhdGlvbnMgYXdheSBmcm9tIHplcm8sIHRoZSBoeXBvdGhldGljYWwgQXBwbGUgbWVhbiByZXR1cm4gc3RhdGVkIGluIEgwLgpXaGVuIHRoZSB0LXZhbHVlIGlzIGJpZ2dlciB0aGFuIDIsIHdlIGhhdmUgc3Ryb25nIHN0YXRpc3RpY2FsIGV2aWRlbmNlIChhdCBsZWFzdCBhdCB0aGUgOTUlIGNvbmZpZGVuY2UgbGV2ZWwpIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIEgwLiBXaHkgdGhpcyBpcyB0aGUgY2FzZT8gTGV04oCZcyBxdWlja2x5IHJldmlldyB3aGF0IGlzIHRoZSB0LVN0dWRlbnQgZGlzdHJpYnV0aW9uIHZzIHRoZSB6IG5vcm1hbCBkaXN0cmlidXRpb24uCkluIGFueSBoeXBvdGhlc2lzIHRlc3Rpbmcgd2UgYXNzdW1lIHRoYXQgdGhlIHZhcmlhYmxlIG9mIGFuYWx5c2lzIGJlaGF2ZXMgbGlrZSBhIHQtU3R1ZGVudCBkaXN0cmlidXRpb24uIFRoZSB0LVN0dWRlbnQgZGlzdHJpYnV0aW9uIGlzIGEgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIHRoYXQgaXMgdmVyeSBzaW1pbGFyIHRvIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uLiBUaGUgbWFpbiBkaWZmZXJlbmNlIGlzIHRoYXQgdGhlIHQtU3R1ZGVudCBkaXN0cmlidXRpb24gYmV0dGVyIG1vZGVscyBleHRyZW1lIHZhbHVlcyBmb3Igc21hbGwgc2FtcGxlcywgYW5kIHJlYWwgZmluYW5jaWFsIHJldHVybnMgdXN1YWxseSBoYXZlIG1vcmUgZXh0cmVtZSB2YWx1ZXMgY29tcGFyZWQgdG8gdGhlIG5vcm1hbCBkaXN0cmlidXRpb24uCldoZW4gdGhlIHNhbXBsZSBzaXplIGlzIGJpZ2dlciB0aGFuIDMwLCB0aGUgbm9ybWFsIHogZGlzdHJpYnV0aW9uIGJlaGF2ZXMgYWxtb3N0IHRoZSBzYW1lIGFzIHRoZSB0IFN0dWRlbnQgZGlzdHJpYnV0aW9uLgpTaW5jZSB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMgaXMgc3VwcG9zZWQgdG8gYmVoYXZlIGxpa2UgYSB0LVN0dWRlbnQgZGlzdHJpYnV0aW9uLCB0aGVuIHdoZW4gdGhlIHQtc3RhdGlzdGljIGlzIGdyZWF0ZXIgdGhhbiAyIHRoaXMgbWVhbnMgdGhhdCB0aGUgaHlwb3RoZXRpY2FsIGRpc3RyaWJ1dGlvbiB3aXRoIG1lYW4gemVybyBpcyB2ZXJ5IGZhciBhd2F5IGZyb20gdGhlIHJlYWwgZGlzdHJpYnV0aW9uIG9mIHRoZSBkYXRhLiBXaGVuIHRoaXMgZGlzdGFuY2UgaXMgMiwgdGhlbiwgYm90aCBkaXN0cmlidXRpb25zIHdpbGwgb3ZlcmxhcCBvbmx5IGluIGFib3V0IDIuNSUhIFRoaXMgbWVhbnMgdGhhdCBpZiB3ZSBhc3N1bWUgdGhhdCB0aGUgaHlwb3RoZXRpY2FsIGRpc3RyaWJ1dGlvbiB3aXRoIG1lYW49MCBpcyB0cnVlLCB0aGVuIGl0IHdpbGwgYmUgdmVyeSB1bmxpa2VseSB0aGF0IHdlIGdvdCBhIG1lYW4gdGhhdCBpcyAyIHN0YW5kYXJkIGRldmlhdGlvbnMgYXdheSBmcm9tIHRoZSB0cnUgdmFsdWUhISBUaGVuLCB3ZSBjYW4gc2F5IHRoYXQgd2UgaGF2ZSBzdHJvbmcgZXZpZGVuY2UgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgd2hlbiB0aGUgdC12YWx1ZSBpcyAyIG9yIGdyZWF0ZXIhCgplLiBDb25jbHVzaW9uIG9mIHRoZSB0ZXN0ClNpbmNlIHRoZSB0LXZhbHVlIG9mIHRoZSB0ZXN0IGlzIGdyZWF0ZXIgdGhhbiAyLCB0aGVuIHdlIGhhdmUgc3Ryb25nIHN0YXRpc3RpY2FsIGV2aWRlbmNlIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgc3RhdGVzIHRoYXQgQXBwbGUgbWVhbiByZXR1cm4gaXMgemVyby4gVGhlcmVmb3JlLCBBQVBMIG1lYW4gcmV0dXJuIGlzIHN0YXRpc3RpY2FsbHkgZ3JlYXRlciB0aGFuIDAuCkFub3RoZXIgbW9yZSBkZXRhaWxlZCBpbnRlcnByZXRhdGlvbiB1c2luZyB0aGUgcC12YWx1ZSBhbmQgdGhlIGNvbmZpZGVuY2UgbGV2ZWwgb2YgdGhlIHRlc3QgaXMgdGhlIGZvbGxvd2luZzoKU2luY2UgdGhlIHQtdmFsdWUgb2YgdGhlIG1lYW4gcmV0dXJuIG9mIEFBUEwgaXMgZ3JlYXRlciB0aGFuIDIgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHAtdmFsdWUgaXMgbGVzcyB0aGFuIDAuMDUsIHdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBhdCB0aGUgOTkuNjY1MDUzOCUgY29uZmlkZW5jZSAoMS1wdmFsdWUpLiBUaGVyZWZvcmUsIEFBUEwgbWVhbiByZXR1cm4gaXMgc3RhdGlzdGljYWxseSBncmVhdGVyIHRoYW4gMCB3aXRoIGEgY29uZmlkZW5jZSBsZXZlbCBvZiA5OS42NjUwNTM4JS4KCiMjIEh5cG90aGVzaXMgdGVzdCBmb3IgY29tcGFyaW5nIDIgc2FtcGxlIG1lYW5zCkRvIGEgaHlwb3RoZXNpcyB0ZXN0IHRvIGNoZWNrIHdoZXRoZXIgdGhlIEFwcGxlIG1lYW4gbW9udGhseSByZXR1cm4gaXMgZ3JlYXRlciB0aGFuIHRoZSBNaWNyb3NvZnQgbWVhbiBtb250aGx5IHJldHVybi4KV2UgZm9sbG93IHRoZSBzYW1lIHN0ZXBzIG9mIGh5cG90aGVzaXMgdGVzdGluZyB3ZSBkZXNjcmliZWQgaW4gdGhlIHByZXZpb3VzIGV4YW1wbGU6CgozLjQuMSBEZWZpbmluZyB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMKSW4gdGhpcyBjYXNlLCB0aGUgdmFyaWFibGUgb2YgYW5hbHlzaXMgaXMgdGhlIGRpZmZlcmVuY2Ugb2YgdHdvIG1lYW4gcmV0dXJucy4gTW9yZSBzcGVjaWZpY2FsbHksIHRoZSB2YXJpYWJsZSBvZiBhbmFseXNpcyBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIEFwcGxlIG1lYW4gcmV0dXJucyBhbmQgTWljcm9zb2Z0IG1lYW4gcmV0dXJucy4gSWYgdGhpcyBkaWZmZXJlbmNlIGlzIGJpZ2dlciB0aGFuIHplcm8sIHRoZW4gd2Ugc2F5IHRoYXQgQXBwbGUgbWVhbiByZXR1cm5zIGlzIGdyZWF0ZXIgdGhhbiBNaWNyb3NvZnQgbWVhbiByZXR1cm5zLgpXZSBzdGFydCBjYWxjdWxhdGluZyB0aGUgbWVhbiBvZiByZXR1cm5zIGZvciBib3RoIHN0b2NrczoKCmBgYHtyfQptZWFuX0FBUExfciA8LSBtZWFuKHJfQUFQTCkKbWVhbl9NU0ZUX3IgPC0gbWVhbihyX01TRlQpCgpwcmludChtZWFuX0FBUExfcikKYGBgCmBgYHtyfQpwcmludChtZWFuX01TRlRfcikKYGBgCgozLjQuMiBXcml0aW5nIHRoZSBudWxsIGFuZCBhbHRlcm5hdGl2ZSBoeXBvdGhlc2VzCgpSZW1lbWJlciB0aGF0IHRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIChIYSkgaXMgYWx3YXlzIG91ciBiZWxpZWYsIGFuZCB0aGUgbnVsbCBoeXBvdGhlc2lzIChIMCkgaXMgdGhlIG9wcG9zaXRlIG9mIG91ciBiZWxpZWYuIFRoZW4gd2UgZGVmaW5lIHRoZSBoeXBvdGhlc2VzIGFzIGZvbGxvd3MuClNpbmNlIHRoZSBtZWFuIHJldHVybiBvZiBBcHBsZSBpcyBoaWdoZXIgdGhhbiB0aGUgbWVhbiByZXR1cm4gb2YgTWljcm9zb2Z0IHdlIHN0YXJ0IGJlbGlldmluZyB0aGF0IEFwcGxlIGlzIHNpZ25pZmljYW50bHkgb2ZmZXJpbmcgaGlnaGVyIGF2ZXJhZ2UgbW9udGhseSByZXR1cm5zIGNvbXBhcmVkIHRvIE1pY3Jvc29mdC4gVGhlbjoKCkgwOiBtZWFuKHJfQUFQTCkgPSBtZWFuKHJfTVNGVCkKCkhhOiBtZWFuKHJfQUFQTCkgPiBtZWFuKHJfTVNGVCkKCkhvd2V2ZXIsIHRoZSBudWxsIGh5cG90aGVzaXMgYWx3YXlzIGhhcyB0byBiZSBzdGF0ZWQgd2l0aCBhIHZhcmlhYmxlIHRoYXQgaXMgZXF1YWwgdG8gYSBzcGVjaWZpYyB2YWx1ZS4gUmVtZW1iZXIgdGhhdCBvdXIgdmFyaWFibGUgb2Ygc3R1ZHkgaXMgdGhlIGRpZmZlcmVuY2Ugb2YgYm90aCBtZWFucy4gVGhlbiwgd2UgY2FuIHJlLWFycmFuZ2UgdGhlIGVxdWFsaXR5IHRvIGxlYXZlIGEgbnVtYmVyIHRvIHRoZSByaWdodDoKCkgwOiBtZWFuKHJfQUFQTCkgLSBtZWFuKHJfTVNGVCkgPSAwCgpIYTogbWVhbihyX0FBUEwpIC0gbWVhbihyX01TRlQpIDw+MAoKV2UgY2FuIGRlZmluZSBvdXIgdmFyaWFibGUgb2Ygc3R1ZHkgYXMgbWVhbmRpZjoKCm1lYW5kaWYgPSBtZWFuKHJfQUFQTCkgLSBtZWFuKHJfTVNGVCkKClRoZW4sIHRoZSBmaW5hbCBzZXR1cCBvZiB0aGUgaHlwb3RoZXNlcyBpczoKCkgwOiBtZWFuZGlmID0gMAoKSGE6IG1lYW5kaWYgPiAwCgpJbiB0aGlzIGNhc2UsIHRoZSB2YXJpYWJsZSBvZiBzdHVkeSBvZiB0aGlzIHRlc3QgaXMgbWVhbmRpZiwgd2hpY2ggaXMgdGhlIGRpZmZlcmVuY2Ugb2YgMiBtZWFucy4gVGhlIG1lYW4gcmV0dXJuIG9mIEFBUEwgYW5kIE1TRlQgYXJlIHJhbmRvbSB2YXJpYWJsZXMsIHNvIHRoZSB2YXJpYWJsZSBvZiB0aGlzIHRlc3QgaXMgYWxzbyBhIHJhbmRvbSB2YXJpYWJsZS4KVG8gY2FsY3VsYXRlIHRoZSB0IHZhbHVlIG9mIHRoaXMgdGVzdCwgd2UgaGF2ZSBlc3RpbWF0ZSB0aGUgc3RhbmRhciBlcnJvciwgd2hpY2ggaXMgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBtZWFuZGlmLgoKMy40LjMgQ2FsY3VsYXRlIHRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgdGVzdApJbiB0aGlzIGNhc2UgdGhlIHN0YW5kYXJkIGVycm9yIGlzIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIGRpZmZlcmVuY2Ugb2YgYm90aCBtZWFucyAobWVhbmRpZmYpLiBSZW1lbWJlciB0aGF0IHRoZSBtZWFucyBvZiByZXR1cm4gb2YgZWFjaCBzdG9jayBhcmUgcmFuZG9tIHZhcmlhYmxlcy4KRnJvbSBiYXNpYyBwcm9iYWJpbGl0eSB0aGVvcnksIGlmIGJvdGggcmFuZG9tIHZhcmlhYmxlcyAoQXBwbGUgbWVhbiByZXR1cm5zIGFuZCBNaWNyb3NvZnQgbWVhbiByZXR1cm5zKSBhcmUgaW5kZXBlbmRlbnQsIHRoZW4gdGhlIHZhcmlhbmNlIG9mIHRoZSBkaWZmZXJlbmNlIG9mIDIgcmFuZG9tIHZhcmlhYmxlcyBpcyB0aGUgU1VNIG9mIHRoZSB2YXJpYW5jZXMhIFRoaXMgc291bmRzIGNvdW50ZXItaW50dWl0aXZlLgoKV0hZIFRIRSBWQVJJQU5DRSBPRiBUSEUgRElGRkVSRU5DRSBPRiAyIFJBTkRPTSBWQVJJQUJMRVMgSVMgVEhFIFNVTSBPRiBUSEUgMiBWQVJJQU5DRVMgSU5TVEVBRCBPRiBCRUlORyBUSEUgRElGRkVSRU5DRSBPRiBCT1RIIFZBUklBTkNFUz8gRE8gWU9VUiBPV04gUkVTRUFSQ0ggQU5EIEJSSUVGTFkgRVhQTEFJTi4KRVZFUlkgVElNRSBTT01FVEhJTkcgSEFQUEVOUyBBVCBSQU5ET00sIFdIRVRIRVIgSVQgQUREUyBUTyBUSEUgUElMRSBPUiBTVUJUUkFDVFMgRlJPTSBJVCxVTkNFUlRBSU5UWSAoVkFSSUFOQ0UpIElOQ1JFQVNFUy4KCgoKUkVTRUFSQ0ggClhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYCgoKUEVSU09OQUwgTk9URVMKVGhpcyBpcyBhbiBleGNlcnB0IEkgZm91bmQgdG8gYmUgZXh0cmVtZWx5IHVzZWZ1bC4KIlRoZSBQeXRoYWdvcmVhbiBUaGVvcmVtIG9mIFN0YXRpc3RpY3MKUXVpY2suIFdoYXTigJlzIHRoZSBtb3N0IGltcG9ydGFudCB0aGVvcmVtIGluIHN0YXRpc3RpY3M/IFRoYXTigJlzIGVhc3kuIEl04oCZcyB0aGUgY2VudHJhbCBsaW1pdCB0aGVvcmVtIChDTFQpLCBoYW5kcyBkb3duLiBPa2F5LCBob3cgYWJvdXQgdGhlIHNlY29uZCBtb3N0IGltcG9ydGFudCB0aGVvcmVtPyBJIHNheSBpdOKAmXMgdGhlIGZhY3QgdGhhdCBmb3IgdGhlIHN1bSBvciBkaWZmZXJlbmNlIG9mIGluZGVwZW5kZW50IHJhbmRvbSB2YXJpYWJsZXMsIHZhcmlhbmNlcyBhZGQ6IgoKVkFSKFgrLXkpPVZBUihYKSt2YXIoWSkKCiJJIGxpa2UgdG8gcmVmZXIgdG8gdGhpcyBzdGF0ZW1lbnQgYXMgdGhlIFB5dGhhZ29yZWFuIHRoZW9yZW0gb2Ygc3RhdGlzdGljcyBmb3Igc2V2ZXJhbCByZWFzb25zOgpXaGVuIHdyaXR0ZW4gaW4gdGVybXMgb2Ygc3RhbmRhcmQgZGV2aWF0aW9ucywgaXQgbG9va3MgbGlrZSB0aGUgUHl0aGFnb3JlYW4gdGhlb3JlbToiCgoiSnVzdCBhcyB0aGUgUHl0aGFnb3JlYW4gdGhlb3JlbSBhcHBsaWVzIG9ubHkgdG8gcmlnaHQgdHJpYW5nbGVzLCB0aGlzIHJlbGF0aW9uc2hpcCBhcHBsaWVzIG9ubHkgdG8gaW5kZXBlbmRlbnQgcmFuZG9tIHZhcmlhYmxlcy4KVGhlIG5hbWUgaGVscHMgc3R1ZGVudHMgcmVtZW1iZXIgYm90aCB0aGUgcmVsYXRpb25zaGlwIGFuZCB0aGUgcmVzdHJpY3Rpb24uCkFzIHlvdSBtYXkgc3VzcGVjdCwgdGhpcyBhbmFsb2d5IGlzIG1vcmUgdGhhbiBhIG1lcmUgY29pbmNpZGVuY2UuIFRoZXJl4oCZcyBhIG5pY2UgZ2VvbWV0cmljIG1vZGVsIHRoYXQgcmVwcmVzZW50cyByYW5kb20gdmFyaWFibGVzIGFzIHZlY3RvcnMgd2hvc2UgbGVuZ3RocyBjb3JyZXNwb25kIHRvIHRoZWlyIHN0YW5kYXJkIGRldmlhdGlvbnMuIFdoZW4gdGhlIHZhcmlhYmxlcyBhcmUgaW5kZXBlbmRlbnQsIHRoZSB2ZWN0b3JzIGFyZSBvcnRob2dvbmFsLiBUaGVuIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHN1bSBvciBkaWZmZXJlbmNlIG9mIHRoZSB2YXJpYWJsZXMgaXMgdGhlIGh5cG90ZW51c2Ugb2YgYSByaWdodCB0cmlhbmdsZS4iCgpYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWAoKCgozLjQuNCBDYWxjdWxhdGlvbiBvZiB0aGUgdC1zdGF0aXN0aWMgb2YgdGhlIHRlc3QKSGVyZSB3ZSBkbyB0aGUgY2FsY3VsYXRpb24gb2YgdC12YWx1ZSBtYW51YWxseSBpbiBSOgpgYGB7cn0KTiA8LSBucm93KHJfQUFQTCkKdCA8LSAobWVhbl9BQVBMX3IgLSBtZWFuX01TRlRfciAtIDApIC8gc3FydCggKDEvTikgKiAodmFyKHJfQUFQTCkgKyB2YXIocl9NU0ZUKSApKQp0CmBgYApgYGB7cn0KdHRlc3QgPC0gdC50ZXN0KGFzLm51bWVyaWMocl9BQVBMKSwgYXMubnVtZXJpYyhyX01TRlQpLCBwYWlyZWQgPSBGQUxTRSwgdmFyLmVxdWFsID0gRkFMU0UpCnR0ZXN0CmBgYApXZSBjYW4gYWxzbyBkaXNwbGF5IG9ubHkgdGhlIHQtdmFsdWUgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHAtdmFsdWU6CmBgYHtyfQpjYXQoInQtdmFsZSBmcm9tIHQudGVzdCA9IiwgdHRlc3Qkc3RhdGlzdGljLCJcbiIpCmBgYApgYGB7cn0KY2F0KCJwLXZhbHVlID0gIiwgdHRlc3QkcC52YWx1ZSkKYGBgCldlIGdvdCB0aGUgc2FtZSB0IHZhbHVlIHRoYW4gdGhlIG1hbnVhbCBjYWxjdWxhdGlvbi4KCjQuNSBJbnRlcnByZXRhdGlvbiBvZiB0aGUgdC1zdGF0aXN0aWMvdC12YWx1ZQpXZSBnb3QgYSB0LXZhbHVlPSAwLjEyMTM2NDYuIFRoaXMgbWVhbnMgdGhhdCB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgZGlmZmVyZW5jZSBvZiBib3RoIG1lYW4gcmV0dXJucyBmcm9tIHplcm8gaXMgb25seSAwLjEyMTM2NDYuIFRoZW4sIHRoZSByZWFsIGRpc3RyaWJ1dGlvbiBvZiBvdXIgdmFyaWFibGUgb2YgYW5hbHlzaXMgaXMgbm90IHRvbyBmYXIgYXdheSBmcm9tIHRoZSBoeXBvdGhldGljYWwgZGlzdHJpYnV0aW9uIHdpdGggYSBkaWZmZXJlbmNlPTAgdG8gc2F5IHRoYXQgdGhlcmUgaXMgYSBzaWduaWZpY2FudCBkaXN0YW5jZSB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4KCjMuNC42IENvbmNsdXNpb24gb2YgdGhlIHRlc3QKU2luY2UgdGhlIHQtdmFsdWUgb2YgdGhlIHRlc3QgaXMgbGVzcyB0aGFuIDIgYW5kIHRoZSBwLXZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAwLjA1LCB0aGVuIHRoZSBudWxsIGh5cG90aGVzaXMgKEgwKSBjYW5ub3QgYmUgcmVqZWN0ZWQuIFRoZXJlZm9yZSwgd2UgY29uY2x1ZGUgdGhhdCB0aGVyZSBpcyBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGF2ZXJhZ2UgbW9udGhseSByZXR1cm5zIG9mIEFBUEwgYW5kIE1TRlQgb3ZlciB0aW1lOyB0aGV5IGFyZSBzdGF0aXN0aWNhbGx5IGVxdWFsLgoKCiMjIFJlYWRpbmcKUmVncmVzc2lvbiBBbmFseXNpcyBpcyBwZXJoYXBzIHRoZSBzaW5nbGUgbW9zdCBpbXBvcnRhbnQgQnVzaW5lc3MgU3RhdGlzdGljcyB0b29sIHVzZWQgaW4gdGhlIGluZHVzdHJ5LiBSZWdyZXNzaW9uIGlzIHRoZSBlbmdpbmUgYmVoaW5kIGEgbXVsdGl0dWRlIG9mIGRhdGEgYW5hbHl0aWNzIGFwcGxpY2F0aW9ucyB1c2VkIGZvciBtYW55IGZvcm1zIG9mIGZvcmVjYXN0aW5nIGFuZCBwcmVkaWN0aW9uLgo=