- Refer to Question 11 from Assignment 1:
- Compute the probability that another random sample of the same size
will produce a sample mean that is at least the same value as the value
of X¯¯¯¯ you observed in Question 11 of Assignment 1.
R./ since we know it is a normal distribution and we know the mean of
the sample of 12 is 5.6875, the population mean is 5.0 and the sample sd
we can use pnorm to calculate the probability of getting another sample
of 12 with the same mean. We need to subtract the probability we found
from 1 and that is the probability of sampling another 12 deliveries
that will have the same mean of 5.6875 –> 0.0562
p5.68 = pnorm(5.6875, 5.0, (1.5/sqrt(12)))
patleast5.68 = 1 - p5.68
patleast5.68
[1] 0.0561756
- Refer to the value of the sample standard deviation S (which you
computed in Exercise 11 of Assignment 1): Compute the probability that
another random sample (again, of the same size) will yield a sample
standard deviation that is between 0.5 hour and 1 hour. R./ P(0.5 <
SD < 1) = P (sd = 1) - P(SD=0.5) Using Chi-square P(SD=0.5) =
P(110.5 / (1.5/sqrt(12))) = P(12.701) = pchisq(12.701, 11) = 0.6867
P(SD=1) = P(111 / (1/sqrt(12))) = P(38.105) = pchisq(38.105) =
0.9999 P(0.5 < SD < 1) = 0.9999 - 0.6867 = 0.3132
Xsq0.5 = (11*0.5 / (1.5/sqrt(12)))
P0.5 = pchisq(Xsq0.5, 11)
P0.5
[1] 0.686732
Xsq1 = (11*1 / (1/sqrt(12)))
P1 = pchisq(Xsq1, 11)
P1
[1] 0.9999249
P = P1 - P0.5
P
[1] 0.3131929
- A 2012 poll carried out by Ipsos Reid in found that “42% of
Canadians, who live outside of Quebec, believe Quebec will separate from
Canada at some point in the future.” A pollster wishes to see if this
sentiment is still present for Canadians who live outside of the
province of Quebec.
- The pollster has determined that they are going to randomly sample
n=1426 Canadian residents who are not residents of Quebec in an attempt
to estimate p - the proportion of all Canadians who live outside of
Quebec (“Rest of Canada”) - who believe that Quebec will separate from
Canada within the next 10 years. Describe the distribution of pˆ, the
proportion of n=1426 randomly chosen Canadians who live outside of
Quebec who believe Quebec will separate from Canada within the next 10
years. (Ensure that your description provides a (i) distribution shape
(ii) a balancing point and (iii) a measure of spread.)
R./ The distribution is bell shaped The balancing point correspond to
the population mean (0.42) The standard deviation is 0.01307
x = seq(300, 800, 0.1)
phat = (x/1426)
sdphat = sqrt(0.42*(1-0.42) / 1426)
sdphat
[1] 0.0130701
plot(phat, dnorm(phat, 0.42, sdphat), yaxt = 'n', xlab="Values of the Sample Proportion", ylab = "Density", main="Distribution of Sample Proportion from n = 1426", type="h", col='blue') + abline(v=0.42, col="blue")
integer(0)

- A recent poll of n=1426 Canadians who are not residents of Quebec
was taken. Of these, 541 thought that Quebec will separate from Canada
in the next 10 years (356 indicated “might happen”; 128 responded
“likely to happen”; 57 indicated “definitely will happen”). The sample
proportion is computed to be pˆ=5411426=0.3794. Under the condition of
the 2012 poll result, how likely is it for another random sample of
n=1426 Canadians (who reside outside of Quebec) to produce a sample
proportion that is at most as 0.3794?
R./ I calculated the sd for the sample proportion, I used pnorm() to
find the probability of getting another sample with a sample proportion
of at most 0.3794 is 0.0009471
sdphat = sqrt(0.42*(1-0.42) / 1426) #calculate phat for this sample
sdphat
[1] 0.0130701
pless037 = pnorm(0.3794, mean=0.42, sd=sdphat)
pless037
[1] 0.000947136
- Consider the steps and associated R Code required to generate a
distribution of the sample proportion, pˆ, when sampling n=1426
Canadians who live outside of Quebec, then determining the proportion
who believe Quebec will separate from Canada within the next 10 years.
Carry out a simulation where you simulate 1000 random samples of n=1426.
Create, then run your code to determine the proportion of your pˆs that
are less than or equal to 0.3794. Provide this proportion.
R./ After running the simulation, I found that the proportion of
phats is 0.001. This proportion changes every time the simulation is
run, I have gotten values from 0 to 0,004
nsamples = 1000 #no. of simulations
sample.phat = numeric(nsamples) #data vector to hold 1000 sample standard deviations of n = 5
size = 1426
s1426data = rbinom(1,size,0.42) #As described https://www.programmingr.com/examples/neat-tricks/sample-r-function/r-rbinom/
counter = 0
for(i in 1:nsamples){
s1426data = rbinom(1,size,0.42) #simulates a binary sample with p = 0.42
sample.phat[i] = s1426data/size #compute the phat of the sample of 1426
if (sample.phat[i] < 0.3794){
counter = counter + 1
}
}
sample.phat[1:5]
[1] 0.4460028 0.4354839 0.3997195 0.4137447 0.4039271
sample.phat[995:999]
[1] 0.4235624 0.4004208 0.4417952 0.4130435 0.3920056
pphatless037 = counter/nsamples
pphatless037
[1] 0.001
- Billy purchases one 6-49 lottery ticket every week and keeps track
of the number of “matches” he has on each of his tickets. To be clear, a
“match” will occur when a number on his ticket matches a number that
appears in the winning combination. A random variable X that keeps track
of the number of matching numbers Billy experiences per week has the
probability distribution function with a mean and standard deviation of
P(X=x) = choose (6, x) * choose(43, 6−x) / choose(49, 6)
x=0,1,2,3,4,5,6. E(X) = μX = 36 / 49 = 0.7347 SD(X) = σX = 0.75998 ≈
0.76 Billy claims that in a year (52 weeks), on average, he manages to
have at least one matching number on his 6-49 ticket. What do you think
about Billy’s claim? Provide a brief commentary about Billy’s claim
using your current knowledge of statistics and probability theory.
R./ The probability of getting at least one matching number is equal
to 1 minus the probability of no getting any number or P(x=0)
P(x >= 1) = 1 - P(x = 0) we obtain P(0) by replacing x with 0 in
the probability function P(X=0) = choose (6, 0) * choose(43, 6−0) /
choose(49, 6) P(X=0) = 0.4360
replacing this value P(X >= 1) = 1 - 0.4360 P(X >= 1) =
0.5640
R./ The probability of getting at least one matching number in 52
draws ( one draw / week) is 0.564 which is greater that the probability
of getting no matching numbers which is 0.436. It is possible that Billy
does get at least one matching number every week for a year.
P0 = choose (6, 0) * choose(43, 6) / choose(49, 6)
P0
[1] 0.435965
Pmore1 = 1 - P0
Pmore1
[1] 0.564035
- A common measure of toxicity for any pollutant is the concentration
of the pollutant that will kill half of the test species in a given
amount of time (usually about 96 hours for the fish species). This
measurement is called the LC50, which refers to the lethal concentration
killing 50% of the test species).
The Environmental Protection Agency has collected data on LC50
measurements for certain chemicals likely to be found in freshwater and
lakes. For a certain species of fish, the LC50 measurements (in parts
per million) for DDT in 12 experiments to determine the LC50 “dose” are
16,5,21,19,10,5,8,2,7,2,4,9
- Use R studio to create the bootstrap distribution of the sample mean
X¯¯¯¯Boot,LC50. Use 2000 “bootstraps” in your work, and display the
distribution.
R./ As follows
# library(mosaic)
library(ggplot2)
library(lattice)
lc50 = c(16,5,21,19,10,5,8,2,7,2,4,9) #create a vector with the values of LC50
lc50.df = data.frame(lc50) # convert the above vector into a dataframe
lc50.df
ntimes = 100
bootdata = numeric(length(lc50.df$lc50)*ntimes)
for(i in 1:ntimes)
{ if (i == 1) bootdata = lc50.df$lc50
else bootdata = c(lc50.df$lc50, bootdata)
}
N = 2000
n.size = length(lc50.df$lc50)
boot.mean = numeric(N)
boot.data = numeric(n.size)
#
for(i in 1:N){
boot.data = sample(lc50.df$lc50, n.size, replace=TRUE) #sample with replacement
boot.mean[i] = mean(boot.data)
}
bootstrap.mean = data.frame(boot.mean) #data frame holding 2000 different bootstrap sample means
head(bootstrap.mean, 4)
NA
tail(bootstrap.mean, 4)
ggplot(bootstrap.mean, aes(x = boot.mean)) + geom_histogram(col="red", fill="blue", binwidth = 0.5) + xlab("Values of Bootstrap Mean") + ylab("Count") + ggtitle("Distribution of Bootstrap Statistic: Sample Mean")
favstats(~boot.mean, data=bootstrap.mean)
- From your result in (a), compute the 95% bootstrap (percentile)
confidence interval for \(\mu_{LC50}\),
the mean LC50 measurement for DDT.
R./ using qdata() on the list of means and then displaying the
distribution with the values for p25 ans p97.5 which are 5.75 and
12.5
p25.lc50 = qdata(~boot.mean, c(0.025, 0.975), data=bootstrap.mean)[1]
p25.lc50[1]
2.5%
5.75
p975.lc50 = qdata(~boot.mean, c(0.025, 0.975), data=bootstrap.mean)[2]
p975.lc50
97.5%
12.5
ggplot(bootstrap.mean, aes(x = boot.mean)) + geom_histogram(col="red", fill="blue", binwidth = 0.5) + xlab("Values of Bootstrap Mean") + ylab("Count") + ggtitle("Distribution of Bootstrap Statistic: Sample Mean with 95% confidence Interval ") + geom_vline(xintercept = p25.lc50, color="red") + geom_vline(xintercept = p975.lc50, color="red")

- Repeat your estimation of \(\mu_{LC50}\), using the “other” confidence
interval covered in Data 602. In the context of these data, interpret
the meaning of the confidence interval. State any conditions/assumptions
that are required in the computation of this confidence interval.
R./Using Student’s T we found P2.5 = 4.9181 and P97.5 = 13.0819
Ttest.lc50 = t.test(~lc50, data=lc50.df)$conf #using default value of 0.95 confidence interval
Ttest.lc50[1]
[1] 4.91814
Ttest.lc50[2]
[1] 13.08186
- Compare your results in parts (b) and (c). If you were to report one
of these confidence intervals, which would you report? Explain your
answer.
R./ Bootstrap for CI95 = (5.75, 12.58) (red in the graph) Student’s T
for CI95 = (4.9181, 13.0817) (blue in the graph) To be on the safer
side, I want to report a tighter interval so I prefer the interval from
Bootstrap
ggplot(bootstrap.mean, aes(x = boot.mean)) + geom_histogram(col="red", fill="blue", binwidth = 0.5) + xlab("Values of Bootstrap Mean") + ylab("Count") + ggtitle("Distribution of Bootstrap Statistic: Sample Mean with 95% confidence Interval ") + geom_vline(xintercept = p25.lc50, color="red") + geom_vline(xintercept = p975.lc50, color="red") + geom_vline(xintercept = Ttest.lc50[1], color="blue") + geom_vline(xintercept = Ttest.lc50[2], color="blue")

- Does one’s educational level influence their opinion about
vaccinations? A recent Angus Reid2 survey was taken. Each person sampled
was asked to respond to the statement “The science around vaccinations
isn’t clear.”
Respondents either “strongly agree”, “moderately agree”, “moderately
disagree”, or “strongly disagree”. The sample was partitioned by level
of education.
There were n=670 respondents who’s highest level of education was
high school or less, of which 348 “disagreed” (moderately disagree or
stongly disagree). There were also n=376 who’s highest level of
education was at least an undergraduate university education. Of these,
274 disagreed.
- Consider the population consisting of all persons, who’s highest
level of education was high school or less and the bootstrap statistic
pˆBoot,HS . Using 1000 iterations/replications, create a bootstrap
distribution of pˆHS . Display your distribution.
R./ From the information given we can calculate pHS = 348 / 670 =
0.52. I use this proportion to create a random list of zeros(agreed) and
ones (disagree). I then use this list to create a table that allows me
to see the amount of zeros and ones in the list. Next I loop 1000 times
to create a sample from the list I created with the size of 670 and
replacement = true. The mean of the sample is then calculated and stored
in an array called phats.hs; then I create a data frame from the
phats.hs list and displayed its histogram
library(binom)
hs = rbinom(n=670,size=1,prob=0.52)
table(hs)
hs
0 1
343 327
phats.hs = numeric(1000) #create a vector to store each of the 1000 bootstrap values of the sample proportion
for(i in 1:1000){
temp.data = sample(hs, length(hs), replace=TRUE) #could have used resample(userofmari) here
phats.hs[i] = mean(temp.data)
}
boot_phat_hs.df = data.frame(phats.hs)
head(boot_phat_hs.df, 4)
tail(boot_phat_hs.df, 4)
tail(boot_phat_hs.df, 4)
ggplot(boot_phat_hs.df, aes(x = phats.hs)) + geom_histogram(col="green", fill="blue", binwidth=0.01) + xlab("Values of the Sample Proportion") + ylab("Count") + ggtitle("Histogram: Distribution of Bootstrap Sample Proportion")

- Now consider a different population that consist of all persons
who’s highest level of education was at least an undergraduate degree.
Repeat part (a), creating a bootstrap distribution for pˆBoot,Uni.
(Again, display your distribution).
R./ From the information given we can calculate pUni= 274 / 376 =
0.73. I use this proportion to create a random list of zeros(agreed) and
ones (disagree). I then use this list to create a table that allows me
to see the amount of zeros and ones in the list. Next I loop 1000 times
to create a sample from the list I created with the size of 376 and
replacement = true. The mean of the sample is then calculated and stored
in an array called phats.uni; then I create a data frame from the
phats.uni list and displayed its histogram
uni = rbinom(n=376,size=1,prob=0.73)
table(uni)
uni
0 1
108 268
phats.uni = numeric(1000)
for(i in 1:1000){
temp.data = sample(uni, length(uni), replace=TRUE)
phats.uni[i] = mean(temp.data)
}
boot_phat_uni.df = data.frame(phats.uni)
head(boot_phat_uni.df, 4)
tail(boot_phat_uni.df, 4)
tail(boot_phat_uni.df, 4)
ggplot(boot_phat_uni.df, aes(x = phats.uni)) + geom_histogram(col="green", fill="blue", binwidth=0.01) + xlab("Values of the Sample Proportion") + ylab("Proportion") + ggtitle("Histogram: Distribution of Bootstrap Sample Proportion")

- You wish to estimate pUni−pHS, the difference between the proportion
of all university-educated Canadians who disagree that the science of
vaccinations isn’t clear and the proportion of all Canadians who’s
highest level of completed education is high school who believe the
same. You wish to have 95% confidence in your result. Think about the
code you created to generate the bootstrap distributions on parts (a)
and (b). Modify the code to you created in parts (a) and (b) to create a
distribution of the bootstrap statistic pˆUni−pˆHS.
R./ As follows
phats.uni_hs = numeric(1000)
for(i in 1:1000){
temp.data.hs = sample(hs, length(hs), replace=TRUE) #could have used resample(userofmari) here
temp.data.uni = sample(uni, length(uni), replace=TRUE)
phats.uni_hs[i] = mean(temp.data.uni) - mean(temp.data.hs)
}
boot_phat_uni_hs.df = data.frame(phats.uni_hs)
head(boot_phat_uni_hs.df, 4)
tail(boot_phat_uni_hs.df, 4)
tail(boot_phat_uni_hs.df, 4)
- Consider your finding in part (c). Compute the 95% bootstrap
percentile confidence interval for pUni−pHs. From your result, does the
proportion of persons with at most a high school education who disagree
the science around vaccinations isn’t clear greater than the similar
proportion of persons with at least an undergraduate university degree?
Write a paragraph that supports your answer.
R./ The proportion of people with a level of education higher than
high school who disagree the science around vaccination isn’t clear is
greater than the proportion of people with a level of education equal or
less than high school. This is evident by the fact that the distribution
of the simulation of pUni−pHs yields values that are greater than 0. The
95% confidence interval shows that most of the values for this
difference falls between 16.68% and 28.32% in favor of people with
higher education than high school.
p25.uni_hs = qdata(~phats.uni_hs, c(0.025, 0.975), data=boot_phat_uni_hs.df)[1]
p25.uni_hs
2.5%
0.1667625
p975.uni_hs = qdata(~phats.uni_hs, c(0.025, 0.975), data=boot_phat_uni_hs.df)[2]
p975.uni_hs
97.5%
0.2831919
ggplot(boot_phat_uni_hs.df, aes(x = phats.uni_hs)) + geom_histogram(col="green", fill="blue", binwidth=0.01) + xlab("Values of the Sample Proportion") + ylab("Count") + ggtitle("Histogram: Distribution of Bootstrap Sample Proportion") + geom_vline(xintercept = p25.uni_hs, color="red") + geom_vline(xintercept = p975.uni_hs, color="red")

- Nanos research3 recently completed a survey of n=1000 Canadians aged
18 years of age or older, asking each “what is your most important
national issue of concern?” 163 responded “Inflation”, 149 responded
“Environment”, 131 responded “Jobs/Economy”. Those were the Top
Three.
- Compute a 95% confidence interval for pInflation, the proportion of
all Canadians aged 18 years or older for whom “Inflation” is the most
important national concern.
R./I can calculate the 95% confidence interval using the
plus-2/plus-4 which gives us 0.1427(p2.5) - 0.1885(p97.5)
prop.test(163 + 2, 1000 + 4, correct=FALSE)$conf
[1] 0.142707 0.188537
attr(,"conf.level")
[1] 0.95
- Similar to your work in Question 4(b), create the distribution of
the bootstrap statistic pˆBoot,Inflation and a 95% bootstrap percentile
confidence interval for pInflation.
R./ Confidence interval 95% = 0.144 - 0.188
infl = rbinom(n=1000,size=1,prob=0.163)
infl.df = data.frame(infl)
head(infl.df, 4)
tail(infl.df)
N = 1000
n.size = length(infl.df$infl)
boot.proportion_infl = numeric(N)
boot.data_infl = numeric(n.size)
for(i in 1:N){
boot.data_infl = sample(infl.df$infl, n.size, replace=TRUE) #sample with replacement
boot.proportion_infl[i] = mean(boot.data_infl)
}
bootstrap.proportion_infl = data.frame(boot.proportion_infl) #data frame holding 2000 different bootstrap sample means
head(bootstrap.proportion_infl, 4)
NA
tail(bootstrap.proportion_infl, 4)
p2.5Infl = qdata(~boot.proportion_infl, c(0.025, 0.975), data = bootstrap.proportion_infl)[1]
p2.5Infl
2.5%
0.143
p97.5Infl = qdata(~boot.proportion_infl, c(0.025, 0.975), data = bootstrap.proportion_infl)[2]
p97.5Infl
97.5%
0.191
ggplot(bootstrap.proportion_infl, aes(x = boot.proportion_infl)) + geom_histogram(col="green", fill="blue", binwidth=0.005) + xlab("Values of the Sample Proportion") + ylab("Count") + ggtitle("Histogram: Distribution of Bootstrap Sample Proportion") + geom_vline(xintercept = p2.5Infl, color="red") + geom_vline(xintercept = p97.5Infl, color="red")

- A similar survey of Canadians in August 2023 - a little over a month
ago - suggested that the proportion of all Canadians who identified
“Inflation” as the most important national concern was
pInflation,Aug_23=0.13 From your results in (a) and (b), can you infer
that the proportion of all Canadians who believe “Inflation” is the most
important national issue has increased since August of this year? Why or
why not? Ensure you invoke a statistical justification.
R./ I can infer that the proportion of Canadians who believe
inflation is the most important issue has increased based on the fact
that the Confidence Interval for the most recent survey goes from 14.4
to 18.8; there is no overlap with the previous value of 0.13 found in
the previous survey, showing us that the proportion has increased
- Refer to the data encountered in Question 4 of this assignment.
Prior to completing parts (a) and (b), carefully read through both parts
(a) and (b).
- Use the Bootstrap method to compute a 98% confidence interval for
μ˜LC50, the median LC50 level. Interpret the meaning of this interval in
the context of these data.
R./ I will proceed to simulate the median with N=2000,and then
calculate the 98% confidence Interval using qdata for the 1% and 99%.
Finally I will graph these results. Confidence Interval 99% = (4, 16) We
can say that there is a 98% probability that the median value for DDT
LC50 is between 4 and 16 ppm
N = 2000
n.size = length(lc50.df$lc50)
boot.median = numeric(N)
boot.data = numeric(n.size)
for(i in 1:N){
boot.data = sample(lc50.df$lc50, n.size, replace=TRUE) #sample with replacement
boot.median[i] = median(boot.data)
}
bootstrap.median = data.frame(boot.median) #data frame holding 2000 different bootstrap sample medians
head(bootstrap.median, 4)
tail(bootstrap.median, 4)
lc50.median_99 = qdata(boot.median, c(0.01, 0.99), data=bootstrap.median)
lc50.median_99
1% 99%
4 16
ggplot(bootstrap.median, aes(x = boot.median)) + geom_histogram(col="red", fill="blue", binwidth=0.8) + xlab("Values of the Sample Median") + ylab("Count") + ggtitle("Histogram: Distribution of Bootstrap Sample Median") + geom_vline(xintercept = lc50.median_99[1], color="green") + geom_vline(xintercept = lc50.median_99[2], color="green")

- Compute the 95% bootstrap percentile confidence interval for the
population standard deviation, σ. In addition, interpret the meaning of
your interval in the context of these data.
R./ For this question, I will find the confidence interval for the
variance first and then take the sq root of these results are thw data
for the 95% confidence interval for the sd: (3.1712, 7.8607)
We can say that there is a 95% probability that the standard
deviation value for DDT LC50 is between 3.1281 and 7.9183 ppm
N = 2000
n.size = length(lc50.df$lc50)
boot.var = numeric(N)
boot.data = numeric(n.size)
for(i in 1:N){
boot.data = sample(lc50.df$lc50, n.size, replace=TRUE) #sample with replacement
boot.var[i] = var(boot.data)
}
bootstrap.var = data.frame(boot.var) #data frame holding 2000 different bootstrap sample variance
head(bootstrap.var, 4)
tail(bootstrap.var, 4)
lc50.var_95 = qdata(boot.var, c(0.025, 0.975), data=bootstrap.var)
lc50.var_95
2.5% 97.5%
10.05682 61.79072
ggplot(bootstrap.var, aes(x = boot.var)) + geom_histogram(col="red", fill="blue", binwidth=1) + xlab("Values of the Sample Variance") + ylab("Count") + ggtitle("Histogram: Distribution of Bootstrap Sample Variance") + geom_vline(xintercept = lc50.var_95[1], color="green") + geom_vline(xintercept = lc50.var_95[2], color="green")

lc50.sd_95 = sqrt(lc50.var_95)
lc50.sd_95
2.5% 97.5%
3.171249 7.860707
- A national survey 4 of n=399 “Gen Z”-ers - someone who is born in
the years 1996 - 2010 (inclusive) was taken. Each was then asked the
following question: “If a federal election were held tomorrow, which one
of the following parties would you vote for in your constituency?” The
results?
128 responded “Conservative” (Conservative Party of Canada) 96
responded “Liberal” (Liberal Party of Canada) 104 responded “NDP” (New
Democratic Party of Canada) Respondents were provided with a few more
“closed options”, including the Bloc Quebecois, People’s Party, and
Green Party.
- Compute the 95% confidence interval for pCon, the proportion of all
Gen Z-ers in Canada that will vote for their respective Conservative
Member of Parliament candidate/constituency, in an election were “held
tomorrow”.
R./ Since we know n and nconservative, we cam use prop.test() to
determine the confidence interval using its default 95% and the
plus-2/plus-4 to make the interval tighter. Pcons 95% CI =
(0.2788,0.3697 ) According to these results we can say with a 95%
confidence that between 27.88 and 36.97 % of Gen Z-ers will vote
conservative.
ci95con.prop = prop.test(128+2, 399+4, correct=FALSE)$conf
ci95con.prop
[1] 0.2788012 0.3697105
attr(,"conf.level")
[1] 0.95
- Consider the bootstrap statistic p˜Con=XCon+2399+4 . Write the R
code that will generate a bootstrap distribution for p˜Con . Use 1000 as
the number of replications/iterations.
nsamples = 1000 #no. of simulations
sample.phat_con = numeric(nsamples) #data vector to hold 1000 samples representing the gen z-ers that choose conservative
size = 399
for(i in 1:nsamples){
boot.data = rbinom(1,size,0.32) #simulates a binary sample representing the genz-ers that choose conservative knowing Pcon = 128/399 = 0.33
sample.phat_con[i] = (boot.data + 2)/(size +4) #compute the phat using plus2/plus4 and stores it in the sample.phat_con list
}
bootstrap.con = data.frame(sample.phat_con)
head(bootstrap.con, 4)
tail(bootstrap.con, 4)
- From your result in part (b), compute a 95% bootstrap confidence
interval for pCon.
ci95con.boot = qdata(~sample.phat_con, c(0.025, 0.975), data=bootstrap.con)
ci95con.boot
2.5% 97.5%
0.2779156 0.3622829
ggplot(bootstrap.con, aes(x = sample.phat_con)) + geom_histogram(col="green", fill="blue", binwidth=0.05) + xlab("Values of the Sample Proportion") + ylab("Count") + ggtitle("Histogram: Distribution of Bootstrap Sample Proportion") + geom_vline(xintercept = ci95con.prop[1], color="red") + geom_vline(xintercept = ci95con.prop[2], color="red") + geom_vline(xintercept = ci95con.boot[1], color="purple") + geom_vline(xintercept = ci95con.boot[2], color="purple")

- Consider your results in parts (a) and (c). Compare the two results.
If you had to pick one as the “best” estimate for the unknown value of
pCon, which one would you select? Provide a justification for your
choice.
R./ from a) CI95.prop = (0.2788, 0.3647) –> 0.3647 - 0.2788 =
0.0909 (red) b) CI95.boot = (0.2779, 0.3628) –> 0.3697 - 0.2754 =
0.0849 (purple)
These intervals are very close, if I have to choose one, I choose the one with the smaller interval which in this case is the interval found by running boostrap
- In this question you will use the albertacountiessampled2019.csv.
The data appearing in this file are the results of a random sample of
n=100 counties in Alberta. For each county, the median household income
was computed. This feature appears in the OriginalValue column.
Read this data into a R data frame. To read this into R, you will
have to select the Raw tab appearing on the top right-hand side.
The bootstrap t statistic is defined as
TBootstrap=X¯¯¯¯Boot−X¯¯¯¯(Sn√) where X¯¯¯¯ and S are the mean and
standard deviation of the sample.
- From these data, generate the distribution of TBootstrap. Display
this distribution. Use 1000 for the number of bootstraps.
alberta.counties = read.csv("albertacountiessampled2019.csv")
income.median = data.frame(alberta.counties$OriginalValue)
head(income.median, 4)
tail(income.median, 4)
stats = favstats(income.median$alberta.counties.OriginalValue)
stats
sample.mean = stats[6]
sample.mean
sample.sd = stats[7]
sample.sd
N = 1000
sample.size = length(income.median$alberta.counties.OriginalValue)
boot.data = numeric(sample.size)
boot.mean = numeric(N)
boot.t = numeric(N)
for (i in 1:N){
boot.data = sample(alberta.counties$OriginalValue, sample.size, replace = TRUE)
boot.mean[i] = mean(boot.data)
t = (boot.mean[i] - sample.mean) / (sample.sd / sqrt(sample.size))
t
boot.t[i] = t
}
boot.meandf = data.frame(boot.mean)
head(boot.meandf)
tail(boot.meandf)
boot.tval = c(N)
for(i in 1:N){
boot.tval[i] = boot.t[[i]][1]
}
boot.tdf = data.frame(boot.tval)
head(boot.tdf)
NA
tail(boot.tdf)
ggplot(boot.tdf, aes(x = boot.tval)) + geom_histogram(col="red", fill="blue", binwidth=0.4) + xlab("Values of Bootstrat T") + ylab("Count") + ggtitle("Histogram: Distribution of Bootstrap T")

- Refer to part (a): A Bootstrap t.Confidence Interval for μ is
defined as: [X¯¯¯¯−t∗α2(Sn−−√),X¯¯¯¯+t∗1−α2(Sn−−√)] where t∗α2 and
t∗1−α2 is are α2 and 1−α2 percentiles from the TBootstrap
distribution.
Compute the 95% bootstrap t confidence interval for
μMedian_Family_Income for all the counties in Alberta.
Note: −tα2 will be a negative value due to the nature of the
Student’s t distribution. Hence the “-” sign in front.
percentileT = quantile(boot.tdf$boot.tval, c(0.025, 0.975))
percentileT
2.5% 97.5%
-2.058206 1.842106
meanCI2.5 = sample.mean - (percentileT[1] * (sample.sd/sqrt(sample.size)))
meanCI2.5$mean
[1] 92128.91
meanCI97.5 = sample.mean - (percentileT[2] * (sample.sd/sqrt(sample.size)))
meanCI97.5$mean
[1] 83239.22
- Compute the (i) 95% bootstrap percentile confidence interval
estimate of μMedian_Family_Income and (ii) the 95% Student’s t
confidence interval for μMedian_Family_Income.
medianIncome.ci95 = qdata(~alberta.counties.OriginalValue, c(0.025, 0.975), data=income.median)
medianIncome.ci95
2.5% 97.5%
34747.5 131119.5
BootTci95 = qdata(boot.tval, c(0.025, 0.975), data=boot.tdf)
BootTci95
2.5% 97.5%
-2.058206 1.842106
D. Consider your results in parts (b) and (c): If you were to report
one of these confidence intervals to a client, what would be your
consultation? Provide a short paragraph explaining what the value of
μMedian_Family_Income Could possibly be, and why you chose the method of
confidence interval estimation to report from.
I would use the 95% Confidence Interval found in part b as it reports
a tighter interval for than the one reported in C
- 83029.28 - 91911.28
- 34747.50 - 131119.50
Ci0tLQp0aXRsZTogIkRBVEE2MDJfQVNTSUdOTUVOVDIiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KMS4gUmVmZXIgdG8gUXVlc3Rpb24gMTEgZnJvbSBBc3NpZ25tZW50IDE6CgphLiBDb21wdXRlIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGFub3RoZXIgcmFuZG9tIHNhbXBsZSBvZiB0aGUgc2FtZSBzaXplIHdpbGwgcHJvZHVjZSBhIHNhbXBsZSBtZWFuIHRoYXQgaXMgYXQgbGVhc3QgdGhlIHNhbWUgdmFsdWUgYXMgdGhlIHZhbHVlIG9mIFjCr8Kvwq/CryB5b3Ugb2JzZXJ2ZWQgaW4gUXVlc3Rpb24gMTEgb2YgQXNzaWdubWVudCAxLgoKUi4vIHNpbmNlIHdlIGtub3cgaXQgaXMgYSBub3JtYWwgZGlzdHJpYnV0aW9uIGFuZCB3ZSBrbm93IHRoZSBtZWFuIG9mIHRoZSBzYW1wbGUgb2YgMTIgaXMgNS42ODc1LCB0aGUgcG9wdWxhdGlvbiBtZWFuIGlzIDUuMCBhbmQgdGhlIHNhbXBsZSBzZCB3ZSBjYW4gdXNlIHBub3JtIHRvIGNhbGN1bGF0ZSB0aGUgcHJvYmFiaWxpdHkgb2YgZ2V0dGluZyBhbm90aGVyIHNhbXBsZSBvZiAxMiB3aXRoIHRoZSBzYW1lIG1lYW4uIFdlIG5lZWQgdG8gc3VidHJhY3QgdGhlIHByb2JhYmlsaXR5IHdlIGZvdW5kIGZyb20gMSBhbmQgdGhhdCBpcyB0aGUgcHJvYmFiaWxpdHkgb2Ygc2FtcGxpbmcgYW5vdGhlciAxMiBkZWxpdmVyaWVzIHRoYXQgd2lsbCBoYXZlIHRoZSBzYW1lIG1lYW4gb2YgNS42ODc1IC0tPiAwLjA1NjIKCmBgYHtyfQpwNS42OCA9IHBub3JtKDUuNjg3NSwgNS4wLCAoMS41L3NxcnQoMTIpKSkKcGF0bGVhc3Q1LjY4ID0gMSAtIHA1LjY4CnBhdGxlYXN0NS42OApgYGAKYi4gUmVmZXIgdG8gdGhlIHZhbHVlIG9mIHRoZSBzYW1wbGUgc3RhbmRhcmQgZGV2aWF0aW9uIFMgKHdoaWNoIHlvdSBjb21wdXRlZCBpbiBFeGVyY2lzZSAxMSBvZiBBc3NpZ25tZW50IDEpOiBDb21wdXRlIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGFub3RoZXIgcmFuZG9tIHNhbXBsZSAoYWdhaW4sIG9mIHRoZSBzYW1lIHNpemUpIHdpbGwgeWllbGQgYSBzYW1wbGUgc3RhbmRhcmQgZGV2aWF0aW9uIHRoYXQgaXMgYmV0d2VlbiAwLjUgaG91ciBhbmQgMSBob3VyLgpSLi8gUCgwLjUgPCBTRCA8IDEpID0gUCAoc2QgPSAxKSAtIFAoU0Q9MC41KQpVc2luZyBDaGktc3F1YXJlClAoU0Q9MC41KSA9IFAoMTEqMC41IC8gKDEuNS9zcXJ0KDEyKSkpID0gUCgxMi43MDEpID0gcGNoaXNxKDEyLjcwMSwgMTEpID0gMC42ODY3ClAoU0Q9MSkgPSBQKDExKjEgLyAoMS9zcXJ0KDEyKSkpID0gUCgzOC4xMDUpID0gcGNoaXNxKDM4LjEwNSkgPSAwLjk5OTkKUCgwLjUgPCBTRCA8IDEpID0gMC45OTk5IC0gMC42ODY3ID0gMC4zMTMyCgpgYGB7cn0KWHNxMC41ID0gKDExKjAuNSAvICgxLjUvc3FydCgxMikpKQpQMC41ID0gcGNoaXNxKFhzcTAuNSwgMTEpClAwLjUKWHNxMSA9ICgxMSoxIC8gKDEvc3FydCgxMikpKQpQMSA9IHBjaGlzcShYc3ExLCAxMSkKUDEKUCA9IFAxIC0gUDAuNQpQCmBgYAoyLiBBIDIwMTIgcG9sbCBjYXJyaWVkIG91dCBieSBJcHNvcyBSZWlkIGluIGZvdW5kIHRoYXQg4oCcNDIlIG9mIENhbmFkaWFucywgd2hvIGxpdmUgb3V0c2lkZSBvZiBRdWViZWMsIGJlbGlldmUgUXVlYmVjIHdpbGwgc2VwYXJhdGUgZnJvbSBDYW5hZGEgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlLuKAnSBBIHBvbGxzdGVyIHdpc2hlcyB0byBzZWUgaWYgdGhpcyBzZW50aW1lbnQgaXMgc3RpbGwgcHJlc2VudCBmb3IgQ2FuYWRpYW5zIHdobyBsaXZlIG91dHNpZGUgb2YgdGhlIHByb3ZpbmNlIG9mIFF1ZWJlYy4KCmEuIFRoZSBwb2xsc3RlciBoYXMgZGV0ZXJtaW5lZCB0aGF0IHRoZXkgYXJlIGdvaW5nIHRvIHJhbmRvbWx5IHNhbXBsZSBuPTE0MjYgQ2FuYWRpYW4gcmVzaWRlbnRzIHdobyBhcmUgbm90IHJlc2lkZW50cyBvZiBRdWViZWMgaW4gYW4gYXR0ZW1wdCB0byBlc3RpbWF0ZSBwIC0gdGhlIHByb3BvcnRpb24gb2YgYWxsIENhbmFkaWFucyB3aG8gbGl2ZSBvdXRzaWRlIG9mIFF1ZWJlYyAo4oCcUmVzdCBvZiBDYW5hZGHigJ0pIC0gd2hvIGJlbGlldmUgdGhhdCBRdWViZWMgd2lsbCBzZXBhcmF0ZSBmcm9tIENhbmFkYSB3aXRoaW4gdGhlIG5leHQgMTAgeWVhcnMuIERlc2NyaWJlIHRoZSBkaXN0cmlidXRpb24gb2YgcMuGLCB0aGUgcHJvcG9ydGlvbiBvZiBuPTE0MjYgcmFuZG9tbHkgY2hvc2VuIENhbmFkaWFucyB3aG8gbGl2ZSBvdXRzaWRlIG9mIFF1ZWJlYyB3aG8gYmVsaWV2ZSBRdWViZWMgd2lsbCBzZXBhcmF0ZSBmcm9tIENhbmFkYSB3aXRoaW4gdGhlIG5leHQgMTAgeWVhcnMuIChFbnN1cmUgdGhhdCB5b3VyIGRlc2NyaXB0aW9uIHByb3ZpZGVzIGEgKGkpIGRpc3RyaWJ1dGlvbiBzaGFwZSAoaWkpIGEgYmFsYW5jaW5nIHBvaW50IGFuZCAoaWlpKSBhIG1lYXN1cmUgb2Ygc3ByZWFkLikKIAogUi4vIFRoZSBkaXN0cmlidXRpb24gaXMgYmVsbCBzaGFwZWQKIFRoZSBiYWxhbmNpbmcgcG9pbnQgY29ycmVzcG9uZCB0byB0aGUgcG9wdWxhdGlvbiBtZWFuICgwLjQyKQogVGhlIHN0YW5kYXJkIGRldmlhdGlvbiBpcyAwLjAxMzA3CmBgYHtyfQp4ID0gc2VxKDMwMCwgODAwLCAwLjEpCnBoYXQgPSAoeC8xNDI2KQpzZHBoYXQgPSBzcXJ0KDAuNDIqKDEtMC40MikgLyAxNDI2KQpzZHBoYXQKYGBgCgoKYGBge3J9CnBsb3QocGhhdCwgZG5vcm0ocGhhdCwgMC40Miwgc2RwaGF0KSwgeWF4dCA9ICduJywgeGxhYj0iVmFsdWVzIG9mIHRoZSBTYW1wbGUgUHJvcG9ydGlvbiIsIHlsYWIgPSAiRGVuc2l0eSIsIG1haW49IkRpc3RyaWJ1dGlvbiBvZiBTYW1wbGUgUHJvcG9ydGlvbiBmcm9tIG4gPSAxNDI2IiwgdHlwZT0iaCIsIGNvbD0nYmx1ZScpICsgYWJsaW5lKHY9MC40MiwgY29sPSJibHVlIikKYGBgCiBiLiBBIHJlY2VudCBwb2xsIG9mIG49MTQyNiBDYW5hZGlhbnMgd2hvIGFyZSBub3QgcmVzaWRlbnRzIG9mIFF1ZWJlYyB3YXMgdGFrZW4uIE9mIHRoZXNlLCA1NDEgdGhvdWdodCB0aGF0IFF1ZWJlYyB3aWxsIHNlcGFyYXRlIGZyb20gQ2FuYWRhIGluIHRoZSBuZXh0IDEwIHllYXJzICgzNTYgaW5kaWNhdGVkIOKAnG1pZ2h0IGhhcHBlbuKAnTsgMTI4IHJlc3BvbmRlZCDigJxsaWtlbHkgdG8gaGFwcGVu4oCdOyA1NyBpbmRpY2F0ZWQg4oCcZGVmaW5pdGVseSB3aWxsIGhhcHBlbuKAnSkuIFRoZSBzYW1wbGUgcHJvcG9ydGlvbiBpcyBjb21wdXRlZCB0byBiZSBwy4Y9NTQxMTQyNj0wLjM3OTQuIFVuZGVyIHRoZSBjb25kaXRpb24gb2YgdGhlIDIwMTIgcG9sbCByZXN1bHQsIGhvdyBsaWtlbHkgaXMgaXQgZm9yIGFub3RoZXIgcmFuZG9tIHNhbXBsZSBvZiBuPTE0MjYgQ2FuYWRpYW5zICh3aG8gcmVzaWRlIG91dHNpZGUgb2YgUXVlYmVjKSB0byBwcm9kdWNlIGEgc2FtcGxlIHByb3BvcnRpb24gdGhhdCBpcyBhdCBtb3N0IGFzIDAuMzc5ND8KIApSLi8gSSBjYWxjdWxhdGVkIHRoZSBzZCBmb3IgdGhlIHNhbXBsZSBwcm9wb3J0aW9uLCBJIHVzZWQgcG5vcm0oKSB0byBmaW5kIHRoZSBwcm9iYWJpbGl0eSBvZiBnZXR0aW5nIGFub3RoZXIgc2FtcGxlIHdpdGggYSBzYW1wbGUgcHJvcG9ydGlvbiBvZiBhdCBtb3N0IDAuMzc5NCBpcyAwLjAwMDk0NzEKYGBge3J9CnNkcGhhdCA9IHNxcnQoMC40MiooMS0wLjQyKSAvIDE0MjYpICNjYWxjdWxhdGUgcGhhdCBmb3IgdGhpcyBzYW1wbGUKc2RwaGF0CnBsZXNzMDM3ID0gcG5vcm0oMC4zNzk0LCBtZWFuPTAuNDIsIHNkPXNkcGhhdCkKcGxlc3MwMzcKYGBgCmMuIENvbnNpZGVyIHRoZSBzdGVwcyBhbmQgYXNzb2NpYXRlZCBSIENvZGUgcmVxdWlyZWQgdG8gZ2VuZXJhdGUgYSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBwcm9wb3J0aW9uLCBwy4YsIHdoZW4gc2FtcGxpbmcgbj0xNDI2IENhbmFkaWFucyB3aG8gbGl2ZSBvdXRzaWRlIG9mIFF1ZWJlYywgdGhlbiBkZXRlcm1pbmluZyB0aGUgcHJvcG9ydGlvbiB3aG8gYmVsaWV2ZSBRdWViZWMgd2lsbCBzZXBhcmF0ZSBmcm9tIENhbmFkYSB3aXRoaW4gdGhlIG5leHQgMTAgeWVhcnMuIENhcnJ5IG91dCBhIHNpbXVsYXRpb24gd2hlcmUgeW91IHNpbXVsYXRlIDEwMDAgcmFuZG9tIHNhbXBsZXMgb2Ygbj0xNDI2LiBDcmVhdGUsIHRoZW4gcnVuIHlvdXIgY29kZSB0byBkZXRlcm1pbmUgdGhlIHByb3BvcnRpb24gb2YgeW91ciBwy4ZzIHRoYXQgYXJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwLjM3OTQuIFByb3ZpZGUgdGhpcyBwcm9wb3J0aW9uLgoKUi4vIEFmdGVyIHJ1bm5pbmcgdGhlIHNpbXVsYXRpb24sIEkgZm91bmQgdGhhdCB0aGUgcHJvcG9ydGlvbiBvZiBwaGF0cyBpcyAwLjAwMS4gClRoaXMgcHJvcG9ydGlvbiBjaGFuZ2VzIGV2ZXJ5IHRpbWUgdGhlIHNpbXVsYXRpb24gaXMgcnVuLCBJIGhhdmUgZ290dGVuIHZhbHVlcyBmcm9tIDAgdG8gMCwwMDQKCmBgYHtyfQpuc2FtcGxlcyA9IDEwMDAgICNuby4gb2Ygc2ltdWxhdGlvbnMKc2FtcGxlLnBoYXQgPSBudW1lcmljKG5zYW1wbGVzKSAjZGF0YSB2ZWN0b3IgdG8gaG9sZCAxMDAwIHNhbXBsZSBzdGFuZGFyZCBkZXZpYXRpb25zIG9mIG4gPSA1CnNpemUgPSAxNDI2CnMxNDI2ZGF0YSA9IHJiaW5vbSgxLHNpemUsMC40MikgI0FzIGRlc2NyaWJlZCBodHRwczovL3d3dy5wcm9ncmFtbWluZ3IuY29tL2V4YW1wbGVzL25lYXQtdHJpY2tzL3NhbXBsZS1yLWZ1bmN0aW9uL3ItcmJpbm9tLwpjb3VudGVyID0gMAoKZm9yKGkgaW4gMTpuc2FtcGxlcyl7CiAgczE0MjZkYXRhID0gcmJpbm9tKDEsc2l6ZSwwLjQyKSAjc2ltdWxhdGVzIGEgYmluYXJ5IHNhbXBsZSB3aXRoIHAgPSAwLjQyCiAgc2FtcGxlLnBoYXRbaV0gPSBzMTQyNmRhdGEvc2l6ZSAjY29tcHV0ZSB0aGUgcGhhdCBvZiB0aGUgc2FtcGxlIG9mIDE0MjYKICBpZiAoc2FtcGxlLnBoYXRbaV0gPCAwLjM3OTQpewogICAgICBjb3VudGVyID0gY291bnRlciArIDEKICB9Cn0KCnNhbXBsZS5waGF0WzE6NV0Kc2FtcGxlLnBoYXRbOTk1Ojk5OV0KCnBwaGF0bGVzczAzNyA9IGNvdW50ZXIvbnNhbXBsZXMKcHBoYXRsZXNzMDM3CmBgYAozLiBCaWxseSBwdXJjaGFzZXMgb25lIDYtNDkgbG90dGVyeSB0aWNrZXQgZXZlcnkgd2VlayBhbmQga2VlcHMgdHJhY2sgb2YgdGhlIG51bWJlciBvZiDigJxtYXRjaGVz4oCdIGhlIGhhcyBvbiBlYWNoIG9mIGhpcyB0aWNrZXRzLiBUbyBiZSBjbGVhciwgYSDigJxtYXRjaOKAnSB3aWxsIG9jY3VyIHdoZW4gYSBudW1iZXIgb24gaGlzIHRpY2tldCBtYXRjaGVzIGEgbnVtYmVyIHRoYXQgYXBwZWFycyBpbiB0aGUgd2lubmluZyBjb21iaW5hdGlvbi4gQSByYW5kb20gdmFyaWFibGUgWCAgdGhhdCBrZWVwcyB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIG1hdGNoaW5nIG51bWJlcnMgQmlsbHkgZXhwZXJpZW5jZXMgcGVyIHdlZWsgaGFzIHRoZSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gZnVuY3Rpb24gd2l0aCBhIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBvZgpQKFg9eCkgPSBjaG9vc2UgKDYsIHgpICogY2hvb3NlKDQzLCA24oiSeCkgLyBjaG9vc2UoNDksIDYpICAgICAgeD0wLDEsMiwzLDQsNSw2LgpFKFgpID0gzrxYID0gMzYgLyA0OSA9IDAuNzM0NwpTRChYKSA9IM+DWCA9IDAuNzU5OTgg4omIIDAuNzYKQmlsbHkgY2xhaW1zIHRoYXQgaW4gYSB5ZWFyICg1MiB3ZWVrcyksIG9uIGF2ZXJhZ2UsIGhlIG1hbmFnZXMgdG8gaGF2ZSBhdCBsZWFzdCBvbmUgbWF0Y2hpbmcgbnVtYmVyIG9uIGhpcyA2LTQ5IHRpY2tldC4gV2hhdCBkbyB5b3UgdGhpbmsgCmFib3V0IEJpbGx54oCZcyBjbGFpbT8gUHJvdmlkZSBhIGJyaWVmIGNvbW1lbnRhcnkgYWJvdXQgQmlsbHnigJlzIGNsYWltIHVzaW5nIHlvdXIgY3VycmVudCBrbm93bGVkZ2Ugb2Ygc3RhdGlzdGljcyBhbmQgcHJvYmFiaWxpdHkgdGhlb3J5LiAKClIuLyBUaGUgcHJvYmFiaWxpdHkgb2YgZ2V0dGluZyBhdCBsZWFzdCBvbmUgbWF0Y2hpbmcgbnVtYmVyIGlzIGVxdWFsIHRvIDEgbWludXMgdGhlIHByb2JhYmlsaXR5IG9mIG5vIGdldHRpbmcgYW55IG51bWJlciBvciBQKHg9MCkgCgpQKHggPj0gMSkgPSAxIC0gUCh4ID0gMCkgCndlIG9idGFpbiBQKDApIGJ5IHJlcGxhY2luZyB4IHdpdGggMCBpbiB0aGUgcHJvYmFiaWxpdHkgZnVuY3Rpb24KUChYPTApID0gY2hvb3NlICg2LCAwKSAqIGNob29zZSg0MywgNuKIkjApIC8gY2hvb3NlKDQ5LCA2KSAKUChYPTApID0gMC40MzYwCgpyZXBsYWNpbmcgdGhpcyB2YWx1ZSAKUChYID49IDEpID0gMSAtIDAuNDM2MApQKFggPj0gMSkgPSAwLjU2NDAKClIuLyBUaGUgcHJvYmFiaWxpdHkgb2YgZ2V0dGluZyBhdCBsZWFzdCBvbmUgbWF0Y2hpbmcgbnVtYmVyIGluIDUyIGRyYXdzICggb25lIGRyYXcgLyB3ZWVrKSBpcyAwLjU2NCB3aGljaCBpcyBncmVhdGVyIHRoYXQgdGhlIHByb2JhYmlsaXR5IG9mIGdldHRpbmcgbm8gbWF0Y2hpbmcgbnVtYmVycyB3aGljaCBpcyAwLjQzNi4gCkl0IGlzIHBvc3NpYmxlIHRoYXQgQmlsbHkgZG9lcyBnZXQgYXQgbGVhc3Qgb25lIG1hdGNoaW5nIG51bWJlciBldmVyeSB3ZWVrIGZvciBhIHllYXIuCgpgYGB7cn0KUDAgPSBjaG9vc2UgKDYsIDApICogY2hvb3NlKDQzLCA2KSAvIGNob29zZSg0OSwgNikgClAwCgpQbW9yZTEgPSAxIC0gUDAKUG1vcmUxCmBgYAo0LiBBIGNvbW1vbiBtZWFzdXJlIG9mIHRveGljaXR5IGZvciBhbnkgcG9sbHV0YW50IGlzIHRoZSBjb25jZW50cmF0aW9uIG9mIHRoZSBwb2xsdXRhbnQgdGhhdCB3aWxsIGtpbGwgaGFsZiBvZiB0aGUgdGVzdCBzcGVjaWVzIGluIGEgZ2l2ZW4gYW1vdW50IG9mIHRpbWUgKHVzdWFsbHkgYWJvdXQgOTYgaG91cnMgZm9yIHRoZSBmaXNoIHNwZWNpZXMpLiBUaGlzIG1lYXN1cmVtZW50IGlzIGNhbGxlZCB0aGUgTEM1MCwgd2hpY2ggcmVmZXJzIHRvIHRoZSBsZXRoYWwgY29uY2VudHJhdGlvbiBraWxsaW5nIDUwJSBvZiB0aGUgdGVzdCBzcGVjaWVzKS4KClRoZSBFbnZpcm9ubWVudGFsIFByb3RlY3Rpb24gQWdlbmN5IGhhcyBjb2xsZWN0ZWQgZGF0YSBvbiBMQzUwIG1lYXN1cmVtZW50cyBmb3IgY2VydGFpbiBjaGVtaWNhbHMgbGlrZWx5IHRvIGJlIGZvdW5kIGluIGZyZXNod2F0ZXIgYW5kIGxha2VzLiBGb3IgYSBjZXJ0YWluIHNwZWNpZXMgb2YgZmlzaCwgdGhlIExDNTAgbWVhc3VyZW1lbnRzIChpbiBwYXJ0cyBwZXIgbWlsbGlvbikgZm9yIEREVCBpbiAxMiBleHBlcmltZW50cyB0byBkZXRlcm1pbmUgdGhlIExDNTAg4oCcZG9zZeKAnSBhcmUKMTYsNSwyMSwxOSwxMCw1LDgsMiw3LDIsNCw5CgphLiBVc2UgUiBzdHVkaW8gdG8gY3JlYXRlIHRoZSBib290c3RyYXAgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgbWVhbiBYwq/Cr8Kvwq9Cb290LExDNTAuIFVzZSAyMDAwIOKAnGJvb3RzdHJhcHPigJ0gaW4geW91ciB3b3JrLCBhbmQgZGlzcGxheSB0aGUgZGlzdHJpYnV0aW9uLgoKUi4vIEFzIGZvbGxvd3MKCmBgYHtyfQojIGxpYnJhcnkobW9zYWljKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkobGF0dGljZSkKbGM1MCA9IGMoMTYsNSwyMSwxOSwxMCw1LDgsMiw3LDIsNCw5KSAgI2NyZWF0ZSBhIHZlY3RvciB3aXRoIHRoZSB2YWx1ZXMgb2YgTEM1MApsYzUwLmRmID0gZGF0YS5mcmFtZShsYzUwKSAgIyBjb252ZXJ0IHRoZSBhYm92ZSB2ZWN0b3IgaW50byBhIGRhdGFmcmFtZQpsYzUwLmRmCmBgYAoKCmBgYHtyfQpudGltZXMgPSAxMDAKYm9vdGRhdGEgPSBudW1lcmljKGxlbmd0aChsYzUwLmRmJGxjNTApKm50aW1lcykKZm9yKGkgaW4gMTpudGltZXMpCnsgIGlmIChpID09IDEpIGJvb3RkYXRhID0gbGM1MC5kZiRsYzUwCiAgIGVsc2UgYm9vdGRhdGEgPSBjKGxjNTAuZGYkbGM1MCwgYm9vdGRhdGEpCn0KCk4gPSAyMDAwCm4uc2l6ZSA9IGxlbmd0aChsYzUwLmRmJGxjNTApCmJvb3QubWVhbiA9IG51bWVyaWMoTikKYm9vdC5kYXRhID0gbnVtZXJpYyhuLnNpemUpCiMKZm9yKGkgaW4gMTpOKXsKICAKICBib290LmRhdGEgPSBzYW1wbGUobGM1MC5kZiRsYzUwLCBuLnNpemUsIHJlcGxhY2U9VFJVRSkgI3NhbXBsZSB3aXRoIHJlcGxhY2VtZW50IAogIGJvb3QubWVhbltpXSA9IG1lYW4oYm9vdC5kYXRhKQp9CmJvb3RzdHJhcC5tZWFuID0gZGF0YS5mcmFtZShib290Lm1lYW4pICNkYXRhIGZyYW1lIGhvbGRpbmcgMjAwMCBkaWZmZXJlbnQgYm9vdHN0cmFwIHNhbXBsZSBtZWFucwpoZWFkKGJvb3RzdHJhcC5tZWFuLCA0KQoKYGBgCmBgYHtyfQp0YWlsKGJvb3RzdHJhcC5tZWFuLCA0KQpgYGAKCgpgYGB7cn0KZ2dwbG90KGJvb3RzdHJhcC5tZWFuLCBhZXMoeCA9IGJvb3QubWVhbikpICsgZ2VvbV9oaXN0b2dyYW0oY29sPSJyZWQiLCBmaWxsPSJibHVlIiwgYmlud2lkdGggPSAwLjUpICsgeGxhYigiVmFsdWVzIG9mIEJvb3RzdHJhcCBNZWFuIikgKyB5bGFiKCJDb3VudCIpICsgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIEJvb3RzdHJhcCBTdGF0aXN0aWM6IFNhbXBsZSBNZWFuIikKYGBgCmBgYHtyfQpmYXZzdGF0cyh+Ym9vdC5tZWFuLCBkYXRhPWJvb3RzdHJhcC5tZWFuKQpgYGAKYi4gRnJvbSB5b3VyIHJlc3VsdCBpbiAoYSksIGNvbXB1dGUgdGhlIDk1JSBib290c3RyYXAgKHBlcmNlbnRpbGUpIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIFwoXG11X3tMQzUwfVwpLCB0aGUgbWVhbiBMQzUwIG1lYXN1cmVtZW50IGZvciBERFQuCgpSLi8gdXNpbmcgcWRhdGEoKSBvbiB0aGUgbGlzdCBvZiBtZWFucyBhbmQgdGhlbiBkaXNwbGF5aW5nIHRoZSBkaXN0cmlidXRpb24gd2l0aCB0aGUgdmFsdWVzIGZvciBwMjUgYW5zIHA5Ny41IHdoaWNoIGFyZSA1Ljc1IGFuZCAxMi41IAoKYGBge3J9CnAyNS5sYzUwID0gcWRhdGEofmJvb3QubWVhbiwgYygwLjAyNSwgMC45NzUpLCBkYXRhPWJvb3RzdHJhcC5tZWFuKVsxXQpwMjUubGM1MFsxXQoKcDk3NS5sYzUwID0gcWRhdGEofmJvb3QubWVhbiwgYygwLjAyNSwgMC45NzUpLCBkYXRhPWJvb3RzdHJhcC5tZWFuKVsyXQpwOTc1LmxjNTAKYGBgCmBgYHtyfQpnZ3Bsb3QoYm9vdHN0cmFwLm1lYW4sIGFlcyh4ID0gYm9vdC5tZWFuKSkgKyBnZW9tX2hpc3RvZ3JhbShjb2w9InJlZCIsIGZpbGw9ImJsdWUiLCBiaW53aWR0aCA9IDAuNSkgKyB4bGFiKCJWYWx1ZXMgb2YgQm9vdHN0cmFwIE1lYW4iKSArIHlsYWIoIkNvdW50IikgKyBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgQm9vdHN0cmFwIFN0YXRpc3RpYzogU2FtcGxlIE1lYW4gd2l0aCA5NSUgY29uZmlkZW5jZSBJbnRlcnZhbCAiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHAyNS5sYzUwLCBjb2xvcj0icmVkIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBwOTc1LmxjNTAsIGNvbG9yPSJyZWQiKQpgYGAKYy4gUmVwZWF0IHlvdXIgZXN0aW1hdGlvbiBvZiBcKFxtdV97TEM1MH1cKSwgdXNpbmcgdGhlIOKAnG90aGVy4oCdIGNvbmZpZGVuY2UgaW50ZXJ2YWwgY292ZXJlZCBpbiBEYXRhIDYwMi4gSW4gdGhlIGNvbnRleHQgb2YgdGhlc2UgZGF0YSwgaW50ZXJwcmV0IHRoZSBtZWFuaW5nIG9mIHRoZSBjb25maWRlbmNlIGludGVydmFsLiBTdGF0ZSBhbnkgY29uZGl0aW9ucy9hc3N1bXB0aW9ucyB0aGF0IGFyZSByZXF1aXJlZCBpbiB0aGUgY29tcHV0YXRpb24gb2YgdGhpcyBjb25maWRlbmNlIGludGVydmFsLgoKUi4vVXNpbmcgU3R1ZGVudCdzIFQgd2UgZm91bmQgUDIuNSA9IDQuOTE4MSBhbmQgUDk3LjUgPSAxMy4wODE5CgoKYGBge3J9ClR0ZXN0LmxjNTAgPSB0LnRlc3QofmxjNTAsIGRhdGE9bGM1MC5kZikkY29uZiAjdXNpbmcgZGVmYXVsdCB2YWx1ZSBvZiAwLjk1IGNvbmZpZGVuY2UgaW50ZXJ2YWwgClR0ZXN0LmxjNTBbMV0KVHRlc3QubGM1MFsyXQpgYGAKZC4gQ29tcGFyZSB5b3VyIHJlc3VsdHMgaW4gcGFydHMgKGIpIGFuZCAoYykuIElmIHlvdSB3ZXJlIHRvIHJlcG9ydCBvbmUgb2YgdGhlc2UgY29uZmlkZW5jZSBpbnRlcnZhbHMsIHdoaWNoIHdvdWxkIHlvdSByZXBvcnQ/IEV4cGxhaW4geW91ciBhbnN3ZXIuCgpSLi8gQm9vdHN0cmFwIGZvciBDSTk1ID0gKDUuNzUsIDEyLjU4KSAocmVkIGluIHRoZSBncmFwaCkKU3R1ZGVudCdzIFQgZm9yIENJOTUgPSAoNC45MTgxLCAxMy4wODE3KSAoYmx1ZSBpbiB0aGUgZ3JhcGgpClRvIGJlIG9uIHRoZSBzYWZlciBzaWRlLCBJIHdhbnQgdG8gcmVwb3J0IGEgdGlnaHRlciBpbnRlcnZhbCBzbyBJIHByZWZlciB0aGUgaW50ZXJ2YWwgZnJvbSBCb290c3RyYXAKCmBgYHtyfQpnZ3Bsb3QoYm9vdHN0cmFwLm1lYW4sIGFlcyh4ID0gYm9vdC5tZWFuKSkgKyBnZW9tX2hpc3RvZ3JhbShjb2w9InJlZCIsIGZpbGw9ImJsdWUiLCBiaW53aWR0aCA9IDAuNSkgKyB4bGFiKCJWYWx1ZXMgb2YgQm9vdHN0cmFwIE1lYW4iKSArIHlsYWIoIkNvdW50IikgKyBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgQm9vdHN0cmFwIFN0YXRpc3RpYzogU2FtcGxlIE1lYW4gd2l0aCA5NSUgY29uZmlkZW5jZSBJbnRlcnZhbCAiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHAyNS5sYzUwLCBjb2xvcj0icmVkIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBwOTc1LmxjNTAsIGNvbG9yPSJyZWQiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IFR0ZXN0LmxjNTBbMV0sIGNvbG9yPSJibHVlIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBUdGVzdC5sYzUwWzJdLCBjb2xvcj0iYmx1ZSIpCmBgYAo1LiBEb2VzIG9uZeKAmXMgZWR1Y2F0aW9uYWwgbGV2ZWwgaW5mbHVlbmNlIHRoZWlyIG9waW5pb24gYWJvdXQgdmFjY2luYXRpb25zPyBBIHJlY2VudCBBbmd1cyBSZWlkMiBzdXJ2ZXkgd2FzIHRha2VuLiBFYWNoIHBlcnNvbiBzYW1wbGVkIHdhcyBhc2tlZCB0byByZXNwb25kIHRvIHRoZSBzdGF0ZW1lbnQg4oCcVGhlIHNjaWVuY2UgYXJvdW5kIHZhY2NpbmF0aW9ucyBpc27igJl0IGNsZWFyLuKAnQoKUmVzcG9uZGVudHMgZWl0aGVyIOKAnHN0cm9uZ2x5IGFncmVl4oCdLCDigJxtb2RlcmF0ZWx5IGFncmVl4oCdLCDigJxtb2RlcmF0ZWx5IGRpc2FncmVl4oCdLCBvciDigJxzdHJvbmdseSBkaXNhZ3JlZeKAnS4gVGhlIHNhbXBsZSB3YXMgcGFydGl0aW9uZWQgYnkgbGV2ZWwgb2YgZWR1Y2F0aW9uLgoKVGhlcmUgd2VyZSBuPTY3MCByZXNwb25kZW50cyB3aG/igJlzIGhpZ2hlc3QgbGV2ZWwgb2YgZWR1Y2F0aW9uIHdhcyBoaWdoIHNjaG9vbCBvciBsZXNzLCBvZiB3aGljaCAzNDgg4oCcZGlzYWdyZWVk4oCdIChtb2RlcmF0ZWx5IGRpc2FncmVlIG9yIHN0b25nbHkgZGlzYWdyZWUpLiBUaGVyZSB3ZXJlIGFsc28gbj0zNzYKIHdob+KAmXMgaGlnaGVzdCBsZXZlbCBvZiBlZHVjYXRpb24gd2FzIGF0IGxlYXN0IGFuIHVuZGVyZ3JhZHVhdGUgdW5pdmVyc2l0eSBlZHVjYXRpb24uIE9mIHRoZXNlLCAyNzQgZGlzYWdyZWVkLgoKCmEuIENvbnNpZGVyIHRoZSBwb3B1bGF0aW9uIGNvbnNpc3Rpbmcgb2YgYWxsIHBlcnNvbnMsIHdob+KAmXMgaGlnaGVzdCBsZXZlbCBvZiBlZHVjYXRpb24gd2FzIGhpZ2ggc2Nob29sIG9yIGxlc3MgYW5kIHRoZSBib290c3RyYXAgc3RhdGlzdGljIHDLhkJvb3QsSFMgLiBVc2luZyAxMDAwIGl0ZXJhdGlvbnMvcmVwbGljYXRpb25zLCBjcmVhdGUgYSBib290c3RyYXAgZGlzdHJpYnV0aW9uIG9mIHDLhkhTCi4gRGlzcGxheSB5b3VyIGRpc3RyaWJ1dGlvbi4KClIuLyBGcm9tIHRoZSBpbmZvcm1hdGlvbiBnaXZlbiB3ZSBjYW4gY2FsY3VsYXRlIHBIUyA9IDM0OCAvIDY3MCA9IDAuNTIuIEkgdXNlIHRoaXMgcHJvcG9ydGlvbiB0byBjcmVhdGUgYSByYW5kb20gbGlzdCBvZiB6ZXJvcyhhZ3JlZWQpIGFuZCBvbmVzIChkaXNhZ3JlZSkuCkkgdGhlbiB1c2UgdGhpcyBsaXN0IHRvIGNyZWF0ZSBhIHRhYmxlIHRoYXQgYWxsb3dzIG1lIHRvIHNlZSB0aGUgYW1vdW50IG9mIHplcm9zIGFuZCBvbmVzIGluIHRoZSBsaXN0LgpOZXh0IEkgbG9vcCAxMDAwIHRpbWVzIHRvIGNyZWF0ZSBhIHNhbXBsZSBmcm9tIHRoZSBsaXN0IEkgY3JlYXRlZCB3aXRoIHRoZSBzaXplIG9mIDY3MCBhbmQgcmVwbGFjZW1lbnQgPSB0cnVlLiBUaGUgbWVhbiBvZiB0aGUgc2FtcGxlIGlzIHRoZW4gY2FsY3VsYXRlZCBhbmQgc3RvcmVkIGluIGFuIGFycmF5IGNhbGxlZCBwaGF0cy5oczsgdGhlbiBJIGNyZWF0ZSBhIGRhdGEgZnJhbWUgZnJvbSB0aGUgcGhhdHMuaHMgbGlzdCBhbmQgZGlzcGxheWVkIGl0cyBoaXN0b2dyYW0KCmBgYHtyfQpsaWJyYXJ5KGJpbm9tKQpocyA9IHJiaW5vbShuPTY3MCxzaXplPTEscHJvYj0wLjUyKQp0YWJsZShocykKYGBgCmBgYHtyfQpwaGF0cy5ocyA9IG51bWVyaWMoMTAwMCkgI2NyZWF0ZSBhIHZlY3RvciB0byBzdG9yZSBlYWNoIG9mIHRoZSAxMDAwIGJvb3RzdHJhcCB2YWx1ZXMgb2YgdGhlIHNhbXBsZSBwcm9wb3J0aW9uCmZvcihpIGluIDE6MTAwMCl7CiAgICAgIHRlbXAuZGF0YSA9IHNhbXBsZShocywgbGVuZ3RoKGhzKSwgcmVwbGFjZT1UUlVFKSAjY291bGQgaGF2ZSB1c2VkIHJlc2FtcGxlKHVzZXJvZm1hcmkpIGhlcmUKICAgICAgcGhhdHMuaHNbaV0gPSBtZWFuKHRlbXAuZGF0YSkKfQpib290X3BoYXRfaHMuZGYgPSBkYXRhLmZyYW1lKHBoYXRzLmhzKQpoZWFkKGJvb3RfcGhhdF9ocy5kZiwgNCkKCmBgYApgYGB7cn0KdGFpbChib290X3BoYXRfaHMuZGYsIDQpCmBgYAoKCmBgYHtyfQpnZ3Bsb3QoYm9vdF9waGF0X2hzLmRmLCBhZXMoeCA9IHBoYXRzLmhzKSkgKyBnZW9tX2hpc3RvZ3JhbShjb2w9ImdyZWVuIiwgZmlsbD0iYmx1ZSIsIGJpbndpZHRoPTAuMDEpICsgeGxhYigiVmFsdWVzIG9mIHRoZSBTYW1wbGUgUHJvcG9ydGlvbiIpICsgeWxhYigiQ291bnQiKSArIGdndGl0bGUoIkhpc3RvZ3JhbTogRGlzdHJpYnV0aW9uIG9mIEJvb3RzdHJhcCBTYW1wbGUgUHJvcG9ydGlvbiIpCmBgYApiLiBOb3cgY29uc2lkZXIgYSBkaWZmZXJlbnQgcG9wdWxhdGlvbiB0aGF0IGNvbnNpc3Qgb2YgYWxsIHBlcnNvbnMgd2hv4oCZcyBoaWdoZXN0IGxldmVsIG9mIGVkdWNhdGlvbiB3YXMgYXQgbGVhc3QgYW4gdW5kZXJncmFkdWF0ZSBkZWdyZWUuIFJlcGVhdCBwYXJ0IChhKSwgY3JlYXRpbmcgYSBib290c3RyYXAgZGlzdHJpYnV0aW9uIGZvciBwy4ZCb290LFVuaS4gKEFnYWluLCBkaXNwbGF5IHlvdXIgZGlzdHJpYnV0aW9uKS4KClIuLyBGcm9tIHRoZSBpbmZvcm1hdGlvbiBnaXZlbiB3ZSBjYW4gY2FsY3VsYXRlIHBVbmk9IDI3NCAvIDM3NiA9IDAuNzMuIEkgdXNlIHRoaXMgcHJvcG9ydGlvbiB0byBjcmVhdGUgYSByYW5kb20gbGlzdCBvZiB6ZXJvcyhhZ3JlZWQpIGFuZCBvbmVzIChkaXNhZ3JlZSkuIEkgdGhlbiB1c2UgdGhpcyBsaXN0IHRvIGNyZWF0ZSBhIHRhYmxlIHRoYXQgYWxsb3dzIG1lIHRvIHNlZSB0aGUgYW1vdW50IG9mIHplcm9zIGFuZCBvbmVzIGluIHRoZSBsaXN0LgpOZXh0IEkgbG9vcCAxMDAwIHRpbWVzIHRvIGNyZWF0ZSBhIHNhbXBsZSBmcm9tIHRoZSBsaXN0IEkgY3JlYXRlZCB3aXRoIHRoZSBzaXplIG9mIDM3NiBhbmQgcmVwbGFjZW1lbnQgPSB0cnVlLiBUaGUgbWVhbiBvZiB0aGUgc2FtcGxlIGlzIHRoZW4gY2FsY3VsYXRlZCBhbmQgc3RvcmVkIGluIGFuIGFycmF5IGNhbGxlZCBwaGF0cy51bmk7IHRoZW4gSSBjcmVhdGUgYSBkYXRhIGZyYW1lIGZyb20gdGhlIHBoYXRzLnVuaSBsaXN0IGFuZCBkaXNwbGF5ZWQgaXRzIGhpc3RvZ3JhbQoKYGBge3J9CnVuaSA9IHJiaW5vbShuPTM3NixzaXplPTEscHJvYj0wLjczKQp0YWJsZSh1bmkpCmBgYApgYGB7cn0KcGhhdHMudW5pID0gbnVtZXJpYygxMDAwKSAKZm9yKGkgaW4gMToxMDAwKXsKICAgICAgdGVtcC5kYXRhID0gc2FtcGxlKHVuaSwgbGVuZ3RoKHVuaSksIHJlcGxhY2U9VFJVRSkgCiAgICAgIHBoYXRzLnVuaVtpXSA9IG1lYW4odGVtcC5kYXRhKQp9CmJvb3RfcGhhdF91bmkuZGYgPSBkYXRhLmZyYW1lKHBoYXRzLnVuaSkKaGVhZChib290X3BoYXRfdW5pLmRmLCA0KQpgYGAKYGBge3J9CnRhaWwoYm9vdF9waGF0X3VuaS5kZiwgNCkKYGBgCgoKYGBge3J9CmdncGxvdChib290X3BoYXRfdW5pLmRmLCBhZXMoeCA9IHBoYXRzLnVuaSkpICsgZ2VvbV9oaXN0b2dyYW0oY29sPSJncmVlbiIsIGZpbGw9ImJsdWUiLCBiaW53aWR0aD0wLjAxKSArIHhsYWIoIlZhbHVlcyBvZiB0aGUgU2FtcGxlIFByb3BvcnRpb24iKSArIHlsYWIoIlByb3BvcnRpb24iKSArIGdndGl0bGUoIkhpc3RvZ3JhbTogRGlzdHJpYnV0aW9uIG9mIEJvb3RzdHJhcCBTYW1wbGUgUHJvcG9ydGlvbiIpIApgYGAKYy4gWW91IHdpc2ggdG8gZXN0aW1hdGUgcFVuaeKIknBIUywgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgcHJvcG9ydGlvbiBvZiBhbGwgdW5pdmVyc2l0eS1lZHVjYXRlZCBDYW5hZGlhbnMgd2hvIGRpc2FncmVlIHRoYXQgdGhlIHNjaWVuY2Ugb2YgdmFjY2luYXRpb25zIGlzbuKAmXQgY2xlYXIgYW5kIHRoZSBwcm9wb3J0aW9uIG9mIGFsbCBDYW5hZGlhbnMgd2hv4oCZcyBoaWdoZXN0IGxldmVsIG9mIGNvbXBsZXRlZCBlZHVjYXRpb24gaXMgaGlnaCBzY2hvb2wgd2hvIGJlbGlldmUgdGhlIHNhbWUuIFlvdSB3aXNoIHRvIGhhdmUgOTUlIGNvbmZpZGVuY2UgaW4geW91ciByZXN1bHQuIFRoaW5rIGFib3V0IHRoZSBjb2RlIHlvdSBjcmVhdGVkIHRvIGdlbmVyYXRlIHRoZSBib290c3RyYXAgZGlzdHJpYnV0aW9ucyBvbiBwYXJ0cyAoYSkgYW5kIChiKS4gTW9kaWZ5IHRoZSBjb2RlIHRvIHlvdSBjcmVhdGVkIGluIHBhcnRzIChhKSBhbmQgKGIpIHRvIGNyZWF0ZSBhIGRpc3RyaWJ1dGlvbiBvZiB0aGUgYm9vdHN0cmFwIHN0YXRpc3RpYyBwy4ZVbmniiJJwy4ZIUy4KClIuLyBBcyBmb2xsb3dzCgpgYGB7cn0KcGhhdHMudW5pX2hzID0gbnVtZXJpYygxMDAwKSAKZm9yKGkgaW4gMToxMDAwKXsKICAgIHRlbXAuZGF0YS5ocyA9IHNhbXBsZShocywgbGVuZ3RoKGhzKSwgcmVwbGFjZT1UUlVFKSAjY291bGQgaGF2ZSB1c2VkIHJlc2FtcGxlKHVzZXJvZm1hcmkpIGhlcmUKICAgIHRlbXAuZGF0YS51bmkgPSBzYW1wbGUodW5pLCBsZW5ndGgodW5pKSwgcmVwbGFjZT1UUlVFKSAgCiAgICBwaGF0cy51bmlfaHNbaV0gPSBtZWFuKHRlbXAuZGF0YS51bmkpIC0gbWVhbih0ZW1wLmRhdGEuaHMpCn0KYm9vdF9waGF0X3VuaV9ocy5kZiA9IGRhdGEuZnJhbWUocGhhdHMudW5pX2hzKQpoZWFkKGJvb3RfcGhhdF91bmlfaHMuZGYsIDQpCgpgYGAKYGBge3J9CnRhaWwoYm9vdF9waGF0X3VuaV9ocy5kZiwgNCkKYGBgCgoKZC4gQ29uc2lkZXIgeW91ciBmaW5kaW5nIGluIHBhcnQgKGMpLiBDb21wdXRlIHRoZSA5NSUgYm9vdHN0cmFwIHBlcmNlbnRpbGUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgcFVuaeKIknBIcy4gRnJvbSB5b3VyIHJlc3VsdCwgZG9lcyB0aGUgcHJvcG9ydGlvbiBvZiBwZXJzb25zIHdpdGggYXQgbW9zdCBhIGhpZ2ggc2Nob29sIGVkdWNhdGlvbiB3aG8gZGlzYWdyZWUgdGhlIHNjaWVuY2UgYXJvdW5kIHZhY2NpbmF0aW9ucyBpc27igJl0IGNsZWFyIGdyZWF0ZXIgdGhhbiB0aGUgc2ltaWxhciBwcm9wb3J0aW9uIG9mIHBlcnNvbnMgd2l0aCBhdCBsZWFzdCBhbiB1bmRlcmdyYWR1YXRlIHVuaXZlcnNpdHkgZGVncmVlPyBXcml0ZSBhIHBhcmFncmFwaCB0aGF0IHN1cHBvcnRzIHlvdXIgYW5zd2VyLgoKUi4vIFRoZSBwcm9wb3J0aW9uIG9mIHBlb3BsZSB3aXRoIGEgbGV2ZWwgb2YgZWR1Y2F0aW9uIGhpZ2hlciB0aGFuIGhpZ2ggc2Nob29sIHdobyBkaXNhZ3JlZSB0aGUgc2NpZW5jZSBhcm91bmQgdmFjY2luYXRpb24gaXNuJ3QgY2xlYXIgaXMgZ3JlYXRlciB0aGFuIHRoZSBwcm9wb3J0aW9uIG9mIHBlb3BsZSB3aXRoIGEgbGV2ZWwgb2YgZWR1Y2F0aW9uIGVxdWFsIG9yIGxlc3MgdGhhbiBoaWdoIHNjaG9vbC4gVGhpcyBpcyBldmlkZW50IGJ5IHRoZSBmYWN0IHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc2ltdWxhdGlvbiBvZiBwVW5p4oiScEhzIHlpZWxkcyB2YWx1ZXMgdGhhdCBhcmUgZ3JlYXRlciB0aGFuIDAuIFRoZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBzaG93cyB0aGF0IG1vc3Qgb2YgdGhlIHZhbHVlcyBmb3IgdGhpcyBkaWZmZXJlbmNlIGZhbGxzIGJldHdlZW4gMTYuNjglIGFuZCAyOC4zMiUgaW4gZmF2b3Igb2YgcGVvcGxlIHdpdGggaGlnaGVyIGVkdWNhdGlvbiB0aGFuIGhpZ2ggc2Nob29sLgoKYGBge3J9CnAyNS51bmlfaHMgPSBxZGF0YSh+cGhhdHMudW5pX2hzLCBjKDAuMDI1LCAwLjk3NSksIGRhdGE9Ym9vdF9waGF0X3VuaV9ocy5kZilbMV0KcDI1LnVuaV9ocwpwOTc1LnVuaV9ocyA9IHFkYXRhKH5waGF0cy51bmlfaHMsIGMoMC4wMjUsIDAuOTc1KSwgZGF0YT1ib290X3BoYXRfdW5pX2hzLmRmKVsyXQpwOTc1LnVuaV9ocwoKYGBgCmBgYHtyfQpnZ3Bsb3QoYm9vdF9waGF0X3VuaV9ocy5kZiwgYWVzKHggPSBwaGF0cy51bmlfaHMpKSArIGdlb21faGlzdG9ncmFtKGNvbD0iZ3JlZW4iLCBmaWxsPSJibHVlIiwgYmlud2lkdGg9MC4wMSkgKyB4bGFiKCJWYWx1ZXMgb2YgdGhlIFNhbXBsZSBQcm9wb3J0aW9uIikgKyB5bGFiKCJDb3VudCIpICsgZ2d0aXRsZSgiSGlzdG9ncmFtOiBEaXN0cmlidXRpb24gb2YgQm9vdHN0cmFwIFNhbXBsZSBQcm9wb3J0aW9uIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBwMjUudW5pX2hzLCBjb2xvcj0icmVkIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBwOTc1LnVuaV9ocywgY29sb3I9InJlZCIpCmBgYAoKCjYuIE5hbm9zIHJlc2VhcmNoMyByZWNlbnRseSBjb21wbGV0ZWQgYSBzdXJ2ZXkgb2Ygbj0xMDAwICBDYW5hZGlhbnMgYWdlZCAxOCB5ZWFycyBvZiBhZ2Ugb3Igb2xkZXIsIGFza2luZyBlYWNoIOKAnHdoYXQgaXMgeW91ciBtb3N0IGltcG9ydGFudCBuYXRpb25hbCBpc3N1ZSBvZiBjb25jZXJuP+KAnSAxNjMgcmVzcG9uZGVkIOKAnEluZmxhdGlvbuKAnSwgMTQ5IHJlc3BvbmRlZCDigJxFbnZpcm9ubWVudOKAnSwgMTMxIHJlc3BvbmRlZCDigJxKb2JzL0Vjb25vbXnigJ0uIFRob3NlIHdlcmUgdGhlIFRvcCBUaHJlZS4KCmEuIENvbXB1dGUgYSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgcEluZmxhdGlvbiwgdGhlIHByb3BvcnRpb24gb2YgYWxsIENhbmFkaWFucyBhZ2VkIDE4IHllYXJzIG9yIG9sZGVyIGZvciB3aG9tIOKAnEluZmxhdGlvbuKAnSBpcyB0aGUgbW9zdCBpbXBvcnRhbnQgbmF0aW9uYWwgY29uY2Vybi4KClIuL0kgY2FuIGNhbGN1bGF0ZSB0aGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgdXNpbmcgdGhlIHBsdXMtMi9wbHVzLTQgd2hpY2ggZ2l2ZXMgdXMgMC4xNDI3KHAyLjUpIC0gMC4xODg1KHA5Ny41KQpgYGB7cn0KcHJvcC50ZXN0KDE2MyArIDIsIDEwMDAgKyA0LCBjb3JyZWN0PUZBTFNFKSRjb25mCmBgYApiLiBTaW1pbGFyIHRvIHlvdXIgd29yayBpbiBRdWVzdGlvbiA0KGIpLCBjcmVhdGUgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgYm9vdHN0cmFwIHN0YXRpc3RpYyBwy4ZCb290LEluZmxhdGlvbgogYW5kIGEgOTUlIGJvb3RzdHJhcCBwZXJjZW50aWxlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIHBJbmZsYXRpb24uCiAKIFIuLyBDb25maWRlbmNlIGludGVydmFsIDk1JSA9IDAuMTQ0IC0gMC4xODgKIApgYGB7cn0KaW5mbCA9IHJiaW5vbShuPTEwMDAsc2l6ZT0xLHByb2I9MC4xNjMpCmluZmwuZGYgPSBkYXRhLmZyYW1lKGluZmwpCmhlYWQoaW5mbC5kZiwgNCkKYGBgCmBgYHtyfQp0YWlsKGluZmwuZGYpCmBgYAoKCmBgYHtyfQpOID0gMTAwMApuLnNpemUgPSBsZW5ndGgoaW5mbC5kZiRpbmZsKQpib290LnByb3BvcnRpb25faW5mbCA9IG51bWVyaWMoTikKYm9vdC5kYXRhX2luZmwgPSBudW1lcmljKG4uc2l6ZSkKCgpmb3IoaSBpbiAxOk4pewogIAogIGJvb3QuZGF0YV9pbmZsID0gc2FtcGxlKGluZmwuZGYkaW5mbCwgbi5zaXplLCByZXBsYWNlPVRSVUUpICNzYW1wbGUgd2l0aCByZXBsYWNlbWVudCAKICBib290LnByb3BvcnRpb25faW5mbFtpXSA9IG1lYW4oYm9vdC5kYXRhX2luZmwpCn0KYm9vdHN0cmFwLnByb3BvcnRpb25faW5mbCA9IGRhdGEuZnJhbWUoYm9vdC5wcm9wb3J0aW9uX2luZmwpICNkYXRhIGZyYW1lIGhvbGRpbmcgMjAwMCBkaWZmZXJlbnQgYm9vdHN0cmFwIHNhbXBsZSBtZWFucwpoZWFkKGJvb3RzdHJhcC5wcm9wb3J0aW9uX2luZmwsIDQpCgpgYGAKYGBge3J9CnRhaWwoYm9vdHN0cmFwLnByb3BvcnRpb25faW5mbCwgNCkKYGBgCgoKYGBge3J9CnAyLjVJbmZsID0gcWRhdGEofmJvb3QucHJvcG9ydGlvbl9pbmZsLCBjKDAuMDI1LCAwLjk3NSksIGRhdGEgPSBib290c3RyYXAucHJvcG9ydGlvbl9pbmZsKVsxXQpwMi41SW5mbApwOTcuNUluZmwgPSBxZGF0YSh+Ym9vdC5wcm9wb3J0aW9uX2luZmwsIGMoMC4wMjUsIDAuOTc1KSwgZGF0YSA9IGJvb3RzdHJhcC5wcm9wb3J0aW9uX2luZmwpWzJdCnA5Ny41SW5mbApgYGAKYGBge3J9CmdncGxvdChib290c3RyYXAucHJvcG9ydGlvbl9pbmZsLCBhZXMoeCA9IGJvb3QucHJvcG9ydGlvbl9pbmZsKSkgKyBnZW9tX2hpc3RvZ3JhbShjb2w9ImdyZWVuIiwgZmlsbD0iYmx1ZSIsIGJpbndpZHRoPTAuMDA1KSArIHhsYWIoIlZhbHVlcyBvZiB0aGUgU2FtcGxlIFByb3BvcnRpb24iKSArIHlsYWIoIkNvdW50IikgKyBnZ3RpdGxlKCJIaXN0b2dyYW06IERpc3RyaWJ1dGlvbiBvZiBCb290c3RyYXAgU2FtcGxlIFByb3BvcnRpb24iKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHAyLjVJbmZsLCBjb2xvcj0icmVkIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBwOTcuNUluZmwsIGNvbG9yPSJyZWQiKQpgYGAKYy4gQSBzaW1pbGFyIHN1cnZleSBvZiBDYW5hZGlhbnMgaW4gQXVndXN0IDIwMjMgLSBhIGxpdHRsZSBvdmVyIGEgbW9udGggYWdvIC0gc3VnZ2VzdGVkIHRoYXQgdGhlIHByb3BvcnRpb24gb2YgYWxsIENhbmFkaWFucyB3aG8gaWRlbnRpZmllZCDigJxJbmZsYXRpb27igJ0gYXMgdGhlIG1vc3QgaW1wb3J0YW50IG5hdGlvbmFsIGNvbmNlcm4gd2FzIHBJbmZsYXRpb24sQXVnXzIzPTAuMTMKRnJvbSB5b3VyIHJlc3VsdHMgaW4gKGEpIGFuZCAoYiksIGNhbiB5b3UgaW5mZXIgdGhhdCB0aGUgcHJvcG9ydGlvbiBvZiBhbGwgQ2FuYWRpYW5zIHdobyBiZWxpZXZlIOKAnEluZmxhdGlvbuKAnSBpcyB0aGUgbW9zdCBpbXBvcnRhbnQgbmF0aW9uYWwgaXNzdWUgaGFzIGluY3JlYXNlZCBzaW5jZSBBdWd1c3Qgb2YgdGhpcyB5ZWFyPyBXaHkgb3Igd2h5IG5vdD8gRW5zdXJlIHlvdSBpbnZva2UgYSBzdGF0aXN0aWNhbCBqdXN0aWZpY2F0aW9uLgoKUi4vIEkgY2FuIGluZmVyIHRoYXQgdGhlIHByb3BvcnRpb24gb2YgQ2FuYWRpYW5zIHdobyBiZWxpZXZlIGluZmxhdGlvbiBpcyB0aGUgbW9zdCBpbXBvcnRhbnQgaXNzdWUgaGFzIGluY3JlYXNlZCBiYXNlZCBvbiB0aGUgZmFjdCB0aGF0IHRoZSBDb25maWRlbmNlIEludGVydmFsIGZvciB0aGUgbW9zdCByZWNlbnQgc3VydmV5IGdvZXMgZnJvbSAxNC40IHRvIDE4Ljg7IHRoZXJlIGlzIG5vIG92ZXJsYXAgd2l0aCB0aGUgcHJldmlvdXMgdmFsdWUgb2YgMC4xMyBmb3VuZCBpbiB0aGUgcHJldmlvdXMgc3VydmV5LCBzaG93aW5nIHVzIHRoYXQgdGhlIHByb3BvcnRpb24gaGFzIGluY3JlYXNlZAoKCjcuIFJlZmVyIHRvIHRoZSBkYXRhIGVuY291bnRlcmVkIGluIFF1ZXN0aW9uIDQgb2YgdGhpcyBhc3NpZ25tZW50LiBQcmlvciB0byBjb21wbGV0aW5nIHBhcnRzIChhKSBhbmQgKGIpLCBjYXJlZnVsbHkgcmVhZCB0aHJvdWdoIGJvdGggcGFydHMgKGEpIGFuZCAoYikuCgphLiBVc2UgdGhlIEJvb3RzdHJhcCBtZXRob2QgdG8gY29tcHV0ZSBhIDk4JSBjb25maWRlbmNlIGludGVydmFsIGZvciDOvMucTEM1MCwgdGhlIG1lZGlhbiBMQzUwIGxldmVsLiBJbnRlcnByZXQgdGhlIG1lYW5pbmcgb2YgdGhpcyBpbnRlcnZhbCBpbiB0aGUgY29udGV4dCBvZiB0aGVzZSBkYXRhLgoKUi4vIEkgd2lsbCBwcm9jZWVkIHRvIHNpbXVsYXRlIHRoZSBtZWRpYW4gd2l0aCBOPTIwMDAsYW5kIHRoZW4gY2FsY3VsYXRlIHRoZSA5OCUgY29uZmlkZW5jZSBJbnRlcnZhbCB1c2luZyBxZGF0YSBmb3IgdGhlIDElIGFuZCA5OSUuIEZpbmFsbHkgSSB3aWxsIGdyYXBoIHRoZXNlIHJlc3VsdHMuIApDb25maWRlbmNlIEludGVydmFsIDk5JSA9ICg0LCAxNikKV2UgY2FuIHNheSB0aGF0IHRoZXJlIGlzIGEgOTglIHByb2JhYmlsaXR5IHRoYXQgdGhlIG1lZGlhbiB2YWx1ZSBmb3IgRERUIExDNTAgaXMgYmV0d2VlbiA0IGFuZCAxNiBwcG0KYGBge3J9Ck4gPSAyMDAwCm4uc2l6ZSA9IGxlbmd0aChsYzUwLmRmJGxjNTApCmJvb3QubWVkaWFuID0gbnVtZXJpYyhOKQpib290LmRhdGEgPSBudW1lcmljKG4uc2l6ZSkKCgpmb3IoaSBpbiAxOk4pewogIAogIGJvb3QuZGF0YSA9IHNhbXBsZShsYzUwLmRmJGxjNTAsIG4uc2l6ZSwgcmVwbGFjZT1UUlVFKSAjc2FtcGxlIHdpdGggcmVwbGFjZW1lbnQgCiAgYm9vdC5tZWRpYW5baV0gPSBtZWRpYW4oYm9vdC5kYXRhKQp9Cgpib290c3RyYXAubWVkaWFuID0gZGF0YS5mcmFtZShib290Lm1lZGlhbikgI2RhdGEgZnJhbWUgaG9sZGluZyAyMDAwIGRpZmZlcmVudCBib290c3RyYXAgc2FtcGxlIG1lZGlhbnMKaGVhZChib290c3RyYXAubWVkaWFuLCA0KQpgYGAKCgpgYGB7cn0KdGFpbChib290c3RyYXAubWVkaWFuLCA0KQpgYGAKCgpgYGB7cn0KbGM1MC5tZWRpYW5fOTkgPSBxZGF0YShib290Lm1lZGlhbiwgYygwLjAxLCAwLjk5KSwgZGF0YT1ib290c3RyYXAubWVkaWFuKQpsYzUwLm1lZGlhbl85OQpgYGAKCgpgYGB7cn0KZ2dwbG90KGJvb3RzdHJhcC5tZWRpYW4sIGFlcyh4ID0gYm9vdC5tZWRpYW4pKSArIGdlb21faGlzdG9ncmFtKGNvbD0icmVkIiwgZmlsbD0iYmx1ZSIsIGJpbndpZHRoPTAuOCkgKyB4bGFiKCJWYWx1ZXMgb2YgdGhlIFNhbXBsZSBNZWRpYW4iKSArIHlsYWIoIkNvdW50IikgKyBnZ3RpdGxlKCJIaXN0b2dyYW06IERpc3RyaWJ1dGlvbiBvZiBCb290c3RyYXAgU2FtcGxlIE1lZGlhbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbGM1MC5tZWRpYW5fOTlbMV0sIGNvbG9yPSJncmVlbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbGM1MC5tZWRpYW5fOTlbMl0sIGNvbG9yPSJncmVlbiIpCmBgYApiLiBDb21wdXRlIHRoZSA5NSUgYm9vdHN0cmFwIHBlcmNlbnRpbGUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uLCDPgy4gSW4gYWRkaXRpb24sIGludGVycHJldCB0aGUgbWVhbmluZyBvZiB5b3VyIGludGVydmFsIGluIHRoZSBjb250ZXh0IG9mIHRoZXNlIGRhdGEuCgpSLi8gRm9yIHRoaXMgcXVlc3Rpb24sIEkgd2lsbCBmaW5kIHRoZSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgdmFyaWFuY2UgZmlyc3QgYW5kIHRoZW4gdGFrZSB0aGUgc3Egcm9vdCBvZiB0aGVzZSByZXN1bHRzIGFyZSB0aHcgZGF0YSBmb3IgdGhlIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgc2Q6ICgzLjE3MTIsIDcuODYwNykKCldlIGNhbiBzYXkgdGhhdCB0aGVyZSBpcyBhIDk1JSBwcm9iYWJpbGl0eSB0aGF0IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gdmFsdWUgZm9yIEREVCBMQzUwIGlzIGJldHdlZW4gMy4xMjgxIGFuZCA3LjkxODMgcHBtCmBgYHtyfQpOID0gMjAwMApuLnNpemUgPSBsZW5ndGgobGM1MC5kZiRsYzUwKQpib290LnZhciA9IG51bWVyaWMoTikKYm9vdC5kYXRhID0gbnVtZXJpYyhuLnNpemUpCgoKZm9yKGkgaW4gMTpOKXsKICAKICBib290LmRhdGEgPSBzYW1wbGUobGM1MC5kZiRsYzUwLCBuLnNpemUsIHJlcGxhY2U9VFJVRSkgI3NhbXBsZSB3aXRoIHJlcGxhY2VtZW50IAogIGJvb3QudmFyW2ldID0gdmFyKGJvb3QuZGF0YSkKfQoKYm9vdHN0cmFwLnZhciA9IGRhdGEuZnJhbWUoYm9vdC52YXIpICNkYXRhIGZyYW1lIGhvbGRpbmcgMjAwMCBkaWZmZXJlbnQgYm9vdHN0cmFwIHNhbXBsZSB2YXJpYW5jZQpoZWFkKGJvb3RzdHJhcC52YXIsIDQpCmBgYAoKYGBge3J9CnRhaWwoYm9vdHN0cmFwLnZhciwgNCkKYGBgCmBgYHtyfQpsYzUwLnZhcl85NSA9IHFkYXRhKGJvb3QudmFyLCBjKDAuMDI1LCAwLjk3NSksIGRhdGE9Ym9vdHN0cmFwLnZhcikKbGM1MC52YXJfOTUKYGBgCgoKYGBge3J9CmdncGxvdChib290c3RyYXAudmFyLCBhZXMoeCA9IGJvb3QudmFyKSkgKyBnZW9tX2hpc3RvZ3JhbShjb2w9InJlZCIsIGZpbGw9ImJsdWUiLCBiaW53aWR0aD0xKSArIHhsYWIoIlZhbHVlcyBvZiB0aGUgU2FtcGxlIFZhcmlhbmNlIikgKyB5bGFiKCJDb3VudCIpICsgZ2d0aXRsZSgiSGlzdG9ncmFtOiBEaXN0cmlidXRpb24gb2YgQm9vdHN0cmFwIFNhbXBsZSBWYXJpYW5jZSIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbGM1MC52YXJfOTVbMV0sIGNvbG9yPSJncmVlbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbGM1MC52YXJfOTVbMl0sIGNvbG9yPSJncmVlbiIpCmBgYAoKYGBge3J9CmxjNTAuc2RfOTUgPSBzcXJ0KGxjNTAudmFyXzk1KQpsYzUwLnNkXzk1CmBgYAo4LiBBIG5hdGlvbmFsIHN1cnZleSA0IG9mIG49Mzk5ICDigJxHZW4gWuKAnS1lcnMgLSBzb21lb25lIHdobyBpcyBib3JuIGluIHRoZSB5ZWFycyAxOTk2IC0gMjAxMCAoaW5jbHVzaXZlKSB3YXMgdGFrZW4uIEVhY2ggd2FzIHRoZW4gYXNrZWQgdGhlIGZvbGxvd2luZyBxdWVzdGlvbjoK4oCcSWYgYSBmZWRlcmFsIGVsZWN0aW9uIHdlcmUgaGVsZCB0b21vcnJvdywgd2hpY2ggb25lIG9mIHRoZSBmb2xsb3dpbmcgcGFydGllcyB3b3VsZCB5b3Ugdm90ZSBmb3IgaW4geW91ciBjb25zdGl0dWVuY3k/4oCdClRoZSByZXN1bHRzPwoKMTI4IHJlc3BvbmRlZCDigJxDb25zZXJ2YXRpdmXigJ0gKENvbnNlcnZhdGl2ZSBQYXJ0eSBvZiBDYW5hZGEpCjk2IHJlc3BvbmRlZCDigJxMaWJlcmFs4oCdIChMaWJlcmFsIFBhcnR5IG9mIENhbmFkYSkKMTA0IHJlc3BvbmRlZCDigJxORFDigJ0gKE5ldyBEZW1vY3JhdGljIFBhcnR5IG9mIENhbmFkYSkKUmVzcG9uZGVudHMgd2VyZSBwcm92aWRlZCB3aXRoIGEgZmV3IG1vcmUg4oCcY2xvc2VkIG9wdGlvbnPigJ0sIGluY2x1ZGluZyB0aGUgQmxvYyBRdWViZWNvaXMsIFBlb3BsZeKAmXMgUGFydHksIGFuZCBHcmVlbiBQYXJ0eS4KCmEuIENvbXB1dGUgdGhlIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciBwQ29uLCB0aGUgcHJvcG9ydGlvbiBvZiBhbGwgR2VuIFotZXJzIGluIENhbmFkYSB0aGF0IHdpbGwgdm90ZSBmb3IgdGhlaXIgcmVzcGVjdGl2ZSBDb25zZXJ2YXRpdmUgTWVtYmVyIG9mIFBhcmxpYW1lbnQgY2FuZGlkYXRlL2NvbnN0aXR1ZW5jeSwgaW4gYW4gZWxlY3Rpb24gd2VyZSDigJxoZWxkIHRvbW9ycm934oCdLgoKUi4vIFNpbmNlIHdlIGtub3cgbiBhbmQgbmNvbnNlcnZhdGl2ZSwgd2UgY2FtIHVzZSBwcm9wLnRlc3QoKSB0byBkZXRlcm1pbmUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgdXNpbmcgaXRzIGRlZmF1bHQgOTUlIGFuZCB0aGUgcGx1cy0yL3BsdXMtNCB0byBtYWtlIHRoZSBpbnRlcnZhbCB0aWdodGVyLgpQY29ucyA5NSUgQ0kgPSAoMC4yNzg4LDAuMzY5NyApCkFjY29yZGluZyB0byB0aGVzZSByZXN1bHRzIHdlIGNhbiBzYXkgd2l0aCBhIDk1JSBjb25maWRlbmNlIHRoYXQgYmV0d2VlbiAyNy44OCBhbmQgMzYuOTcgJSBvZiBHZW4gWi1lcnMgd2lsbCB2b3RlIGNvbnNlcnZhdGl2ZS4KCmBgYHtyfQpjaTk1Y29uLnByb3AgPSBwcm9wLnRlc3QoMTI4KzIsIDM5OSs0LCBjb3JyZWN0PUZBTFNFKSRjb25mCmNpOTVjb24ucHJvcApgYGAKYi4gQ29uc2lkZXIgdGhlIGJvb3RzdHJhcCBzdGF0aXN0aWMgcMucQ29uPVhDb24rMjM5OSs0Ci4gV3JpdGUgdGhlIFIgY29kZSB0aGF0IHdpbGwgZ2VuZXJhdGUgYSBib290c3RyYXAgZGlzdHJpYnV0aW9uIGZvciBwy5xDb24KLiBVc2UgMTAwMCBhcyB0aGUgbnVtYmVyIG9mIHJlcGxpY2F0aW9ucy9pdGVyYXRpb25zLgoKYGBge3J9Cm5zYW1wbGVzID0gMTAwMCAgI25vLiBvZiBzaW11bGF0aW9ucwpzYW1wbGUucGhhdF9jb24gPSBudW1lcmljKG5zYW1wbGVzKSAjZGF0YSB2ZWN0b3IgdG8gaG9sZCAxMDAwIHNhbXBsZXMgcmVwcmVzZW50aW5nIHRoZSBnZW4gei1lcnMgdGhhdCBjaG9vc2UgY29uc2VydmF0aXZlCnNpemUgPSAzOTkKCmZvcihpIGluIDE6bnNhbXBsZXMpewogIGJvb3QuZGF0YSA9IHJiaW5vbSgxLHNpemUsMC4zMikgI3NpbXVsYXRlcyBhIGJpbmFyeSBzYW1wbGUgcmVwcmVzZW50aW5nIHRoZSBnZW56LWVycyB0aGF0IGNob29zZSBjb25zZXJ2YXRpdmUga25vd2luZyBQY29uID0gMTI4LzM5OSA9IDAuMzMKICBzYW1wbGUucGhhdF9jb25baV0gPSAoYm9vdC5kYXRhICsgMikvKHNpemUgKzQpICNjb21wdXRlIHRoZSBwaGF0IHVzaW5nIHBsdXMyL3BsdXM0IGFuZCBzdG9yZXMgaXQgaW4gdGhlIHNhbXBsZS5waGF0X2NvbiBsaXN0Cn0KCmJvb3RzdHJhcC5jb24gPSBkYXRhLmZyYW1lKHNhbXBsZS5waGF0X2NvbikKaGVhZChib290c3RyYXAuY29uLCA0KQpgYGAKYGBge3J9CnRhaWwoYm9vdHN0cmFwLmNvbiwgNCkKYGBgCgoKYy4gRnJvbSB5b3VyIHJlc3VsdCBpbiBwYXJ0IChiKSwgY29tcHV0ZSBhIDk1JSBib290c3RyYXAgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgcENvbi4KCmBgYHtyfQpjaTk1Y29uLmJvb3QgPSBxZGF0YSh+c2FtcGxlLnBoYXRfY29uLCBjKDAuMDI1LCAwLjk3NSksIGRhdGE9Ym9vdHN0cmFwLmNvbikKY2k5NWNvbi5ib290CmBgYApgYGB7cn0KZ2dwbG90KGJvb3RzdHJhcC5jb24sIGFlcyh4ID0gc2FtcGxlLnBoYXRfY29uKSkgKyBnZW9tX2hpc3RvZ3JhbShjb2w9ImdyZWVuIiwgZmlsbD0iYmx1ZSIsIGJpbndpZHRoPTAuMDUpICsgeGxhYigiVmFsdWVzIG9mIHRoZSBTYW1wbGUgUHJvcG9ydGlvbiIpICsgeWxhYigiQ291bnQiKSArIGdndGl0bGUoIkhpc3RvZ3JhbTogRGlzdHJpYnV0aW9uIG9mIEJvb3RzdHJhcCBTYW1wbGUgUHJvcG9ydGlvbiIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY2k5NWNvbi5wcm9wWzFdLCBjb2xvcj0icmVkIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjaTk1Y29uLnByb3BbMl0sIGNvbG9yPSJyZWQiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGNpOTVjb24uYm9vdFsxXSwgY29sb3I9InB1cnBsZSIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gY2k5NWNvbi5ib290WzJdLCBjb2xvcj0icHVycGxlIikKYGBgCgpkLiBDb25zaWRlciB5b3VyIHJlc3VsdHMgaW4gcGFydHMgKGEpIGFuZCAoYykuIENvbXBhcmUgdGhlIHR3byByZXN1bHRzLiBJZiB5b3UgaGFkIHRvIHBpY2sgb25lIGFzIHRoZSDigJxiZXN04oCdIGVzdGltYXRlIGZvciB0aGUgdW5rbm93biB2YWx1ZSBvZiBwQ29uLCB3aGljaCBvbmUgd291bGQgeW91IHNlbGVjdD8gUHJvdmlkZSBhIGp1c3RpZmljYXRpb24gZm9yIHlvdXIgY2hvaWNlLgoKUi4vIGZyb20gYSkgQ0k5NS5wcm9wID0gKDAuMjc4OCwgMC4zNjQ3KSAtLT4gMC4zNjQ3IC0gMC4yNzg4ID0gMC4wOTA5IChyZWQpCiAgICAgICAgIGIpIENJOTUuYm9vdCA9ICgwLjI3NzksIDAuMzYyOCkgLS0+IDAuMzY5NyAtIDAuMjc1NCA9IDAuMDg0OSAocHVycGxlKQogICAgICAgICAKICAgICAgICAgVGhlc2UgaW50ZXJ2YWxzIGFyZSB2ZXJ5IGNsb3NlLCBpZiBJIGhhdmUgdG8gY2hvb3NlIG9uZSwgSSBjaG9vc2UgdGhlIG9uZSB3aXRoIHRoZSBzbWFsbGVyIGludGVydmFsIHdoaWNoIGluIHRoaXMgY2FzZSBpcyB0aGUgaW50ZXJ2YWwgZm91bmQgYnkgcnVubmluZyBib29zdHJhcAoKOS4gSW4gdGhpcyBxdWVzdGlvbiB5b3Ugd2lsbCB1c2UgdGhlIGFsYmVydGFjb3VudGllc3NhbXBsZWQyMDE5LmNzdi4gVGhlIGRhdGEgYXBwZWFyaW5nIGluIHRoaXMgZmlsZSBhcmUgdGhlIHJlc3VsdHMgb2YgYSByYW5kb20gc2FtcGxlIG9mIG49MTAwIGNvdW50aWVzIGluIEFsYmVydGEuIEZvciBlYWNoIGNvdW50eSwgdGhlIG1lZGlhbiBob3VzZWhvbGQgaW5jb21lIHdhcyBjb21wdXRlZC4gVGhpcyBmZWF0dXJlIGFwcGVhcnMgaW4gdGhlIE9yaWdpbmFsVmFsdWUgY29sdW1uLgoKUmVhZCB0aGlzIGRhdGEgaW50byBhIFIgZGF0YSBmcmFtZS4gVG8gcmVhZCB0aGlzIGludG8gUiwgeW91IHdpbGwgaGF2ZSB0byBzZWxlY3QgdGhlIFJhdyB0YWIgYXBwZWFyaW5nIG9uIHRoZSB0b3AgcmlnaHQtaGFuZCBzaWRlLgoKVGhlIGJvb3RzdHJhcCB0IHN0YXRpc3RpYyBpcyBkZWZpbmVkIGFzClRCb290c3RyYXA9WMKvwq/Cr8KvQm9vdOKIkljCr8Kvwq/CryhTbuKImikKd2hlcmUgWMKvwq/Cr8KvCiBhbmQgUwogYXJlIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHNhbXBsZS4KCmEuIEZyb20gdGhlc2UgZGF0YSwgZ2VuZXJhdGUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBUQm9vdHN0cmFwLiBEaXNwbGF5IHRoaXMgZGlzdHJpYnV0aW9uLiBVc2UgMTAwMCBmb3IgdGhlIG51bWJlciBvZiBib290c3RyYXBzLgoKYGBge3J9CmFsYmVydGEuY291bnRpZXMgPSByZWFkLmNzdigiYWxiZXJ0YWNvdW50aWVzc2FtcGxlZDIwMTkuY3N2IikKaW5jb21lLm1lZGlhbiA9IGRhdGEuZnJhbWUoYWxiZXJ0YS5jb3VudGllcyRPcmlnaW5hbFZhbHVlKQpoZWFkKGluY29tZS5tZWRpYW4sIDQpCmBgYApgYGB7cn0KdGFpbChpbmNvbWUubWVkaWFuLCA0KQpgYGAKYGBge3J9CnN0YXRzID0gZmF2c3RhdHMoaW5jb21lLm1lZGlhbiRhbGJlcnRhLmNvdW50aWVzLk9yaWdpbmFsVmFsdWUpCnN0YXRzCmBgYApgYGB7cn0Kc2FtcGxlLm1lYW4gPSBzdGF0c1s2XQpzYW1wbGUubWVhbgpgYGAKCmBgYHtyfQpzYW1wbGUuc2QgPSBzdGF0c1s3XQpzYW1wbGUuc2QKYGBgCmBgYHtyfQpOID0gMTAwMApzYW1wbGUuc2l6ZSA9IGxlbmd0aChpbmNvbWUubWVkaWFuJGFsYmVydGEuY291bnRpZXMuT3JpZ2luYWxWYWx1ZSkKYm9vdC5kYXRhID0gbnVtZXJpYyhzYW1wbGUuc2l6ZSkKYm9vdC5tZWFuID0gbnVtZXJpYyhOKQpib290LnQgPSBudW1lcmljKE4pCgpmb3IgKGkgaW4gMTpOKXsKICBib290LmRhdGEgPSBzYW1wbGUoYWxiZXJ0YS5jb3VudGllcyRPcmlnaW5hbFZhbHVlLCBzYW1wbGUuc2l6ZSwgcmVwbGFjZSA9IFRSVUUpCiAgYm9vdC5tZWFuW2ldID0gbWVhbihib290LmRhdGEpCiAgdCA9IChib290Lm1lYW5baV0gLSBzYW1wbGUubWVhbikgLyAoc2FtcGxlLnNkIC8gc3FydChzYW1wbGUuc2l6ZSkpCiAgdAogIGJvb3QudFtpXSA9IHQKfQoKYm9vdC5tZWFuZGYgPSBkYXRhLmZyYW1lKGJvb3QubWVhbikKaGVhZChib290Lm1lYW5kZikKYGBgCgpgYGB7cn0KdGFpbChib290Lm1lYW5kZikKYGBgCgpgYGB7cn0KYm9vdC50dmFsID0gYyhOKQpmb3IoaSBpbiAxOk4pewogIGJvb3QudHZhbFtpXSA9IGJvb3QudFtbaV1dWzFdCn0KCmJvb3QudGRmID0gZGF0YS5mcmFtZShib290LnR2YWwpCmhlYWQoYm9vdC50ZGYpCgpgYGAKYGBge3J9CnRhaWwoYm9vdC50ZGYpCmBgYAoKYGBge3J9CmdncGxvdChib290LnRkZiwgYWVzKHggPSBib290LnR2YWwpKSArIGdlb21faGlzdG9ncmFtKGNvbD0icmVkIiwgZmlsbD0iYmx1ZSIsIGJpbndpZHRoPTAuNCkgKyB4bGFiKCJWYWx1ZXMgb2YgQm9vdHN0cmF0IFQiKSArIHlsYWIoIkNvdW50IikgKyBnZ3RpdGxlKCJIaXN0b2dyYW06IERpc3RyaWJ1dGlvbiBvZiBCb290c3RyYXAgVCIpCgpgYGAKYi4gUmVmZXIgdG8gcGFydCAoYSk6IEEgQm9vdHN0cmFwIHQuQ29uZmlkZW5jZSBJbnRlcnZhbCBmb3IgzrwgIGlzIGRlZmluZWQgYXM6CltYwq/Cr8Kvwq/iiJJ04oiXzrEyKFNu4oiS4oiS4oiaKSxYwq/Cr8Kvwq8rdOKIlzHiiJLOsTIoU27iiJLiiJLiiJopXQp3aGVyZSB04oiXzrEyCiBhbmQgdOKIlzHiiJLOsTIKIGlzIGFyZSDOsTIKIGFuZCAx4oiSzrEyCiBwZXJjZW50aWxlcyBmcm9tIHRoZSBUQm9vdHN0cmFwIGRpc3RyaWJ1dGlvbi4KCkNvbXB1dGUgdGhlIDk1JSBib290c3RyYXAgdCBjb25maWRlbmNlIGludGVydmFsIGZvciDOvE1lZGlhbl9GYW1pbHlfSW5jb21lIGZvciBhbGwgdGhlIGNvdW50aWVzIGluIEFsYmVydGEuCgpOb3RlOiDiiJJ0zrEyICB3aWxsIGJlIGEgbmVnYXRpdmUgdmFsdWUgZHVlIHRvIHRoZSBuYXR1cmUgb2YgdGhlIFN0dWRlbnTigJlzIHQgIGRpc3RyaWJ1dGlvbi4gSGVuY2UgdGhlIOKAnC3igJ0gc2lnbiBpbiBmcm9udC4KCmBgYHtyfQpwZXJjZW50aWxlVCA9IHF1YW50aWxlKGJvb3QudGRmJGJvb3QudHZhbCwgYygwLjAyNSwgMC45NzUpKQpwZXJjZW50aWxlVApgYGAKYGBge3J9Cm1lYW5DSTIuNSA9IHNhbXBsZS5tZWFuIC0gKHBlcmNlbnRpbGVUWzFdICogKHNhbXBsZS5zZC9zcXJ0KHNhbXBsZS5zaXplKSkpCm1lYW5DSTIuNSRtZWFuCmBgYAogCmBgYHtyfQptZWFuQ0k5Ny41ID0gc2FtcGxlLm1lYW4gLSAocGVyY2VudGlsZVRbMl0gKiAoc2FtcGxlLnNkL3NxcnQoc2FtcGxlLnNpemUpKSkKbWVhbkNJOTcuNSRtZWFuCmBgYApjLiBDb21wdXRlIHRoZSAoaSkgOTUlIGJvb3RzdHJhcCBwZXJjZW50aWxlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZXN0aW1hdGUgb2YgzrxNZWRpYW5fRmFtaWx5X0luY29tZSAgYW5kIChpaSkgdGhlIDk1JSBTdHVkZW504oCZcyB0IGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIM68TWVkaWFuX0ZhbWlseV9JbmNvbWUuCmBgYHtyfQptZWRpYW5JbmNvbWUuY2k5NSA9IHFkYXRhKH5hbGJlcnRhLmNvdW50aWVzLk9yaWdpbmFsVmFsdWUsIGMoMC4wMjUsIDAuOTc1KSwgZGF0YT1pbmNvbWUubWVkaWFuKQptZWRpYW5JbmNvbWUuY2k5NQoKYGBgCgoKYGBge3J9CkJvb3RUY2k5NSA9IHFkYXRhKGJvb3QudHZhbCwgYygwLjAyNSwgMC45NzUpLCBkYXRhPWJvb3QudGRmKQpCb290VGNpOTUKCmBgYApELiBDb25zaWRlciB5b3VyIHJlc3VsdHMgaW4gcGFydHMgKGIpIGFuZCAoYyk6IElmIHlvdSB3ZXJlIHRvIHJlcG9ydCBvbmUgb2YgdGhlc2UgY29uZmlkZW5jZSBpbnRlcnZhbHMgdG8gYSBjbGllbnQsIHdoYXQgd291bGQgYmUgeW91ciBjb25zdWx0YXRpb24/IFByb3ZpZGUgYSBzaG9ydCBwYXJhZ3JhcGggZXhwbGFpbmluZyB3aGF0IHRoZSB2YWx1ZSBvZiDOvE1lZGlhbl9GYW1pbHlfSW5jb21lIENvdWxkIHBvc3NpYmx5IGJlLCBhbmQgd2h5IHlvdSBjaG9zZSB0aGUgbWV0aG9kIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZXN0aW1hdGlvbiB0byByZXBvcnQgZnJvbS4KCkkgd291bGQgdXNlIHRoZSA5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbCBmb3VuZCBpbiBwYXJ0IGIgYXMgaXQgcmVwb3J0cyBhIHRpZ2h0ZXIgaW50ZXJ2YWwgZm9yIHRoYW4gdGhlIG9uZSByZXBvcnRlZCBpbiBDCgpiKSA4MzAyOS4yOCAtIDkxOTExLjI4CmMpIDM0NzQ3LjUwIC0gMTMxMTE5LjUwCgo=