Your Exercise
In this section, your expected to get familiar with confidential intervals exercise:
Exercise 1
Find a point estimate of average university student Age with the sample data from survey!
Solution:
Firstly, we call the survey data by using library(MASS). Afterward, we save the survey data of the student age. To find the point estimate of the average student age, we write the code using the mean function. It turns out that not all of the students have filled the age section, so we use na.rm=TRUE to filter out the missing value
## [1] 20.37451
The result of the coding of the point estimate average above is 20.37451 years
## [1] 19.54600 21.20303
## attr(,"conf.level")
## [1] 0.95
The confidence intervals for the average university student age is 19.546 - 21.20303. Hence, the 95% confidence level includes the true population mean which is equal to 20.37451 years.
Exercise 2
Assume the population standard deviation \(\sigma\) of the student Age in data survey is 7. Find the margin of error and interval estimate at 95% confidence level.
Solution:
We need to filter out the missing values in survey$Age by using na.omit function and save it as age.response. After that, we compute the standard error of the mean. Therefore, there are two tails in this normal distribution, the 95% confidence level would indicate the 97.5th percentile of the normal distribution at the upper tail. So, to get the margin of error, we multiply the qnorm(0.975) with the standard error of the mean.
## [1] 0.8911934
Then we can find the margin of error is 0.8911934 years. After that, we add it with the sample mean to find the confidence interval.
## [1] 20.37451
## [1] 19.48332 21.26571
The margin of error of the student age by assuming the population standard deviation is 7 at the 95% confidence level is 0.8911934 years. The confidence interval for this case is in between 19.48332 and 21.26571 years.
\(Alternative\) \(Solution\)
For the alternative solution, we can use the z.test function in the TeachingDemos package. It also has to be installed and loaded into the workspace.
## Warning: package 'TeachingDemos' was built under R version 3.6.3
##
## One Sample z-test
##
## data: age.response
## z = 44.809, n = 237.0000, Std. Dev. = 7.0000, Std. Dev. of the sample
## mean = 0.4547, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 19.48332 21.26571
## sample estimates:
## mean of age.response
## 20.37451
Exercise 3
Without assuming the population standard deviation \(\sigma\) of the student Age in survey, find the margin of error and interval estimate at 95% confidence level.
Solution:
We load the package of MASS first to get the data of survey. After that, we filter out the missing value using na.omit,assign the length using length funciton, and write the sample standard deviation. Then, we estimating the standard error and margin of error (upper tail 95% of confidence level) like the code below
## [1] 0.8957872
We find that the margin of error for the upper tail 95% of confidence intervals is 0.8957872 years.
## [1] 20.37451
## [1] 19.47873 21.27030
The result of the margin of error for the student age survey is 0.8957872 years at 95% confidence level and the confidence interval is in between 19.47873 and 21.27030 years.
\(Alternative\) \(Solution\)
##
## One Sample t-test
##
## data: age.response
## t = 48.447, df = 236, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 19.54600 21.20303
## sample estimates:
## mean of x
## 20.37451
Exercise 4
Improve the quality of a sample survey by increasing the sample size with unknown standard deviation \(\sigma\)!.
Solution:
Since, we dont know the standard deviation is and we need to improve the qualitiy of a sample survey, we are going to assume that half of the student write down the survey which give us the maximum variability. So, now the p is 0.5. Now, let’s say that we want 5% margin of error and 95% confidence level that give us the Z calues of 1.86.
## [1] 384.1459
So, we got 384.1459 or 384 sample sizes to improve the quality of a sample survey with unknown standard deviation \(\sigma\)!.`
Exercise 5
Assume you don’t have planned proportion estimate, find the sample size needed to achieve 5% margin of error for the male student survey at 95% confidence level!
Solution:
What we know:
- 5% margin of error
- 95% confidence interval So, we can get \(z\) = 1.96
First we need to find out the number of male students. We can find it using sum function and dividing it by n to find the male student proportion in this sample survey
## [1] 118
## [1] 0.5
The number of male student is 118. The proportion of the male student is 0.5.
Now, we want to find the sample size to achieve 5% margin of error for the male student survey at 95% confidence level
## [1] 384.1459
The, we get that we need 384.1459 or 384 sample size to achieve 5% margin of error for the male student survey at 95% confidence level.
Exercise 6
Perform confidence intervals analysis on this data set from 2004 that includes data on average hourly earnings, marital status, gender, and age for thousands of people.
\(Solution:\)
First we read the csv of cps04 before we find the confidence interval of the average hourly earnings, marital status, gender, and age for thousands of people.
## [1] 0.1920964
## [1] 16.7712
## [1] 16.57911 16.96330
From the code above, we can know that the margin of error of average hourly earnings is 0.1920964. xbar (sample mean) is 6.7712 while the confidence interval is inbetween 16.57911 and 16.96330.
## [1] 0.06340892
## [1] 29.75445
## [1] 29.69104 29.81785
From the code above, we can know that the margin of error of age is 0.06340892. xbar (sample mean) is 29.75445 while the confidence interval is inbetween 29.69104 and 29.81785 years.
## [1] 3313
## [1] 0.01080662
## [1] 0.414851
## [1] 0.4040444 0.4256576
From the code above, we can know that the total of the female is 3313 and the margin of error of age is 0.01080662. xbar (sample mean) is 0.414851 while the confidence interval is inbetween 0.4040444 and 0.4256576. From this interval we know that, there are more male than female participants
## [1] 3640
## [1] 0.01092388
## [1] 0.4557976
## [1] 0.4448738 0.4667215
From the code above, we can know that the total of the bachelor is 3460 and the margin of error of age is 0.01092388. xbar (sample mean) is 0.4557976 while the confidence interval is inbetween 0.4448738 and 0.4667215. From this interval we know that, there are more not bachelor than bachelor participants
Case Study
Assume you have access to data on an entire population, say the size of every house in all residential home sales in Ames, Iowa between 2006 and 2010 it’s straight forward to answer questions like,
- How big is the typical house in Ames?
- How much variation is there in sizes of houses?.
- How much is the average price of house in Ames?
- How much is the confidence interval price of house in Ames?
But, If you have access to only a sample of the population, as is often the case, the task becomes more complicated. What is your best guess for the typical size if you only know the sizes of several dozen houses? This sort of situation requires that you use your sample to make inference on what your population looks like.
Collect Data
To access the data in R, type the following code:
In this case study we’ll start with a simple random sample of size 60 from the population. Specifically, this is a simple random sample of size 60. Note that the data set has information on many housing variables, but for the first portion of the lab we’ll focus on the size of the house, represented by the variable Gr.Liv.Area.
Visualization
As usual, before you begin to analyze more about your data. It’s important to visualize the data in advance. Here, we use a random sample of size 60 from the population.

# Make a histogram of your sample
hist(samp, main ="Distribution fo Samp",
col = "deeppink3",
xlim = c(200, 3500),
freq = F,
xlab = "Samp")
# ...and add a density curve
curve(dnorm(x,
mean=mean(samp),
sd=sd(samp)), add=T,
col="blue", lwd=2)

Your Challenge:
- Describe the distribution of your sample. What would you say is the “typical” size within your sample? Also state precisely what you interpreted “typical” to mean.
- Would you expect another student’s distribution to be identical to yours? Would you expect it to be similar? Why or why not?
\(Answer\)
- My sample distribution is right skewed. The typical size is to be the mean of my sample population. To know that we can use
sumarry function to find the mean. So, the “typical” size within my sample is 1514. For your information, a typical mean is the value that is near the most simultaneous values in the distribution.
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 672 1100 1484 1514 1933 2690
- I would expect that they have almost the same as i have or similar but not identical to my distribution because this is a random sample of 60 randomly selected observations.
Confidence Intervals
One of the most common ways to describe the typical or central value of a distribution is to use the mean. In this case we can calculate the mean of the sample using,
## [1] 1514.133
Return for a moment to the question that first motivated this lab: based on this sample, what can we infer about the population? Based only on this single sample, the best estimate of the average living area of houses sold in Ames would be the sample mean, usually denoted as \(\bar{x}\) (here we’re calling it sample_mean). That serves as a good point estimate but it would be useful to also communicate how uncertain we are of that estimate. This can be captured by using a confidence interval.
We can calculate a 95% confidence interval for a sample mean by adding and subtracting 1.96 standard errors to the point estimate (I assume that you have been familiar with this formula).
## [1] 1381.351 1646.915
This is an important inference that we’ve just made: even though we don’t know what the full population looks like, we’re 95% confident that the true average size of houses in Ames lies between the values lower and upper. There are a few conditions that must be met for this interval to be valid.
Your Challenge:
- For the confidence interval to be valid, the sample mean must be normally distributed and have standard error $ s/$. What conditions must be met for this to be true?
- What does “95% confidence” mean?
- Does your confidence interval capture the true average size of houses in
Ames? If you are working on this case study, does your classmate’s interval capture this value?
\(Answer\)
The conditions that must be met for this to be true are there are at least thirty independent observations without being too skewed. Also, more impotantly, the sample mean of the distribution properly estimated by a normal model.
95% confidence is a confidence interval level for the normal model. Also, it is with the standard error. Usually, 95% confidence means that it have 5% of margin of error.The formula of the confidence interval is \(point\) \(estimate\) ± Standard of error . z (which is corresponding to the confidence level).
Yes, my confidence interval captures the true average houses in Ames. Of course, my neighbour’s interval will also capture this value as well.
Simulation
let’s simulate a scenario of confidence interval in classroom to capture the true average size of houses in Ames. Suppose we have 100 students in the classroom.
## [1] 97
Using R, we’re going to recreate many samples to learn more about how sample means and confidence intervals vary from one sample to another. Loops come in handy here (If you are unfamiliar with loops, review the Sampling Distribution Lab).
Here is the rough outline:
- Obtain a random sample.
- Calculate and store the sample’s mean and standard deviation.
- Repeat steps (1) and (2) 50 times.
- Use these stored statistics to calculate many confidence intervals.
But before we do all of this, we need to first create empty vectors where we can save the means and standard deviations that will be calculated from each sample. And while we’re at it, let’s also store the desired sample size as \(n\).
## [1] 60
Now we’re ready for the loop where we calculate the means and standard deviations of 50 random samples.
## [1] 2206 3672 2270 1786 1041 2614 1655 1378 1250 1884 1358 764 1176 1595 1419
## [16] 1620 1299 1097 1073 1647 1220 1086 1928 1412 1091 2263 1968 1261 1538 793
## [31] 1337 1768 1604 1609 1479 980 480 816 951 1069 1709 1742 2237 1458 864
## [46] 1665 1778 1949 1040 1414 954 1142 1614 1368 5642 1383 1242 816 2082 1728
Lastly, we construct the confidence intervals.
Lower bounds of these 50 confidence intervals are stored in lower_vector, and the upper bounds are in upper_vector. Let’s view the first interval.
## [1] 1400.415 1718.352

## [1] -1.959964
## [1] 1.959964
Your Challenge:
- What proportion of your confidence intervals include the true population mean? Is this proportion exactly equal to the confidence level? If not, explain why.
- Pick a confidence level of your choosing, provided it is 99%. What is the appropriate critical value?
- Calculate 50 confidence intervals at the confidence level you chose in the previous question. You do not need to obtain new samples, simply calculate new intervals based on the sample means and standard deviations you have already collected. Using the plot_ci function, plot all intervals and calculate the proportion of intervals that include the true population mean. How does this percentage compare to the confidence level selected for the intervals?
\(Answer\)
- The proportion of my confidence intervals include the true population mean is 97%. This proportion is not exactly equal to the confidence level only approximately near and all of the confidence intervals are all created from random samples.
## [1] 0.03333333
## [1] 0.03
- Pick a confidence level of your choosing, provided it is not 99%. What is the appropriate critical value?
Solution:
Because we cannot choose 99%, let’s choose 70%
## [1] 2.326348
- Calculate 50 confidence intervals at the confidence level you chose in the previous question. You do not need to obtain new samples, simply calculate new intervals based on the sample means and standard deviations you have already collected. Using the plot_ci function, plot all intervals and calculate the proportion of intervals that include the true population mean. How does this percentage compare to the confidence level selected for the intervals?

## [1] 1475.033 1643.734
## [1] 16
## [1] 0.2666667
## [1] 0.27
So, from this answer only 67% include the population mean. From this we know, the proportion is not exactly the same as the confidence level but very close
LS0tDQp0aXRsZTogIkNvbmZpZGVuY2UgSW50ZXJ2YWxzIg0KYXV0aG9yOiAiU29maWEgTmlja2xhdXMgUy4iDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KLS0tDQoNCmBgYHtyIExvZ28sIGVjaG89RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnNDAlJ30NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJodHRwczovL2dpdGh1Yi5jb20vQmFrdGktU2lyZWdhci9pbWFnZXMvYmxvYi9tYXN0ZXIvbG9nby5wbmc/cmF3PXRydWUiKQ0KYGBgDQoNCiMgQnJpZWYgSW50cm9kdWN0aW9uIA0KDQpQbGVhc2Ugd2F0Y2hpbmcgdGhpcyB2aWRlbywgdG8gZ2V0IHNvbWUgaWRlYXMgYWJvdXQgQ29uZmlkZW5jZSBJbnRlcnZhbHMgKENJKQ0KDQo8Y2VudGVyPg0KPGlmcmFtZSB3aWR0aD0iODAwIiBoZWlnaHQ9IjQ1MCIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9NYlhUaGJUU3JWSSIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhY2NlbGVyb21ldGVyOyBhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSIgYWxsb3dmdWxsc2NyZWVuPjwvaWZyYW1lPg0KPC9jZW50ZXI+DQoNCg0KIyBDSSBpbiBCdXNpbmVzcyANCg0KVGhpcyB2aWRlbyBndWlkZSB5b3UsIGhvdyBjYW4geW91IGFwcGx5IENvbmZpZGVuY2UgSW50ZXJ2YWxzIGluIEJ1c2luZXNzLg0KDQo8Y2VudGVyPg0KPGlmcmFtZSB3aWR0aD0iODAwIiBoZWlnaHQ9IjQ1MCIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9fSkdBTGV0TWNqbyIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhY2NlbGVyb21ldGVyOyBhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSIgYWxsb3dmdWxsc2NyZWVuPjwvaWZyYW1lPg0KPC9jZW50ZXI+DQoNCg0KIyBZb3VyIEV4ZXJjaXNlIA0KDQpJbiB0aGlzIHNlY3Rpb24sIHlvdXIgZXhwZWN0ZWQgdG8gZ2V0IGZhbWlsaWFyIHdpdGggY29uZmlkZW50aWFsIGludGVydmFscyBleGVyY2lzZTogDQoNCiMjIEV4ZXJjaXNlIDENCg0KRmluZCBhIHBvaW50IGVzdGltYXRlIG9mIGF2ZXJhZ2UgdW5pdmVyc2l0eSBzdHVkZW50IGBBZ2VgIHdpdGggdGhlIHNhbXBsZSBkYXRhIGZyb20gYHN1cnZleWAhDQoNClNvbHV0aW9uOg0KDQpGaXJzdGx5LCB3ZSBjYWxsIHRoZSBzdXJ2ZXkgZGF0YSBieSB1c2luZyBgbGlicmFyeShNQVNTKWAuIEFmdGVyd2FyZCwgd2Ugc2F2ZSB0aGUgc3VydmV5IGRhdGEgb2YgdGhlIHN0dWRlbnQgYWdlLiBUbyBmaW5kIHRoZSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgYXZlcmFnZSAgc3R1ZGVudCBhZ2UsIHdlIHdyaXRlIHRoZSBjb2RlIHVzaW5nIHRoZSBtZWFuIGZ1bmN0aW9uLiBJdCB0dXJucyBvdXQgdGhhdCBub3QgYWxsIG9mIHRoZSBzdHVkZW50cyBoYXZlIGZpbGxlZCB0aGUgYWdlIHNlY3Rpb24sIHNvIHdlIHVzZSBgbmEucm09VFJVRWAgdG8gZmlsdGVyIG91dCB0aGUgbWlzc2luZyB2YWx1ZQ0KYGBge3J9DQojIFByZXNlbnRzIHRoZSBNQVNTIHBhY2thZ2UgZGF0YSBzZXQgc3VydmV5DQpsaWJyYXJ5KE1BU1MpDQoNCiMgU2F2ZSB0aGUgc3VydmV5IGRhdGEgb2Ygc3R1ZGVudCBhZ2UNCmFnZW9mc3VydmV5ID0gc3VydmV5JEFnZQ0KDQojIEZpbmQgdGhlIHBvaW50IGVzdGltYXRlIG9mIHN0dWRlbnQgYWdlDQojIEFzIGl0IHR1cm5lZCBvdXQsIG5vdCBhbGwgdGhlIHN0dWRlbnQgaGF2ZSBmaWxsIHRoZSBhZ2Ugc2VjdGlvbiwgc28gd2UgbWhhdmUgdG8gZmlsdGVyIG91dCB0aGUgbWlzc2luZyB2YWx1ZXMuIFRoZXJlZm9yZSwgd2UgYXBwbHkgdGhlIG5hLnJtIGFyZ3VtZW50IGFzIFRSVUUNCm1lYW4oYWdlb2ZzdXJ2ZXksIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpUaGUgcmVzdWx0IG9mIHRoZSBjb2Rpbmcgb2YgdGhlIHBvaW50IGVzdGltYXRlIGF2ZXJhZ2UgYWJvdmUgaXMgMjAuMzc0NTEgeWVhcnMNCg0KYGBge3J9DQpwb2ludC5lc3RpbWF0ZSA8LXQudGVzdChhZ2VvZnN1cnZleSwgY29uZi5sZXZlbCA9IDAuOTUgKQ0KcG9pbnQuZXN0aW1hdGUkY29uZi5pbnQNCmBgYA0KDQpUaGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgZm9yIHRoZSBhdmVyYWdlIHVuaXZlcnNpdHkgc3R1ZGVudCBhZ2UgaXMgYDE5LjU0NiAtIDIxLjIwMzAzYC4gSGVuY2UsIHRoZSA5NSUgY29uZmlkZW5jZSBsZXZlbCBpbmNsdWRlcyB0aGUgdHJ1ZSBwb3B1bGF0aW9uIG1lYW4gd2hpY2ggaXMgZXF1YWwgdG8gMjAuMzc0NTEgeWVhcnMuDQoNCiMjIEV4ZXJjaXNlIDINCg0KQXNzdW1lIHRoZSBwb3B1bGF0aW9uIHN0YW5kYXJkIGRldmlhdGlvbiAkXHNpZ21hJCBvZiB0aGUgc3R1ZGVudCBgQWdlYCBpbiBkYXRhIGBzdXJ2ZXlgIGlzIDcuIEZpbmQgdGhlIG1hcmdpbiBvZiBlcnJvciBhbmQgaW50ZXJ2YWwgZXN0aW1hdGUgYXQgOTUlIGNvbmZpZGVuY2UgbGV2ZWwuDQoNClNvbHV0aW9uOg0KDQpXZSBuZWVkIHRvIGZpbHRlciBvdXQgdGhlIG1pc3NpbmcgdmFsdWVzIGluIGBzdXJ2ZXkkQWdlYCBieSB1c2luZyBgbmEub21pdGAgZnVuY3Rpb24gYW5kIHNhdmUgaXQgYXMgYWdlLnJlc3BvbnNlLiBBZnRlciB0aGF0LCB3ZSBjb21wdXRlIHRoZSBzdGFuZGFyZCBlcnJvciBvZiB0aGUgbWVhbi4gVGhlcmVmb3JlLCB0aGVyZSBhcmUgdHdvIHRhaWxzIGluIHRoaXMgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgdGhlIDk1JSBjb25maWRlbmNlIGxldmVsIHdvdWxkIGluZGljYXRlIHRoZSA5Ny41dGggcGVyY2VudGlsZSBvZiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBhdCB0aGUgdXBwZXIgdGFpbC4gU28sIHRvIGdldCB0aGUgbWFyZ2luIG9mIGVycm9yLCB3ZSBtdWx0aXBseSB0aGUgYHFub3JtKDAuOTc1KWAgd2l0aCB0aGUgc3RhbmRhcmQgZXJyb3Igb2YgdGhlIG1lYW4uDQpgYGB7cn0NCmxpYnJhcnkoTUFTUykNCmFnZS5yZXNwb25zZSA9IG5hLm9taXQoc3VydmV5JEFnZSkNCm4gPSBsZW5ndGgoYWdlLnJlc3BvbnNlKQ0KDQojIHBvcHVsYXRpb24gb2Ygc3RhbmRhcmQgZGV2aWF0aW9uDQpzaWdtYSA9IDcNCg0KIyBzdGFuZGFyZCBlcnJvciANClNFID0gc2lnbWEvc3FydChuKQ0KDQojIG1hcmdpbiBvZiBlcnJvcg0KRSA9IHFub3JtKDAuOTc1KSpTRQ0KRQ0KYGBgDQoNClRoZW4gd2UgY2FuIGZpbmQgdGhlIG1hcmdpbiBvZiBlcnJvciBpcyAwLjg5MTE5MzQgeWVhcnMuIA0KQWZ0ZXIgdGhhdCwgd2UgYWRkIGl0IHdpdGggdGhlIHNhbXBsZSBtZWFuIHRvIGZpbmQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCmBgYHtyfQ0KIyBzYW1wbGUgbWVhbg0KeGJhciA9IG1lYW4oYWdlLnJlc3BvbnNlKQ0KeGJhcg0KDQojQ29uZmlkZW5jZSBpbnRlcnZhbA0KeGJhciArIGMoLUUsRSkNCmBgYA0KDQpUaGUgbWFyZ2luIG9mIGVycm9yIG9mIHRoZSBzdHVkZW50IGFnZSBieSBhc3N1bWluZyB0aGUgcG9wdWxhdGlvbiBzdGFuZGFyZCBkZXZpYXRpb24gaXMgNyBhdCB0aGUgOTUlIGNvbmZpZGVuY2UgbGV2ZWwgaXMgMC44OTExOTM0IHllYXJzLiBUaGUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhpcyBjYXNlIGlzIGluIGJldHdlZW4gMTkuNDgzMzIgYW5kIDIxLjI2NTcxIHllYXJzLg0KDQokQWx0ZXJuYXRpdmUkICRTb2x1dGlvbiQNCg0KRm9yIHRoZSBhbHRlcm5hdGl2ZSBzb2x1dGlvbiwgd2UgY2FuIHVzZSB0aGUgYHoudGVzdGAgZnVuY3Rpb24gaW4gdGhlIGBUZWFjaGluZ0RlbW9zYCBwYWNrYWdlLiBJdCBhbHNvIGhhcyB0byBiZSBpbnN0YWxsZWQgYW5kIGxvYWRlZCBpbnRvIHRoZSB3b3Jrc3BhY2UuDQoNCmBgYHtyfQ0KbGlicmFyeShUZWFjaGluZ0RlbW9zKQ0Kei50ZXN0KGFnZS5yZXNwb25zZSwgc2Q9c2lnbWEpDQpgYGANCg0KDQojIyBFeGVyY2lzZSAzDQoNCldpdGhvdXQgYXNzdW1pbmcgdGhlIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uICRcc2lnbWEkIG9mIHRoZSBzdHVkZW50IGBBZ2VgIGluIHN1cnZleSwgZmluZCB0aGUgbWFyZ2luIG9mIGVycm9yIGFuZCBpbnRlcnZhbCBlc3RpbWF0ZSBhdCA5NSUgY29uZmlkZW5jZSBsZXZlbC4NCg0KU29sdXRpb246DQoNCldlIGxvYWQgdGhlIHBhY2thZ2Ugb2YgTUFTUyBmaXJzdCB0byBnZXQgdGhlIGRhdGEgb2Ygc3VydmV5LiBBZnRlciB0aGF0LCB3ZSBmaWx0ZXIgb3V0IHRoZSBtaXNzaW5nIHZhbHVlIHVzaW5nIGBuYS5vbWl0YCxhc3NpZ24gdGhlIGxlbmd0aCB1c2luZyBgbGVuZ3RoYCBmdW5jaXRvbiwgYW5kIHdyaXRlIHRoZSBzYW1wbGUgc3RhbmRhcmQgZGV2aWF0aW9uLiBUaGVuLCB3ZSBlc3RpbWF0aW5nIHRoZSBzdGFuZGFyZCBlcnJvciBhbmQgbWFyZ2luIG9mIGVycm9yICh1cHBlciB0YWlsIDk1JSBvZiBjb25maWRlbmNlIGxldmVsKSBsaWtlIHRoZSBjb2RlIGJlbG93DQoNCmBgYHtyfQ0KIyBsb2FkIHRoZSBwYWNrYWdlIG9mIE1BU1MNCmxpYnJhcnkoTUFTUykNCg0KIyBGaWx0ZXIgb3V0IHRoZSBtaXNzaW5nIHZhbHVlDQphZ2UucmVzcG9uc2UgPSBuYS5vbWl0KHN1cnZleSRBZ2UpDQoNCiMgYXNzaWduIHRoZSBsZW5ndGgNCm4gPSBsZW5ndGgoYWdlLnJlc3BvbnNlKQ0KDQojIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb24gDQpzID0gNw0KDQojIEVzdGltYXRpbmcgc3RhbmRhcmQgZXJyb3INClNFID0gcy9zcXJ0KG4pDQoNCiMgTWFyZ2luIG9mIGVycm9yICh1cHBlciB0YWlsIDk1JSBvZiBDb25maWRlbmNlIEludGVydmFsKQ0KRSA9IHF0KDAuOTc1LCBkZj0gbiAtMSkqU0UNCkUNCmBgYA0KDQpXZSBmaW5kIHRoYXQgdGhlIG1hcmdpbiBvZiBlcnJvciBmb3IgdGhlIHVwcGVyIHRhaWwgOTUlIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGlzIDAuODk1Nzg3MiB5ZWFycy4NCg0KYGBge3J9DQojIHNhbXBsZSBtZWFuDQp4YmFyID0gbWVhbihhZ2UucmVzcG9uc2UpDQp4YmFyDQoNCiMgQ29uZmlkZW5jZSBJbnRlcnZhbA0KeGJhcitjKC1FLCBFKQ0KDQpgYGANCg0KVGhlIHJlc3VsdCBvZiB0aGUgbWFyZ2luIG9mIGVycm9yIGZvciB0aGUgc3R1ZGVudCBhZ2Ugc3VydmV5IGlzIDAuODk1Nzg3MiB5ZWFycyBhdCA5NSUgY29uZmlkZW5jZSBsZXZlbCBhbmQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgaW4gYmV0d2VlbiAxOS40Nzg3MyBhbmQgMjEuMjcwMzAgeWVhcnMuDQoNCiRBbHRlcm5hdGl2ZSQgJFNvbHV0aW9uJA0KYGBge3J9DQpsaWJyYXJ5KHN0YXRzKQ0KdC50ZXN0KGFnZS5yZXNwb25zZSkNCmBgYA0KDQoNCg0KIyMgRXhlcmNpc2UgNA0KDQpJbXByb3ZlIHRoZSBxdWFsaXR5IG9mIGEgc2FtcGxlIGBzdXJ2ZXlgIGJ5IGluY3JlYXNpbmcgdGhlIHNhbXBsZSBzaXplIHdpdGggdW5rbm93biBzdGFuZGFyZCBkZXZpYXRpb24gJFxzaWdtYSQhLg0KDQpTb2x1dGlvbjoNCg0KU2luY2UsIHdlIGRvbnQga25vdyB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIGlzIGFuZCB3ZSBuZWVkIHRvIGltcHJvdmUgdGhlIHF1YWxpdGl5IG9mIGEgc2FtcGxlIHN1cnZleSwgd2UgYXJlIGdvaW5nIHRvIGFzc3VtZSB0aGF0IGhhbGYgb2YgdGhlIHN0dWRlbnQgd3JpdGUgZG93biB0aGUgc3VydmV5IHdoaWNoIGdpdmUgdXMgdGhlIG1heGltdW0gdmFyaWFiaWxpdHkuIFNvLCBub3cgdGhlIHAgaXMgMC41LiBOb3csIGxldCdzIHNheSB0aGF0IHdlIHdhbnQgNSUgbWFyZ2luIG9mIGVycm9yIGFuZCA5NSUgY29uZmlkZW5jZSBsZXZlbCB0aGF0IGdpdmUgdXMgdGhlIFogY2FsdWVzIG9mIDEuODYuDQoNCmBgYHtyfQ0KenN0YXIgPSBxbm9ybSgwLjk3NSkNCih6c3Rhcl4yKigwLjUpKiAoMC41KSkvICgwLjA1KV4yDQpgYGANCg0KU28sIHdlIGdvdCAzODQuMTQ1OSBvciAzODQgc2FtcGxlIHNpemVzIHRvIGltcHJvdmUgdGhlIHF1YWxpdHkgb2YgYSBzYW1wbGUgYHN1cnZleWAgd2l0aCB1bmtub3duIHN0YW5kYXJkIGRldmlhdGlvbiAkXHNpZ21hJCEuYA0KDQojIyBFeGVyY2lzZSA1DQoNCkFzc3VtZSB5b3UgZG9u4oCZdCBoYXZlIHBsYW5uZWQgcHJvcG9ydGlvbiBlc3RpbWF0ZSwgZmluZCB0aGUgc2FtcGxlIHNpemUgbmVlZGVkIHRvIGFjaGlldmUgNSUgbWFyZ2luIG9mIGVycm9yIGZvciB0aGUgbWFsZSBzdHVkZW50IGBzdXJ2ZXlgIGF0IDk1JSBjb25maWRlbmNlIGxldmVsIQ0KDQpTb2x1dGlvbjoNCg0KV2hhdCB3ZSBrbm93Og0KDQogICogNSUgbWFyZ2luIG9mIGVycm9yDQogICogOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwNClNvLCB3ZSBjYW4gZ2V0ICR6JCA9IDEuOTYNCg0KRmlyc3Qgd2UgbmVlZCB0byBmaW5kIG91dCB0aGUgbnVtYmVyIG9mIG1hbGUgc3R1ZGVudHMuIFdlIGNhbiBmaW5kIGl0IHVzaW5nIGBzdW1gIGZ1bmN0aW9uIGFuZCBkaXZpZGluZyBpdCBieSBuIHRvIGZpbmQgdGhlIG1hbGUgc3R1ZGVudCBwcm9wb3J0aW9uIGluIHRoaXMgc2FtcGxlIHN1cnZleQ0KDQpgYGB7cn0NCmxpYnJhcnkoTUFTUykNCmdlbmRlci5yZXNwb25zZSA9IG5hLm9taXQoc3VydmV5JFNleCkNCm4gPSBsZW5ndGgoZ2VuZGVyLnJlc3BvbnNlKQ0KayA9IHN1bShnZW5kZXIucmVzcG9uc2UgPT0gIk1hbGUiKQ0Kaw0KcGJhciAgPSBrL247cGJhcg0KYGBgDQpUaGUgbnVtYmVyIG9mIG1hbGUgc3R1ZGVudCBpcyAxMTguIFRoZSBwcm9wb3J0aW9uIG9mIHRoZSBtYWxlIHN0dWRlbnQgaXMgMC41LiAgDQoNCk5vdywgd2Ugd2FudCB0byBmaW5kIHRoZSBzYW1wbGUgc2l6ZSB0byBhY2hpZXZlIDUlIG1hcmdpbiBvZiBlcnJvciBmb3IgdGhlIG1hbGUgc3R1ZGVudCBgc3VydmV5YCBhdCA5NSUgY29uZmlkZW5jZSBsZXZlbA0KDQpgYGB7cn0NCnpzdGFyID0gcW5vcm0oMC45NzUpDQpwPTAuNQ0KDQojTWFyZ2luIG9yIGVycm9yDQpFID0gMC4wNQ0KenN0YXJeMipwKigxLXApL0VeMg0KYGBgDQoNClRoZSwgd2UgZ2V0IHRoYXQgd2UgbmVlZCAzODQuMTQ1OSBvciAzODQgc2FtcGxlIHNpemUgdG8gYWNoaWV2ZSA1JSBtYXJnaW4gb2YgZXJyb3IgZm9yIHRoZSBtYWxlIHN0dWRlbnQgc3VydmV5IGF0IDk1JSBjb25maWRlbmNlIGxldmVsLg0KDQoNCiMjIEV4ZXJjaXNlIDYNCg0KUGVyZm9ybSBjb25maWRlbmNlIGludGVydmFscyBhbmFseXNpcyBvbiB0aGlzIFtkYXRhIHNldF0oaHR0cDovL211cnJheWxheC5vcmcvZGF0YXNldHMvY3BzMDQuY3N2KSBmcm9tIDIwMDQgdGhhdCBpbmNsdWRlcyBkYXRhIG9uIGF2ZXJhZ2UgaG91cmx5IGVhcm5pbmdzLCBtYXJpdGFsIHN0YXR1cywgZ2VuZGVyLCBhbmQgYWdlIGZvciB0aG91c2FuZHMgb2YgcGVvcGxlLg0KDQokU29sdXRpb246JA0KDQpGaXJzdCB3ZSByZWFkIHRoZSBjc3Ygb2YgY3BzMDQgYmVmb3JlIHdlIGZpbmQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgIHRoZSBhdmVyYWdlIGhvdXJseSBlYXJuaW5ncywgbWFyaXRhbCBzdGF0dXMsIGdlbmRlciwgYW5kIGFnZSBmb3IgdGhvdXNhbmRzIG9mIHBlb3BsZS4NCg0KDQpgYGB7cn0NCmNwczA0IDwtcmVhZC5jc3YoImNwczA0LmNzdiIsIGhlYWRlciA9IFQsIHNlcCA9ICIsIikNCg0KIyBBdmVyYWdlIGhvdXJseSBlYXJuaW5ncw0KYXZnaG91ci5yZXNwb25zZSA9IG5hLm9taXQoY3BzMDQkYWhlKQ0KDQpuID0gbGVuZ3RoKGF2Z2hvdXIucmVzcG9uc2UpDQoNCiMgU3RhbmRhcmQgRGV2aWF0aW9uDQpzaWdtYSA9IHNkKGF2Z2hvdXIucmVzcG9uc2UpDQoNCiMgU3RhbmRhcmQgZXJyb3Igb2YgdGhlIG1lYW4NClNFID0gc2lnbWEgL3NxcnQobikNCg0KIyBNYXJnaW4gb2YgZXJyb3INCkUgPSBxbm9ybSgwLjk3NSkqU0UNCkUNCg0KeGJhciA8LSBtZWFuKGF2Z2hvdXIucmVzcG9uc2UpDQp4YmFyDQoNCnhiYXIgK2MoLUUsRSkNCg0KYGBgDQoNCkZyb20gdGhlIGNvZGUgYWJvdmUsIHdlIGNhbiBrbm93IHRoYXQgdGhlIG1hcmdpbiBvZiBlcnJvciBvZiBhdmVyYWdlIGhvdXJseSBlYXJuaW5ncyBpcyAwLjE5MjA5NjQuIHhiYXIgKHNhbXBsZSBtZWFuKSBpcyA2Ljc3MTIgd2hpbGUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgaW5iZXR3ZWVuIDE2LjU3OTExIGFuZCAxNi45NjMzMC4NCg0KYGBge3J9DQojIEFnZQ0KYWdlLnJlc3BvbiA9IG5hLm9taXQoY3BzMDQkYWdlKQ0KbiA9IGxlbmd0aChhZ2UucmVzcG9uKQ0KDQojU3RhbmRhcmQgRGV2aWF0aW9uDQpzaWdtYSA9IHNkKGFnZS5yZXNwb24pDQoNCiNzdGFuZGFyZCBlcnJvciBvZiB0aGUgbWVhbg0KU0U9c2lnbWEvc3FydChuKQ0KDQojIE1hcmdpbiBvZiBlcnJvcg0KRT0gcW5vcm0oMC45NzUpKlNFDQpFDQoNCnhiYXIgPC0gbWVhbihhZ2UucmVzcG9uKQ0KeGJhcg0KDQp4YmFyK2MoLUUsRSkNCg0KYGBgDQoNCkZyb20gdGhlIGNvZGUgYWJvdmUsIHdlIGNhbiBrbm93IHRoYXQgdGhlIG1hcmdpbiBvZiBlcnJvciBvZiBhZ2UgaXMgMC4wNjM0MDg5Mi4geGJhciAoc2FtcGxlIG1lYW4pIGlzIDI5Ljc1NDQ1IHdoaWxlIHRoZSBjb25maWRlbmNlIGludGVydmFsIGlzIGluYmV0d2VlbiAyOS42OTEwNCBhbmQgIDI5LjgxNzg1IHllYXJzLg0KDQpgYGB7cn0NCiMgRmVtYWxlDQoNCmZlbWFsZS5yZXNwb25zZSA9IG5hLm9taXQoY3BzMDQkZmVtYWxlKQ0KbiA9IGxlbmd0aChmZW1hbGUucmVzcG9uc2UpDQprID0gc3VtKGZlbWFsZS5yZXNwb25zZSA9PSAiMSIpDQprDQoNCiNTdGFuZGFyZCBEZXZpYXRpb24NCnNpZ21hID0gc2QoZmVtYWxlLnJlc3BvbnNlKQ0KDQojc3RhbmRhcmQgZXJyb3Igb2YgdGhlIG1lYW4NClNFPXNpZ21hL3NxcnQobikNCg0KIyBNYXJnaW4gb2YgZXJyb3INCkU9IHFub3JtKDAuOTc1KSpTRQ0KRQ0KDQp4YmFyIDwtIG1lYW4oZmVtYWxlLnJlc3BvbnNlKQ0KeGJhcg0KDQp4YmFyK2MoLUUsRSkNCg0KDQpgYGANCg0KRnJvbSB0aGUgY29kZSBhYm92ZSwgd2UgY2FuIGtub3cgdGhhdCB0aGUgdG90YWwgb2YgdGhlIGZlbWFsZSBpcyAzMzEzIGFuZCB0aGUgbWFyZ2luIG9mIGVycm9yIG9mIGFnZSBpcyAwLjAxMDgwNjYyLiB4YmFyIChzYW1wbGUgbWVhbikgaXMgMC40MTQ4NTEgd2hpbGUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgaW5iZXR3ZWVuIDAuNDA0MDQ0NCAgYW5kIDAuNDI1NjU3Ni4gRnJvbSB0aGlzIGludGVydmFsIHdlIGtub3cgdGhhdCwgdGhlcmUgYXJlIG1vcmUgbWFsZSB0aGFuIGZlbWFsZSBwYXJ0aWNpcGFudHMNCg0KDQpgYGB7cn0NCiMgQmFjaGVsb3INCg0KYmFjaGVsb3IucmVzcG9uc2UgPSBuYS5vbWl0KGNwczA0JGJhY2hlbG9yKQ0KbiA9IGxlbmd0aChiYWNoZWxvci5yZXNwb25zZSkNCmsgPSBzdW0oYmFjaGVsb3IucmVzcG9uc2UgPT0gIjEiKQ0Kaw0KDQojU3RhbmRhcmQgRGV2aWF0aW9uDQpzaWdtYSA9IHNkKGJhY2hlbG9yLnJlc3BvbnNlKQ0KDQojc3RhbmRhcmQgZXJyb3Igb2YgdGhlIG1lYW4NClNFPXNpZ21hL3NxcnQobikNCg0KIyBNYXJnaW4gb2YgZXJyb3INCkU9IHFub3JtKDAuOTc1KSpTRQ0KRQ0KDQp4YmFyIDwtIG1lYW4oYmFjaGVsb3IucmVzcG9uc2UpDQp4YmFyDQoNCnhiYXIrYygtRSxFKQ0KYGBgDQoNCkZyb20gdGhlIGNvZGUgYWJvdmUsIHdlIGNhbiBrbm93IHRoYXQgdGhlIHRvdGFsIG9mIHRoZSBiYWNoZWxvciBpcyAzNDYwIGFuZCB0aGUgbWFyZ2luIG9mIGVycm9yIG9mIGFnZSBpcyAwLjAxMDkyMzg4LiB4YmFyIChzYW1wbGUgbWVhbikgaXMgMC40NTU3OTc2IHdoaWxlIHRoZSBjb25maWRlbmNlIGludGVydmFsIGlzIGluYmV0d2VlbiAwLjQ0NDg3MzggYW5kIDAuNDY2NzIxNS4gRnJvbSB0aGlzIGludGVydmFsIHdlIGtub3cgdGhhdCwgdGhlcmUgYXJlIG1vcmUgbm90IGJhY2hlbG9yIHRoYW4gYmFjaGVsb3IgcGFydGljaXBhbnRzDQoNCg0KIyBDYXNlIFN0dWR5IA0KDQpBc3N1bWUgeW91IGhhdmUgYWNjZXNzIHRvIGRhdGEgb24gYW4gZW50aXJlIHBvcHVsYXRpb24sIHNheSB0aGUgc2l6ZSBvZiBldmVyeSBob3VzZSBpbiBbYWxsIHJlc2lkZW50aWFsIGhvbWUgc2FsZXMgaW4gQW1lcywgSW93YSBiZXR3ZWVuIDIwMDYgYW5kIDIwMTBdKGh0dHBzOi8vd3d3Lm9wZW5pbnRyby5vcmcvYm9vay9zdGF0ZGF0YS8/ZGF0YT1hbWVzKSBpdOKAmXMgc3RyYWlnaHQgZm9yd2FyZCB0byBhbnN3ZXIgcXVlc3Rpb25zIGxpa2UsIA0KDQoqIEhvdyBiaWcgaXMgdGhlIHR5cGljYWwgaG91c2UgaW4gQW1lcz8gDQoqIEhvdyBtdWNoIHZhcmlhdGlvbiBpcyB0aGVyZSBpbiBzaXplcyBvZiBob3VzZXM/LiANCiogSG93IG11Y2ggaXMgdGhlIGF2ZXJhZ2UgcHJpY2Ugb2YgaG91c2UgaW4gQW1lcz8NCiogSG93IG11Y2ggaXMgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgcHJpY2Ugb2YgaG91c2UgaW4gQW1lcz8NCg0KQnV0LCBJZiB5b3UgaGF2ZSBhY2Nlc3MgdG8gb25seSBhIHNhbXBsZSBvZiB0aGUgcG9wdWxhdGlvbiwgYXMgaXMgb2Z0ZW4gdGhlIGNhc2UsIHRoZSB0YXNrIGJlY29tZXMgbW9yZSBjb21wbGljYXRlZC4gV2hhdCBpcyB5b3VyIGJlc3QgZ3Vlc3MgZm9yIHRoZSB0eXBpY2FsIHNpemUgaWYgeW91IG9ubHkga25vdyB0aGUgc2l6ZXMgb2Ygc2V2ZXJhbCBkb3plbiBob3VzZXM/IFRoaXMgc29ydCBvZiBzaXR1YXRpb24gcmVxdWlyZXMgdGhhdCB5b3UgdXNlIHlvdXIgc2FtcGxlIHRvIG1ha2UgaW5mZXJlbmNlIG9uIHdoYXQgeW91ciBwb3B1bGF0aW9uIGxvb2tzIGxpa2UuDQoNCg0KIyMgQ29sbGVjdCBEYXRhDQoNClRvIGFjY2VzcyB0aGUgZGF0YSBpbiBSLCB0eXBlIHRoZSBmb2xsb3dpbmcgY29kZToNCg0KYGBge3J9DQpkb3dubG9hZC5maWxlKCJodHRwOi8vd3d3Lm9wZW5pbnRyby5vcmcvc3RhdC9kYXRhL2FtZXMuUkRhdGEiLCBkZXN0ZmlsZSA9ICJhbWVzLlJEYXRhIikNCmxvYWQoImFtZXMuUkRhdGEiKQ0KYGBgDQoNCkluIHRoaXMgY2FzZSBzdHVkeSB3ZeKAmWxsIHN0YXJ0IHdpdGggYSBzaW1wbGUgcmFuZG9tIHNhbXBsZSBvZiBzaXplIDYwIGZyb20gdGhlIHBvcHVsYXRpb24uIFNwZWNpZmljYWxseSwgdGhpcyBpcyBhIHNpbXBsZSByYW5kb20gc2FtcGxlIG9mIHNpemUgNjAuIE5vdGUgdGhhdCB0aGUgZGF0YSBzZXQgaGFzIGluZm9ybWF0aW9uIG9uIG1hbnkgaG91c2luZyB2YXJpYWJsZXMsIGJ1dCBmb3IgdGhlIGZpcnN0IHBvcnRpb24gb2YgdGhlIGxhYiB3ZeKAmWxsIGZvY3VzIG9uIHRoZSBzaXplIG9mIHRoZSBob3VzZSwgcmVwcmVzZW50ZWQgYnkgdGhlIHZhcmlhYmxlIGBHci5MaXYuQXJlYWAuDQoNCmBgYHtyfQ0KI3JhbmRvbWx5IHNldCBzZWVkIHRvIGZpeCBvdXRwdXRzIGluIHRoaXMgYXNzaWdubWVudA0Kc2V0LnNlZWQoMCkNCnBvcHVsYXRpb24gPC0gYW1lcyRHci5MaXYuQXJlYQ0Kc2FtcCA8LSBzYW1wbGUocG9wdWxhdGlvbiwgNjApDQoNCmBgYA0KDQoNCiMjIFZpc3VhbGl6YXRpb24NCg0KQXMgdXN1YWwsIGJlZm9yZSB5b3UgYmVnaW4gdG8gYW5hbHl6ZSBtb3JlIGFib3V0IHlvdXIgZGF0YS4gSXQncyBpbXBvcnRhbnQgdG8gdmlzdWFsaXplIHRoZSBkYXRhIGluIGFkdmFuY2UuIEhlcmUsIHdlIHVzZSBhIHJhbmRvbSBzYW1wbGUgb2Ygc2l6ZSA2MCBmcm9tIHRoZSBwb3B1bGF0aW9uLg0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtDQpsaWJyYXJ5KG1vbWVudHMpDQpoaXN0KHNhbXAsIGJyZWFrcyA9IDIwLCBjb2wgPSAncGluaycpDQpgYGANCg0KYGBge3J9DQojIE1ha2UgYSBoaXN0b2dyYW0gb2YgeW91ciBzYW1wbGUNCmhpc3Qoc2FtcCwgbWFpbiA9IkRpc3RyaWJ1dGlvbiBmbyBTYW1wIiwgDQogICAgIGNvbCA9ICJkZWVwcGluazMiLCANCiAgICAgeGxpbSA9IGMoMjAwLCAzNTAwKSwgDQogICAgIGZyZXEgPSBGLA0KICAgICB4bGFiID0gIlNhbXAiKQ0KIyAuLi5hbmQgYWRkIGEgZGVuc2l0eSBjdXJ2ZQ0KY3VydmUoZG5vcm0oeCwgDQogICAgICAgICAgICBtZWFuPW1lYW4oc2FtcCksIA0KICAgICAgICAgICAgc2Q9c2Qoc2FtcCkpLCBhZGQ9VCwgDQogICAgICAgICAgICBjb2w9ImJsdWUiLCBsd2Q9MikNCmBgYA0KDQoqKllvdXIgQ2hhbGxlbmdlOioqIA0KDQoqIERlc2NyaWJlIHRoZSBkaXN0cmlidXRpb24gb2YgeW91ciBzYW1wbGUuIFdoYXQgd291bGQgeW91IHNheSBpcyB0aGUg4oCcdHlwaWNhbOKAnSBzaXplIHdpdGhpbiB5b3VyIHNhbXBsZT8gQWxzbyBzdGF0ZSBwcmVjaXNlbHkgd2hhdCB5b3UgaW50ZXJwcmV0ZWQg4oCcdHlwaWNhbOKAnSB0byBtZWFuLiANCiogV291bGQgeW91IGV4cGVjdCBhbm90aGVyIHN0dWRlbnTigJlzIGRpc3RyaWJ1dGlvbiB0byBiZSBpZGVudGljYWwgdG8geW91cnM/IFdvdWxkIHlvdSBleHBlY3QgaXQgdG8gYmUgc2ltaWxhcj8gV2h5IG9yIHdoeSBub3Q/DQoNCiRBbnN3ZXIkDQoNCiogTXkgc2FtcGxlIGRpc3RyaWJ1dGlvbiBpcyByaWdodCBza2V3ZWQuIFRoZSB0eXBpY2FsIHNpemUgaXMgdG8gYmUgdGhlIG1lYW4gb2YgbXkgc2FtcGxlIHBvcHVsYXRpb24uIFRvIGtub3cgdGhhdCB3ZSBjYW4gdXNlIGBzdW1hcnJ5YCBmdW5jdGlvbiB0byBmaW5kIHRoZSBtZWFuLiBTbywgdGhlICJ0eXBpY2FsIiBzaXplIHdpdGhpbiBteSBzYW1wbGUgaXMgMTUxNC4gRm9yIHlvdXIgaW5mb3JtYXRpb24sIGEgdHlwaWNhbCBtZWFuIGlzIHRoZSB2YWx1ZSB0aGF0IGlzIG5lYXIgdGhlIG1vc3Qgc2ltdWx0YW5lb3VzIHZhbHVlcyBpbiB0aGUgZGlzdHJpYnV0aW9uLiANCg0KYGBge3J9DQpzdW1tYXJ5KHNhbXApDQpgYGANCg0KKiBJIHdvdWxkIGV4cGVjdCB0aGF0IHRoZXkgaGF2ZSBhbG1vc3QgdGhlIHNhbWUgYXMgaSBoYXZlIG9yIHNpbWlsYXIgIGJ1dCBub3QgaWRlbnRpY2FsIHRvIG15IGRpc3RyaWJ1dGlvbiBiZWNhdXNlIHRoaXMgaXMgYSByYW5kb20gc2FtcGxlIG9mIDYwIHJhbmRvbWx5IHNlbGVjdGVkIG9ic2VydmF0aW9ucy4gDQoNCg0KIyMgQ29uZmlkZW5jZSBJbnRlcnZhbHMNCg0KT25lIG9mIHRoZSBtb3N0IGNvbW1vbiB3YXlzIHRvIGRlc2NyaWJlIHRoZSB0eXBpY2FsIG9yIGNlbnRyYWwgdmFsdWUgb2YgYSBkaXN0cmlidXRpb24gaXMgdG8gdXNlIHRoZSBtZWFuLiBJbiB0aGlzIGNhc2Ugd2UgY2FuIGNhbGN1bGF0ZSB0aGUgbWVhbiBvZiB0aGUgc2FtcGxlIHVzaW5nLA0KDQpgYGB7cn0NCnNhbXBsZV9tZWFuIDwtIG1lYW4oc2FtcCkNCnNhbXBsZV9tZWFuDQpgYGANClJldHVybiBmb3IgYSBtb21lbnQgdG8gdGhlIHF1ZXN0aW9uIHRoYXQgZmlyc3QgbW90aXZhdGVkIHRoaXMgbGFiOiBiYXNlZCBvbiB0aGlzIHNhbXBsZSwgd2hhdCBjYW4gd2UgaW5mZXIgYWJvdXQgdGhlIHBvcHVsYXRpb24/IEJhc2VkIG9ubHkgb24gdGhpcyBzaW5nbGUgc2FtcGxlLCB0aGUgYmVzdCBlc3RpbWF0ZSBvZiB0aGUgYXZlcmFnZSBsaXZpbmcgYXJlYSBvZiBob3VzZXMgc29sZCBpbiBBbWVzIHdvdWxkIGJlIHRoZSBzYW1wbGUgbWVhbiwgdXN1YWxseSBkZW5vdGVkIGFzICRcYmFye3h9JCAoaGVyZSB3ZeKAmXJlIGNhbGxpbmcgaXQgYHNhbXBsZV9tZWFuYCkuIFRoYXQgc2VydmVzIGFzIGEgZ29vZCBwb2ludCBlc3RpbWF0ZSBidXQgaXQgd291bGQgYmUgdXNlZnVsIHRvIGFsc28gY29tbXVuaWNhdGUgaG93IHVuY2VydGFpbiB3ZSBhcmUgb2YgdGhhdCBlc3RpbWF0ZS4gVGhpcyBjYW4gYmUgY2FwdHVyZWQgYnkgdXNpbmcgYSBjb25maWRlbmNlIGludGVydmFsLg0KDQpXZSBjYW4gY2FsY3VsYXRlIGEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIGEgc2FtcGxlIG1lYW4gYnkgYWRkaW5nIGFuZCBzdWJ0cmFjdGluZyAxLjk2IHN0YW5kYXJkIGVycm9ycyB0byB0aGUgcG9pbnQgZXN0aW1hdGUgKEkgYXNzdW1lIHRoYXQgeW91IGhhdmUgYmVlbiBmYW1pbGlhciB3aXRoIHRoaXMgZm9ybXVsYSkuDQoNCmBgYHtyfQ0Kc2UgPC0gc2Qoc2FtcCkgLyBzcXJ0KDYwKQ0KbG93ZXIgPC0gc2FtcGxlX21lYW4gLSAxLjk2ICogc2UNCnVwcGVyIDwtIHNhbXBsZV9tZWFuICsgMS45NiAqIHNlDQpjKGxvd2VyLCB1cHBlcikNCmBgYA0KVGhpcyBpcyBhbiBpbXBvcnRhbnQgaW5mZXJlbmNlIHRoYXQgd2XigJl2ZSBqdXN0IG1hZGU6IGV2ZW4gdGhvdWdoIHdlIGRvbuKAmXQga25vdyB3aGF0IHRoZSBmdWxsIHBvcHVsYXRpb24gbG9va3MgbGlrZSwgd2XigJlyZSA5NSUgY29uZmlkZW50IHRoYXQgdGhlIHRydWUgYXZlcmFnZSBzaXplIG9mIGhvdXNlcyBpbiBgQW1lc2AgbGllcyBiZXR3ZWVuIHRoZSB2YWx1ZXMgbG93ZXIgYW5kIHVwcGVyLiBUaGVyZSBhcmUgYSBmZXcgY29uZGl0aW9ucyB0aGF0IG11c3QgYmUgbWV0IGZvciB0aGlzIGludGVydmFsIHRvIGJlIHZhbGlkLg0KDQoqKllvdXIgQ2hhbGxlbmdlOioqIA0KDQoqIEZvciB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCB0byBiZSB2YWxpZCwgdGhlIHNhbXBsZSBtZWFuIG11c3QgYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgYW5kIGhhdmUgc3RhbmRhcmQgZXJyb3IgJCBzL1xzcXJ0e259JC4gV2hhdCBjb25kaXRpb25zIG11c3QgYmUgbWV0IGZvciB0aGlzIHRvIGJlIHRydWU/DQoqIFdoYXQgZG9lcyDigJw5NSUgY29uZmlkZW5jZeKAnSBtZWFuPw0KKiBEb2VzIHlvdXIgY29uZmlkZW5jZSBpbnRlcnZhbCBjYXB0dXJlIHRoZSB0cnVlIGF2ZXJhZ2Ugc2l6ZSBvZiBob3VzZXMgaW4gYEFtZXNgPyBJZiB5b3UgYXJlIHdvcmtpbmcgb24gdGhpcyBjYXNlIHN0dWR5LCBkb2VzIHlvdXIgY2xhc3NtYXRl4oCZcyBpbnRlcnZhbCBjYXB0dXJlIHRoaXMgdmFsdWU/DQoNCiRBbnN3ZXIkDQoNCiogVGhlIGNvbmRpdGlvbnMgdGhhdCBtdXN0IGJlIG1ldCBmb3IgdGhpcyB0byBiZSB0cnVlIGFyZSB0aGVyZSBhcmUgYXQgbGVhc3QgdGhpcnR5ICBpbmRlcGVuZGVudCBvYnNlcnZhdGlvbnMgd2l0aG91dCBiZWluZyB0b28gc2tld2VkLiBBbHNvLCBtb3JlIGltcG90YW50bHksIHRoZSBzYW1wbGUgbWVhbiBvZiB0aGUgZGlzdHJpYnV0aW9uIHByb3Blcmx5IGVzdGltYXRlZCBieSBhIG5vcm1hbCBtb2RlbC4NCg0KKiA5NSUgY29uZmlkZW5jZSAgaXMgYSBjb25maWRlbmNlIGludGVydmFsIGxldmVsIGZvciB0aGUgbm9ybWFsIG1vZGVsLiBBbHNvLCBpdCBpcyB3aXRoIHRoZSBzdGFuZGFyZCBlcnJvci4gVXN1YWxseSwgOTUlIGNvbmZpZGVuY2UgbWVhbnMgdGhhdCBpdCBoYXZlIDUlIG9mIG1hcmdpbiBvZiBlcnJvci5UaGUgZm9ybXVsYSBvZiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBpcyAkcG9pbnQkICRlc3RpbWF0ZSQgwrEgU3RhbmRhcmQgb2YgZXJyb3IgLiB6ICh3aGljaCBpcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBjb25maWRlbmNlIGxldmVsKS4gDQoNCiogWWVzLCBteSBjb25maWRlbmNlIGludGVydmFsIGNhcHR1cmVzIHRoZSB0cnVlIGF2ZXJhZ2UgaG91c2VzIGluIEFtZXMuIE9mIGNvdXJzZSwgbXkgbmVpZ2hib3VyJ3MgaW50ZXJ2YWwgd2lsbCBhbHNvIGNhcHR1cmUgdGhpcyB2YWx1ZSAgYXMgd2VsbC4NCg0KIyMgU2ltdWxhdGlvbiANCg0KbGV04oCZcyBzaW11bGF0ZSBhIHNjZW5hcmlvIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaW4gY2xhc3Nyb29tIHRvIGNhcHR1cmUgdGhlIHRydWUgYXZlcmFnZSBzaXplIG9mIGhvdXNlcyBpbiBgQW1lc2AuIFN1cHBvc2Ugd2UgaGF2ZSAxMDAgc3R1ZGVudHMgaW4gdGhlIGNsYXNzcm9vbS4gDQoNCmBgYHtyfQ0KY291bnQgPSAwDQpmb3IgKGkgaW4gMToxMDApIHsNCiAgc2FtcCA8LSBzYW1wbGUocG9wdWxhdGlvbiw2MCkNCiAgc2FtcF9tZWFuPC0gbWVhbihzYW1wKQ0KICBzZSA8LSBzZChzYW1wKS9zcXJ0KDYwKQ0KICBsb3dlciA8LSBzYW1wX21lYW4tMS45NipzZQ0KICB1cHBlciA8LSBzYW1wX21lYW4rMS45NipzZQ0KICBpZiAoKGxvd2VyIDw9IDE0OTkuNjkpICYgKHVwcGVyID49IDE0OTkuNjkpKSB7DQogICAgY291bnQgPSBjb3VudCsxDQogIH0gIA0KfQ0KY291bnQNCmBgYA0KVXNpbmcgUiwgd2XigJlyZSBnb2luZyB0byByZWNyZWF0ZSBtYW55IHNhbXBsZXMgdG8gbGVhcm4gbW9yZSBhYm91dCBob3cgc2FtcGxlIG1lYW5zIGFuZCBjb25maWRlbmNlIGludGVydmFscyB2YXJ5IGZyb20gb25lIHNhbXBsZSB0byBhbm90aGVyLiBMb29wcyBjb21lIGluIGhhbmR5IGhlcmUgKElmIHlvdSBhcmUgdW5mYW1pbGlhciB3aXRoIGxvb3BzLCByZXZpZXcgdGhlIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBMYWIpLg0KDQpIZXJlIGlzIHRoZSByb3VnaCBvdXRsaW5lOg0KDQoqIE9idGFpbiBhIHJhbmRvbSBzYW1wbGUuDQoqIENhbGN1bGF0ZSBhbmQgc3RvcmUgdGhlIHNhbXBsZeKAmXMgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uLg0KKiBSZXBlYXQgc3RlcHMgKDEpIGFuZCAoMikgNTAgdGltZXMuDQoqIFVzZSB0aGVzZSBzdG9yZWQgc3RhdGlzdGljcyB0byBjYWxjdWxhdGUgbWFueSBjb25maWRlbmNlIGludGVydmFscy4NCg0KQnV0IGJlZm9yZSB3ZSBkbyBhbGwgb2YgdGhpcywgd2UgbmVlZCB0byBmaXJzdCBjcmVhdGUgZW1wdHkgdmVjdG9ycyB3aGVyZSB3ZSBjYW4gc2F2ZSB0aGUgbWVhbnMgYW5kIHN0YW5kYXJkIGRldmlhdGlvbnMgdGhhdCB3aWxsIGJlIGNhbGN1bGF0ZWQgZnJvbSBlYWNoIHNhbXBsZS4gQW5kIHdoaWxlIHdl4oCZcmUgYXQgaXQsIGxldOKAmXMgYWxzbyBzdG9yZSB0aGUgZGVzaXJlZCBzYW1wbGUgc2l6ZSBhcyAkbiQuDQoNCg0KYGBge3J9DQpzYW1wX21lYW4gPC0gcmVwKE5BLCA1MCkNCnNhbXBfc2QgPC0gcmVwKE5BLCA1MCkNCm4gPC0gNjANCm4NCmBgYA0KDQpOb3cgd2XigJlyZSByZWFkeSBmb3IgdGhlIGxvb3Agd2hlcmUgd2UgY2FsY3VsYXRlIHRoZSBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiA1MCByYW5kb20gc2FtcGxlcy4NCg0KYGBge3J9DQpmb3IoaSBpbiAxOjUwKXsNCiAgc2FtcCA8LSBzYW1wbGUocG9wdWxhdGlvbiwgbikgIyBvYnRhaW4gYSBzYW1wbGUgb2Ygc2l6ZSBuID0gNjAgZnJvbSB0aGUgcG9wdWxhdGlvbg0KICBzYW1wX21lYW5baV0gPC0gbWVhbihzYW1wKSAgICAjIHNhdmUgc2FtcGxlIG1lYW4gaW4gaXRoIGVsZW1lbnQgb2Ygc2FtcF9tZWFuDQogIHNhbXBfc2RbaV0gPC0gc2Qoc2FtcCkgICAgICAgICMgc2F2ZSBzYW1wbGUgc2QgaW4gaXRoIGVsZW1lbnQgb2Ygc2FtcF9zZA0KfQ0Kc2FtcA0KYGBgDQoNCkxhc3RseSwgd2UgY29uc3RydWN0IHRoZSBjb25maWRlbmNlIGludGVydmFscy4NCg0KYGBge3J9DQpsb3dlcl92ZWN0b3IgPC0gc2FtcF9tZWFuIC0gMS45NiAqIHNhbXBfc2QgLyBzcXJ0KG4pIA0KdXBwZXJfdmVjdG9yIDwtIHNhbXBfbWVhbiArIDEuOTYgKiBzYW1wX3NkIC8gc3FydChuKQ0KYGBgDQoNCg0KTG93ZXIgYm91bmRzIG9mIHRoZXNlIDUwIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSBzdG9yZWQgaW4gYGxvd2VyX3ZlY3RvcmAsIGFuZCB0aGUgdXBwZXIgYm91bmRzIGFyZSBpbiBgdXBwZXJfdmVjdG9yYC4gTGV04oCZcyB2aWV3IHRoZSBmaXJzdCBpbnRlcnZhbC4NCg0KYGBge3J9DQpjKGxvd2VyX3ZlY3RvclsxXSwgdXBwZXJfdmVjdG9yWzFdKQ0KYGBgDQpgYGB7cn0NCiMgY29uZmlkZW50aWFsIGludGVydmFsIHZpc3VhbGl6YXRpb24NCnBsb3RfY2kobG93ZXJfdmVjdG9yLCB1cHBlcl92ZWN0b3IsIG1lYW4ocG9wdWxhdGlvbikpDQojIEZvciBhIDk1JSBjb25maWRlbmNlIGludGVydmFsLCB0aGUgY3JpdGljYWwgdmFsdWUgaXMgLTEuOTU5OTY0IGFuZCAxLjk1OTk2NC4NCnFub3JtKCgxLTAuOTUpLzIpDQpxbm9ybSgoMSswLjk1KS8yKQ0KYGBgDQoNCioqWW91ciBDaGFsbGVuZ2U6KiogDQoNCiogV2hhdCBwcm9wb3J0aW9uIG9mIHlvdXIgY29uZmlkZW5jZSBpbnRlcnZhbHMgaW5jbHVkZSB0aGUgdHJ1ZSBwb3B1bGF0aW9uIG1lYW4/IElzIHRoaXMgcHJvcG9ydGlvbiBleGFjdGx5IGVxdWFsIHRvIHRoZSBjb25maWRlbmNlIGxldmVsPyBJZiBub3QsIGV4cGxhaW4gd2h5Lg0KKiBQaWNrIGEgY29uZmlkZW5jZSBsZXZlbCBvZiB5b3VyIGNob29zaW5nLCBwcm92aWRlZCBpdCBpcyA5OSUuIFdoYXQgaXMgdGhlIGFwcHJvcHJpYXRlIGNyaXRpY2FsIHZhbHVlPw0KKiBDYWxjdWxhdGUgNTAgY29uZmlkZW5jZSBpbnRlcnZhbHMgYXQgdGhlIGNvbmZpZGVuY2UgbGV2ZWwgeW91IGNob3NlIGluIHRoZSBwcmV2aW91cyBxdWVzdGlvbi4gWW91IGRvIG5vdCBuZWVkIHRvIG9idGFpbiBuZXcgc2FtcGxlcywgc2ltcGx5IGNhbGN1bGF0ZSBuZXcgaW50ZXJ2YWxzIGJhc2VkIG9uIHRoZSBzYW1wbGUgbWVhbnMgYW5kIHN0YW5kYXJkIGRldmlhdGlvbnMgeW91IGhhdmUgYWxyZWFkeSBjb2xsZWN0ZWQuIFVzaW5nIHRoZSBwbG90X2NpIGZ1bmN0aW9uLCBwbG90IGFsbCBpbnRlcnZhbHMgYW5kIGNhbGN1bGF0ZSB0aGUgcHJvcG9ydGlvbiBvZiBpbnRlcnZhbHMgdGhhdCBpbmNsdWRlIHRoZSB0cnVlIHBvcHVsYXRpb24gbWVhbi4gSG93IGRvZXMgdGhpcyBwZXJjZW50YWdlIGNvbXBhcmUgdG8gdGhlIGNvbmZpZGVuY2UgbGV2ZWwgc2VsZWN0ZWQgZm9yIHRoZSBpbnRlcnZhbHM/DQoNCiRBbnN3ZXIkDQoNCiogVGhlIHByb3BvcnRpb24gb2YgbXkgY29uZmlkZW5jZSBpbnRlcnZhbHMgaW5jbHVkZSB0aGUgdHJ1ZSBwb3B1bGF0aW9uIG1lYW4gaXMgOTclLiBUaGlzIHByb3BvcnRpb24gaXMgbm90IGV4YWN0bHkgZXF1YWwgdG8gdGhlIGNvbmZpZGVuY2UgbGV2ZWwgb25seSBhcHByb3hpbWF0ZWx5IG5lYXIgIGFuZCBhbGwgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFyZSBhbGwgY3JlYXRlZCBmcm9tIHJhbmRvbSBzYW1wbGVzLg0KDQpgYGB7cn0NClZlY3RvciA8LWRhdGEuZnJhbWUobG93ZXJfdmVjdG9yLHVwcGVyX3ZlY3RvcikNCm1lYW5wb3B1bGF0aW9uID0gbWVhbihwb3B1bGF0aW9uKQ0KDQpsZWZ0IDwtIHN1bShWZWN0b3IkdXBwZXJfdmVjdG9yIDxtZWFucG9wdWxhdGlvbikNCnJpZ2h0IDwtIHN1bShWZWN0b3IkbG93ZXJfdmVjdG9yID4gbWVhbnBvcHVsYXRpb24pDQoNCk5vdEluY2x1ZGluZ01lYW4gPC0gbGVmdCtyaWdodA0KDQpwcm9wb3J0aW9uIDwtIChOb3RJbmNsdWRpbmdNZWFuL24pDQpwcm9wb3J0aW9uDQpwcm9wb3J0aW9uIDwtIHJvdW5kKHByb3BvcnRpb24sMikNCnByb3BvcnRpb24NCmBgYA0KDQoNCiogUGljayBhIGNvbmZpZGVuY2UgbGV2ZWwgb2YgeW91ciBjaG9vc2luZywgcHJvdmlkZWQgaXQgaXMgbm90IDk5JS4gV2hhdCBpcyB0aGUgYXBwcm9wcmlhdGUgY3JpdGljYWwgdmFsdWU/DQoNClNvbHV0aW9uOg0KDQpCZWNhdXNlIHdlIGNhbm5vdCBjaG9vc2UgOTklLCBsZXQncyBjaG9vc2UgNzAlDQoNCmBgYHtyfQ0KeCA8LSAxLSg5OC8xMDApDQp5IDwtIDEtKHgvMikNCmN2IDwtcW5vcm0oeSkNCmN2DQpgYGANCg0KKiBDYWxjdWxhdGUgNTAgY29uZmlkZW5jZSBpbnRlcnZhbHMgYXQgdGhlIGNvbmZpZGVuY2UgbGV2ZWwgeW91IGNob3NlIGluIHRoZSBwcmV2aW91cyBxdWVzdGlvbi4gWW91IGRvIG5vdCBuZWVkIHRvIG9idGFpbiBuZXcgc2FtcGxlcywgc2ltcGx5IGNhbGN1bGF0ZSBuZXcgaW50ZXJ2YWxzIGJhc2VkIG9uIHRoZSBzYW1wbGUgbWVhbnMgYW5kIHN0YW5kYXJkIGRldmlhdGlvbnMgeW91IGhhdmUgYWxyZWFkeSBjb2xsZWN0ZWQuIFVzaW5nIHRoZSBwbG90X2NpIGZ1bmN0aW9uLCBwbG90IGFsbCBpbnRlcnZhbHMgYW5kIGNhbGN1bGF0ZSB0aGUgcHJvcG9ydGlvbiBvZiBpbnRlcnZhbHMgdGhhdCBpbmNsdWRlIHRoZSB0cnVlIHBvcHVsYXRpb24gbWVhbi4gSG93IGRvZXMgdGhpcyBwZXJjZW50YWdlIGNvbXBhcmUgdG8gdGhlIGNvbmZpZGVuY2UgbGV2ZWwgc2VsZWN0ZWQgZm9yIHRoZSBpbnRlcnZhbHM/DQoNCg0KYGBge3J9DQpsb3dlcl92ZWN0b3IgPC0gc2FtcF9tZWFuIC0gMS4wNCAqIHNhbXBfc2QgLyBzcXJ0KG4pIA0KdXBwZXJfdmVjdG9yIDwtIHNhbXBfbWVhbiArIDEuMDQgKiBzYW1wX3NkIC8gc3FydChuKQ0KDQpwbG90X2NpKGxvd2VyX3ZlY3RvciwgdXBwZXJfdmVjdG9yLCBtZWFuKHBvcHVsYXRpb24pKQ0KYyhsb3dlcl92ZWN0b3JbMV0sIHVwcGVyX3ZlY3RvclsxXSkNCg0KYGBgDQoNCmBgYHtyfQ0KVmVjdG9yIDwtZGF0YS5mcmFtZSAobG93ZXJfdmVjdG9yLCB1cHBlcl92ZWN0b3IgKQ0KbWVhbm9mcG9wdWxhdGlvbiA8LSBtZWFuIChwb3B1bGF0aW9uKQ0KDQpsZWZ0IDwtIHN1bShWZWN0b3IkdXBwZXJfdmVjdG9yIDwgbWVhbm9mcG9wdWxhdGlvbikNCnJpZ2h0IDwtc3VtKFZlY3RvciRsb3dlcl92ZWN0b3IgPiBtZWFub2Zwb3B1bGF0aW9uKQ0KDQpOb3RJbmNsdWRpbmdNZWFuIDwtIGxlZnQrcmlnaHQNCk5vdEluY2x1ZGluZ01lYW4NCmBgYA0KDQpgYGB7cn0NCnByb3BvcnRpb24gPC0gKE5vdEluY2x1ZGluZ01lYW4vbikNCnByb3BvcnRpb24gDQpwcm9wb3J0aW9uIDwtIHJvdW5kKHByb3BvcnRpb24sMikNCnByb3BvcnRpb24NCmBgYA0KDQpTbywgZnJvbSB0aGlzIGFuc3dlciBvbmx5IDY3JSBpbmNsdWRlIHRoZSBwb3B1bGF0aW9uIG1lYW4uIEZyb20gdGhpcyB3ZSBrbm93LCB0aGUgcHJvcG9ydGlvbiBpcyBub3QgZXhhY3RseSB0aGUgc2FtZSBhcyB0aGUgY29uZmlkZW5jZSBsZXZlbCBidXQgdmVyeSBjbG9zZQ==