knitr::opts_chunk$set(eval = TRUE, message = FALSE, warning = FALSE)
set.seed(1234)
library(tidyverse)
library(openintro)
library(infer)
Exercise 1
Describe the distribution of responses in this sample. How does it
compare to the distribution of responses in the population.
Hint: Although the sample_n function takes a random
sample of observations (i.e. rows) from the dataset, you can still refer
to the variables in the dataset with the same names. Code you presented
earlier for visualizing and summarizing the population data will still
be useful for the sample, however be careful to not label your
proportion p since you’re now calculating a sample
statistic, not a population parameters. You can customize the label of
the statistics to indicate that it comes from the sample.
The distribution is similar to the actual population. It only differs
by a small decimal in the benefits and doesn’t benefit groups.
set.seed(1234)
global_monitor <- tibble(
scientist_work = c(rep("Benefits", 80000), rep("Doesn't benefit", 20000))
)
ggplot(global_monitor, aes(x = scientist_work)) +
geom_bar() +
labs(
x = "", y = "",
title = "Do you believe that the work scientists do benefit people like you?"
) +
coord_flip()

global_monitor %>%
count(scientist_work) %>%
mutate(p = n /sum(n))
## # A tibble: 2 Ă— 3
## scientist_work n p
## <chr> <int> <dbl>
## 1 Benefits 80000 0.8
## 2 Doesn't benefit 20000 0.2
set.seed(1234)
samp1 <- global_monitor %>%
sample_n(50)
ggplot(samp1, aes(x = scientist_work)) +
geom_bar() +
labs(
x = "", y = "",
title = "Do you believe that the work scientists do benefit people like you?"
) +
coord_flip()

samp1 %>%
count(scientist_work) %>%
mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
## scientist_work n p_hat
## <chr> <int> <dbl>
## 1 Benefits 37 0.74
## 2 Doesn't benefit 13 0.26
Exercise 2
Would you expect the sample proportion to match the sample
proportion of another student’s sample? Why, or why not? If the answer
is no, would you expect the proportions to be somewhat different or very
different? Ask a student team to confirm your answer.
I would expect the sample proportion to be similar to another
student’s sample. If they used the same seed, then it would be the same.
If they used a different seed, it would likely be different but similar.
I would expect them to be similar because the original data was 80% to
20%, so the sample would probably be close to this. They are much more
likely to get close to 80% for the Benefits group and close o 20% for
the Doesn’t Benefit group. I confirmed my answer by running the sample
again with a different seed. The results were 72% and 28%. This is
similar to my sample.
set.seed(5678)
samp <- global_monitor %>%
sample_n(50)
ggplot(samp, aes(x = scientist_work)) +
geom_bar() +
labs(
x = "", y = "",
title = "Do you believe that the work scientists do benefit people like you?"
) +
coord_flip()

samp |>
count(scientist_work) |>
mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
## scientist_work n p_hat
## <chr> <int> <dbl>
## 1 Benefits 36 0.72
## 2 Doesn't benefit 14 0.28
Exercise 3
Take a second sample, also of size 50, and call it samp2. How does
the sample proportion of samp2 compare with that of samp1? Suppose we
took two more samples, one of size 100 and one of size 1000. Which would
you think would provide a more accurate estimate of the population
proportion?
The sample proportion is similar to samp1. The two proportions are
off by a few tenths of a percent. I would assume a sample of 1000 would
be more accurate. I tested it below, and it turned out that the sample
of size 1000 was more accurate. The results also are probably affected
by the seed, but in this case, the sample of size 1000 was more accurate
than 100.
set.seed(246)
samp2 <- global_monitor %>%
sample_n(50)
ggplot(samp2, aes(x = scientist_work)) +
geom_bar() +
labs(
x = "", y = "",
title = "Do you believe that the work scientists do benefit people like you?"
) +
coord_flip()

samp2 |>
count(scientist_work) |>
mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
## scientist_work n p_hat
## <chr> <int> <dbl>
## 1 Benefits 41 0.82
## 2 Doesn't benefit 9 0.18
set.seed(500)
samp3 <- global_monitor %>%
sample_n(100)
ggplot(samp3, aes(x = scientist_work)) +
geom_bar() +
labs(
x = "", y = "",
title = "Do you believe that the work scientists do benefit people like you?"
) +
coord_flip()

samp3 |>
count(scientist_work) |>
mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
## scientist_work n p_hat
## <chr> <int> <dbl>
## 1 Benefits 85 0.85
## 2 Doesn't benefit 15 0.15
set.seed(500)
samp4 <- global_monitor %>%
sample_n(1000)
ggplot(samp4, aes(x = scientist_work)) +
geom_bar() +
labs(
x = "", y = "",
title = "Do you believe that the work scientists do benefit people like you?"
) +
coord_flip()

samp4 |>
count(scientist_work) |>
mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
## scientist_work n p_hat
## <chr> <int> <dbl>
## 1 Benefits 790 0.79
## 2 Doesn't benefit 210 0.21
Exercise 4
How many elements are there in sample_props50? Describe the sampling
distribution, and be sure to specifically note its center. Make sure to
include a plot of the distribution in your answer.
It has 14999 rows (elements), but it is supposed to have 15000. The
distribution looks normally distributed. It is symmetrical with a bell
curve. The center is at 0., which is the original proportion for the
population.
sample_props50 <- global_monitor %>%
rep_sample_n(size = 50, reps = 15000, replace = TRUE) %>%
count(scientist_work) %>%
mutate(p_hat = n /sum(n)) %>%
filter(scientist_work == "Doesn't benefit")
length(sample_props50$scientist_work)
## [1] 15000
ggplot(data = sample_props50, aes(x = p_hat)) +
geom_histogram(binwidth = 0.02) +
labs(
x = "p_hat (Doesn't benefit)",
title = "Sampling distribution of p_hat",
subtitle = "Sample size = 50, Number of samples = 15000"
)

Exercise 5
To make sure you understand how sampling distributions are built,
and exactly what the rep_sample_n function does, try modifying the code
to create a sampling distribution of 25 sample
proportions from samples of size 10, and put
them in a data frame named sample_props_small. Print the output. How
many observations are there in this object called sample_props_small?
What does each observation represent?
There are 24 observations in the object. Each observation represents
one repetition of taking a sample of 10 people and getting the
proportion of people who said Doesn’t Benefit.
sample_props_small <- global_monitor %>%
rep_sample_n(size = 10, reps = 25, replace = TRUE) %>%
count(scientist_work) %>%
mutate(p_hat = n /sum(n)) %>%
filter(scientist_work == "Doesn't benefit")
ggplot(data = sample_props_small, aes(x = p_hat)) +
geom_histogram(binwidth = 0.02) +
labs(
x = "p_hat (Doesn't benefit)",
title = "Sampling distribution of p_hat",
subtitle = "Sample size = 10, Number of samples = 25"
)

Exercise 6
Use the app below to create sampling distributions of proportions of
Doesn’t benefit from samples of size 10, 50, and 100. Use 5,000
simulations. What does each observation in the sampling distribution
represent? How does the mean, standard error, and shape of the sampling
distribution change as the sample size increases? How (if at all) do
these values change if you increase the number of simulations? (You do
not need to include plots in your answer.)
Each observation in the distribution represents the proportion in one
sample of people who responded “Doesn’t Benefit.”
When the sample size increased from 10 to 50, the mean became the
same as the population proportion, and the standard error decreased.
Also, the shape of the distribution became much more normally
distributed. When the sample size increased from 50 to 100, the mean
remained the same (equal to the population proportion), and the standard
error decreased. Also, the shape of the distribution stayed normally
distributed.
Increasing the number of simulations barely changed the mean or
standard error, but the distributions became more normally distributed
with a higher number of simulations.
Exercise 7
Take a sample of size 15 from the population and calculate the
proportion of people in this sample who think the work scientists do
enhances their lives. Using this sample, what is your best point
estimate of the population proportion of people who think the work
scientists do enchances their lives?
The estimate I calculated from this sample was about 0.73.
set.seed(1234)
samp1 <- global_monitor %>%
sample_n(15)
ggplot(samp1, aes(x = scientist_work)) +
geom_bar() +
labs(
x = "", y = "",
title = "Do you believe that the work scientists do benefit people like you?"
) +
coord_flip()

samp1 %>%
count(scientist_work) %>%
mutate(p_hat = n /sum(n))
## # A tibble: 2 Ă— 3
## scientist_work n p_hat
## <chr> <int> <dbl>
## 1 Benefits 11 0.733
## 2 Doesn't benefit 4 0.267
Exercise 8
Since you have access to the population, simulate the sampling
distribution of proportion of those who think the work scientists do
enchances their lives for samples of size 15 by taking 2000 samples from
the population of size 15 and computing 2000 sample proportions. Store
these proportions in as sample_props15. Plot the data, then describe the
shape of this sampling distribution. Based on this sampling
distribution, what would you guess the true proportion of those who
think the work scientists do enchances their lives to be? Finally,
calculate and report the population proportion.
This sampling distribution is left-skewed.
I would guess that the true proportion is 0.80. The population
proportion is actually 0.8034333.
sample_props15 <- global_monitor %>%
rep_sample_n(size = 15, reps = 2000, replace = TRUE) %>%
count(scientist_work) %>%
mutate(p_hat = n /sum(n)) %>%
filter(scientist_work == "Benefits")
ggplot(data = sample_props15, aes(x = p_hat)) +
geom_histogram(binwidth = 0.02) +
labs(
x = "p_hat (Benefits)",
title = "Sampling distribution of p_hat",
subtitle = "Sample size = 15, Number of samples = 2000"
)

mean(sample_props15$p_hat)
## [1] 0.7996333
Exercise 9
Change your sample size from 15 to 150, then compute the sampling
distribution using the same method as above, and store these proportions
in a new object called sample_props150. Describe the shape of this
sampling distribution and compare it to the sampling distribution for a
sample size of 15. Based on this sampling distribution, what would you
guess to be the true proportion of those who think the work scientists
do enchances their lives?
This sampling distribution is about normally distributed. It is much
more normal than the distribution for a sample size of 15.
I would guess the true proportion of those who think scientists
enhance lives is about 0.80.
sample_props150 <- global_monitor %>%
rep_sample_n(size = 150, reps = 2000, replace = TRUE) %>%
count(scientist_work) %>%
mutate(p_hat = n /sum(n)) %>%
filter(scientist_work == "Benefits")
ggplot(data = sample_props150, aes(x = p_hat)) +
geom_histogram(binwidth = 0.02) +
labs(
x = "p_hat (Benefits)",
title = "Sampling distribution of p_hat",
subtitle = "Sample size = 150, Number of samples = 2000"
)

Exercise 10
Of the sampling distributions from 2 and 3, which has a smaller
spread? If you’re concerned with making estimates that are more often
close to the true value, would you prefer a sampling distribution with a
large or small spread?
The sampling distribution from exercise 9 has a smaller spread. I
would prefer a sampling distribution with a small spread, because it is
more likely to be more accurate. Distributions with a small spread have
less of an error typically. Also, in the examples I have done, the
population proportion was at the center of the distributions with less
spread and with more spread, so it probably does not matter which one is
used. Using a distribution with more spread will more likely contain the
true proportion, but the center of the distribution might not be as
accurate as one with less spread.
LS0tDQp0aXRsZTogIkxhYiA1YTogU2FtcGxpbmcgRGlzdHJpYnV0aW9ucyINCmF1dGhvcjogIkp1bGlhIEZlcnJpcyINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0DQotLS0NCg0KYGBge3J9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZXZhbCA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQ0Kc2V0LnNlZWQoMTIzNCkNCmBgYA0KDQpgYGB7ciBsb2FkLXBhY2thZ2VzLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KG9wZW5pbnRybykNCmxpYnJhcnkoaW5mZXIpDQoNCmBgYA0KDQojIyBFeGVyY2lzZSAxDQoNCiMjIyBEZXNjcmliZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHJlc3BvbnNlcyBpbiB0aGlzIHNhbXBsZS4gSG93IGRvZXMgaXQgY29tcGFyZSB0byB0aGUgZGlzdHJpYnV0aW9uIG9mIHJlc3BvbnNlcyBpbiB0aGUgcG9wdWxhdGlvbi4gKipIaW50OioqIEFsdGhvdWdoIHRoZSBzYW1wbGVfbiBmdW5jdGlvbiB0YWtlcyBhIHJhbmRvbSBzYW1wbGUgb2Ygb2JzZXJ2YXRpb25zIChpLmUuIHJvd3MpIGZyb20gdGhlIGRhdGFzZXQsIHlvdSBjYW4gc3RpbGwgcmVmZXIgdG8gdGhlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldCB3aXRoIHRoZSBzYW1lIG5hbWVzLiBDb2RlIHlvdSBwcmVzZW50ZWQgZWFybGllciBmb3IgdmlzdWFsaXppbmcgYW5kIHN1bW1hcml6aW5nIHRoZSBwb3B1bGF0aW9uIGRhdGEgd2lsbCBzdGlsbCBiZSB1c2VmdWwgZm9yIHRoZSBzYW1wbGUsIGhvd2V2ZXIgYmUgY2FyZWZ1bCB0byBub3QgbGFiZWwgeW91ciBwcm9wb3J0aW9uIGBwYCBzaW5jZSB5b3UncmUgbm93IGNhbGN1bGF0aW5nIGEgc2FtcGxlIHN0YXRpc3RpYywgbm90IGEgcG9wdWxhdGlvbiBwYXJhbWV0ZXJzLiBZb3UgY2FuIGN1c3RvbWl6ZSB0aGUgbGFiZWwgb2YgdGhlIHN0YXRpc3RpY3MgdG8gaW5kaWNhdGUgdGhhdCBpdCBjb21lcyBmcm9tIHRoZSBzYW1wbGUuDQoNClRoZSBkaXN0cmlidXRpb24gaXMgc2ltaWxhciB0byB0aGUgYWN0dWFsIHBvcHVsYXRpb24uIEl0IG9ubHkgZGlmZmVycyBieSBhIHNtYWxsIGRlY2ltYWwgaW4gdGhlIGJlbmVmaXRzIGFuZCBkb2Vzbid0IGJlbmVmaXQgZ3JvdXBzLg0KDQpgYGB7ciBleGVyY2lzZS0xfQ0Kc2V0LnNlZWQoMTIzNCkNCmdsb2JhbF9tb25pdG9yIDwtIHRpYmJsZSgNCiAgc2NpZW50aXN0X3dvcmsgPSBjKHJlcCgiQmVuZWZpdHMiLCA4MDAwMCksIHJlcCgiRG9lc24ndCBiZW5lZml0IiwgMjAwMDApKQ0KKQ0KDQpnZ3Bsb3QoZ2xvYmFsX21vbml0b3IsIGFlcyh4ID0gc2NpZW50aXN0X3dvcmspKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKA0KICAgIHggPSAiIiwgeSA9ICIiLA0KICAgIHRpdGxlID0gIkRvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHBlb3BsZSBsaWtlIHlvdT8iDQogICkgKw0KICBjb29yZF9mbGlwKCkgDQoNCmdsb2JhbF9tb25pdG9yICU+JQ0KICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogIG11dGF0ZShwID0gbiAvc3VtKG4pKQ0KDQpzZXQuc2VlZCgxMjM0KQ0KDQpzYW1wMSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oNTApDQoNCmdncGxvdChzYW1wMSwgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiRG8geW91IGJlbGlldmUgdGhhdCB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXQgcGVvcGxlIGxpa2UgeW91PyINCiAgKSArDQogIGNvb3JkX2ZsaXAoKSANCg0Kc2FtcDEgJT4lDQogIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDINCg0KIyMjIFdvdWxkIHlvdSBleHBlY3QgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIHRvIG1hdGNoIHRoZSBzYW1wbGUgcHJvcG9ydGlvbiBvZiBhbm90aGVyIHN0dWRlbnQncyBzYW1wbGU/IFdoeSwgb3Igd2h5IG5vdD8gSWYgdGhlIGFuc3dlciBpcyBubywgd291bGQgeW91IGV4cGVjdCB0aGUgcHJvcG9ydGlvbnMgdG8gYmUgc29tZXdoYXQgZGlmZmVyZW50IG9yIHZlcnkgZGlmZmVyZW50PyBBc2sgYSBzdHVkZW50IHRlYW0gdG8gY29uZmlybSB5b3VyIGFuc3dlci4NCg0KSSB3b3VsZCBleHBlY3QgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIHRvIGJlIHNpbWlsYXIgdG8gYW5vdGhlciBzdHVkZW50J3Mgc2FtcGxlLiBJZiB0aGV5IHVzZWQgdGhlIHNhbWUgc2VlZCwgdGhlbiBpdCB3b3VsZCBiZSB0aGUgc2FtZS4gSWYgdGhleSB1c2VkIGEgZGlmZmVyZW50IHNlZWQsIGl0IHdvdWxkIGxpa2VseSBiZSBkaWZmZXJlbnQgYnV0IHNpbWlsYXIuIEkgd291bGQgZXhwZWN0IHRoZW0gdG8gYmUgc2ltaWxhciBiZWNhdXNlIHRoZSBvcmlnaW5hbCBkYXRhIHdhcyA4MCUgdG8gMjAlLCBzbyB0aGUgc2FtcGxlIHdvdWxkIHByb2JhYmx5IGJlIGNsb3NlIHRvIHRoaXMuIFRoZXkgYXJlIG11Y2ggbW9yZSBsaWtlbHkgdG8gZ2V0IGNsb3NlIHRvIDgwJSBmb3IgdGhlIEJlbmVmaXRzIGdyb3VwIGFuZCBjbG9zZSBvIDIwJSBmb3IgdGhlIERvZXNuJ3QgQmVuZWZpdCBncm91cC4gSSBjb25maXJtZWQgbXkgYW5zd2VyIGJ5IHJ1bm5pbmcgdGhlIHNhbXBsZSBhZ2FpbiB3aXRoIGEgZGlmZmVyZW50IHNlZWQuIFRoZSByZXN1bHRzIHdlcmUgNzIlIGFuZCAyOCUuIFRoaXMgaXMgc2ltaWxhciB0byBteSBzYW1wbGUuDQoNCmBgYHtyIGV4ZXJjaXNlLTJ9DQpzZXQuc2VlZCg1Njc4KQ0KDQpzYW1wIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICBzYW1wbGVfbig1MCkNCg0KZ2dwbG90KHNhbXAsIGFlcyh4ID0gc2NpZW50aXN0X3dvcmspKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKA0KICAgIHggPSAiIiwgeSA9ICIiLA0KICAgIHRpdGxlID0gIkRvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHBlb3BsZSBsaWtlIHlvdT8iDQogICkgKw0KICBjb29yZF9mbGlwKCkgDQoNCnNhbXAgfD4NCiAgY291bnQoc2NpZW50aXN0X3dvcmspIHw+DQogIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkNCmBgYA0KDQojIyBFeGVyY2lzZSAzDQoNCiMjIyBUYWtlIGEgc2Vjb25kIHNhbXBsZSwgYWxzbyBvZiBzaXplIDUwLCBhbmQgY2FsbCBpdCBzYW1wMi4gSG93IGRvZXMgdGhlIHNhbXBsZSBwcm9wb3J0aW9uIG9mIHNhbXAyIGNvbXBhcmUgd2l0aCB0aGF0IG9mIHNhbXAxPyBTdXBwb3NlIHdlIHRvb2sgdHdvIG1vcmUgc2FtcGxlcywgb25lIG9mIHNpemUgMTAwIGFuZCBvbmUgb2Ygc2l6ZSAxMDAwLiBXaGljaCB3b3VsZCB5b3UgdGhpbmsgd291bGQgcHJvdmlkZSBhIG1vcmUgYWNjdXJhdGUgZXN0aW1hdGUgb2YgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbj8NCg0KVGhlIHNhbXBsZSBwcm9wb3J0aW9uIGlzIHNpbWlsYXIgdG8gc2FtcDEuIFRoZSB0d28gcHJvcG9ydGlvbnMgYXJlIG9mZiBieSBhIGZldyB0ZW50aHMgb2YgYSBwZXJjZW50LiBJIHdvdWxkIGFzc3VtZSBhIHNhbXBsZSBvZiAxMDAwIHdvdWxkIGJlIG1vcmUgYWNjdXJhdGUuIEkgdGVzdGVkIGl0IGJlbG93LCBhbmQgaXQgdHVybmVkIG91dCB0aGF0IHRoZSBzYW1wbGUgb2Ygc2l6ZSAxMDAwIHdhcyBtb3JlIGFjY3VyYXRlLiBUaGUgcmVzdWx0cyBhbHNvIGFyZSBwcm9iYWJseSBhZmZlY3RlZCBieSB0aGUgc2VlZCwgYnV0IGluIHRoaXMgY2FzZSwgdGhlIHNhbXBsZSBvZiBzaXplIDEwMDAgd2FzIG1vcmUgYWNjdXJhdGUgdGhhbiAxMDAuDQoNCmBgYHtyIGV4ZXJjaXNlLTN9DQpzZXQuc2VlZCgyNDYpDQoNCnNhbXAyIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICBzYW1wbGVfbig1MCkNCg0KZ2dwbG90KHNhbXAyLCBhZXMoeCA9IHNjaWVudGlzdF93b3JrKSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICB0aXRsZSA9ICJEbyB5b3UgYmVsaWV2ZSB0aGF0IHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gYmVuZWZpdCBwZW9wbGUgbGlrZSB5b3U/Ig0KICApICsNCiAgY29vcmRfZmxpcCgpIA0KDQpzYW1wMiB8Pg0KICBjb3VudChzY2llbnRpc3Rfd29yaykgfD4NCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KDQpzZXQuc2VlZCg1MDApDQoNCnNhbXAzIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICBzYW1wbGVfbigxMDApDQoNCmdncGxvdChzYW1wMywgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiRG8geW91IGJlbGlldmUgdGhhdCB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXQgcGVvcGxlIGxpa2UgeW91PyINCiAgKSArDQogIGNvb3JkX2ZsaXAoKSANCg0Kc2FtcDMgfD4NCiAgY291bnQoc2NpZW50aXN0X3dvcmspIHw+DQogIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkNCg0Kc2V0LnNlZWQoNTAwKQ0KDQpzYW1wNCA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oMTAwMCkNCg0KZ2dwbG90KHNhbXA0LCBhZXMoeCA9IHNjaWVudGlzdF93b3JrKSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICB0aXRsZSA9ICJEbyB5b3UgYmVsaWV2ZSB0aGF0IHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gYmVuZWZpdCBwZW9wbGUgbGlrZSB5b3U/Ig0KICApICsNCiAgY29vcmRfZmxpcCgpIA0KDQpzYW1wNCB8Pg0KICBjb3VudChzY2llbnRpc3Rfd29yaykgfD4NCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDQNCg0KIyMjIEhvdyBtYW55IGVsZW1lbnRzIGFyZSB0aGVyZSBpbiBzYW1wbGVfcHJvcHM1MD8gRGVzY3JpYmUgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgYW5kIGJlIHN1cmUgdG8gc3BlY2lmaWNhbGx5IG5vdGUgaXRzIGNlbnRlci4gTWFrZSBzdXJlIHRvIGluY2x1ZGUgYSBwbG90IG9mIHRoZSBkaXN0cmlidXRpb24gaW4geW91ciBhbnN3ZXIuDQoNCkl0IGhhcyAxNDk5OSByb3dzIChlbGVtZW50cyksIGJ1dCBpdCBpcyBzdXBwb3NlZCB0byBoYXZlIDE1MDAwLiBUaGUgZGlzdHJpYnV0aW9uIGxvb2tzIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBJdCBpcyBzeW1tZXRyaWNhbCB3aXRoIGEgYmVsbCBjdXJ2ZS4gVGhlIGNlbnRlciBpcyBhdCAwLiwgd2hpY2ggaXMgdGhlIG9yaWdpbmFsIHByb3BvcnRpb24gZm9yIHRoZSBwb3B1bGF0aW9uLg0KDQpgYGB7ciBleGVyY2lzZS00fQ0Kc2FtcGxlX3Byb3BzNTAgPC0gZ2xvYmFsX21vbml0b3IgJT4lDQogICAgICAgICAgICAgICAgICAgIHJlcF9zYW1wbGVfbihzaXplID0gNTAsIHJlcHMgPSAxNTAwMCwgcmVwbGFjZSA9IFRSVUUpICU+JQ0KICAgICAgICAgICAgICAgICAgICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgICAgICAgICAgICAgIGZpbHRlcihzY2llbnRpc3Rfd29yayA9PSAiRG9lc24ndCBiZW5lZml0IikNCg0KbGVuZ3RoKHNhbXBsZV9wcm9wczUwJHNjaWVudGlzdF93b3JrKQ0KDQpnZ3Bsb3QoZGF0YSA9IHNhbXBsZV9wcm9wczUwLCBhZXMoeCA9IHBfaGF0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDIpICsNCiAgbGFicygNCiAgICB4ID0gInBfaGF0IChEb2Vzbid0IGJlbmVmaXQpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gNTAsIE51bWJlciBvZiBzYW1wbGVzID0gMTUwMDAiDQogICkNCmBgYA0KDQojIyBFeGVyY2lzZSA1DQoNCiMjIyBUbyBtYWtlIHN1cmUgeW91IHVuZGVyc3RhbmQgaG93IHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgYXJlIGJ1aWx0LCBhbmQgZXhhY3RseSB3aGF0IHRoZSByZXBfc2FtcGxlX24gZnVuY3Rpb24gZG9lcywgdHJ5IG1vZGlmeWluZyB0aGUgY29kZSB0byBjcmVhdGUgYSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgKioyNSBzYW1wbGUgcHJvcG9ydGlvbnMqKiBmcm9tICoqc2FtcGxlcyBvZiBzaXplIDEwKiosIGFuZCBwdXQgdGhlbSBpbiBhIGRhdGEgZnJhbWUgbmFtZWQgc2FtcGxlX3Byb3BzX3NtYWxsLiBQcmludCB0aGUgb3V0cHV0LiBIb3cgbWFueSBvYnNlcnZhdGlvbnMgYXJlIHRoZXJlIGluIHRoaXMgb2JqZWN0IGNhbGxlZCBzYW1wbGVfcHJvcHNfc21hbGw/IFdoYXQgZG9lcyBlYWNoIG9ic2VydmF0aW9uIHJlcHJlc2VudD8NCg0KVGhlcmUgYXJlIDI0IG9ic2VydmF0aW9ucyBpbiB0aGUgb2JqZWN0LiBFYWNoIG9ic2VydmF0aW9uIHJlcHJlc2VudHMgb25lIHJlcGV0aXRpb24gb2YgdGFraW5nIGEgc2FtcGxlIG9mIDEwIHBlb3BsZSBhbmQgZ2V0dGluZyB0aGUgcHJvcG9ydGlvbiBvZiBwZW9wbGUgd2hvIHNhaWQgRG9lc24ndCBCZW5lZml0Lg0KDQpgYGB7ciBleGVyY2lzZS01fQ0Kc2FtcGxlX3Byb3BzX3NtYWxsIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICAgICAgICAgICAgICAgICAgICByZXBfc2FtcGxlX24oc2l6ZSA9IDEwLCByZXBzID0gMjUsIHJlcGxhY2UgPSBUUlVFKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICAgICAgICAgICAgICAgICAgICBtdXRhdGUocF9oYXQgPSBuIC9zdW0obikpICU+JQ0KICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoc2NpZW50aXN0X3dvcmsgPT0gIkRvZXNuJ3QgYmVuZWZpdCIpDQoNCmdncGxvdChkYXRhID0gc2FtcGxlX3Byb3BzX3NtYWxsLCBhZXMoeCA9IHBfaGF0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDIpICsNCiAgbGFicygNCiAgICB4ID0gInBfaGF0IChEb2Vzbid0IGJlbmVmaXQpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTAsIE51bWJlciBvZiBzYW1wbGVzID0gMjUiDQogICkNCmBgYA0KDQojIyBFeGVyY2lzZSA2DQoNCiMjIyBVc2UgdGhlIGFwcCBiZWxvdyB0byBjcmVhdGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBvZiBwcm9wb3J0aW9ucyBvZiAqRG9lc24ndCBiZW5lZml0KiBmcm9tIHNhbXBsZXMgb2Ygc2l6ZSAxMCwgNTAsIGFuZCAxMDAuIFVzZSA1LDAwMCBzaW11bGF0aW9ucy4gV2hhdCBkb2VzIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiByZXByZXNlbnQ/IEhvdyBkb2VzIHRoZSBtZWFuLCBzdGFuZGFyZCBlcnJvciwgYW5kIHNoYXBlIG9mIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gY2hhbmdlIGFzIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZXM/IEhvdyAoaWYgYXQgYWxsKSBkbyB0aGVzZSB2YWx1ZXMgY2hhbmdlIGlmIHlvdSBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHNpbXVsYXRpb25zPyAoWW91IGRvIG5vdCBuZWVkIHRvIGluY2x1ZGUgcGxvdHMgaW4geW91ciBhbnN3ZXIuKQ0KDQpFYWNoIG9ic2VydmF0aW9uIGluIHRoZSBkaXN0cmlidXRpb24gcmVwcmVzZW50cyB0aGUgcHJvcG9ydGlvbiBpbiBvbmUgc2FtcGxlIG9mIHBlb3BsZSB3aG8gcmVzcG9uZGVkICJEb2Vzbid0IEJlbmVmaXQuIg0KDQpXaGVuIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZWQgZnJvbSAxMCB0byA1MCwgdGhlIG1lYW4gYmVjYW1lIHRoZSBzYW1lIGFzIHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24sIGFuZCB0aGUgc3RhbmRhcmQgZXJyb3IgZGVjcmVhc2VkLiBBbHNvLCB0aGUgc2hhcGUgb2YgdGhlIGRpc3RyaWJ1dGlvbiBiZWNhbWUgbXVjaCBtb3JlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBXaGVuIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZWQgZnJvbSA1MCB0byAxMDAsIHRoZSBtZWFuIHJlbWFpbmVkIHRoZSBzYW1lIChlcXVhbCB0byB0aGUgcG9wdWxhdGlvbiBwcm9wb3J0aW9uKSwgYW5kIHRoZSBzdGFuZGFyZCBlcnJvciBkZWNyZWFzZWQuIEFsc28sIHRoZSBzaGFwZSBvZiB0aGUgZGlzdHJpYnV0aW9uIHN0YXllZCBub3JtYWxseSBkaXN0cmlidXRlZC4NCg0KSW5jcmVhc2luZyB0aGUgbnVtYmVyIG9mIHNpbXVsYXRpb25zIGJhcmVseSBjaGFuZ2VkIHRoZSBtZWFuIG9yIHN0YW5kYXJkIGVycm9yLCBidXQgdGhlIGRpc3RyaWJ1dGlvbnMgYmVjYW1lIG1vcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aCBhIGhpZ2hlciBudW1iZXIgb2Ygc2ltdWxhdGlvbnMuDQoNCmBgYHtyIGV4ZXJjaXNlLTYsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0UsIHJlc3VsdHMgPSBUUlVFfQ0KIyBUaGlzIFIgY2h1bmsgd2lsbCBvbmx5IHJ1biBpbiBpbnRlcmFjdGl2ZSBtb2RlLg0Kc2hpbnlBcHAoDQogIHVpIDwtIGZsdWlkUGFnZSgNCiAgICANCiAgICAjIFNpZGViYXIgd2l0aCBhIHNsaWRlciBpbnB1dCBmb3IgbnVtYmVyIG9mIGJpbnMgDQogICAgc2lkZWJhckxheW91dCgNCiAgICAgIHNpZGViYXJQYW5lbCgNCiAgICAgICAgDQogICAgICAgIHNlbGVjdElucHV0KCJvdXRjb21lIiwNCiAgICAgICAgICAgICAgICAgICAgIk91dGNvbWUgb2YgaW50ZXJlc3Q6IiwNCiAgICAgICAgICAgICAgICAgICAgY2hvaWNlcyA9IGMoIkJlbmVmaXRzIiwgIkRvZXNuJ3QgYmVuZWZpdCIpLA0KICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZCA9ICJEb2Vzbid0IGJlbmVmaXQiKSwNCiAgICAgICAgDQogICAgICAgIG51bWVyaWNJbnB1dCgibl9zYW1wIiwNCiAgICAgICAgICAgICAgICAgICAgICJTYW1wbGUgc2l6ZToiLA0KICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwNCiAgICAgICAgICAgICAgICAgICAgIG1heCA9IG5yb3coZ2xvYmFsX21vbml0b3IpLA0KICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAzMCksDQogICAgICAgIA0KICAgICAgICBudW1lcmljSW5wdXQoIm5fcmVwIiwNCiAgICAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2Ygc2FtcGxlczoiLA0KICAgICAgICAgICAgICAgICAgICAgbWluID0gMSwNCiAgICAgICAgICAgICAgICAgICAgIG1heCA9IDMwMDAwLA0KICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAxNTAwMCksDQogICAgICAgIA0KICAgICAgICBocigpLA0KICAgICAgICANCiAgICAgICAgc2xpZGVySW5wdXQoImJpbndpZHRoIiwNCiAgICAgICAgICAgICAgICAgICAgIkJpbndpZHRoOiIsDQogICAgICAgICAgICAgICAgICAgIG1pbiA9IDAsIG1heCA9IDAuNSwNCiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAwLjAyLA0KICAgICAgICAgICAgICAgICAgICBzdGVwID0gMC4wMDUpDQogICAgICAgIA0KICAgICAgKSwNCiAgICAgIA0KICAgICAgIyBTaG93IGEgcGxvdCBvZiB0aGUgZ2VuZXJhdGVkIGRpc3RyaWJ1dGlvbg0KICAgICAgbWFpblBhbmVsKA0KICAgICAgICBwbG90T3V0cHV0KCJzYW1wbGluZ19wbG90IiksDQogICAgICAgIHRleHRPdXRwdXQoInNhbXBsaW5nX21lYW4iKSwNCiAgICAgICAgdGV4dE91dHB1dCgic2FtcGxpbmdfc2UiKQ0KICAgICAgKQ0KICAgICkNCiAgKSwNCiAgDQogIHNlcnZlciA8LSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0KSB7DQogICAgDQogICAgIyBjcmVhdGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uDQogICAgc2FtcGxpbmdfZGlzdCA8LSByZWFjdGl2ZSh7DQogICAgICBnbG9iYWxfbW9uaXRvciAlPiUNCiAgICAgICAgcmVwX3NhbXBsZV9uKHNpemUgPSBpbnB1dCRuX3NhbXAsIHJlcHMgPSBpbnB1dCRuX3JlcCwgcmVwbGFjZSA9IFRSVUUpICU+JQ0KICAgICAgICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgIGZpbHRlcihzY2llbnRpc3Rfd29yayA9PSBpbnB1dCRvdXRjb21lKQ0KICAgIH0pDQogICAgDQogICAgIyBwbG90IHNhbXBsaW5nIGRpc3RyaWJ1dGlvbg0KICAgIG91dHB1dCRzYW1wbGluZ19wbG90IDwtIHJlbmRlclBsb3Qoew0KICAgICAgDQogICAgICBnZ3Bsb3Qoc2FtcGxpbmdfZGlzdCgpLCBhZXMoeCA9IHBfaGF0KSkgKw0KICAgICAgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IGlucHV0JGJpbndpZHRoKSArDQogICAgICAgIHhsaW0oMCwgMSkgKw0KICAgICAgICBsYWJzKA0KICAgICAgICAgIHggPSBwYXN0ZTAoInBfaGF0ICgiLCBpbnB1dCRvdXRjb21lLCAiKSIpLA0KICAgICAgICAgIHRpdGxlID0gIlNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBwX2hhdCIsDQogICAgICAgICAgc3VidGl0bGUgPSBwYXN0ZTAoIlNhbXBsZSBzaXplID0gIiwgaW5wdXQkbl9zYW1wLCAiIE51bWJlciBvZiBzYW1wbGVzID0gIiwgaW5wdXQkbl9yZXApDQogICAgICAgICkgKw0KICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNikpDQogICAgfSkNCiAgICANCiAgICBnZ3Bsb3QoZGF0YSA9IHNhbXBsZV9wcm9wczUwLCBhZXMoeCA9IHBfaGF0KSkgKw0KICAgICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAyKSArDQogICAgICBsYWJzKA0KICAgICAgICB4ID0gInBfaGF0IChEb2Vzbid0IGJlbmVmaXQpIiwNCiAgICAgICAgdGl0bGUgPSAiU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHBfaGF0IiwNCiAgICAgICAgc3VidGl0bGUgPSAiU2FtcGxlIHNpemUgPSA1MCwgTnVtYmVyIG9mIHNhbXBsZXMgPSAxNTAwMCINCiAgICAgICkNCiAgICANCiAgICAjIG1lYW4gb2Ygc2FtcGxpbmcgZGlzdHJpYnV0aW9uDQogICAgb3V0cHV0JHNhbXBsaW5nX21lYW4gPC0gcmVuZGVyVGV4dCh7DQogICAgICBwYXN0ZTAoIk1lYW4gb2Ygc2FtcGxpbmcgZGlzdHJpYnV0aW9uID0gIiwgcm91bmQobWVhbihzYW1wbGluZ19kaXN0KCkkcF9oYXQpLCAyKSkNCiAgICB9KQ0KICAgIA0KICAgICMgbWVhbiBvZiBzYW1wbGluZyBkaXN0cmlidXRpb24NCiAgICBvdXRwdXQkc2FtcGxpbmdfc2UgPC0gcmVuZGVyVGV4dCh7DQogICAgICBwYXN0ZTAoIlNFIG9mIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiA9ICIsIHJvdW5kKHNkKHNhbXBsaW5nX2Rpc3QoKSRwX2hhdCksIDIpKQ0KICAgIH0pDQogIH0sDQogIA0KICBvcHRpb25zID0gbGlzdChoZWlnaHQgPSA5MDApIA0KKQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDcNCg0KIyMjIFRha2UgYSBzYW1wbGUgb2Ygc2l6ZSAxNSBmcm9tIHRoZSBwb3B1bGF0aW9uIGFuZCBjYWxjdWxhdGUgdGhlIHByb3BvcnRpb24gb2YgcGVvcGxlIGluIHRoaXMgc2FtcGxlIHdobyB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGVuaGFuY2VzIHRoZWlyIGxpdmVzLiBVc2luZyB0aGlzIHNhbXBsZSwgd2hhdCBpcyB5b3VyIGJlc3QgcG9pbnQgZXN0aW1hdGUgb2YgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbiBvZiBwZW9wbGUgd2hvIHRoaW5rIHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gZW5jaGFuY2VzIHRoZWlyIGxpdmVzPw0KDQpUaGUgZXN0aW1hdGUgSSBjYWxjdWxhdGVkIGZyb20gdGhpcyBzYW1wbGUgd2FzIGFib3V0IDAuNzMuDQoNCmBgYHtyIGV4ZXJjaXNlLTd9DQpzZXQuc2VlZCgxMjM0KQ0KDQpzYW1wMSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oMTUpDQoNCmdncGxvdChzYW1wMSwgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiRG8geW91IGJlbGlldmUgdGhhdCB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXQgcGVvcGxlIGxpa2UgeW91PyINCiAgKSArDQogIGNvb3JkX2ZsaXAoKSANCg0Kc2FtcDEgJT4lDQogIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKQ0KDQoNCmBgYA0KDQojIyBFeGVyY2lzZSA4DQoNCiMjIyBTaW5jZSB5b3UgaGF2ZSBhY2Nlc3MgdG8gdGhlIHBvcHVsYXRpb24sIHNpbXVsYXRlIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcHJvcG9ydGlvbiBvZiB0aG9zZSB3aG8gdGhpbmsgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBlbmNoYW5jZXMgdGhlaXIgbGl2ZXMgZm9yIHNhbXBsZXMgb2Ygc2l6ZSAxNSBieSB0YWtpbmcgMjAwMCBzYW1wbGVzIGZyb20gdGhlIHBvcHVsYXRpb24gb2Ygc2l6ZSAxNSBhbmQgY29tcHV0aW5nIDIwMDAgc2FtcGxlIHByb3BvcnRpb25zLiBTdG9yZSB0aGVzZSBwcm9wb3J0aW9ucyBpbiBhcyBzYW1wbGVfcHJvcHMxNS4gUGxvdCB0aGUgZGF0YSwgdGhlbiBkZXNjcmliZSB0aGUgc2hhcGUgb2YgdGhpcyBzYW1wbGluZyBkaXN0cmlidXRpb24uIEJhc2VkIG9uIHRoaXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCB3aGF0IHdvdWxkIHlvdSBndWVzcyB0aGUgdHJ1ZSBwcm9wb3J0aW9uIG9mIHRob3NlIHdobyB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGVuY2hhbmNlcyB0aGVpciBsaXZlcyB0byBiZT8gRmluYWxseSwgY2FsY3VsYXRlIGFuZCByZXBvcnQgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbi4NCg0KVGhpcyBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgbGVmdC1za2V3ZWQuDQoNCkkgd291bGQgZ3Vlc3MgdGhhdCB0aGUgdHJ1ZSBwcm9wb3J0aW9uIGlzIDAuODAuIFRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24gaXMgYWN0dWFsbHkgMC44MDM0MzMzLg0KDQpgYGB7ciBleGVyY2lzZS04fQ0KDQpzYW1wbGVfcHJvcHMxNSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgICAgICAgICAgICAgICAgICAgcmVwX3NhbXBsZV9uKHNpemUgPSAxNSwgcmVwcyA9IDIwMDAsIHJlcGxhY2UgPSBUUlVFKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICAgICAgICAgICAgICAgICAgICBtdXRhdGUocF9oYXQgPSBuIC9zdW0obikpICU+JQ0KICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoc2NpZW50aXN0X3dvcmsgPT0gIkJlbmVmaXRzIikNCg0KZ2dwbG90KGRhdGEgPSBzYW1wbGVfcHJvcHMxNSwgYWVzKHggPSBwX2hhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAyKSArDQogIGxhYnMoDQogICAgeCA9ICJwX2hhdCAoQmVuZWZpdHMpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTUsIE51bWJlciBvZiBzYW1wbGVzID0gMjAwMCINCiAgKQ0KDQptZWFuKHNhbXBsZV9wcm9wczE1JHBfaGF0KQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDkNCg0KIyMjIENoYW5nZSB5b3VyIHNhbXBsZSBzaXplIGZyb20gMTUgdG8gMTUwLCB0aGVuIGNvbXB1dGUgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB1c2luZyB0aGUgc2FtZSBtZXRob2QgYXMgYWJvdmUsIGFuZCBzdG9yZSB0aGVzZSBwcm9wb3J0aW9ucyBpbiBhIG5ldyBvYmplY3QgY2FsbGVkIHNhbXBsZV9wcm9wczE1MC4gRGVzY3JpYmUgdGhlIHNoYXBlIG9mIHRoaXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGFuZCBjb21wYXJlIGl0IHRvIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gZm9yIGEgc2FtcGxlIHNpemUgb2YgMTUuIEJhc2VkIG9uIHRoaXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCB3aGF0IHdvdWxkIHlvdSBndWVzcyB0byBiZSB0aGUgdHJ1ZSBwcm9wb3J0aW9uIG9mIHRob3NlIHdobyB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGVuY2hhbmNlcyB0aGVpciBsaXZlcz8NCg0KVGhpcyBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgYWJvdXQgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIEl0IGlzIG11Y2ggbW9yZSBub3JtYWwgdGhhbiB0aGUgZGlzdHJpYnV0aW9uIGZvciBhIHNhbXBsZSBzaXplIG9mIDE1Lg0KDQpJIHdvdWxkIGd1ZXNzIHRoZSB0cnVlIHByb3BvcnRpb24gb2YgdGhvc2Ugd2hvIHRoaW5rIHNjaWVudGlzdHMgZW5oYW5jZSBsaXZlcyBpcyBhYm91dCAwLjgwLg0KDQpgYGB7ciBleGVyY2lzZS05fQ0KDQpzYW1wbGVfcHJvcHMxNTAgPC0gZ2xvYmFsX21vbml0b3IgJT4lDQogICAgICAgICAgICAgICAgICAgIHJlcF9zYW1wbGVfbihzaXplID0gMTUwLCByZXBzID0gMjAwMCwgcmVwbGFjZSA9IFRSVUUpICU+JQ0KICAgICAgICAgICAgICAgICAgICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgICAgICAgICAgICAgIGZpbHRlcihzY2llbnRpc3Rfd29yayA9PSAiQmVuZWZpdHMiKQ0KDQpnZ3Bsb3QoZGF0YSA9IHNhbXBsZV9wcm9wczE1MCwgYWVzKHggPSBwX2hhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAyKSArDQogIGxhYnMoDQogICAgeCA9ICJwX2hhdCAoQmVuZWZpdHMpIiwNCiAgICB0aXRsZSA9ICJTYW1wbGluZyBkaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTUwLCBOdW1iZXIgb2Ygc2FtcGxlcyA9IDIwMDAiDQogICkNCg0KYGBgDQoNCiMjIEV4ZXJjaXNlIDEwDQoNCiMjIyBPZiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBmcm9tIDIgYW5kIDMsIHdoaWNoIGhhcyBhIHNtYWxsZXIgc3ByZWFkPyBJZiB5b3UncmUgY29uY2VybmVkIHdpdGggbWFraW5nIGVzdGltYXRlcyB0aGF0IGFyZSBtb3JlIG9mdGVuIGNsb3NlIHRvIHRoZSB0cnVlIHZhbHVlLCB3b3VsZCB5b3UgcHJlZmVyIGEgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHdpdGggYSBsYXJnZSBvciBzbWFsbCBzcHJlYWQ/DQoNClRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gZnJvbSBleGVyY2lzZSA5IGhhcyBhIHNtYWxsZXIgc3ByZWFkLiBJIHdvdWxkIHByZWZlciBhIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB3aXRoIGEgc21hbGwgc3ByZWFkLCBiZWNhdXNlIGl0IGlzIG1vcmUgbGlrZWx5IHRvIGJlIG1vcmUgYWNjdXJhdGUuIERpc3RyaWJ1dGlvbnMgd2l0aCBhIHNtYWxsIHNwcmVhZCBoYXZlIGxlc3Mgb2YgYW4gZXJyb3IgdHlwaWNhbGx5LiBBbHNvLCBpbiB0aGUgZXhhbXBsZXMgSSBoYXZlIGRvbmUsIHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24gd2FzIGF0IHRoZSBjZW50ZXIgb2YgdGhlIGRpc3RyaWJ1dGlvbnMgd2l0aCBsZXNzIHNwcmVhZCBhbmQgd2l0aCBtb3JlIHNwcmVhZCwgc28gaXQgcHJvYmFibHkgZG9lcyBub3QgbWF0dGVyIHdoaWNoIG9uZSBpcyB1c2VkLiBVc2luZyBhIGRpc3RyaWJ1dGlvbiB3aXRoIG1vcmUgc3ByZWFkIHdpbGwgbW9yZSBsaWtlbHkgY29udGFpbiB0aGUgdHJ1ZSBwcm9wb3J0aW9uLCBidXQgdGhlIGNlbnRlciBvZiB0aGUgZGlzdHJpYnV0aW9uIG1pZ2h0IG5vdCBiZSBhcyBhY2N1cmF0ZSBhcyBvbmUgd2l0aCBsZXNzIHNwcmVhZC4NCg==