Note: If you Rmd file submission knits you will receive total of (5 points)

1. PROBLEM SOLVING PART

Problem 1 (5 pts) - similar to Pr. 5 / page 238 in text A box contains 20 consecutive balls numbered 1 to 20. If four numbers are drawn at random, how many ways are there for the largest number to be a 13 and the smallest number to be 3 ?

Use the Fundamental Principle of Counting!

Solution:

YOUR CODE HERE:

choose(10, 2) #choosing 20/2 and 2

Problem 2 (5 pts) - similar to Pr. 14 / page 239 in text On a multiple-choice exam with four possible answers for each of the five questions, what is the probability that a student would get four or more correct answers just by guessing?

Hint: Use the fact that \(P(E ∩ F) = P(E) · P(F)\) for two independent event (generalized for more than events) Getting one answer correct is independent of another.

Also

\[P(at least 4) = P(exactly 4) + P(exactly 5)\]

the last events are mutually exclusive so \(P(A \cup B) = P(A) + P(B)\)

YOUR CODE HERE:

#refrencing probability and random vars exercise line 244 and 
choose(5, 4)*(1/4)^4*(2/4)^1 + choose(5, 5)*(1/4)^5*(2/3)^0 #P(atleast4) = P(exactly4) + P(exactly5)
rbinom(200, 5, 0.25) #generates random samples of 200 students 
sum(dbinom(x = 4:200, size = 5, prob = 0.25)) #summation of 200 students to get at least 4 questions correct on a 5 question test

Out of 200 students who adopt this test taking approach how many are expected to get at least 4 correct? Hint: Use Binomial experiment settings to answer this questions.

Solution:

Problem 3 (5 pts) - similar to Pr. 44 page 243 in text Consider tossing four fair coins. There are 16 possible outcomes, e.g HHHH,HHHT,HHTH,HTHH,THHH, ... possible outcomes. Define X as the random variable “number of heads showing when four coins are tossed.” Obtain the mean and the variance of X. Simulate tossing three fair coins 10,000 times. Compute the simulated mean and variance of X. Are the simulated values within 2% of the theoretical answers? Hint: to find the theoretical values use dbinom (x= , size = , prob = )

Solution:

YOUR CODE HERE:

#refrencing Prbability and Random Vars exercises line 296 & notes week 5 line 182
library(MASS)

SS <- expand.grid(toss1 = 0:1, toss2 = 0:1, toss3 = 0:1, toss4 = 0:1) #Initializing coin tosses
SumCoinToss <- apply(SS, 1, sum) #Sum of tosses
PDF <- fractions(table(SumCoinToss)/ 16) # Creates pdf function
PDF
SumCoinToss

x <- 0:4 #Possible number of heads in four tosses
Mean <- sum(x * PDF) #mean of random variable
Variance <- sum((x - Mean)^2 * PDF) #Variance of variable
Mean
Variance

sum(dbinom (x = , size = 16, prob = 0.02)) #??

Problem 4 (5 pts) - similar to Pr. 11 / page 307 in text

Traffic volume is an important factor for determining the most cost-effective method to surface a road. Suppose that the average number of vehicles passing a certain point on a road is 5 every 60 seconds.

  1. Find the probability that more than 12 cars will pass the point in a period of 3 minutes.
  2. What is the probability that more than 100 cars pass the point in half an hour?

Hint: Adjust the Poisson parameter \(\lambda = 5\) every 60 seconds to # per every 3 minutes

YOUR CODE HERE:

#Refrencing notes 4 line 251 and Univariate Prob Distributions exercises line 100
1 - ppois(x = 12, lambda = 5) #P(X > 12/5) = 1 - P(X <= 7/4)
1 - ppois(x = 100, lambda = 150) #P(X > 100/150) = 1 - P(X <= 100/150)

Problem 5 (5 pts) - similar to Pr. 18 / page 308 in text Suppose the percentage of drinks sold from a vending machine are 70% and 30% for soft drinks and bottled water, respectively.

  1. What is the probability that on a randomly selected day, the first soft drink is the fourth drink sold?
  2. Find the probability that exactly 4 out of 10 drinks sold is a soft drink.

Hint: Let X = number of waters (failures) purchased before the first soft drink is purchased. Then, \(X \sim Geo(0.70)\).

Solution:

YOUR CODE HERE:

#referencing notes week 5 line 334
dgeom(x = 3, 0.7) # P(x = 3) where x is number of failures before first soft drink
  1. Let X = number of soft drinks sold. Then, \(X \sim Bin(10, 0.70)\) and \(P(X = 1) = 0\) since one has:
pbinom(4, 10, 0.7) #P(x = 4) where x is 4 soft drinks sold for size 10

Problem 6 (10 pts) - Exponential Distribution: Light Bulbs If the life of a certain type of light bulb has an exponential distribution with a mean of 10 months,find

  1. The probability that a randomly selected light bulb lasts between 6 and 15 months.
  2. The 95th percentile of the distribution. How the probability of the light bulb to last more than 36 months compare to 0.05?
  3. The probability that a light bulb that has lasted for 10 months will last more than 25 months.

Solution:

YOUR CODE HERE:

#refrencing Univariate Prob Distributions exercises line 160 & notes week 5 line 419
pexp(15, 1/10) - pexp(6, 1/10) # pexp(q, rate = 1, lower.tail = TRUE, log.p = FALSE)

f1 <- function(x){(1/10) * exp(-x/10)}
integrate(f1, lower = 6, upper = 12)$value

qexp(0.95, 1/10) #Checking 95% of distribution, qexp(p, rate = 1, lower.tail = TRUE, log.p = FALSE)

pexp(25, 1/10, lower = FALSE)/pexp(10, 1/10, lower = FALSE)

Problem 7 (10 pts) - Pr. 8 page 400 A population has the following elements: 2, 5, 8, 12, 13 (finite population).

  1. Enumerate all the samples of size 2 that can be drawn with and without replacement. (Hint: Use the srs() function from the PASWR2 package)

  2. Calculate the mean of the population.

  3. Calculate the variance of the population.

  4. Calculate the standard deviation of the population.

  5. Calculate the mean of the sample mean, \(E[X]\).

  6. Calculate the variance of the sampled mean, \(Var(\bar X)\)

  7. Calculate the standard deviation of the sample mean.

  8. Calculate the mean of the sample variance, \(E[S^2]\)

  9. Is the variance of \(\bar X\) larger when sampling with or without replacement? Explain your answer

Solution:

YOUR CODE HERE:

#refrencing Sampling Distribution exercises line 206
library(PASWR2)

p <- c(2,5,8,12,13)

SRS2 <- srs(p, 2)
xbarSRS2 <- apply(SRS2, 1, mean)
c(mean(xbarSRS2), var(xbarSRS2), sd(xbarSRS2))

p_value <- c(2,5,8,12,13)
mean(p_value)
var(p_value)
sd(p_value)

Problem 8 (10 pts) - similar to Pr. 10 / page 400 in text

Use the data frame WHEATUSA2004 from the PASWR2 package; draw all samples of sizes 4, 5, and 6; and calculate the mean of the means. What size provides the best approximation to the population mean? What is the variance of these means?

Solution: The mean of the means for samples of size two, three, and four are all equal to 1148.7333 (the population mean). Consequently, all samples provide equal approximations to the population mean when taking all possible samples of a given sample size. The variance of the means, however, decreases with increasing sample size from 645755.872 for samples of size four, to 496720.646 for samples of size five, to 397374.397 for samples of size six.

Hint: Use the srs() function from the PASWR2 package to draw simple random samples.

YOUR CODE HERE:

#refrencing sampling distributions exercises line 206
library(PASWR2)

SRS4 <- srs(WHEATUSA2004$acres, 4) #using srs function and declaring variable SRS4 to find acres for sample size 4
xbarSRS4 <- apply(SRS4, 1, mean)   #applying mean to data
c(mean(xbarSRS4), var(xbarSRS4))   #finding mean and variance

SRS5 <- srs(WHEATUSA2004$acres, 5) #sample size 5
xbarSRS5 <- apply(SRS5, 1, mean)
c(mean(xbarSRS5), var(xbarSRS5))

SRS6 <- srs(WHEATUSA2004$acres, 6) #sample size 6
xbarSRS6 <- apply(SRS6, 1, mean)
c(mean(xbarSRS6), var(xbarSRS6))

Problem 9 (10 pts) - Pr. 16 / page 513 in text

A group of engineers working with physicians in a research hospital is developing a new device to measure blood glucose levels. Based on measurements taken from patients in a previous study, the physicians assert that the new device provides blood glucose levels slightly higher than those provided by the old device. To corroborate their suspicion, 15 diabetic patients were randomly selected, and their blood glucose levels were measured with both the new and the old devices. The measurements, in mg/100 ml, appear in data frame GLUCOSE from the PASWR2 package:

  1. Are the samples independent? Why or why not?
  2. If the blood glucose level is a normally distributed random variable, compute a 95% confidence interval for the mean differences of the population.
  3. Use the results in (b) to decide whether or not the two devices give the same results.

Solution:

  1. Hint: look at the QQ-plot to see if normality is reasonable.

YOUR CODE HERE:

GLUCOSE <- GLUCOSE %>% mutate(DIFF = old-new) # create variable DIFF for the difference between old and new level

head(GLUCOSE)

ggplot(data = GLUCOSE, aes(sample = DIFF)) +
  stat_qq() +
  theme_bw()

CI <- t.test(GLUCOSE$DIFF)$conf # use t-test since the sample size is small < 30
CI

The 95% confidence interval for the mean differences of the population is [−16.3614,−12.7586].

  1. The confidence interval suggests that on average, the new device reports higher blood glucose levels than the old device.

Problem 10 (10 pts) - similar to Pr. 9 / page 511 in text

A large company wants to estimate the proportion of its accounts that are paid on time.

  1. How large a sample is needed to estimate the true proportion within 2% with a 95% confidence level?

  2. Suppose 700 out of 800 accounts are paid on time. Construct 95% confidence intervals for the true proportion of accounts that are paid on time using an asymptotic confidence interval, an Agresti Coull confidence interval.

Hint: Use the nsize() and binom.confint() from the library(binom)

Solution:

YOUR CODE HERE:

#refrencing point estimation and cl line 206
library(binom)

#(a) 
nsize(b = 0.02, p = 0.5, conf.level = 0.95, type = "pi") #minimum sample size no more than 2% error

#(b)
binom.confint(x = 700, n = 800, conf.level = 0.95, methods = "asymptotic") #asymptotic confidence interval
binom.confint(x = 700, n = 800, conf.level = 0.95, methods = "ac") #Agresti Coull Confidence interval

Problem 11 (10 pts) - Pr. 10 / page 511 in text

In a study conducted at Appalachian State University, students used digital oral thermometers to record their temperatures each day they came to class. A randomly selected day of student temperatures is provided in the following table and in the data frame STATTEMPS. Information is also provided with regard to subject gender and the hour of the day when the students’ temperatures were measured.

Direction: load the data with data(STATTEMPS) having the library(PASWR2) loaded.

Hint: Use t.test(temperature ~ gender, data = STATTEMPS, mu = 0, paired = FALSE) the x ad y values are given with formula expression formula = temperature ~ gender. Then use the $ access to obtain the confidence interval: CI <- t.test(temperature ~ gender, data = STATTEMPS, mu = 0, paired = FALSE)$conf

  1. Construct a 95% confidence interval for the true average temperature difference between females and males. Does the interval contain the value zero? What does this suggest about gender temperature differences?

  2. Construct a 95% confidence interval for the true average temperature difference between students taking their temperatures at 8 a.m. and students taking their temperatures at 9 a.m. Give a reason why one group appears to have a higher temperature reading.

Solution:

YOUR CODE HERE:

library(PASWR2)
data(STATTEMPS)
#(a)
t.test(temperature ~ gender, data = STATTEMPS, mu = 0, paired = FALSE)
CI <- t.test(temperature ~ gender, data = STATTEMPS, mu = 0, paired = FALSE)$conf


#(b)
t.test(temperature ~ class, data = STATTEMPS, mu = 0, paired = FALSE)
CI <- t.test(temperature ~ class, data = STATTEMPS, mu = 0, paired = FALSE)$conf

A 95% confidence interval for the true average difference between students taking their temperatures at 8 a.m. and students taking their temperatures at 9 a.m. is [−2.4965,−0.2564]. Note that this interval does not contain 0, indicating that the there is evidence to suggest students in the 8 a.m. class have temperatures that are not as warm as the 9 a.m. class. One possible explanation is that students roll straight out of bed and into the 8 a.m. class. Consequently, their temperatures are closer to their sleeping temperatures which are lower than their waking temperature’s.

2. BRAINSTORMING PART:

How do we form confidence intervals when normality assumtion is not reasonable and we have small sample size so the Central Limit Theorem does not apply?

Look for the answer with the following :

Empirical bootstrap confidence interval for the mean.

For the data contained in a vector x = c(36,30,37,43,42,43,43,46,40,42) Estimate the mean μ of the underlying distribution and give an 90% bootstrap confidence interval.

x = c(36,30,37,43,42,43,43,46,40,42)
qqnorm(x) # see if the data appear to follow normal distribution

Data is not quite normal as it appears on the Q-Q PLOT!


n = length(x)
set.seed(25)  

# sample mean
xbar = mean(x)

cat("data mean = ",xbar,'\n')

nboot = 10000 # number of bootstrap samples 

# Generate 10000 bootstrap samples, i.e. an n x 10000 array of random resamples from x.
tmpdata = sample(x,n*nboot, replace=TRUE) # sample with replacement
bootstrapsample = matrix(tmpdata, nrow=n, ncol=nboot)

# Compute the sample mean xbar for each bootstrap sample
xbarstar = colMeans(bootstrapsample)

# Compute delta* for each bootstrap sample (difference between the original mean and the bootstrap sample mean)
deltastar = xbarstar - xbar

# Find the 0.1 and 0.9 quantiles for deltastar
d = quantile(deltastar,c(0.05,0.95)) # for the 905 CI we need 90% area between the quantiles


# Calculate the 90\% confidence interval for the mean.
ci = xbar - c(d[2],d[1])
ci

We can achieve the same CI with the functions boot() and boot.ci() from the package boot


MEAN <- function(data, i){
  d <- data[i]
   M <- mean(d)
  }
boot.obj <- boot(x, statistic = MEAN, 10000)
CI <- boot.ci(boot.obj, conf = 0.90,type = "all") # all type of bootstrap intervals will be returned
CI

3. BOOTSTRAP ESTIMATION PART

Review the problem below.

Pr. 30 / page 695 in text

The “Wisconsin Card Sorting Test” is widely used by psychiatrists, neurologists, and neuropsychologists with patients who have a brain injury, neurodegenerative disease, or a mental illness such as schizophrenia. Patients with any sort of frontal lobe lesion generally do poorly on the test. The data frame WCST and the following table contain the test scores from a group of 50 patients from the Virgen del Camino Hospital (Pamplona, Spain).

  1. Use the function eda() from the PASWR2 package to explore the data and decide if normality can be assumed. For details type in console ?eda

  2. What assumption(s) must be made to compute a 95% confidence interval for the population mean?

  3. Compute the confidence interval from (b).

  4. Compute a 95% BCa bootstrap confidence interval for the mean test score.

  5. Should you use the confidence interval reported in (c) or the confidence interval reported in (d)?

Solution:

  1. Assuming the variable score has a normal distribution is not reasonable.

See the results of EDA analysis below:

data(WCST)

WCST %>% pull(score) %>% eda()
  1. In order to construct a 95% confidence interval for the population mean, one assumes that the values in the variable score are taken from a normal distribution. Although this is not a reasonable assumption, the sample size might be sufficiently large to overcome the skewness in the parent population. Consequently, one might appeal to the Central Limit Theorem and claim that the sampling distribution of X is approximately normal due to the sample size (50). In this problem, the skewness is quite severe, and one should not be overly confident in the final interval.

  2. If we assume normality one has:

# CI <- with(data = WCST, t.test(score)$conf) # 

# or using piping
CI <- WCST %>% pull(score) %>% t.test() %>% .$conf
CI
  1. Use the boot.ci() nonparametric bootstrap CIs functions to obtain the bootstrap CI.
library(boot) # use boot package
MEAN <- function(data, i){
  d <- data[i]
   M <- mean(d)
  }

set.seed(13)

B <- 10^4 - 1 # number of bootstrap samples

b.obj <- boot(data = WCST$score, statistic = MEAN, R = B) # bootstrap object of class "boot" containing the output of a bootstrap calculation
CIB <- boot.ci(b.obj, conf = 0.95, type = "bca")
CIB

Problem 12 (10 pts) Set the seed to 23 (group 1), 45 (group 2), 67 (group 3), and 89 (group 4). Draw random sample of size 20 from exponential distribution with mean \(\lambda = 4\) (\(rate = \frac{1}{4}\)). Produce all bootstrap CI with the function boot.ci (use type = “all”).

How many of them contain the true mean for the sampled distribution?

YOUR CODE HERE:

library(boot)

set.seed(67) # uncomment by setting the value per your group designation
b.obj <- boot(data = set.seed, statistic = MEAN, R = 20)
CIB <- boot.ci(b.obj, type = "all")
CIB

EXTRA XREDIT (10 pts) Set the seed to 23 (group 1), 45 (group 2), 67 (group 3), and 89 (group 4). Draw random sample of size 25 from \(Bin(20,\frac{1}{5})\). Produce all bootstrap CI with the function boot.ci (use type = “all”).

How many of them contain the true mean for the \(Bin(20,\frac{1}{5})\)?

YOUR CODE HERE:

set.seed(67) # uncomment by setting the value per your group designation
bin <- pbinom(67, 20, 1/5)
b.obj <- boot(data = bin, statistic = MEAN, R = 25)
CIB <- boot.ci(b.obj, type = "all")
CIB
LS0tDQp0aXRsZTogIlNUQVQyNzAgLSBQcm9qZWN0IDIgLSBDbGFzc2ljYWwgUHJvYmFiaWxpdHkgYW5kIFN0YXRpc3RpY3MgUHJvYmxlbXMgYW5kIEJvb3RzdHJhcCBFc3RpbWF0aW9uIg0KYXV0aG9yOiAiS3lsZSBBLiBTY2h1bHR6LCBHYWJyaWVsIEouIFNjaHdpbmdoYW1tZXIsIFNoYW5pYSBULiBsZWFrIGZyYWl6ZXIsIERlcmVrIFcuIEpvbmVzIg0KZGF0ZTogIkZhbGwgMjAyMCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KDQoNCmBgYHtyIHBhY2thZ2VzLCBlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCiMgbG9hZCB0aGUgcGFja2FnZXMgZm9yIGdyYXBoaW5nIGFuZCBkYXRhIHdyYW5nbGluZw0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShQQVNXUjIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShsYXR0aWNlKQ0KbGlicmFyeShib290KQ0KbGlicmFyeShNQVNTKQ0KYGBgDQoNCg0KTm90ZTogSWYgeW91IGBSbWRgIGZpbGUgc3VibWlzc2lvbiBrbml0cyB5b3Ugd2lsbCByZWNlaXZlIHRvdGFsIG9mICoqKDUgcG9pbnRzKSoqDQoNCg0KIyMgMS4gUFJPQkxFTSBTT0xWSU5HIFBBUlQNCg0KKipQcm9ibGVtIDEgKDUgcHRzKSAtIHNpbWlsYXIgdG8gUHIuIDUgLyBwYWdlIDIzOCBpbiB0ZXh0KiogDQpBIGJveCBjb250YWlucyAyMCBjb25zZWN1dGl2ZSBiYWxscyBudW1iZXJlZCAxIHRvIDIwLiBJZiBmb3VyIG51bWJlcnMgYXJlIGRyYXduIGF0IHJhbmRvbSwgaG93IG1hbnkgd2F5cyBhcmUgdGhlcmUgZm9yIHRoZSBsYXJnZXN0IG51bWJlciB0byBiZSBhIDEzIGFuZCB0aGUgc21hbGxlc3QgbnVtYmVyIHRvIGJlIDMgPw0KDQpVc2UgdGhlIEZ1bmRhbWVudGFsIFByaW5jaXBsZSBvZiBDb3VudGluZyEgDQoNCioqU29sdXRpb246KiogDQoNCllPVVIgQ09ERSBIRVJFOg0KDQpgYGB7cn0NCmNob29zZSgxMCwgMikgI2Nob29zaW5nIDIwLzIgYW5kIDINCg0KYGBgDQoNCg0KDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KDQoNCioqUHJvYmxlbSAyICg1IHB0cykgLSBzaW1pbGFyIHRvIFByLiAxNCAvIHBhZ2UgMjM5IGluIHRleHQqKiBPbiBhIG11bHRpcGxlLWNob2ljZSBleGFtIHdpdGggKipmb3VyKiogcG9zc2libGUgYW5zd2VycyBmb3IgZWFjaCBvZiB0aGUgZml2ZSBxdWVzdGlvbnMsIHdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBzdHVkZW50IHdvdWxkIGdldCBmb3VyIG9yIG1vcmUgY29ycmVjdCBhbnN3ZXJzIGp1c3QgYnkgZ3Vlc3Npbmc/DQoNCkhpbnQ6IFVzZSB0aGUgZmFjdCB0aGF0ICRQKEUg4oipIEYpID0gUChFKSDCtyBQKEYpJCBmb3IgdHdvIGluZGVwZW5kZW50IGV2ZW50IChnZW5lcmFsaXplZCBmb3IgbW9yZSB0aGFuIGV2ZW50cykgR2V0dGluZyBvbmUgYW5zd2VyIGNvcnJlY3QgaXMgaW5kZXBlbmRlbnQgb2YgYW5vdGhlci4gDQoNCkFsc28gDQoNCiQkUChhdCBsZWFzdCA0KSA9IFAoZXhhY3RseSA0KSArIFAoZXhhY3RseSA1KSQkDQoNCnRoZSBsYXN0IGV2ZW50cyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIHNvICRQKEEgXGN1cCBCKSA9IFAoQSkgKyBQKEIpJA0KDQpZT1VSIENPREUgSEVSRToNCg0KYGBge3J9DQojcmVmcmVuY2luZyBwcm9iYWJpbGl0eSBhbmQgcmFuZG9tIHZhcnMgZXhlcmNpc2UgbGluZSAyNDQgYW5kIA0KY2hvb3NlKDUsIDQpKigxLzQpXjQqKDIvNCleMSArIGNob29zZSg1LCA1KSooMS80KV41KigyLzMpXjAgI1AoYXRsZWFzdDQpID0gUChleGFjdGx5NCkgKyBQKGV4YWN0bHk1KQ0KcmJpbm9tKDIwMCwgNSwgMC4yNSkgI2dlbmVyYXRlcyByYW5kb20gc2FtcGxlcyBvZiAyMDAgc3R1ZGVudHMgDQpzdW0oZGJpbm9tKHggPSA0OjIwMCwgc2l6ZSA9IDUsIHByb2IgPSAwLjI1KSkgI3N1bW1hdGlvbiBvZiAyMDAgc3R1ZGVudHMgdG8gZ2V0IGF0IGxlYXN0IDQgcXVlc3Rpb25zIGNvcnJlY3Qgb24gYSA1IHF1ZXN0aW9uIHRlc3QNCmBgYA0KDQpPdXQgb2YgMjAwIHN0dWRlbnRzIHdobyBhZG9wdCB0aGlzIHRlc3QgdGFraW5nIGFwcHJvYWNoIGhvdyBtYW55IGFyZSBleHBlY3RlZCB0byBnZXQgYXQgbGVhc3QgNCBjb3JyZWN0PyAqKkhpbnQ6KiogVXNlIEJpbm9taWFsIGV4cGVyaW1lbnQgc2V0dGluZ3MgdG8gYW5zd2VyIHRoaXMgcXVlc3Rpb25zLg0KDQoNCiMjIyMgU29sdXRpb246IA0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KKipQcm9ibGVtIDMgKDUgcHRzKSAtIHNpbWlsYXIgdG8gUHIuIDQ0IHBhZ2UgMjQzIGluIHRleHQqKiAgQ29uc2lkZXIgdG9zc2luZyAqKmZvdXIqKiBmYWlyIGNvaW5zLiBUaGVyZSBhcmUgMTYgcG9zc2libGUgb3V0Y29tZXMsIGUuZyBgSEhISCxISEhULEhIVEgsSFRISCxUSEhILCAuLi5gIHBvc3NpYmxlIG91dGNvbWVzLiBEZWZpbmUgYFhgIGFzIHRoZSByYW5kb20gdmFyaWFibGUg4oCcbnVtYmVyIG9mIGhlYWRzIHNob3dpbmcgd2hlbiBmb3VyIGNvaW5zIGFyZSB0b3NzZWQu4oCdIE9idGFpbiB0aGUgbWVhbiBhbmQgdGhlIHZhcmlhbmNlIG9mIFguIFNpbXVsYXRlIHRvc3NpbmcgdGhyZWUgZmFpciBjb2lucyAxMCwwMDAgdGltZXMuIENvbXB1dGUgdGhlIHNpbXVsYXRlZCBtZWFuIGFuZCB2YXJpYW5jZSBvZiBYLiBBcmUgdGhlIHNpbXVsYXRlZCB2YWx1ZXMgd2l0aGluIDIlIG9mIHRoZSB0aGVvcmV0aWNhbCBhbnN3ZXJzPyANCkhpbnQ6IHRvIGZpbmQgdGhlIHRoZW9yZXRpY2FsIHZhbHVlcyB1c2UgYGRiaW5vbSAoeD0gLCBzaXplID0gLCBwcm9iID0gIClgDQoNCg0KKipTb2x1dGlvbjoqKg0KDQpZT1VSIENPREUgSEVSRToNCmBgYHtyfQ0KI3JlZnJlbmNpbmcgUHJiYWJpbGl0eSBhbmQgUmFuZG9tIFZhcnMgZXhlcmNpc2VzIGxpbmUgMjk2ICYgbm90ZXMgd2VlayA1IGxpbmUgMTgyDQpsaWJyYXJ5KE1BU1MpDQoNClNTIDwtIGV4cGFuZC5ncmlkKHRvc3MxID0gMDoxLCB0b3NzMiA9IDA6MSwgdG9zczMgPSAwOjEsIHRvc3M0ID0gMDoxKSAjSW5pdGlhbGl6aW5nIGNvaW4gdG9zc2VzDQpTdW1Db2luVG9zcyA8LSBhcHBseShTUywgMSwgc3VtKSAjU3VtIG9mIHRvc3Nlcw0KUERGIDwtIGZyYWN0aW9ucyh0YWJsZShTdW1Db2luVG9zcykvIDE2KSAjIENyZWF0ZXMgcGRmIGZ1bmN0aW9uDQpQREYNClN1bUNvaW5Ub3NzDQoNCnggPC0gMDo0ICNQb3NzaWJsZSBudW1iZXIgb2YgaGVhZHMgaW4gZm91ciB0b3NzZXMNCk1lYW4gPC0gc3VtKHggKiBQREYpICNtZWFuIG9mIHJhbmRvbSB2YXJpYWJsZQ0KVmFyaWFuY2UgPC0gc3VtKCh4IC0gTWVhbileMiAqIFBERikgI1ZhcmlhbmNlIG9mIHZhcmlhYmxlDQpNZWFuDQpWYXJpYW5jZQ0KDQpzdW0oZGJpbm9tICh4ID0gLCBzaXplID0gMTYsIHByb2IgPSAwLjAyKSkgIz8/DQpgYGANCg0KKipQcm9ibGVtIDQgKDUgcHRzKSAtIHNpbWlsYXIgdG8gUHIuIDExIC8gcGFnZSAzMDcgaW4gdGV4dCoqDQoNClRyYWZmaWMgdm9sdW1lIGlzIGFuIGltcG9ydGFudCBmYWN0b3IgZm9yIGRldGVybWluaW5nIHRoZSBtb3N0IGNvc3QtZWZmZWN0aXZlIG1ldGhvZCB0byBzdXJmYWNlIGEgcm9hZC4gU3VwcG9zZSB0aGF0IHRoZSBhdmVyYWdlIG51bWJlciBvZiB2ZWhpY2xlcyBwYXNzaW5nIGEgY2VydGFpbiBwb2ludCBvbiBhIHJvYWQgaXMgNSBldmVyeSA2MCBzZWNvbmRzLg0KDQooYSkgRmluZCB0aGUgcHJvYmFiaWxpdHkgdGhhdCBtb3JlIHRoYW4gMTIgY2FycyB3aWxsIHBhc3MgdGhlIHBvaW50IGluIGEgcGVyaW9kIG9mIDMgbWludXRlcy4NCihiKSBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IG1vcmUgdGhhbiAxMDAgY2FycyBwYXNzIHRoZSBwb2ludCBpbiBoYWxmIGFuIGhvdXI/DQoNCkhpbnQ6IEFkanVzdCB0aGUgUG9pc3NvbiBwYXJhbWV0ZXIgJFxsYW1iZGEgPSA1JCBldmVyeSA2MCBzZWNvbmRzIHRvIGAjYCBwZXIgZXZlcnkgMyBtaW51dGVzDQoNCllPVVIgQ09ERSBIRVJFOg0KDQpgYGB7ciBwciAxMX0NCiNSZWZyZW5jaW5nIG5vdGVzIDQgbGluZSAyNTEgYW5kIFVuaXZhcmlhdGUgUHJvYiBEaXN0cmlidXRpb25zIGV4ZXJjaXNlcyBsaW5lIDEwMA0KMSAtIHBwb2lzKHggPSAxMiwgbGFtYmRhID0gNSkgI1AoWCA+IDEyLzUpID0gMSAtIFAoWCA8PSA3LzQpDQoxIC0gcHBvaXMoeCA9IDEwMCwgbGFtYmRhID0gMTUwKSAjUChYID4gMTAwLzE1MCkgPSAxIC0gUChYIDw9IDEwMC8xNTApDQpgYGANCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoNCioqUHJvYmxlbSA1ICg1IHB0cykgLSBzaW1pbGFyIHRvIFByLiAxOCAvIHBhZ2UgMzA4IGluIHRleHQqKg0KU3VwcG9zZSB0aGUgcGVyY2VudGFnZSBvZiBkcmlua3Mgc29sZCBmcm9tIGEgdmVuZGluZyBtYWNoaW5lIGFyZSA3MCUgYW5kIDMwJSBmb3Igc29mdCBkcmlua3MgYW5kIGJvdHRsZWQgd2F0ZXIsIHJlc3BlY3RpdmVseS4NCg0KKGEpIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgb24gYSByYW5kb21seSBzZWxlY3RlZCBkYXksIHRoZSBmaXJzdCBzb2Z0IGRyaW5rIGlzIHRoZQ0KZm91cnRoIGRyaW5rIHNvbGQ/DQooYikgRmluZCB0aGUgcHJvYmFiaWxpdHkgdGhhdCBleGFjdGx5IDQgb3V0IG9mIDEwIGRyaW5rcyBzb2xkIGlzIGEgc29mdCBkcmluay4NCg0KSGludDogTGV0IGBYYCA9IG51bWJlciBvZiB3YXRlcnMgKGZhaWx1cmVzKSBwdXJjaGFzZWQgYmVmb3JlIHRoZSBmaXJzdCBzb2Z0IGRyaW5rIGlzIHB1cmNoYXNlZC4NClRoZW4sICRYIFxzaW0gR2VvKDAuNzApJC4NCg0KKipTb2x1dGlvbjoqKiANCg0KWU9VUiBDT0RFIEhFUkU6DQoNCihhKSANCg0KYGBge3IgcHIuIDE4YX0NCiNyZWZlcmVuY2luZyBub3RlcyB3ZWVrIDUgbGluZSAzMzQNCmRnZW9tKHggPSAzLCAwLjcpICMgUCh4ID0gMykgd2hlcmUgeCBpcyBudW1iZXIgb2YgZmFpbHVyZXMgYmVmb3JlIGZpcnN0IHNvZnQgZHJpbmsNCmBgYA0KDQooYikgTGV0IGBYYCA9IG51bWJlciBvZiBzb2Z0IGRyaW5rcyBzb2xkLiBUaGVuLCAkWCBcc2ltIEJpbigxMCwgMC43MCkkIGFuZCAkUChYID0gMSkgPSAwJCBzaW5jZSBvbmUgaGFzOg0KDQpgYGB7ciBwci4gMThifQ0KcGJpbm9tKDQsIDEwLCAwLjcpICNQKHggPSA0KSB3aGVyZSB4IGlzIDQgc29mdCBkcmlua3Mgc29sZCBmb3Igc2l6ZSAxMA0KYGBgDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoqKlByb2JsZW0gNiAoMTAgcHRzKSAtIEV4cG9uZW50aWFsIERpc3RyaWJ1dGlvbjogTGlnaHQgQnVsYnMqKiBJZiB0aGUgbGlmZSBvZiBhIGNlcnRhaW4gdHlwZSBvZiBsaWdodCBidWxiIGhhcyBhbiBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gd2l0aCBhIG1lYW4gb2YgMTAgbW9udGhzLGZpbmQNCg0KKGEpIFRoZSBwcm9iYWJpbGl0eSB0aGF0IGEgcmFuZG9tbHkgc2VsZWN0ZWQgbGlnaHQgYnVsYiBsYXN0cyBiZXR3ZWVuIDYgYW5kIDE1IG1vbnRocy4NCihiKSBUaGUgOTV0aCBwZXJjZW50aWxlIG9mIHRoZSBkaXN0cmlidXRpb24uIA0KICAgIEhvdyB0aGUgcHJvYmFiaWxpdHkgb2YgdGhlIGxpZ2h0IGJ1bGIgdG8gbGFzdCBtb3JlIHRoYW4gMzYgbW9udGhzIGNvbXBhcmUgdG8gYDAuMDVgPyAgDQooYykgVGhlIHByb2JhYmlsaXR5IHRoYXQgYSBsaWdodCBidWxiIHRoYXQgaGFzIGxhc3RlZCBmb3IgMTAgbW9udGhzIHdpbGwgbGFzdCBtb3JlIHRoYW4gMjUgbW9udGhzLg0KDQoqKlNvbHV0aW9uOioqDQoNCllPVVIgQ09ERSBIRVJFOg0KDQpgYGB7ciBFeC4gNC4xN30NCiNyZWZyZW5jaW5nIFVuaXZhcmlhdGUgUHJvYiBEaXN0cmlidXRpb25zIGV4ZXJjaXNlcyBsaW5lIDE2MCAmIG5vdGVzIHdlZWsgNSBsaW5lIDQxOQ0KcGV4cCgxNSwgMS8xMCkgLSBwZXhwKDYsIDEvMTApICMgcGV4cChxLCByYXRlID0gMSwgbG93ZXIudGFpbCA9IFRSVUUsIGxvZy5wID0gRkFMU0UpDQoNCmYxIDwtIGZ1bmN0aW9uKHgpeygxLzEwKSAqIGV4cCgteC8xMCl9DQppbnRlZ3JhdGUoZjEsIGxvd2VyID0gNiwgdXBwZXIgPSAxMikkdmFsdWUNCg0KcWV4cCgwLjk1LCAxLzEwKSAjQ2hlY2tpbmcgOTUlIG9mIGRpc3RyaWJ1dGlvbiwgcWV4cChwLCByYXRlID0gMSwgbG93ZXIudGFpbCA9IFRSVUUsIGxvZy5wID0gRkFMU0UpDQoNCnBleHAoMjUsIDEvMTAsIGxvd2VyID0gRkFMU0UpL3BleHAoMTAsIDEvMTAsIGxvd2VyID0gRkFMU0UpDQoNCg0KYGBgDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCg0KKipQcm9ibGVtIDcgKDEwIHB0cykgLSBQci4gOCBwYWdlIDQwMCAqKiBBIHBvcHVsYXRpb24gaGFzIHRoZSBmb2xsb3dpbmcgZWxlbWVudHM6IDIsIDUsIDgsIDEyLCAxMyAoKipmaW5pdGUgcG9wdWxhdGlvbioqKS4NCg0KKGEpIEVudW1lcmF0ZSBhbGwgdGhlIHNhbXBsZXMgb2Ygc2l6ZSAyIHRoYXQgY2FuIGJlIGRyYXduIHdpdGggYW5kIHdpdGhvdXQgcmVwbGFjZW1lbnQuIChIaW50OiBVc2UgdGhlIGBzcnMoKWAgZnVuY3Rpb24gZnJvbSB0aGUgYFBBU1dSMmAgcGFja2FnZSkNCg0KKGIpIENhbGN1bGF0ZSB0aGUgbWVhbiBvZiB0aGUgcG9wdWxhdGlvbi4NCg0KKGMpIENhbGN1bGF0ZSB0aGUgdmFyaWFuY2Ugb2YgdGhlIHBvcHVsYXRpb24uDQoNCihkKSBDYWxjdWxhdGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiB0aGUgcG9wdWxhdGlvbi4NCg0KKGUpIENhbGN1bGF0ZSB0aGUgbWVhbiBvZiB0aGUgc2FtcGxlIG1lYW4sICRFW1hdJC4NCg0KKGYpIENhbGN1bGF0ZSB0aGUgdmFyaWFuY2Ugb2YgdGhlIHNhbXBsZWQgbWVhbiwgJFZhcihcYmFyIFgpJA0KDQooZykgQ2FsY3VsYXRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHNhbXBsZSBtZWFuLg0KDQooaCkgQ2FsY3VsYXRlIHRoZSBtZWFuIG9mIHRoZSBzYW1wbGUgdmFyaWFuY2UsICRFW1NeMl0kDQoNCihpKSBJcyB0aGUgdmFyaWFuY2Ugb2YgJFxiYXIgWCQgbGFyZ2VyIHdoZW4gc2FtcGxpbmcgd2l0aCBvciB3aXRob3V0IHJlcGxhY2VtZW50PyBFeHBsYWluIHlvdXIgYW5zd2VyDQoNCg0KKipTb2x1dGlvbjoqKg0KDQpZT1VSIENPREUgSEVSRToNCmBgYHtyfQ0KI3JlZnJlbmNpbmcgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIGV4ZXJjaXNlcyBsaW5lIDIwNg0KbGlicmFyeShQQVNXUjIpDQoNCnAgPC0gYygyLDUsOCwxMiwxMykNCg0KU1JTMiA8LSBzcnMocCwgMikNCnhiYXJTUlMyIDwtIGFwcGx5KFNSUzIsIDEsIG1lYW4pDQpjKG1lYW4oeGJhclNSUzIpLCB2YXIoeGJhclNSUzIpLCBzZCh4YmFyU1JTMikpDQoNCnBfdmFsdWUgPC0gYygyLDUsOCwxMiwxMykNCm1lYW4ocF92YWx1ZSkNCnZhcihwX3ZhbHVlKQ0Kc2QocF92YWx1ZSkNCg0KYGBgDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KDQoqKlByb2JsZW0gOCAoMTAgcHRzKSAtIHNpbWlsYXIgdG8gUHIuIDEwIC8gcGFnZSA0MDAgaW4gdGV4dCoqIA0KDQpVc2UgdGhlIGRhdGEgZnJhbWUgYFdIRUFUVVNBMjAwNGAgZnJvbSB0aGUgYFBBU1dSMmAgcGFja2FnZTsgZHJhdyBhbGwgc2FtcGxlcyBvZiBzaXplcyA0LA0KNSwgYW5kIDY7IGFuZCBjYWxjdWxhdGUgdGhlIG1lYW4gb2YgdGhlIG1lYW5zLiBXaGF0IHNpemUgcHJvdmlkZXMgdGhlIGJlc3QgYXBwcm94aW1hdGlvbg0KdG8gdGhlIHBvcHVsYXRpb24gbWVhbj8gV2hhdCBpcyB0aGUgdmFyaWFuY2Ugb2YgdGhlc2UgbWVhbnM/DQoNCioqU29sdXRpb246KiogVGhlIG1lYW4gb2YgdGhlIG1lYW5zIGZvciBzYW1wbGVzIG9mIHNpemUgdHdvLCB0aHJlZSwgYW5kIGZvdXIgYXJlIGFsbCBlcXVhbCB0byBgMTE0OC43MzMzYA0KKHRoZSBwb3B1bGF0aW9uIG1lYW4pLiBDb25zZXF1ZW50bHksIGFsbCBzYW1wbGVzIHByb3ZpZGUgZXF1YWwgYXBwcm94aW1hdGlvbnMgdG8gdGhlIHBvcHVsYXRpb24gbWVhbiB3aGVuIHRha2luZyBhbGwgcG9zc2libGUgc2FtcGxlcyBvZiBhIGdpdmVuIHNhbXBsZSBzaXplLiBUaGUgdmFyaWFuY2Ugb2YgdGhlIG1lYW5zLCBob3dldmVyLCBkZWNyZWFzZXMgd2l0aCBpbmNyZWFzaW5nIHNhbXBsZSBzaXplIGZyb20gYDY0NTc1NS44NzJgIGZvciBzYW1wbGVzIG9mIHNpemUgZm91ciwgdG8gYDQ5NjcyMC42NDZgIGZvciBzYW1wbGVzIG9mIHNpemUgZml2ZSwgdG8gYDM5NzM3NC4zOTdgIGZvciBzYW1wbGVzIG9mIHNpemUgc2l4Lg0KDQoNCioqSGludDoqKiBVc2UgdGhlIGBzcnMoKWAgZnVuY3Rpb24gZnJvbSB0aGUgYFBBU1dSMmAgcGFja2FnZSB0byBkcmF3IHNpbXBsZSByYW5kb20gc2FtcGxlcy4NCg0KWU9VUiBDT0RFIEhFUkU6DQpgYGB7cn0NCiNyZWZyZW5jaW5nIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgZXhlcmNpc2VzIGxpbmUgMjA2DQpsaWJyYXJ5KFBBU1dSMikNCg0KU1JTNCA8LSBzcnMoV0hFQVRVU0EyMDA0JGFjcmVzLCA0KSAjdXNpbmcgc3JzIGZ1bmN0aW9uIGFuZCBkZWNsYXJpbmcgdmFyaWFibGUgU1JTNCB0byBmaW5kIGFjcmVzIGZvciBzYW1wbGUgc2l6ZSA0DQp4YmFyU1JTNCA8LSBhcHBseShTUlM0LCAxLCBtZWFuKSAgICNhcHBseWluZyBtZWFuIHRvIGRhdGENCmMobWVhbih4YmFyU1JTNCksIHZhcih4YmFyU1JTNCkpICAgI2ZpbmRpbmcgbWVhbiBhbmQgdmFyaWFuY2UNCg0KU1JTNSA8LSBzcnMoV0hFQVRVU0EyMDA0JGFjcmVzLCA1KSAjc2FtcGxlIHNpemUgNQ0KeGJhclNSUzUgPC0gYXBwbHkoU1JTNSwgMSwgbWVhbikNCmMobWVhbih4YmFyU1JTNSksIHZhcih4YmFyU1JTNSkpDQoNClNSUzYgPC0gc3JzKFdIRUFUVVNBMjAwNCRhY3JlcywgNikgI3NhbXBsZSBzaXplIDYNCnhiYXJTUlM2IDwtIGFwcGx5KFNSUzYsIDEsIG1lYW4pDQpjKG1lYW4oeGJhclNSUzYpLCB2YXIoeGJhclNSUzYpKQ0KDQoNCg0KYGBgDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCioqUHJvYmxlbSA5ICgxMCBwdHMpIC0gUHIuIDE2IC8gcGFnZSA1MTMgaW4gdGV4dCoqIA0KDQpBIGdyb3VwIG9mIGVuZ2luZWVycyB3b3JraW5nIHdpdGggcGh5c2ljaWFucyBpbiBhIHJlc2VhcmNoIGhvc3BpdGFsIGlzIGRldmVsb3BpbmcgYQ0KbmV3IGRldmljZSB0byBtZWFzdXJlIGJsb29kIGdsdWNvc2UgbGV2ZWxzLiBCYXNlZCBvbiBtZWFzdXJlbWVudHMgdGFrZW4gZnJvbSBwYXRpZW50cw0KaW4gYSBwcmV2aW91cyBzdHVkeSwgdGhlIHBoeXNpY2lhbnMgYXNzZXJ0IHRoYXQgdGhlIG5ldyBkZXZpY2UgcHJvdmlkZXMgYmxvb2QgZ2x1Y29zZSBsZXZlbHMNCnNsaWdodGx5IGhpZ2hlciB0aGFuIHRob3NlIHByb3ZpZGVkIGJ5IHRoZSBvbGQgZGV2aWNlLiBUbyBjb3Jyb2JvcmF0ZSB0aGVpciBzdXNwaWNpb24sIGAxNWANCmRpYWJldGljIHBhdGllbnRzIHdlcmUgcmFuZG9tbHkgc2VsZWN0ZWQsIGFuZCB0aGVpciBibG9vZCBnbHVjb3NlIGxldmVscyB3ZXJlIG1lYXN1cmVkIHdpdGgNCmJvdGggdGhlIG5ldyBhbmQgdGhlIG9sZCBkZXZpY2VzLiBUaGUgbWVhc3VyZW1lbnRzLCBpbiBgbWcvMTAwIG1sYCwgYXBwZWFyIGluIGRhdGEgZnJhbWUgYEdMVUNPU0VgIGZyb20gdGhlIGBQQVNXUjJgIHBhY2thZ2U6DQoNCihhKSBBcmUgdGhlIHNhbXBsZXMgaW5kZXBlbmRlbnQ/IFdoeSBvciB3aHkgbm90Pw0KKGIpIElmIHRoZSBibG9vZCBnbHVjb3NlIGxldmVsIGlzIGEgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgcmFuZG9tIHZhcmlhYmxlLCBjb21wdXRlIGEgOTUlDQpjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgbWVhbiBkaWZmZXJlbmNlcyBvZiB0aGUgcG9wdWxhdGlvbi4NCihjKSBVc2UgdGhlIHJlc3VsdHMgaW4gKGIpIHRvIGRlY2lkZSB3aGV0aGVyIG9yIG5vdCB0aGUgdHdvIGRldmljZXMgZ2l2ZSB0aGUgc2FtZSByZXN1bHRzLg0KDQoqKlNvbHV0aW9uOioqIA0KDQooYSkNCg0KKGIpICoqSGludDoqKiBsb29rIGF0IHRoZSBRUS1wbG90IHRvIHNlZSBpZiBub3JtYWxpdHkgaXMgcmVhc29uYWJsZS4NCg0KWU9VUiBDT0RFIEhFUkU6DQpgYGB7cn0NCkdMVUNPU0UgPC0gR0xVQ09TRSAlPiUgbXV0YXRlKERJRkYgPSBvbGQtbmV3KSAjIGNyZWF0ZSB2YXJpYWJsZSBESUZGIGZvciB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG9sZCBhbmQgbmV3IGxldmVsDQoNCmhlYWQoR0xVQ09TRSkNCg0KZ2dwbG90KGRhdGEgPSBHTFVDT1NFLCBhZXMoc2FtcGxlID0gRElGRikpICsNCiAgc3RhdF9xcSgpICsNCiAgdGhlbWVfYncoKQ0KDQpDSSA8LSB0LnRlc3QoR0xVQ09TRSRESUZGKSRjb25mICMgdXNlIHQtdGVzdCBzaW5jZSB0aGUgc2FtcGxlIHNpemUgaXMgc21hbGwgPCAzMA0KQ0kNCmBgYA0KDQpUaGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSBtZWFuIGRpZmZlcmVuY2VzIG9mIHRoZSBwb3B1bGF0aW9uIGlzIGBb4oiSMTYuMzYxNCziiJIxMi43NTg2XWAuDQoNCihjKSBUaGUgY29uZmlkZW5jZSBpbnRlcnZhbCBzdWdnZXN0cyB0aGF0IG9uIGF2ZXJhZ2UsIHRoZSBuZXcgZGV2aWNlIHJlcG9ydHMgaGlnaGVyIGJsb29kDQpnbHVjb3NlIGxldmVscyB0aGFuIHRoZSBvbGQgZGV2aWNlLg0KDQoNCioqUHJvYmxlbSAxMCAoMTAgcHRzKSAtIHNpbWlsYXIgdG8gUHIuIDkgLyBwYWdlIDUxMSBpbiB0ZXh0KiogDQoNCkEgbGFyZ2UgY29tcGFueSB3YW50cyB0byBlc3RpbWF0ZSB0aGUgcHJvcG9ydGlvbiBvZiBpdHMgYWNjb3VudHMgdGhhdCBhcmUgcGFpZCBvbiB0aW1lLg0KDQooYSkgSG93IGxhcmdlIGEgc2FtcGxlIGlzIG5lZWRlZCB0byBlc3RpbWF0ZSB0aGUgdHJ1ZSBwcm9wb3J0aW9uIHdpdGhpbiAyJSB3aXRoIGEgOTUlDQpjb25maWRlbmNlIGxldmVsPw0KDQooYikgU3VwcG9zZSA3MDAgb3V0IG9mIDgwMCBhY2NvdW50cyBhcmUgcGFpZCBvbiB0aW1lLiBDb25zdHJ1Y3QgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzDQpmb3IgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiBhY2NvdW50cyB0aGF0IGFyZSBwYWlkIG9uIHRpbWUgdXNpbmcgYW4gYXN5bXB0b3RpYyBjb25maWRlbmNlDQppbnRlcnZhbCwgYW4gQWdyZXN0aSBDb3VsbCBjb25maWRlbmNlIGludGVydmFsLg0KDQpIaW50OiBVc2UgdGhlIGBuc2l6ZSgpYCBhbmQgYGJpbm9tLmNvbmZpbnQoKWAgZnJvbSB0aGUgYGxpYnJhcnkoYmlub20pYA0KDQoqKlNvbHV0aW9uOioqDQoNCllPVVIgQ09ERSBIRVJFOg0KYGBge3J9DQojcmVmcmVuY2luZyBwb2ludCBlc3RpbWF0aW9uIGFuZCBjbCBsaW5lIDIwNg0KbGlicmFyeShiaW5vbSkNCg0KIyhhKSANCm5zaXplKGIgPSAwLjAyLCBwID0gMC41LCBjb25mLmxldmVsID0gMC45NSwgdHlwZSA9ICJwaSIpICNtaW5pbXVtIHNhbXBsZSBzaXplIG5vIG1vcmUgdGhhbiAyJSBlcnJvcg0KDQojKGIpDQpiaW5vbS5jb25maW50KHggPSA3MDAsIG4gPSA4MDAsIGNvbmYubGV2ZWwgPSAwLjk1LCBtZXRob2RzID0gImFzeW1wdG90aWMiKSAjYXN5bXB0b3RpYyBjb25maWRlbmNlIGludGVydmFsDQpiaW5vbS5jb25maW50KHggPSA3MDAsIG4gPSA4MDAsIGNvbmYubGV2ZWwgPSAwLjk1LCBtZXRob2RzID0gImFjIikgI0FncmVzdGkgQ291bGwgQ29uZmlkZW5jZSBpbnRlcnZhbA0KDQpgYGANCg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCioqUHJvYmxlbSAxMSAoMTAgcHRzKSAtIFByLiAxMCAvIHBhZ2UgNTExIGluIHRleHQqKg0KDQpJbiBhIHN0dWR5IGNvbmR1Y3RlZCBhdCAqKkFwcGFsYWNoaWFuIFN0YXRlIFVuaXZlcnNpdHkqKiwgc3R1ZGVudHMgdXNlZCBkaWdpdGFsIG9yYWwNCnRoZXJtb21ldGVycyB0byByZWNvcmQgdGhlaXIgdGVtcGVyYXR1cmVzIGVhY2ggZGF5IHRoZXkgY2FtZSB0byBjbGFzcy4gQSByYW5kb21seQ0Kc2VsZWN0ZWQgZGF5IG9mIHN0dWRlbnQgdGVtcGVyYXR1cmVzIGlzIHByb3ZpZGVkIGluIHRoZSBmb2xsb3dpbmcgdGFibGUgYW5kIGluIHRoZSBkYXRhDQpmcmFtZSBgU1RBVFRFTVBTYC4gSW5mb3JtYXRpb24gaXMgYWxzbyBwcm92aWRlZCB3aXRoIHJlZ2FyZCB0byBzdWJqZWN0IGdlbmRlciBhbmQgdGhlIGhvdXINCm9mIHRoZSBkYXkgd2hlbiB0aGUgc3R1ZGVudHPigJkgdGVtcGVyYXR1cmVzIHdlcmUgbWVhc3VyZWQuDQoNCkRpcmVjdGlvbjogbG9hZCB0aGUgZGF0YSB3aXRoIGBkYXRhKFNUQVRURU1QUylgIGhhdmluZyB0aGUgYGxpYnJhcnkoUEFTV1IyKWAgbG9hZGVkLg0KDQoqKkhpbnQ6KiogDQpVc2UgYHQudGVzdCh0ZW1wZXJhdHVyZSB+IGdlbmRlciwgZGF0YSA9IFNUQVRURU1QUywgbXUgPSAwLCBwYWlyZWQgPSBGQUxTRSlgIHRoZSBgeGAgYWQgYHlgIHZhbHVlcyBhcmUgZ2l2ZW4gd2l0aCBmb3JtdWxhIGV4cHJlc3Npb24gYGZvcm11bGEgPSB0ZW1wZXJhdHVyZSB+IGdlbmRlcmAuIFRoZW4gdXNlIHRoZSBgJGAgYWNjZXNzIHRvIG9idGFpbiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbDogDQpgQ0kgPC0gdC50ZXN0KHRlbXBlcmF0dXJlIH4gZ2VuZGVyLCBkYXRhID0gU1RBVFRFTVBTLCBtdSA9IDAsIHBhaXJlZCA9IEZBTFNFKSRjb25mYCANCg0KKGEpIENvbnN0cnVjdCBhIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgdHJ1ZSBhdmVyYWdlIHRlbXBlcmF0dXJlIGRpZmZlcmVuY2UgYmV0d2Vlbg0KZmVtYWxlcyBhbmQgbWFsZXMuIERvZXMgdGhlIGludGVydmFsIGNvbnRhaW4gdGhlIHZhbHVlIHplcm8/IFdoYXQgZG9lcyB0aGlzIHN1Z2dlc3QNCmFib3V0IGdlbmRlciB0ZW1wZXJhdHVyZSBkaWZmZXJlbmNlcz8NCg0KDQooYikgQ29uc3RydWN0IGEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZSB0cnVlIGF2ZXJhZ2UgdGVtcGVyYXR1cmUgZGlmZmVyZW5jZSBiZXR3ZWVuDQpzdHVkZW50cyB0YWtpbmcgdGhlaXIgdGVtcGVyYXR1cmVzIGF0IDggYS5tLiBhbmQgc3R1ZGVudHMgdGFraW5nIHRoZWlyIHRlbXBlcmF0dXJlcw0KYXQgOSBhLm0uIEdpdmUgYSByZWFzb24gd2h5IG9uZSBncm91cCBhcHBlYXJzIHRvIGhhdmUgYSBoaWdoZXIgdGVtcGVyYXR1cmUgcmVhZGluZy4NCg0KKipTb2x1dGlvbjoqKiANCg0KWU9VUiBDT0RFIEhFUkU6DQpgYGB7cn0NCmxpYnJhcnkoUEFTV1IyKQ0KZGF0YShTVEFUVEVNUFMpDQojKGEpDQp0LnRlc3QodGVtcGVyYXR1cmUgfiBnZW5kZXIsIGRhdGEgPSBTVEFUVEVNUFMsIG11ID0gMCwgcGFpcmVkID0gRkFMU0UpDQpDSSA8LSB0LnRlc3QodGVtcGVyYXR1cmUgfiBnZW5kZXIsIGRhdGEgPSBTVEFUVEVNUFMsIG11ID0gMCwgcGFpcmVkID0gRkFMU0UpJGNvbmYNCg0KDQojKGIpDQp0LnRlc3QodGVtcGVyYXR1cmUgfiBjbGFzcywgZGF0YSA9IFNUQVRURU1QUywgbXUgPSAwLCBwYWlyZWQgPSBGQUxTRSkNCkNJIDwtIHQudGVzdCh0ZW1wZXJhdHVyZSB+IGNsYXNzLCBkYXRhID0gU1RBVFRFTVBTLCBtdSA9IDAsIHBhaXJlZCA9IEZBTFNFKSRjb25mDQoNCg0KYGBgDQoNCkEgYDk1JWAgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHRydWUgYXZlcmFnZSBkaWZmZXJlbmNlIGJldHdlZW4gc3R1ZGVudHMgdGFraW5nIHRoZWlyIHRlbXBlcmF0dXJlcw0KYXQgYDhgIGEubS4gYW5kIHN0dWRlbnRzIHRha2luZyB0aGVpciB0ZW1wZXJhdHVyZXMgYXQgYDlgIGEubS4gaXMgYFviiJIyLjQ5NjUs4oiSMC4yNTY0XWAuDQpOb3RlIHRoYXQgdGhpcyBpbnRlcnZhbCBkb2VzIG5vdCBjb250YWluIGAwYCwgaW5kaWNhdGluZyB0aGF0IHRoZSB0aGVyZSBpcyBldmlkZW5jZSB0byBzdWdnZXN0DQpzdHVkZW50cyBpbiB0aGUgYDhgIGEubS4gY2xhc3MgaGF2ZSB0ZW1wZXJhdHVyZXMgdGhhdCBhcmUgbm90IGFzIHdhcm0gYXMgdGhlIGA5YCBhLm0uIGNsYXNzLg0KT25lIHBvc3NpYmxlIGV4cGxhbmF0aW9uIGlzIHRoYXQgc3R1ZGVudHMgcm9sbCBzdHJhaWdodCBvdXQgb2YgYmVkIGFuZCBpbnRvIHRoZSBgOGAgYS5tLiBjbGFzcy4NCkNvbnNlcXVlbnRseSwgdGhlaXIgdGVtcGVyYXR1cmVzIGFyZSBjbG9zZXIgdG8gdGhlaXIgc2xlZXBpbmcgdGVtcGVyYXR1cmVzIHdoaWNoIGFyZSBsb3dlcg0KdGhhbiB0aGVpciB3YWtpbmcgdGVtcGVyYXR1cmXigJlzLg0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCiMjIDIuIEJSQUlOU1RPUk1JTkcgUEFSVDogDQoNCiMjIyBIb3cgZG8gd2UgZm9ybSBjb25maWRlbmNlIGludGVydmFscyB3aGVuIG5vcm1hbGl0eSBhc3N1bXRpb24gaXMgbm90IHJlYXNvbmFibGUgYW5kIHdlIGhhdmUgc21hbGwgc2FtcGxlIHNpemUgc28gdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSBkb2VzIG5vdCBhcHBseT8NCg0KDQo+IExvb2sgZm9yIHRoZSBhbnN3ZXIgd2l0aCB0aGUgZm9sbG93aW5nIDogDQoNCioqRW1waXJpY2FsIGJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgbWVhbi4qKg0KDQpGb3IgdGhlIGRhdGEgY29udGFpbmVkIGluIGEgdmVjdG9yIGB4ID0gYygzNiwzMCwzNyw0Myw0Miw0Myw0Myw0Niw0MCw0MilgIEVzdGltYXRlIHRoZSBtZWFuIGDOvGAgb2YgdGhlIHVuZGVybHlpbmcgZGlzdHJpYnV0aW9uIGFuZCBnaXZlIGFuIGA5MCVgIGJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFsLg0KDQpgYGB7cn0NCnggPSBjKDM2LDMwLDM3LDQzLDQyLDQzLDQzLDQ2LDQwLDQyKQ0KcXFub3JtKHgpICMgc2VlIGlmIHRoZSBkYXRhIGFwcGVhciB0byBmb2xsb3cgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KYGBgDQoNCj4gRGF0YSBpcyBub3QgcXVpdGUgbm9ybWFsIGFzIGl0IGFwcGVhcnMgb24gdGhlIFEtUSBQTE9UIQ0KDQpgYGB7cn0NCg0KbiA9IGxlbmd0aCh4KQ0Kc2V0LnNlZWQoMjUpICANCg0KIyBzYW1wbGUgbWVhbg0KeGJhciA9IG1lYW4oeCkNCg0KY2F0KCJkYXRhIG1lYW4gPSAiLHhiYXIsJ1xuJykNCg0KbmJvb3QgPSAxMDAwMCAjIG51bWJlciBvZiBib290c3RyYXAgc2FtcGxlcyANCg0KIyBHZW5lcmF0ZSAxMDAwMCBib290c3RyYXAgc2FtcGxlcywgaS5lLiBhbiBuIHggMTAwMDAgYXJyYXkgb2YgcmFuZG9tIHJlc2FtcGxlcyBmcm9tIHguDQp0bXBkYXRhID0gc2FtcGxlKHgsbipuYm9vdCwgcmVwbGFjZT1UUlVFKSAjIHNhbXBsZSB3aXRoIHJlcGxhY2VtZW50DQpib290c3RyYXBzYW1wbGUgPSBtYXRyaXgodG1wZGF0YSwgbnJvdz1uLCBuY29sPW5ib290KQ0KDQojIENvbXB1dGUgdGhlIHNhbXBsZSBtZWFuIHhiYXIgZm9yIGVhY2ggYm9vdHN0cmFwIHNhbXBsZQ0KeGJhcnN0YXIgPSBjb2xNZWFucyhib290c3RyYXBzYW1wbGUpDQoNCiMgQ29tcHV0ZSBkZWx0YSogZm9yIGVhY2ggYm9vdHN0cmFwIHNhbXBsZSAoZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBvcmlnaW5hbCBtZWFuIGFuZCB0aGUgYm9vdHN0cmFwIHNhbXBsZSBtZWFuKQ0KZGVsdGFzdGFyID0geGJhcnN0YXIgLSB4YmFyDQoNCiMgRmluZCB0aGUgMC4xIGFuZCAwLjkgcXVhbnRpbGVzIGZvciBkZWx0YXN0YXINCmQgPSBxdWFudGlsZShkZWx0YXN0YXIsYygwLjA1LDAuOTUpKSAjIGZvciB0aGUgOTA1IENJIHdlIG5lZWQgOTAlIGFyZWEgYmV0d2VlbiB0aGUgcXVhbnRpbGVzDQoNCg0KIyBDYWxjdWxhdGUgdGhlIDkwXCUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIG1lYW4uDQpjaSA9IHhiYXIgLSBjKGRbMl0sZFsxXSkNCmNpDQpgYGANCg0KPiBXZSBjYW4gYWNoaWV2ZSB0aGUgc2FtZSBDSSB3aXRoIHRoZSBmdW5jdGlvbnMgYGJvb3QoKWAgYW5kIGBib290LmNpKClgIGZyb20gdGhlIHBhY2thZ2UgYGJvb3RgDQoNCmBgYHtyfQ0KDQpNRUFOIDwtIGZ1bmN0aW9uKGRhdGEsIGkpew0KICBkIDwtIGRhdGFbaV0NCiAgIE0gPC0gbWVhbihkKQ0KICB9DQpib290Lm9iaiA8LSBib290KHgsIHN0YXRpc3RpYyA9IE1FQU4sIDEwMDAwKQ0KQ0kgPC0gYm9vdC5jaShib290Lm9iaiwgY29uZiA9IDAuOTAsdHlwZSA9ICJhbGwiKSAjIGFsbCB0eXBlIG9mIGJvb3RzdHJhcCBpbnRlcnZhbHMgd2lsbCBiZSByZXR1cm5lZA0KQ0kNCmBgYA0KDQoNCg0KDQojIyAzLiBCT09UU1RSQVAgRVNUSU1BVElPTiBQQVJUDQoNCj4gUmV2aWV3IHRoZSBwcm9ibGVtIGJlbG93Lg0KDQoqKlByLiAzMCAvIHBhZ2UgNjk1IGluIHRleHQqKg0KDQpUaGUg4oCcV2lzY29uc2luIENhcmQgU29ydGluZyBUZXN04oCdIGlzIHdpZGVseSB1c2VkIGJ5IHBzeWNoaWF0cmlzdHMsIG5ldXJvbG9naXN0cywgYW5kDQpuZXVyb3BzeWNob2xvZ2lzdHMgd2l0aCBwYXRpZW50cyB3aG8gaGF2ZSBhIGJyYWluIGluanVyeSwgbmV1cm9kZWdlbmVyYXRpdmUgZGlzZWFzZSwgb3IgYQ0KbWVudGFsIGlsbG5lc3Mgc3VjaCBhcyBzY2hpem9waHJlbmlhLiBQYXRpZW50cyB3aXRoIGFueSBzb3J0IG9mIGZyb250YWwgbG9iZSBsZXNpb24gZ2VuZXJhbGx5DQpkbyBwb29ybHkgb24gdGhlIHRlc3QuIFRoZSBkYXRhIGZyYW1lIGBXQ1NUYCBhbmQgdGhlIGZvbGxvd2luZyB0YWJsZSBjb250YWluIHRoZSB0ZXN0IHNjb3Jlcw0KZnJvbSBhIGdyb3VwIG9mIDUwIHBhdGllbnRzIGZyb20gdGhlIFZpcmdlbiBkZWwgQ2FtaW5vIEhvc3BpdGFsIChQYW1wbG9uYSwgU3BhaW4pLg0KDQooYSkgVXNlIHRoZSBmdW5jdGlvbiBgZWRhKClgIGZyb20gdGhlIGBQQVNXUjJgIHBhY2thZ2UgdG8gZXhwbG9yZSB0aGUgZGF0YSBhbmQgZGVjaWRlIGlmDQpub3JtYWxpdHkgY2FuIGJlIGFzc3VtZWQuIEZvciBkZXRhaWxzIHR5cGUgaW4gY29uc29sZSBgP2VkYWANCg0KKGIpIFdoYXQgYXNzdW1wdGlvbihzKSBtdXN0IGJlIG1hZGUgdG8gY29tcHV0ZSBhIGA5NSVgIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHRoZQ0KcG9wdWxhdGlvbiBtZWFuPw0KDQooYykgQ29tcHV0ZSB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbCBmcm9tIChiKS4NCg0KKGQpIENvbXB1dGUgYSA5NSUgQkNhIGJvb3RzdHJhcCBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgbWVhbiB0ZXN0IHNjb3JlLg0KDQooZSkgU2hvdWxkIHlvdSB1c2UgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgcmVwb3J0ZWQgaW4gKGMpIG9yIHRoZSBjb25maWRlbmNlIGludGVydmFsIHJlcG9ydGVkDQppbiAoZCk/DQoNCioqU29sdXRpb246KioNCg0KKGEpIEFzc3VtaW5nIHRoZSB2YXJpYWJsZSBzY29yZSBoYXMgYSBub3JtYWwgZGlzdHJpYnV0aW9uIGlzIG5vdCByZWFzb25hYmxlLg0KDQpTZWUgdGhlIHJlc3VsdHMgb2YgRURBIGFuYWx5c2lzIGJlbG93Og0KDQoNCmBgYHtyfQ0KZGF0YShXQ1NUKQ0KDQpXQ1NUICU+JSBwdWxsKHNjb3JlKSAlPiUgZWRhKCkNCmBgYA0KDQooYikgSW4gb3JkZXIgdG8gY29uc3RydWN0IGEgYDk1JWAgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHBvcHVsYXRpb24gbWVhbiwgb25lIGFzc3VtZXMNCnRoYXQgdGhlIHZhbHVlcyBpbiB0aGUgdmFyaWFibGUgc2NvcmUgYXJlIHRha2VuIGZyb20gYSAqKm5vcm1hbCBkaXN0cmlidXRpb24qKi4gQWx0aG91Z2ggdGhpcw0KaXMgbm90IGEgcmVhc29uYWJsZSBhc3N1bXB0aW9uLCB0aGUgc2FtcGxlIHNpemUgbWlnaHQgYmUgc3VmZmljaWVudGx5IGxhcmdlIHRvIG92ZXJjb21lIHRoZQ0Kc2tld25lc3MgaW4gdGhlIHBhcmVudCBwb3B1bGF0aW9uLiBDb25zZXF1ZW50bHksIG9uZSBtaWdodCBhcHBlYWwgdG8gdGhlICoqQ2VudHJhbCBMaW1pdCBUaGVvcmVtKiogYW5kIGNsYWltIHRoYXQgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBgWGAgaXMgKiphcHByb3hpbWF0ZWx5IG5vcm1hbCoqIGR1ZSB0bw0KdGhlIHNhbXBsZSBzaXplIGAoNTApYC4gSW4gdGhpcyBwcm9ibGVtLCB0aGUgc2tld25lc3MgaXMgcXVpdGUgc2V2ZXJlLCBhbmQgb25lIHNob3VsZCBub3QgYmUNCm92ZXJseSBjb25maWRlbnQgaW4gdGhlIGZpbmFsIGludGVydmFsLg0KDQooYykgSWYgd2UgYXNzdW1lIG5vcm1hbGl0eSBvbmUgaGFzOg0KDQpgYGB7cn0NCiMgQ0kgPC0gd2l0aChkYXRhID0gV0NTVCwgdC50ZXN0KHNjb3JlKSRjb25mKSAjIA0KDQojIG9yIHVzaW5nIHBpcGluZw0KQ0kgPC0gV0NTVCAlPiUgcHVsbChzY29yZSkgJT4lIHQudGVzdCgpICU+JSAuJGNvbmYNCkNJDQpgYGANCiANCihkKSBVc2UgdGhlIGBib290LmNpKClgIG5vbnBhcmFtZXRyaWMgYm9vdHN0cmFwIENJcyBmdW5jdGlvbnMgdG8gb2J0YWluIHRoZSBib290c3RyYXAgQ0kuDQoNCg0KYGBge3J9DQpsaWJyYXJ5KGJvb3QpICMgdXNlIGJvb3QgcGFja2FnZQ0KTUVBTiA8LSBmdW5jdGlvbihkYXRhLCBpKXsNCiAgZCA8LSBkYXRhW2ldDQogICBNIDwtIG1lYW4oZCkNCiAgfQ0KDQpzZXQuc2VlZCgxMykNCg0KQiA8LSAxMF40IC0gMSAjIG51bWJlciBvZiBib290c3RyYXAgc2FtcGxlcw0KDQpiLm9iaiA8LSBib290KGRhdGEgPSBXQ1NUJHNjb3JlLCBzdGF0aXN0aWMgPSBNRUFOLCBSID0gQikgIyBib290c3RyYXAgb2JqZWN0IG9mIGNsYXNzICJib290IiBjb250YWluaW5nIHRoZSBvdXRwdXQgb2YgYSBib290c3RyYXAgY2FsY3VsYXRpb24NCkNJQiA8LSBib290LmNpKGIub2JqLCBjb25mID0gMC45NSwgdHlwZSA9ICJiY2EiKQ0KQ0lCDQpgYGANCg0KKipQcm9ibGVtIDEyICgxMCBwdHMpKiogU2V0IHRoZSBzZWVkIHRvIGAyM2AgKCoqZ3JvdXAgMSoqKSwgYDQ1YCAoKipncm91cCAyKiopLCBgNjdgICgqKmdyb3VwIDMqKiksIGFuZCBgODlgICgqKmdyb3VwIDQqKikuIERyYXcgcmFuZG9tIHNhbXBsZSBvZiBzaXplIGAyMGAgZnJvbSBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gd2l0aCBtZWFuICRcbGFtYmRhID0gNCQgKCRyYXRlID0gXGZyYWN7MX17NH0kKS4gUHJvZHVjZSBhbGwgYm9vdHN0cmFwIENJIHdpdGggdGhlIGZ1bmN0aW9uIGBib290LmNpYCAodXNlIHR5cGUgPSAiYWxsIikuDQoNCkhvdyBtYW55IG9mIHRoZW0gY29udGFpbiB0aGUgdHJ1ZSBtZWFuIGZvciB0aGUgc2FtcGxlZCBkaXN0cmlidXRpb24/DQoNCllPVVIgQ09ERSBIRVJFOg0KYGBge3J9DQpsaWJyYXJ5KGJvb3QpDQoNCnNldC5zZWVkKDY3KSAjIHVuY29tbWVudCBieSBzZXR0aW5nIHRoZSB2YWx1ZSBwZXIgeW91ciBncm91cCBkZXNpZ25hdGlvbg0KYi5vYmogPC0gYm9vdChkYXRhID0gc2V0LnNlZWQsIHN0YXRpc3RpYyA9IE1FQU4sIFIgPSAyMCkNCkNJQiA8LSBib290LmNpKGIub2JqLCB0eXBlID0gImFsbCIpDQpDSUINCg0KYGBgDQoNCg0KDQoqKkVYVFJBIFhSRURJVCAoMTAgcHRzKSoqIFNldCB0aGUgc2VlZCB0byBgMjNgICgqKmdyb3VwIDEqKiksIGA0NWAgKCoqZ3JvdXAgMioqKSwgYDY3YCAoKipncm91cCAzKiopLCBhbmQgYDg5YCAoKipncm91cCA0KiopLiBEcmF3IHJhbmRvbSBzYW1wbGUgb2Ygc2l6ZSBgMjVgIGZyb20gJEJpbigyMCxcZnJhY3sxfXs1fSkkLiBQcm9kdWNlIGFsbCBib290c3RyYXAgQ0kgd2l0aCB0aGUgZnVuY3Rpb24gYGJvb3QuY2lgICh1c2UgdHlwZSA9ICJhbGwiKS4NCg0KSG93IG1hbnkgb2YgdGhlbSBjb250YWluIHRoZSB0cnVlIG1lYW4gZm9yIHRoZSAgJEJpbigyMCxcZnJhY3sxfXs1fSkkPw0KDQpZT1VSIENPREUgSEVSRToNCmBgYHtyfQ0Kc2V0LnNlZWQoNjcpICMgdW5jb21tZW50IGJ5IHNldHRpbmcgdGhlIHZhbHVlIHBlciB5b3VyIGdyb3VwIGRlc2lnbmF0aW9uDQpiaW4gPC0gcGJpbm9tKDY3LCAyMCwgMS81KQ0KYi5vYmogPC0gYm9vdChkYXRhID0gYmluLCBzdGF0aXN0aWMgPSBNRUFOLCBSID0gMjUpDQpDSUIgPC0gYm9vdC5jaShiLm9iaiwgdHlwZSA9ICJhbGwiKQ0KQ0lCDQoNCmBgYA0K