library(tidyverse)
library(openintro)
library(infer)
set.seed(110)
#Create population assuming population size of 100,000.  20% think the work of scientists do not benefit them; 80% think the work does benefit them. Dataframe:  global_monitor; scientist_work:  variable that contains responses to the question "Do you believe that the work scientists do benefit you?"

global_monitor <- tibble(
  scientist_work = c(rep("Benefits", 80000), rep("Doesn't benefit", 20000))
)

Visualize the distribution of these responses by using a bar plot.

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() 

Obtain summary statistics to confirm the data frame was constructed correctly. …

global_monitor %>%
  count(scientist_work) %>%
  mutate(p = n /sum(n))
## # A tibble: 2 x 3
##   scientist_work      n     p
## * <chr>           <int> <dbl>
## 1 Benefits        80000   0.8
## 2 Doesn't benefit 20000   0.2

In this lab, you have access to the entire population, but this is rarely the case in real life. Gathering information on an entire population is often extremely costly or impossible. Because of this, we often take a sample of the population and use that to understand the properties of the population.

If you are interested in estimating the proportion of people who don’t think the work scientists do benefits them, you can use the sample_n command to survey the population.

This command collects a simple random sample of size 50 from the global_monitor dataset, and assigns the result to samp1. This is similar to randomly drawing names from a hat that contains the names of all in the population. Working with these 50 names is considerably simpler than working with all 100,000 people in the population.

#take sample of entire population of global_monitor
set.seed(1)
samp1 <- global_monitor %>%
  sample_n(50)

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 summarising 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.

Answer 1. Visualize the distribution of the sample by using a bar plot (see below). 2. Obtain summary statistics to confirm the data frame was constructed correctly (see below).

When using the population, 80% believed scientists work benefits while 20% believed it does not. When using the random sample of 50, 76% believed it benefits while 24% believed it did not.

I moved the “seed” code inside each R-chunk and re-executed, and the numbers changed. While similar, the sample is still a bit different
than the population.

#Visualize the distribution of the sample by using a bar plot.
set.seed(1)
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()

Obtain summary statistics to confirm the data frame was constructed correctly.

set.seed(1)
samp1 %>%
  count(scientist_work) %>%
  mutate(s = n /sum(n))
## # A tibble: 2 x 3
##   scientist_work      n     s
## * <chr>           <int> <dbl>
## 1 Benefits           38  0.76
## 2 Doesn't benefit    12  0.24

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.

**Answer With the first test I ran, I had 6 that “doesn’t benefit” and 44 that “benefits.” When I re-ran the test, I had 12 that “doesn’t benefit” and 38 that “benefits.” It was a jump from 12% to 24% for “doesn’t benefit.” It was a decrease from 88% to 76% for “benefits.” I would expect the sample proportion to be quite different from another student’s.

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?

**Answer: With Samp2(50) and different seeds set initially inside each R-chunk, the sample was like the original population (20% does not benefit; 80% does benefit)

With Samp3(100) and different seeds set initially inside each R-chunk, the sample was a little lower with 18% “not benefit” and 82% “does benefit.”

With Samp4(1,000) and different seeds set initially inside each R-chunk, the sample showed .791 and .209 for “benefits” and “not benefit”, respectively. The larger the sample, the more accurate the estimate of the population as seen in Samp4.

By increasing the number of samples tested, we can get a more accurate estimate of the population proportion. Samp3 with 100 or Samp4 with 1,000 might be best.

#second sample, also of size 50, and call it samp2
set.seed(11)
samp2 <- global_monitor %>%
  sample_n(50)
#Visualize the distribution of the sample by using a bar plot.
set.seed(1)
ggplot(samp2, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Sample 2:  Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip()

set.seed(4)
samp2 %>%
  count(scientist_work) %>%
  mutate(s = n /sum(n))
## # A tibble: 2 x 3
##   scientist_work      n     s
## * <chr>           <int> <dbl>
## 1 Benefits           40   0.8
## 2 Doesn't benefit    10   0.2
#third sample, 100, and call it samp3
set.seed(222)
samp3 <- global_monitor %>%
  sample_n(100)
#Visualize the distribution of the sample by using a bar plot.
set.seed(333)
ggplot(samp3, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Sample 3:  Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip()

set.seed(444)
samp3 %>%
  count(scientist_work) %>%
  mutate(s = n /sum(n))
## # A tibble: 2 x 3
##   scientist_work      n     s
## * <chr>           <int> <dbl>
## 1 Benefits           82  0.82
## 2 Doesn't benefit    18  0.18
#fourth sample, 1000, and call it samp4
set.seed(222)
samp4 <- global_monitor %>%
  sample_n(1000)
#Visualize the distribution of the sample by using a bar plot.
set.seed(444)
ggplot(samp4, aes(x = scientist_work)) +
  geom_bar() +
  labs(
    x = "", y = "",
    title = "Sample 4:  Do you believe that the work scientists do benefit people like you?"
  ) +
  coord_flip()

set.seed(555)
samp4 %>%
  count(scientist_work) %>%
  mutate(s = n /sum(n))
## # A tibble: 2 x 3
##   scientist_work      n     s
## * <chr>           <int> <dbl>
## 1 Benefits          791 0.791
## 2 Doesn't benefit   209 0.209

Every time you take another random sample, you might get a different sample proportion. It’s useful to get a sense of just how much variability you should expect when estimating the population mean this way. The distribution of sample proportions, called the sampling distribution (of the proportion), can help you understand this variability.

#take 15,000 different samples of size 50 from the population
#rep_sample_n function is for repetition. Rather than taking a single sample of size n (50) from the population of all people in the population, repeat this sampling procedure rep times in order to build a distribution of a series of sample statistics, which is called the sampling distribution.
#calculate the proportion of responses in each sample
#filter for only the "doesn't benefit" responses
#store each result in a vector called sample_props50
#replace = TRUE since sampling distributions are constructed by sampling with replacement.

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")

Visualize the distribution of these proportions with a histogram.

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 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.

Answer There are 15,000 elements in sample_props50. Around 20% (3,000 of the 15,000 elements in sample_props50) believe scientist work doesn’t benefit. The mean is appears to be about the same as the original dataset and more concentrated than the graph above.

set.seed(555)
ggplot(sample_props50, aes(x = p_hat)) +
  geom_bar() +
  labs(
    x = "p_hat   Doesn't Benefit", y = "Count",
    title = "Sample _props50:  Sampling Distribution of p_hat"
  ) +
  coord_flip()

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?

**Answer: There are 25 samples, each with 10 observations. See below.
Each element is the mean of 25 random samples.

#take 25 different samples of size 10 from the population
#rep_sample_n function is for repetition. Rather than taking a single sample of size n (10) from the population of all people in the population, repeat this sampling procedure rep times in order to build a distribution of a series of sample statistics, which is called the sampling distribution.
#calculate the proportion of responses in each sample
#filter for only the "doesn't benefit" responses
#store each result in a vector called sample_propssmall
#replace = TRUE since sampling distributions are constructed by sampling with replacement.


sample_propssmall <- 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")

Visualize the distribution of these proportions with a histogram.

set.seed(555)
ggplot(sample_propssmall, aes(x = p_hat)) +
  geom_bar() +
  labs(
    x = "p_hat   Doesn't Benefit", y = "Count",
    title = "Sample _propssmall:  Sampling Distribution of p_hat",
    subtitle = "Sample size = 10, Number of samples = 25"
  ) +
  coord_flip()

The sampling distribution computed below tells a lot about estimating the true proportion of people who think that the work scientists do doesn’t benefit them. Because the sample proportion is an unbiased estimator, the sampling distribution is centered at the true population proportion, and the spread of the distribution indicates how much variability is incurred by sampling only 50 people at a time from the population.

#rep_sample_n function: to compute a sampling distribution, specifically, the sampling distribution of the proportions from samples of 50 people.

ggplot(data = sample_props50, aes(x = p_hat)) +
  geom_histogram(binwidth = 0.02)

Exercise 6

Use the app to get a sense of the effect that sample size has on sampling distribution.

Use the app 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.)

**Answer n = 10; reps=5,000; mean = .22; SE = .11 n = 50; reps=5,000; mean = .2; SE = .06 - by increasing the sample size, there was a change in the mean and notable change in SE; n =100; reps=5,000; mean = .2; SE = .04 - by increasing the sample size, there was a change in the mean and SE n =100;reps=10,000; mean = .2; SE = .04 - by increasing the reps, there was no change in the mean and SE n =100;reps=50,000; mean = .2; SE = .04 - by increasing the reps, there was no change in the mean and SE

When the sample size increases, the distribution becomes more normal. The mean (center point of the distribution) is more accurate when the sample size is larger.

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 enhances their lives?

**Answer:
If the sampling distribution is centered at the true population proportion, it looks like around 80% of the population believe the work of scientists enhance their lives. My best point estimate is approximately .8

FYI, I attempted using a rep = to 1, but that didn’t work. Instead, I used reps = 25.

#take 25 different samples of size 15 from the population
#rep_sample_n function is for repetition. Rather than taking a single sample of size n (15) from the population of all people in the population, repeat this sampling procedure rep times in order to build a distribution of a series of sample statistics, which is called the sampling distribution.
#calculate the proportion of responses in each sample
#filter for only the "benefist" responses
#store each result in a vector called sample_props15a
#replace = TRUE since sampling distributions are constructed by sampling with replacement.


sample_props15a <- global_monitor %>%
                    rep_sample_n(size = 15, reps = 25, replace = TRUE) %>%
                    count(scientist_work) %>%
                    mutate(p_hat = n /sum(n)) %>%
                    filter(scientist_work == "Benefits")

Visualize with a histogram

set.seed(575)
ggplot(sample_props15a, aes(x = p_hat)) +
  geom_bar() +
  labs(
    x = "p_hat   Benefits", y = "Count",
    title = "Sample _props15a:  Sampling Distribution of p_hat",
    subtitle = "Sample size = 15, Number of samples = 25"
  ) +
  coord_flip()

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.

**Answer I would expect the sampling distribution is centered at the true population proportion (sample mean to be somewhat like population mean), 80% from the 2,000 samples believe scientists work do enhance their lives.

#take 2000 different samples of size 15 from the population
#rep_sample_n function is for repetition. Rather than taking a single sample of size n (15) from the population of all people in the population, repeat this sampling procedure rep times in order to build a distribution of a series of sample statistics, which is called the sampling distribution.
#calculate the proportion of responses in each sample
#filter for only the "benefits" responses
#store each result in a vector called sampl_props15
#replace = TRUE since sampling distributions are constructed by sampling with replacement.


sampl_props15 <- global_monitor %>%
                    rep_sample_n(size = 15, reps = 2000, replace = TRUE) %>%
                    count(scientist_work) %>%
                    mutate(s_hat = n /sum(n)) %>%
                    filter(scientist_work == "Benefits")

Visualize with a histogram

set.seed(575)
ggplot(sampl_props15, aes(x = s_hat)) +
  geom_bar() +
  labs(
    x = "s_hat   Benefits", y = "Count",
    title = "Sampl _props15:  Sampling Distribution of p_hat",
    subtitle = "Sample size = 15, Number of samples = 2000"
  ) +
  coord_flip()

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?

**Answer

The mean of the sample size of 150 is more concentrated than that of sample size 15. The mean appears to be a better estimate with the increased sample size.

#take 2000 different samples of size 150 from the population
#rep_sample_n function is for repetition. Rather than taking a single sample of size n (150) from the population of all people in the population, repeat this sampling procedure rep times in order to build a distribution of a series of sample statistics, which is called the sampling distribution.
#calculate the proportion of responses in each sample
#filter for only the "benefits" responses
#store each result in a vector called sampl_props150
#replace = TRUE since sampling distributions are constructed by sampling with replacement.


sampl_props150 <- global_monitor %>%
                    rep_sample_n(size = 150, reps = 2000, replace = TRUE) %>%
                    count(scientist_work) %>%
                    mutate(s_hat = n /sum(n)) %>%
                    filter(scientist_work == "Benefits")

Visualize with a histogram

set.seed(575)
ggplot(sampl_props150, aes(x = s_hat)) +
  geom_bar() +
  labs(
    x = "s_hat   Benefits", y = "Count",
    title = "Sampl _props150:  Sampling Distribution of p_hat",
    subtitle = "Sample size = 150, Number of samples = 2000"
  ) +
  coord_flip()

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?

**Answer The larger sample size has a smaller spread and would be preferable for a sampling distribution. Above, when working in Exercises 2 and 3, we were working with samples of 50 and 100. The sample with 100 has a smaller spread.

LS0tDQp0aXRsZTogIkludHJvZHVjdGlvbiB0byBJbmZlcmVuY2UiDQphdXRob3I6ICJBYXJ5biBaaW1tZXJtYW4iDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydA0KLS0tDQoNCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkob3BlbmludHJvKQ0KbGlicmFyeShpbmZlcikNCnNldC5zZWVkKDExMCkNCmBgYA0KDQoNCmBgYHtyfQ0KI0NyZWF0ZSBwb3B1bGF0aW9uIGFzc3VtaW5nIHBvcHVsYXRpb24gc2l6ZSBvZiAxMDAsMDAwLiAgMjAlIHRoaW5rIHRoZSB3b3JrIG9mIHNjaWVudGlzdHMgZG8gbm90IGJlbmVmaXQgdGhlbTsgODAlIHRoaW5rIHRoZSB3b3JrIGRvZXMgYmVuZWZpdCB0aGVtLiBEYXRhZnJhbWU6ICBnbG9iYWxfbW9uaXRvcjsgc2NpZW50aXN0X3dvcms6ICB2YXJpYWJsZSB0aGF0IGNvbnRhaW5zIHJlc3BvbnNlcyB0byB0aGUgcXVlc3Rpb24gIkRvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHlvdT8iDQoNCmdsb2JhbF9tb25pdG9yIDwtIHRpYmJsZSgNCiAgc2NpZW50aXN0X3dvcmsgPSBjKHJlcCgiQmVuZWZpdHMiLCA4MDAwMCksIHJlcCgiRG9lc24ndCBiZW5lZml0IiwgMjAwMDApKQ0KKQ0KYGBgDQoNCg0KVmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlc2UgcmVzcG9uc2VzIGJ5IHVzaW5nIGEgYmFyIHBsb3QuDQoNCmBgYHtyIGNvZGUtY2h1bmstbGFiZWx9DQpnZ3Bsb3QoZ2xvYmFsX21vbml0b3IsIGFlcyh4ID0gc2NpZW50aXN0X3dvcmspKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKA0KICAgIHggPSAiIiwgeSA9ICIiLA0KICAgIHRpdGxlID0gIkRvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHBlb3BsZSBsaWtlIHlvdT8iDQogICkgKw0KICBjb29yZF9mbGlwKCkgDQpgYGANCk9idGFpbiBzdW1tYXJ5IHN0YXRpc3RpY3MgdG8gY29uZmlybSB0aGUgZGF0YSBmcmFtZSB3YXMgY29uc3RydWN0ZWQgY29ycmVjdGx5Lg0KLi4uDQpgYGB7cn0NCmdsb2JhbF9tb25pdG9yICU+JQ0KICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogIG11dGF0ZShwID0gbiAvc3VtKG4pKQ0KYGBgDQoNCkluIHRoaXMgbGFiLCB5b3UgaGF2ZSBhY2Nlc3MgdG8gdGhlIGVudGlyZSBwb3B1bGF0aW9uLCBidXQgdGhpcyBpcyByYXJlbHkgdGhlIGNhc2UgaW4gcmVhbCBsaWZlLiBHYXRoZXJpbmcgaW5mb3JtYXRpb24gb24gYW4gZW50aXJlIHBvcHVsYXRpb24gaXMgb2Z0ZW4gZXh0cmVtZWx5IGNvc3RseSBvciBpbXBvc3NpYmxlLiBCZWNhdXNlIG9mIHRoaXMsIHdlIG9mdGVuIHRha2UgYSBzYW1wbGUgb2YgdGhlIHBvcHVsYXRpb24gYW5kIHVzZSB0aGF0IHRvIHVuZGVyc3RhbmQgdGhlIHByb3BlcnRpZXMgb2YgdGhlIHBvcHVsYXRpb24uDQoNCklmIHlvdSBhcmUgaW50ZXJlc3RlZCBpbiBlc3RpbWF0aW5nIHRoZSBwcm9wb3J0aW9uIG9mIHBlb3BsZSB3aG8gZG9u4oCZdCB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXRzIHRoZW0sIHlvdSBjYW4gdXNlIHRoZSBzYW1wbGVfbiBjb21tYW5kIHRvIHN1cnZleSB0aGUgcG9wdWxhdGlvbi4NCg0KVGhpcyBjb21tYW5kIGNvbGxlY3RzIGEgc2ltcGxlIHJhbmRvbSBzYW1wbGUgb2Ygc2l6ZSA1MCBmcm9tIHRoZSBnbG9iYWxfbW9uaXRvciBkYXRhc2V0LCBhbmQgYXNzaWducyB0aGUgcmVzdWx0IHRvIHNhbXAxLiBUaGlzIGlzIHNpbWlsYXIgdG8gcmFuZG9tbHkgZHJhd2luZyBuYW1lcyBmcm9tIGEgaGF0IHRoYXQgY29udGFpbnMgdGhlIG5hbWVzIG9mIGFsbCBpbiB0aGUgcG9wdWxhdGlvbi4gV29ya2luZyB3aXRoIHRoZXNlIDUwIG5hbWVzIGlzIGNvbnNpZGVyYWJseSBzaW1wbGVyIHRoYW4gd29ya2luZyB3aXRoIGFsbCAxMDAsMDAwIHBlb3BsZSBpbiB0aGUgcG9wdWxhdGlvbi4NCg0KYGBge3J9DQojdGFrZSBzYW1wbGUgb2YgZW50aXJlIHBvcHVsYXRpb24gb2YgZ2xvYmFsX21vbml0b3INCnNldC5zZWVkKDEpDQpzYW1wMSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oNTApDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDENCg0KRGVzY3JpYmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiByZXNwb25zZXMgaW4gdGhpcyBzYW1wbGUuIEhvdyBkb2VzIGl0IGNvbXBhcmUgdG8gdGhlIGRpc3RyaWJ1dGlvbiBvZiByZXNwb25zZXMgaW4gdGhlIHBvcHVsYXRpb24uIEhpbnQ6IEFsdGhvdWdoIHRoZSBzYW1wbGVfbiBmdW5jdGlvbiB0YWtlcyBhIHJhbmRvbSBzYW1wbGUgb2Ygb2JzZXJ2YXRpb25zIChpLmUuIHJvd3MpIGZyb20gdGhlIGRhdGFzZXQsIHlvdSBjYW4gc3RpbGwgcmVmZXIgdG8gdGhlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldCB3aXRoIHRoZSBzYW1lIG5hbWVzLiBDb2RlIHlvdSBwcmVzZW50ZWQgZWFybGllciBmb3IgdmlzdWFsaXppbmcgYW5kIHN1bW1hcmlzaW5nIHRoZSBwb3B1bGF0aW9uIGRhdGEgd2lsbCBzdGlsbCBiZSB1c2VmdWwgZm9yIHRoZSBzYW1wbGUsIGhvd2V2ZXIgYmUgY2FyZWZ1bCB0byBub3QgbGFiZWwgeW91ciBwcm9wb3J0aW9uIHAgc2luY2UgeW914oCZcmUgbm93IGNhbGN1bGF0aW5nIGEgc2FtcGxlIHN0YXRpc3RpYywgbm90IGEgcG9wdWxhdGlvbiBwYXJhbWV0ZXJzLiBZb3UgY2FuIGN1c3RvbWl6ZSB0aGUgbGFiZWwgb2YgdGhlIHN0YXRpc3RpY3MgdG8gaW5kaWNhdGUgdGhhdCBpdCBjb21lcyBmcm9tIHRoZSBzYW1wbGUuDQoNCg0KKipBbnN3ZXIqKg0KICAgMS4gIFZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBzYW1wbGUgYnkgdXNpbmcgYSBiYXIgcGxvdCAoc2VlIGJlbG93KS4NCiAgIDIuICBPYnRhaW4gc3VtbWFyeSBzdGF0aXN0aWNzIHRvIGNvbmZpcm0gdGhlIGRhdGEgZnJhbWUgd2FzIGNvbnN0cnVjdGVkIGNvcnJlY3RseSAoc2VlIGJlbG93KS4NCiAgIA0KICAgV2hlbiB1c2luZyB0aGUgcG9wdWxhdGlvbiwgODAlIGJlbGlldmVkIHNjaWVudGlzdHMgd29yayBiZW5lZml0cyB3aGlsZSAyMCUgYmVsaWV2ZWQgaXQgZG9lcyBub3QuICBXaGVuIHVzaW5nIHRoZSByYW5kb20gc2FtcGxlIG9mIDUwLCA3NiUgDQogICBiZWxpZXZlZCBpdCBiZW5lZml0cyB3aGlsZSAyNCUgYmVsaWV2ZWQgaXQgZGlkIG5vdC4NCiAgIA0KICAgSSBtb3ZlZCB0aGUgInNlZWQiIGNvZGUgaW5zaWRlIGVhY2ggUi1jaHVuayBhbmQgcmUtZXhlY3V0ZWQsIGFuZCB0aGUgbnVtYmVycyBjaGFuZ2VkLiAgV2hpbGUgc2ltaWxhciwgdGhlIHNhbXBsZSBpcyBzdGlsbCBhIGJpdCBkaWZmZXJlbnQgIA0KICAgdGhhbiB0aGUgcG9wdWxhdGlvbi4gIA0KYGBge3J9DQojVmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBieSB1c2luZyBhIGJhciBwbG90Lg0Kc2V0LnNlZWQoMSkNCmdncGxvdChzYW1wMSwgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiRG8geW91IGJlbGlldmUgdGhhdCB0aGUgd29yayBzY2llbnRpc3RzIGRvIGJlbmVmaXQgcGVvcGxlIGxpa2UgeW91PyINCiAgKSArDQogIGNvb3JkX2ZsaXAoKQ0KYGBgDQpPYnRhaW4gc3VtbWFyeSBzdGF0aXN0aWNzIHRvIGNvbmZpcm0gdGhlIGRhdGEgZnJhbWUgd2FzIGNvbnN0cnVjdGVkIGNvcnJlY3RseS4NCg0KYGBge3J9DQpzZXQuc2VlZCgxKQ0Kc2FtcDEgJT4lDQogIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgbXV0YXRlKHMgPSBuIC9zdW0obikpDQpgYGANCg0KDQojIyMgRXhlcmNpc2UgMg0KV291bGQgeW91IGV4cGVjdCB0aGUgc2FtcGxlIHByb3BvcnRpb24gdG8gbWF0Y2ggdGhlIHNhbXBsZSBwcm9wb3J0aW9uIG9mIGFub3RoZXIgc3R1ZGVudOKAmXMgc2FtcGxlPyBXaHksIG9yIHdoeSBub3Q/IElmIHRoZSBhbnN3ZXIgaXMgbm8sIHdvdWxkIHlvdSBleHBlY3QgdGhlIHByb3BvcnRpb25zIHRvIGJlIHNvbWV3aGF0IGRpZmZlcmVudCBvciB2ZXJ5IGRpZmZlcmVudD8gQXNrIGEgc3R1ZGVudCB0ZWFtIHRvIGNvbmZpcm0geW91ciBhbnN3ZXIuDQoNCioqQW5zd2VyDQpXaXRoIHRoZSBmaXJzdCB0ZXN0IEkgcmFuLCBJIGhhZCA2IHRoYXQgImRvZXNuJ3QgYmVuZWZpdCIgYW5kIDQ0IHRoYXQgImJlbmVmaXRzLiIgV2hlbiBJIHJlLXJhbiB0aGUgdGVzdCwgSSBoYWQgMTIgdGhhdCAiZG9lc24ndCBiZW5lZml0IiBhbmQgMzggdGhhdCAiYmVuZWZpdHMuIiBJdCB3YXMgYSBqdW1wIGZyb20gMTIlIHRvIDI0JSBmb3IgImRvZXNuJ3QgYmVuZWZpdC4iIEl0IHdhcyBhIGRlY3JlYXNlIGZyb20gODglIHRvIDc2JSBmb3IgImJlbmVmaXRzLiIgIEkgd291bGQgZXhwZWN0IHRoZSBzYW1wbGUgcHJvcG9ydGlvbiB0byBiZSBxdWl0ZSBkaWZmZXJlbnQgZnJvbSBhbm90aGVyIHN0dWRlbnQncy4gIA0KDQoNCg0KIyMjIEV4ZXJjaXNlIDMNClRha2UgYSBzZWNvbmQgc2FtcGxlLCBhbHNvIG9mIHNpemUgNTAsIGFuZCBjYWxsIGl0IHNhbXAyLiBIb3cgZG9lcyB0aGUgc2FtcGxlIHByb3BvcnRpb24gb2Ygc2FtcDIgY29tcGFyZSB3aXRoIHRoYXQgb2Ygc2FtcDE/IFN1cHBvc2Ugd2UgdG9vayB0d28gbW9yZSBzYW1wbGVzLCBvbmUgb2Ygc2l6ZSAxMDAgYW5kIG9uZSBvZiBzaXplIDEwMDAuIFdoaWNoIHdvdWxkIHlvdSB0aGluayB3b3VsZCBwcm92aWRlIGEgbW9yZSBhY2N1cmF0ZSBlc3RpbWF0ZSBvZiB0aGUgcG9wdWxhdGlvbiBwcm9wb3J0aW9uPw0KDQoqKkFuc3dlcjoNCldpdGggU2FtcDIoNTApIGFuZCBkaWZmZXJlbnQgc2VlZHMgc2V0IGluaXRpYWxseSBpbnNpZGUgZWFjaCBSLWNodW5rLCB0aGUgc2FtcGxlIHdhcyBsaWtlIHRoZSBvcmlnaW5hbCBwb3B1bGF0aW9uICgyMCUgZG9lcyBub3QgYmVuZWZpdDsgODAlIGRvZXMgYmVuZWZpdCkNCg0KV2l0aCBTYW1wMygxMDApIGFuZCBkaWZmZXJlbnQgc2VlZHMgc2V0IGluaXRpYWxseSBpbnNpZGUgZWFjaCBSLWNodW5rLCB0aGUgc2FtcGxlIHdhcyBhIGxpdHRsZSBsb3dlciB3aXRoIDE4JSAibm90IGJlbmVmaXQiIGFuZCA4MiUgImRvZXMgYmVuZWZpdC4iDQoNCldpdGggU2FtcDQoMSwwMDApIGFuZCBkaWZmZXJlbnQgc2VlZHMgc2V0IGluaXRpYWxseSBpbnNpZGUgZWFjaCBSLWNodW5rLCB0aGUgc2FtcGxlIHNob3dlZCAuNzkxIGFuZCAuMjA5IGZvciAiYmVuZWZpdHMiIGFuZCAibm90IGJlbmVmaXQiLCByZXNwZWN0aXZlbHkuICBUaGUgbGFyZ2VyIHRoZSBzYW1wbGUsIHRoZSBtb3JlIGFjY3VyYXRlIHRoZSBlc3RpbWF0ZSBvZiB0aGUgcG9wdWxhdGlvbiBhcyBzZWVuIGluIFNhbXA0LiAgDQoNCg0KQnkgaW5jcmVhc2luZyB0aGUgbnVtYmVyIG9mIHNhbXBsZXMgdGVzdGVkLCB3ZSBjYW4gZ2V0IGEgbW9yZSBhY2N1cmF0ZSBlc3RpbWF0ZSBvZiB0aGUgcG9wdWxhdGlvbiBwcm9wb3J0aW9uLiAgU2FtcDMgd2l0aCAxMDAgb3IgU2FtcDQgd2l0aCAxLDAwMCBtaWdodCBiZSBiZXN0Lg0KYGBge3J9DQojc2Vjb25kIHNhbXBsZSwgYWxzbyBvZiBzaXplIDUwLCBhbmQgY2FsbCBpdCBzYW1wMg0Kc2V0LnNlZWQoMTEpDQpzYW1wMiA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oNTApDQpgYGANCg0KYGBge3J9DQojVmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBieSB1c2luZyBhIGJhciBwbG90Lg0Kc2V0LnNlZWQoMSkNCmdncGxvdChzYW1wMiwgYWVzKHggPSBzY2llbnRpc3Rfd29yaykpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICIiLCB5ID0gIiIsDQogICAgdGl0bGUgPSAiU2FtcGxlIDI6ICBEbyB5b3UgYmVsaWV2ZSB0aGF0IHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gYmVuZWZpdCBwZW9wbGUgbGlrZSB5b3U/Ig0KICApICsNCiAgY29vcmRfZmxpcCgpDQpgYGANCg0KYGBge3J9DQpzZXQuc2VlZCg0KQ0Kc2FtcDIgJT4lDQogIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgbXV0YXRlKHMgPSBuIC9zdW0obikpDQpgYGANCg0KYGBge3J9DQojdGhpcmQgc2FtcGxlLCAxMDAsIGFuZCBjYWxsIGl0IHNhbXAzDQpzZXQuc2VlZCgyMjIpDQpzYW1wMyA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgc2FtcGxlX24oMTAwKQ0KYGBgDQoNCg0KYGBge3J9DQojVmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBieSB1c2luZyBhIGJhciBwbG90Lg0Kc2V0LnNlZWQoMzMzKQ0KZ2dwbG90KHNhbXAzLCBhZXMoeCA9IHNjaWVudGlzdF93b3JrKSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICB0aXRsZSA9ICJTYW1wbGUgMzogIERvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHBlb3BsZSBsaWtlIHlvdT8iDQogICkgKw0KICBjb29yZF9mbGlwKCkNCmBgYA0KYGBge3J9DQpzZXQuc2VlZCg0NDQpDQpzYW1wMyAlPiUNCiAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICBtdXRhdGUocyA9IG4gL3N1bShuKSkNCmBgYA0KDQpgYGB7cn0NCiNmb3VydGggc2FtcGxlLCAxMDAwLCBhbmQgY2FsbCBpdCBzYW1wNA0Kc2V0LnNlZWQoMjIyKQ0Kc2FtcDQgPC0gZ2xvYmFsX21vbml0b3IgJT4lDQogIHNhbXBsZV9uKDEwMDApDQpgYGANCg0KYGBge3J9DQojVmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHNhbXBsZSBieSB1c2luZyBhIGJhciBwbG90Lg0Kc2V0LnNlZWQoNDQ0KQ0KZ2dwbG90KHNhbXA0LCBhZXMoeCA9IHNjaWVudGlzdF93b3JrKSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gIiIsIHkgPSAiIiwNCiAgICB0aXRsZSA9ICJTYW1wbGUgNDogIERvIHlvdSBiZWxpZXZlIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBiZW5lZml0IHBlb3BsZSBsaWtlIHlvdT8iDQogICkgKw0KICBjb29yZF9mbGlwKCkNCmBgYA0KYGBge3J9DQpzZXQuc2VlZCg1NTUpDQpzYW1wNCAlPiUNCiAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICBtdXRhdGUocyA9IG4gL3N1bShuKSkNCmBgYA0KRXZlcnkgdGltZSB5b3UgdGFrZSBhbm90aGVyIHJhbmRvbSBzYW1wbGUsIHlvdSBtaWdodCBnZXQgYSBkaWZmZXJlbnQgc2FtcGxlIHByb3BvcnRpb24uIEl04oCZcyB1c2VmdWwgdG8gZ2V0IGEgc2Vuc2Ugb2YganVzdCBob3cgbXVjaCB2YXJpYWJpbGl0eSB5b3Ugc2hvdWxkIGV4cGVjdCB3aGVuIGVzdGltYXRpbmcgdGhlIHBvcHVsYXRpb24gbWVhbiB0aGlzIHdheS4gVGhlIGRpc3RyaWJ1dGlvbiBvZiBzYW1wbGUgcHJvcG9ydGlvbnMsIGNhbGxlZCB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIChvZiB0aGUgcHJvcG9ydGlvbiksIGNhbiBoZWxwIHlvdSB1bmRlcnN0YW5kIHRoaXMgdmFyaWFiaWxpdHkuIA0KYGBge3J9DQojdGFrZSAxNSwwMDAgZGlmZmVyZW50IHNhbXBsZXMgb2Ygc2l6ZSA1MCBmcm9tIHRoZSBwb3B1bGF0aW9uDQojcmVwX3NhbXBsZV9uIGZ1bmN0aW9uIGlzIGZvciByZXBldGl0aW9uLiBSYXRoZXIgdGhhbiB0YWtpbmcgYSBzaW5nbGUgc2FtcGxlIG9mIHNpemUgbiAoNTApIGZyb20gdGhlIHBvcHVsYXRpb24gb2YgYWxsIHBlb3BsZSBpbiB0aGUgcG9wdWxhdGlvbiwgcmVwZWF0IHRoaXMgc2FtcGxpbmcgcHJvY2VkdXJlIHJlcCB0aW1lcyBpbiBvcmRlciB0byBidWlsZCBhIGRpc3RyaWJ1dGlvbiBvZiBhIHNlcmllcyBvZiBzYW1wbGUgc3RhdGlzdGljcywgd2hpY2ggaXMgY2FsbGVkIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24uDQojY2FsY3VsYXRlIHRoZSBwcm9wb3J0aW9uIG9mIHJlc3BvbnNlcyBpbiBlYWNoIHNhbXBsZQ0KI2ZpbHRlciBmb3Igb25seSB0aGUgImRvZXNuJ3QgYmVuZWZpdCIgcmVzcG9uc2VzDQojc3RvcmUgZWFjaCByZXN1bHQgaW4gYSB2ZWN0b3IgY2FsbGVkIHNhbXBsZV9wcm9wczUwDQojcmVwbGFjZSA9IFRSVUUgc2luY2Ugc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBhcmUgY29uc3RydWN0ZWQgYnkgc2FtcGxpbmcgd2l0aCByZXBsYWNlbWVudC4NCg0Kc2FtcGxlX3Byb3BzNTAgPC0gZ2xvYmFsX21vbml0b3IgJT4lDQogICAgICAgICAgICAgICAgICAgIHJlcF9zYW1wbGVfbihzaXplID0gNTAsIHJlcHMgPSAxNTAwMCwgcmVwbGFjZSA9IFRSVUUpICU+JQ0KICAgICAgICAgICAgICAgICAgICBjb3VudChzY2llbnRpc3Rfd29yaykgJT4lDQogICAgICAgICAgICAgICAgICAgIG11dGF0ZShwX2hhdCA9IG4gL3N1bShuKSkgJT4lDQogICAgICAgICAgICAgICAgICAgIGZpbHRlcihzY2llbnRpc3Rfd29yayA9PSAiRG9lc24ndCBiZW5lZml0IikNCmBgYA0KVmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlc2UgcHJvcG9ydGlvbnMgd2l0aCBhIGhpc3RvZ3JhbS4NCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBzYW1wbGVfcHJvcHM1MCwgYWVzKHggPSBwX2hhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjAyKSArDQogIGxhYnMoDQogICAgeCA9ICJwX2hhdCAoRG9lc24ndCBiZW5lZml0KSIsDQogICAgdGl0bGUgPSAiU2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHBfaGF0IiwNCiAgICBzdWJ0aXRsZSA9ICJTYW1wbGUgc2l6ZSA9IDUwLCBOdW1iZXIgb2Ygc2FtcGxlcyA9IDE1MDAwIg0KICApDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDQNCg0KSG93IG1hbnkgZWxlbWVudHMgYXJlIHRoZXJlIGluIHNhbXBsZV9wcm9wczUwPyBEZXNjcmliZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCBhbmQgYmUgc3VyZSB0byBzcGVjaWZpY2FsbHkgbm90ZSBpdHMgY2VudGVyLiBNYWtlIHN1cmUgdG8gaW5jbHVkZSBhIHBsb3Qgb2YgdGhlIGRpc3RyaWJ1dGlvbiBpbiB5b3VyIGFuc3dlci4NCg0KKipBbnN3ZXIqKg0KVGhlcmUgYXJlIDE1LDAwMCBlbGVtZW50cyBpbiBzYW1wbGVfcHJvcHM1MC4gIEFyb3VuZCAyMCUgKDMsMDAwIG9mIHRoZSAxNSwwMDAgZWxlbWVudHMgaW4gc2FtcGxlX3Byb3BzNTApIGJlbGlldmUgc2NpZW50aXN0IHdvcmsgZG9lc24ndCBiZW5lZml0LiAgVGhlIG1lYW4gaXMgYXBwZWFycyB0byBiZSBhYm91dCB0aGUgc2FtZSBhcyB0aGUgb3JpZ2luYWwgZGF0YXNldCBhbmQgbW9yZSBjb25jZW50cmF0ZWQgdGhhbiB0aGUgZ3JhcGggYWJvdmUuIA0KDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoNTU1KQ0KZ2dwbG90KHNhbXBsZV9wcm9wczUwLCBhZXMoeCA9IHBfaGF0KSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gInBfaGF0ICAgRG9lc24ndCBCZW5lZml0IiwgeSA9ICJDb3VudCIsDQogICAgdGl0bGUgPSAiU2FtcGxlIF9wcm9wczUwOiAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIHBfaGF0Ig0KICApICsNCiAgY29vcmRfZmxpcCgpDQogIA0KYGBgDQoNCg0KDQojIyMgRXhlcmNpc2UgNQ0KVG8gbWFrZSBzdXJlIHlvdSB1bmRlcnN0YW5kIGhvdyBzYW1wbGluZyBkaXN0cmlidXRpb25zIGFyZSBidWlsdCwgYW5kIGV4YWN0bHkgd2hhdCB0aGUgcmVwX3NhbXBsZV9uIGZ1bmN0aW9uIGRvZXMsIHRyeSBtb2RpZnlpbmcgdGhlIGNvZGUgdG8gY3JlYXRlIGEgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIDI1IHNhbXBsZSBwcm9wb3J0aW9ucyBmcm9tIHNhbXBsZXMgb2Ygc2l6ZSAxMCwgYW5kIHB1dCB0aGVtIGluIGEgZGF0YSBmcmFtZSBuYW1lZCBzYW1wbGVfcHJvcHNfc21hbGwuIFByaW50IHRoZSBvdXRwdXQuIEhvdyBtYW55IG9ic2VydmF0aW9ucyBhcmUgdGhlcmUgaW4gdGhpcyBvYmplY3QgY2FsbGVkIHNhbXBsZV9wcm9wc19zbWFsbD8gV2hhdCBkb2VzIGVhY2ggb2JzZXJ2YXRpb24gcmVwcmVzZW50Pw0KDQoqKkFuc3dlcjogIFRoZXJlIGFyZSAyNSBzYW1wbGVzLCBlYWNoIHdpdGggMTAgb2JzZXJ2YXRpb25zLiAgU2VlIGJlbG93LiAgDQpFYWNoIGVsZW1lbnQgaXMgdGhlIG1lYW4gb2YgMjUgcmFuZG9tIHNhbXBsZXMuDQoNCmBgYHtyfQ0KI3Rha2UgMjUgZGlmZmVyZW50IHNhbXBsZXMgb2Ygc2l6ZSAxMCBmcm9tIHRoZSBwb3B1bGF0aW9uDQojcmVwX3NhbXBsZV9uIGZ1bmN0aW9uIGlzIGZvciByZXBldGl0aW9uLiBSYXRoZXIgdGhhbiB0YWtpbmcgYSBzaW5nbGUgc2FtcGxlIG9mIHNpemUgbiAoMTApIGZyb20gdGhlIHBvcHVsYXRpb24gb2YgYWxsIHBlb3BsZSBpbiB0aGUgcG9wdWxhdGlvbiwgcmVwZWF0IHRoaXMgc2FtcGxpbmcgcHJvY2VkdXJlIHJlcCB0aW1lcyBpbiBvcmRlciB0byBidWlsZCBhIGRpc3RyaWJ1dGlvbiBvZiBhIHNlcmllcyBvZiBzYW1wbGUgc3RhdGlzdGljcywgd2hpY2ggaXMgY2FsbGVkIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24uDQojY2FsY3VsYXRlIHRoZSBwcm9wb3J0aW9uIG9mIHJlc3BvbnNlcyBpbiBlYWNoIHNhbXBsZQ0KI2ZpbHRlciBmb3Igb25seSB0aGUgImRvZXNuJ3QgYmVuZWZpdCIgcmVzcG9uc2VzDQojc3RvcmUgZWFjaCByZXN1bHQgaW4gYSB2ZWN0b3IgY2FsbGVkIHNhbXBsZV9wcm9wc3NtYWxsDQojcmVwbGFjZSA9IFRSVUUgc2luY2Ugc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBhcmUgY29uc3RydWN0ZWQgYnkgc2FtcGxpbmcgd2l0aCByZXBsYWNlbWVudC4NCg0KDQpzYW1wbGVfcHJvcHNzbWFsbCA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgICAgICAgICAgICAgICAgICAgcmVwX3NhbXBsZV9uKHNpemUgPSAxMCwgcmVwcyA9IDI1LCByZXBsYWNlID0gVFJVRSkgJT4lDQogICAgICAgICAgICAgICAgICAgIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHNjaWVudGlzdF93b3JrID09ICJEb2Vzbid0IGJlbmVmaXQiKQ0KDQoNCmBgYA0KVmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlc2UgcHJvcG9ydGlvbnMgd2l0aCBhIGhpc3RvZ3JhbS4NCg0KYGBge3J9DQpzZXQuc2VlZCg1NTUpDQpnZ3Bsb3Qoc2FtcGxlX3Byb3Bzc21hbGwsIGFlcyh4ID0gcF9oYXQpKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKA0KICAgIHggPSAicF9oYXQgICBEb2Vzbid0IEJlbmVmaXQiLCB5ID0gIkNvdW50IiwNCiAgICB0aXRsZSA9ICJTYW1wbGUgX3Byb3Bzc21hbGw6ICBTYW1wbGluZyBEaXN0cmlidXRpb24gb2YgcF9oYXQiLA0KICAgIHN1YnRpdGxlID0gIlNhbXBsZSBzaXplID0gMTAsIE51bWJlciBvZiBzYW1wbGVzID0gMjUiDQogICkgKw0KICBjb29yZF9mbGlwKCkNCmBgYA0KDQpUaGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGNvbXB1dGVkIGJlbG93IHRlbGxzIGEgbG90IGFib3V0IGVzdGltYXRpbmcgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiBwZW9wbGUgd2hvIHRoaW5rIHRoYXQgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBkb2VzbuKAmXQgYmVuZWZpdCB0aGVtLiBCZWNhdXNlIHRoZSBzYW1wbGUgcHJvcG9ydGlvbiBpcyBhbiB1bmJpYXNlZCBlc3RpbWF0b3IsIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gaXMgY2VudGVyZWQgYXQgdGhlIHRydWUgcG9wdWxhdGlvbiBwcm9wb3J0aW9uLCBhbmQgdGhlIHNwcmVhZCBvZiB0aGUgZGlzdHJpYnV0aW9uIGluZGljYXRlcyBob3cgbXVjaCB2YXJpYWJpbGl0eSBpcyBpbmN1cnJlZCBieSBzYW1wbGluZyBvbmx5IDUwIHBlb3BsZSBhdCBhIHRpbWUgZnJvbSB0aGUgcG9wdWxhdGlvbi4NCg0KYGBge3J9DQojcmVwX3NhbXBsZV9uIGZ1bmN0aW9uOiB0byBjb21wdXRlIGEgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLCBzcGVjaWZpY2FsbHksIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gb2YgdGhlIHByb3BvcnRpb25zIGZyb20gc2FtcGxlcyBvZiA1MCBwZW9wbGUuDQoNCmdncGxvdChkYXRhID0gc2FtcGxlX3Byb3BzNTAsIGFlcyh4ID0gcF9oYXQpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4wMikNCmBgYA0KDQoNCg0KIyMjIEV4ZXJjaXNlIDYNClVzZSB0aGUgYXBwIHRvIGdldCBhIHNlbnNlIG9mIHRoZSBlZmZlY3QgdGhhdCBzYW1wbGUgc2l6ZSBoYXMgb24gc2FtcGxpbmcgZGlzdHJpYnV0aW9uLg0KDQpVc2UgdGhlIGFwcCB0byBjcmVhdGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9ucyBvZiBwcm9wb3J0aW9ucyBvZiBEb2VzbuKAmXQgYmVuZWZpdCBmcm9tIHNhbXBsZXMgb2Ygc2l6ZSAxMCwgNTAsIGFuZCAxMDAuIFVzZSA1LDAwMCBzaW11bGF0aW9ucy4gV2hhdCBkb2VzIGVhY2ggb2JzZXJ2YXRpb24gaW4gdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiByZXByZXNlbnQ/IEhvdyBkb2VzIHRoZSBtZWFuLCBzdGFuZGFyZCBlcnJvciwgYW5kIHNoYXBlIG9mIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gY2hhbmdlIGFzIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZXM/IEhvdyAoaWYgYXQgYWxsKSBkbyB0aGVzZSB2YWx1ZXMgY2hhbmdlIGlmIHlvdSBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIHNpbXVsYXRpb25zPyAoWW91IGRvIG5vdCBuZWVkIHRvIGluY2x1ZGUgcGxvdHMgaW4geW91ciBhbnN3ZXIuKQ0KDQoNCioqQW5zd2VyDQpuID0gMTA7IHJlcHM9NSwwMDA7IG1lYW4gPSAuMjI7IFNFID0gLjExDQpuID0gNTA7IHJlcHM9NSwwMDA7IG1lYW4gPSAuMjsgIFNFID0gLjA2IC0gYnkgaW5jcmVhc2luZyB0aGUgc2FtcGxlIHNpemUsIHRoZXJlIHdhcyBhIGNoYW5nZSBpbiB0aGUgbWVhbiBhbmQgbm90YWJsZSBjaGFuZ2UgaW4gU0U7IA0KbiA9MTAwOyByZXBzPTUsMDAwOyBtZWFuID0gLjI7ICBTRSA9IC4wNCAtIGJ5IGluY3JlYXNpbmcgdGhlIHNhbXBsZSBzaXplLCB0aGVyZSB3YXMgYSBjaGFuZ2UgaW4gdGhlIG1lYW4gYW5kIFNFDQpuID0xMDA7cmVwcz0xMCwwMDA7IG1lYW4gPSAuMjsgIFNFID0gLjA0IC0gYnkgaW5jcmVhc2luZyB0aGUgcmVwcywgdGhlcmUgd2FzIG5vIGNoYW5nZSBpbiB0aGUgbWVhbiBhbmQgU0UNCm4gPTEwMDtyZXBzPTUwLDAwMDsgbWVhbiA9IC4yOyAgU0UgPSAuMDQgLSBieSBpbmNyZWFzaW5nIHRoZSByZXBzLCB0aGVyZSB3YXMgbm8gY2hhbmdlIGluIHRoZSBtZWFuIGFuZCBTRQ0KDQpXaGVuIHRoZSBzYW1wbGUgc2l6ZSBpbmNyZWFzZXMsIHRoZSBkaXN0cmlidXRpb24gYmVjb21lcyBtb3JlIG5vcm1hbC4gIFRoZSBtZWFuIChjZW50ZXIgcG9pbnQgb2YgdGhlIGRpc3RyaWJ1dGlvbikgDQppcyBtb3JlIGFjY3VyYXRlIHdoZW4gdGhlIHNhbXBsZSBzaXplIGlzIGxhcmdlci4NCg0KDQoNCg0KIyMjIEV4ZXJjaXNlIDcNClRha2UgYSBzYW1wbGUgb2Ygc2l6ZSAxNSBmcm9tIHRoZSBwb3B1bGF0aW9uIGFuZCBjYWxjdWxhdGUgdGhlIHByb3BvcnRpb24gb2YgcGVvcGxlIGluIHRoaXMgc2FtcGxlIHdobyB0aGluayB0aGUgd29yayBzY2llbnRpc3RzIGRvIGVuaGFuY2VzIHRoZWlyIGxpdmVzLiBVc2luZyB0aGlzIHNhbXBsZSwgd2hhdCBpcyB5b3VyIGJlc3QgcG9pbnQgZXN0aW1hdGUgb2YgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbiBvZiBwZW9wbGUgd2hvIHRoaW5rIHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gZW5oYW5jZXMgdGhlaXIgbGl2ZXM/DQoNCioqQW5zd2VyOiAgDQpJZiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGlzIGNlbnRlcmVkIGF0IHRoZSB0cnVlIHBvcHVsYXRpb24gcHJvcG9ydGlvbiwgaXQgbG9va3MgbGlrZSBhcm91bmQgODAlIG9mIHRoZSBwb3B1bGF0aW9uIGJlbGlldmUgdGhlIHdvcmsgb2Ygc2NpZW50aXN0cyBlbmhhbmNlIHRoZWlyIGxpdmVzLiBNeSBiZXN0IHBvaW50IGVzdGltYXRlIGlzIGFwcHJveGltYXRlbHkgLjgNCg0KRllJLCBJIGF0dGVtcHRlZCB1c2luZyBhIHJlcCA9IHRvIDEsIGJ1dCB0aGF0IGRpZG4ndCB3b3JrLiAgSW5zdGVhZCwgSSB1c2VkIHJlcHMgPSAyNS4gDQoNCg0KYGBge3J9DQojdGFrZSAyNSBkaWZmZXJlbnQgc2FtcGxlcyBvZiBzaXplIDE1IGZyb20gdGhlIHBvcHVsYXRpb24NCiNyZXBfc2FtcGxlX24gZnVuY3Rpb24gaXMgZm9yIHJlcGV0aXRpb24uIFJhdGhlciB0aGFuIHRha2luZyBhIHNpbmdsZSBzYW1wbGUgb2Ygc2l6ZSBuICgxNSkgZnJvbSB0aGUgcG9wdWxhdGlvbiBvZiBhbGwgcGVvcGxlIGluIHRoZSBwb3B1bGF0aW9uLCByZXBlYXQgdGhpcyBzYW1wbGluZyBwcm9jZWR1cmUgcmVwIHRpbWVzIGluIG9yZGVyIHRvIGJ1aWxkIGEgZGlzdHJpYnV0aW9uIG9mIGEgc2VyaWVzIG9mIHNhbXBsZSBzdGF0aXN0aWNzLCB3aGljaCBpcyBjYWxsZWQgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbi4NCiNjYWxjdWxhdGUgdGhlIHByb3BvcnRpb24gb2YgcmVzcG9uc2VzIGluIGVhY2ggc2FtcGxlDQojZmlsdGVyIGZvciBvbmx5IHRoZSAiYmVuZWZpc3QiIHJlc3BvbnNlcw0KI3N0b3JlIGVhY2ggcmVzdWx0IGluIGEgdmVjdG9yIGNhbGxlZCBzYW1wbGVfcHJvcHMxNWENCiNyZXBsYWNlID0gVFJVRSBzaW5jZSBzYW1wbGluZyBkaXN0cmlidXRpb25zIGFyZSBjb25zdHJ1Y3RlZCBieSBzYW1wbGluZyB3aXRoIHJlcGxhY2VtZW50Lg0KDQoNCnNhbXBsZV9wcm9wczE1YSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgICAgICAgICAgICAgICAgICAgcmVwX3NhbXBsZV9uKHNpemUgPSAxNSwgcmVwcyA9IDI1LCByZXBsYWNlID0gVFJVRSkgJT4lDQogICAgICAgICAgICAgICAgICAgIGNvdW50KHNjaWVudGlzdF93b3JrKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHBfaGF0ID0gbiAvc3VtKG4pKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHNjaWVudGlzdF93b3JrID09ICJCZW5lZml0cyIpDQoNCg0KYGBgDQoNClZpc3VhbGl6ZSB3aXRoIGEgaGlzdG9ncmFtDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoNTc1KQ0KZ2dwbG90KHNhbXBsZV9wcm9wczE1YSwgYWVzKHggPSBwX2hhdCkpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICJwX2hhdCAgIEJlbmVmaXRzIiwgeSA9ICJDb3VudCIsDQogICAgdGl0bGUgPSAiU2FtcGxlIF9wcm9wczE1YTogIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBvZiBwX2hhdCIsDQogICAgc3VidGl0bGUgPSAiU2FtcGxlIHNpemUgPSAxNSwgTnVtYmVyIG9mIHNhbXBsZXMgPSAyNSINCiAgKSArDQogIGNvb3JkX2ZsaXAoKQ0KDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDgNCg0KU2luY2UgeW91IGhhdmUgYWNjZXNzIHRvIHRoZSBwb3B1bGF0aW9uLCBzaW11bGF0ZSB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHByb3BvcnRpb24gb2YgdGhvc2Ugd2hvIHRoaW5rIHRoZSB3b3JrIHNjaWVudGlzdHMgZG8gZW5jaGFuY2VzIHRoZWlyIGxpdmVzIGZvciBzYW1wbGVzIG9mIHNpemUgMTUgYnkgdGFraW5nIDIwMDAgc2FtcGxlcyBmcm9tIHRoZSBwb3B1bGF0aW9uIG9mIHNpemUgMTUgYW5kIGNvbXB1dGluZyAyMDAwIHNhbXBsZSBwcm9wb3J0aW9ucy4gU3RvcmUgdGhlc2UgcHJvcG9ydGlvbnMgaW4gYXMgc2FtcGxlX3Byb3BzMTUuIFBsb3QgdGhlIGRhdGEsIHRoZW4gZGVzY3JpYmUgdGhlIHNoYXBlIG9mIHRoaXMgc2FtcGxpbmcgZGlzdHJpYnV0aW9uLiBCYXNlZCBvbiB0aGlzIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgd2hhdCB3b3VsZCB5b3UgZ3Vlc3MgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiB0aG9zZSB3aG8gdGhpbmsgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBlbmNoYW5jZXMgdGhlaXIgbGl2ZXMgdG8gYmU/IEZpbmFsbHksIGNhbGN1bGF0ZSBhbmQgcmVwb3J0IHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb24uDQoNCioqQW5zd2VyDQpJIHdvdWxkIGV4cGVjdCAgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBpcyBjZW50ZXJlZCBhdCB0aGUgdHJ1ZSBwb3B1bGF0aW9uIHByb3BvcnRpb24gKHNhbXBsZSBtZWFuIHRvIGJlIHNvbWV3aGF0IGxpa2UgcG9wdWxhdGlvbiBtZWFuKSwNCjgwJSBmcm9tIHRoZSAyLDAwMCBzYW1wbGVzIGJlbGlldmUgc2NpZW50aXN0cyB3b3JrIGRvIGVuaGFuY2UgdGhlaXIgbGl2ZXMuIA0KDQpgYGB7cn0NCiN0YWtlIDIwMDAgZGlmZmVyZW50IHNhbXBsZXMgb2Ygc2l6ZSAxNSBmcm9tIHRoZSBwb3B1bGF0aW9uDQojcmVwX3NhbXBsZV9uIGZ1bmN0aW9uIGlzIGZvciByZXBldGl0aW9uLiBSYXRoZXIgdGhhbiB0YWtpbmcgYSBzaW5nbGUgc2FtcGxlIG9mIHNpemUgbiAoMTUpIGZyb20gdGhlIHBvcHVsYXRpb24gb2YgYWxsIHBlb3BsZSBpbiB0aGUgcG9wdWxhdGlvbiwgcmVwZWF0IHRoaXMgc2FtcGxpbmcgcHJvY2VkdXJlIHJlcCB0aW1lcyBpbiBvcmRlciB0byBidWlsZCBhIGRpc3RyaWJ1dGlvbiBvZiBhIHNlcmllcyBvZiBzYW1wbGUgc3RhdGlzdGljcywgd2hpY2ggaXMgY2FsbGVkIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24uDQojY2FsY3VsYXRlIHRoZSBwcm9wb3J0aW9uIG9mIHJlc3BvbnNlcyBpbiBlYWNoIHNhbXBsZQ0KI2ZpbHRlciBmb3Igb25seSB0aGUgImJlbmVmaXRzIiByZXNwb25zZXMNCiNzdG9yZSBlYWNoIHJlc3VsdCBpbiBhIHZlY3RvciBjYWxsZWQgc2FtcGxfcHJvcHMxNQ0KI3JlcGxhY2UgPSBUUlVFIHNpbmNlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgYXJlIGNvbnN0cnVjdGVkIGJ5IHNhbXBsaW5nIHdpdGggcmVwbGFjZW1lbnQuDQoNCg0Kc2FtcGxfcHJvcHMxNSA8LSBnbG9iYWxfbW9uaXRvciAlPiUNCiAgICAgICAgICAgICAgICAgICAgcmVwX3NhbXBsZV9uKHNpemUgPSAxNSwgcmVwcyA9IDIwMDAsIHJlcGxhY2UgPSBUUlVFKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICAgICAgICAgICAgICAgICAgICBtdXRhdGUoc19oYXQgPSBuIC9zdW0obikpICU+JQ0KICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoc2NpZW50aXN0X3dvcmsgPT0gIkJlbmVmaXRzIikNCg0KYGBgDQpWaXN1YWxpemUgd2l0aCBhIGhpc3RvZ3JhbQ0KDQpgYGB7cn0NCnNldC5zZWVkKDU3NSkNCmdncGxvdChzYW1wbF9wcm9wczE1LCBhZXMoeCA9IHNfaGF0KSkgKw0KICBnZW9tX2JhcigpICsNCiAgbGFicygNCiAgICB4ID0gInNfaGF0ICAgQmVuZWZpdHMiLCB5ID0gIkNvdW50IiwNCiAgICB0aXRsZSA9ICJTYW1wbCBfcHJvcHMxNTogIFNhbXBsaW5nIERpc3RyaWJ1dGlvbiBvZiBwX2hhdCIsDQogICAgc3VidGl0bGUgPSAiU2FtcGxlIHNpemUgPSAxNSwgTnVtYmVyIG9mIHNhbXBsZXMgPSAyMDAwIg0KICApICsNCiAgY29vcmRfZmxpcCgpDQpgYGANCg0KDQojIyMgRXhlcmNpc2UgOQ0KDQpDaGFuZ2UgeW91ciBzYW1wbGUgc2l6ZSBmcm9tIDE1IHRvIDE1MCwgdGhlbiBjb21wdXRlIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24gdXNpbmcgdGhlIHNhbWUgbWV0aG9kIGFzIGFib3ZlLCBhbmQgc3RvcmUgdGhlc2UgcHJvcG9ydGlvbnMgaW4gYSBuZXcgb2JqZWN0IGNhbGxlZCBzYW1wbGVfcHJvcHMxNTAuIERlc2NyaWJlIHRoZSBzaGFwZSBvZiB0aGlzIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBhbmQgY29tcGFyZSBpdCB0byB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIGZvciBhIHNhbXBsZSBzaXplIG9mIDE1LiBCYXNlZCBvbiB0aGlzIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiwgd2hhdCB3b3VsZCB5b3UgZ3Vlc3MgdG8gYmUgdGhlIHRydWUgcHJvcG9ydGlvbiBvZiB0aG9zZSB3aG8gdGhpbmsgdGhlIHdvcmsgc2NpZW50aXN0cyBkbyBlbmNoYW5jZXMgdGhlaXIgbGl2ZXM/DQoNCioqQW5zd2VyDQoNClRoZSBtZWFuIG9mIHRoZSBzYW1wbGUgc2l6ZSBvZiAxNTAgaXMgbW9yZSBjb25jZW50cmF0ZWQgdGhhbiB0aGF0IG9mIHNhbXBsZSBzaXplIDE1LiBUaGUgbWVhbiBhcHBlYXJzIHRvIGJlIGEgYmV0dGVyIGVzdGltYXRlIHdpdGggdGhlIGluY3JlYXNlZCBzYW1wbGUgc2l6ZS4NCg0KYGBge3J9DQojdGFrZSAyMDAwIGRpZmZlcmVudCBzYW1wbGVzIG9mIHNpemUgMTUwIGZyb20gdGhlIHBvcHVsYXRpb24NCiNyZXBfc2FtcGxlX24gZnVuY3Rpb24gaXMgZm9yIHJlcGV0aXRpb24uIFJhdGhlciB0aGFuIHRha2luZyBhIHNpbmdsZSBzYW1wbGUgb2Ygc2l6ZSBuICgxNTApIGZyb20gdGhlIHBvcHVsYXRpb24gb2YgYWxsIHBlb3BsZSBpbiB0aGUgcG9wdWxhdGlvbiwgcmVwZWF0IHRoaXMgc2FtcGxpbmcgcHJvY2VkdXJlIHJlcCB0aW1lcyBpbiBvcmRlciB0byBidWlsZCBhIGRpc3RyaWJ1dGlvbiBvZiBhIHNlcmllcyBvZiBzYW1wbGUgc3RhdGlzdGljcywgd2hpY2ggaXMgY2FsbGVkIHRoZSBzYW1wbGluZyBkaXN0cmlidXRpb24uDQojY2FsY3VsYXRlIHRoZSBwcm9wb3J0aW9uIG9mIHJlc3BvbnNlcyBpbiBlYWNoIHNhbXBsZQ0KI2ZpbHRlciBmb3Igb25seSB0aGUgImJlbmVmaXRzIiByZXNwb25zZXMNCiNzdG9yZSBlYWNoIHJlc3VsdCBpbiBhIHZlY3RvciBjYWxsZWQgc2FtcGxfcHJvcHMxNTANCiNyZXBsYWNlID0gVFJVRSBzaW5jZSBzYW1wbGluZyBkaXN0cmlidXRpb25zIGFyZSBjb25zdHJ1Y3RlZCBieSBzYW1wbGluZyB3aXRoIHJlcGxhY2VtZW50Lg0KDQoNCnNhbXBsX3Byb3BzMTUwIDwtIGdsb2JhbF9tb25pdG9yICU+JQ0KICAgICAgICAgICAgICAgICAgICByZXBfc2FtcGxlX24oc2l6ZSA9IDE1MCwgcmVwcyA9IDIwMDAsIHJlcGxhY2UgPSBUUlVFKSAlPiUNCiAgICAgICAgICAgICAgICAgICAgY291bnQoc2NpZW50aXN0X3dvcmspICU+JQ0KICAgICAgICAgICAgICAgICAgICBtdXRhdGUoc19oYXQgPSBuIC9zdW0obikpICU+JQ0KICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoc2NpZW50aXN0X3dvcmsgPT0gIkJlbmVmaXRzIikNCmBgYA0KDQpWaXN1YWxpemUgd2l0aCBhIGhpc3RvZ3JhbQ0KDQpgYGB7cn0NCnNldC5zZWVkKDU3NSkNCmdncGxvdChzYW1wbF9wcm9wczE1MCwgYWVzKHggPSBzX2hhdCkpICsNCiAgZ2VvbV9iYXIoKSArDQogIGxhYnMoDQogICAgeCA9ICJzX2hhdCAgIEJlbmVmaXRzIiwgeSA9ICJDb3VudCIsDQogICAgdGl0bGUgPSAiU2FtcGwgX3Byb3BzMTUwOiAgU2FtcGxpbmcgRGlzdHJpYnV0aW9uIG9mIHBfaGF0IiwNCiAgICBzdWJ0aXRsZSA9ICJTYW1wbGUgc2l6ZSA9IDE1MCwgTnVtYmVyIG9mIHNhbXBsZXMgPSAyMDAwIg0KICApICsNCiAgY29vcmRfZmxpcCgpDQpgYGANCg0KDQoNCiMjIyBFeGVyY2lzZSAxMA0KT2YgdGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbnMgZnJvbSAyIGFuZCAzLCB3aGljaCBoYXMgYSBzbWFsbGVyIHNwcmVhZD8gSWYgeW914oCZcmUgY29uY2VybmVkIHdpdGggbWFraW5nIGVzdGltYXRlcyB0aGF0IGFyZSBtb3JlIG9mdGVuIGNsb3NlIHRvIHRoZSB0cnVlIHZhbHVlLCB3b3VsZCB5b3UgcHJlZmVyIGEgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIHdpdGggYSBsYXJnZSBvciBzbWFsbCBzcHJlYWQ/DQoNCioqQW5zd2VyDQpUaGUgbGFyZ2VyIHNhbXBsZSBzaXplIGhhcyBhIHNtYWxsZXIgc3ByZWFkIGFuZCB3b3VsZCBiZSBwcmVmZXJhYmxlIGZvciBhIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbi4gQWJvdmUsIHdoZW4gd29ya2luZyBpbiBFeGVyY2lzZXMgMiBhbmQgMywgd2Ugd2VyZSB3b3JraW5nIHdpdGggc2FtcGxlcyBvZiA1MCBhbmQgMTAwLiAgVGhlIHNhbXBsZSB3aXRoIDEwMCBoYXMgYSBzbWFsbGVyIHNwcmVhZC4gDQoNCg==