library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.0.3
library(openintro)
## Warning: package 'openintro' was built under R version 4.0.3
## Warning: package 'airports' was built under R version 4.0.3
## Warning: package 'cherryblossom' was built under R version 4.0.3
## Warning: package 'usdata' was built under R version 4.0.3
library(ggplot2)
data("fastfood", package = 'openintro')
view(fastfood)
#filtering restaraunt information via name
mcdonalds <- fastfood %>%
  filter(restaurant == "Mcdonalds")
mcdonalds
## # A tibble: 57 x 17
##    restaurant item  calories cal_fat total_fat sat_fat trans_fat cholesterol
##    <chr>      <chr>    <dbl>   <dbl>     <dbl>   <dbl>     <dbl>       <dbl>
##  1 Mcdonalds  Arti~      380      60         7       2       0            95
##  2 Mcdonalds  Sing~      840     410        45      17       1.5         130
##  3 Mcdonalds  Doub~     1130     600        67      27       3           220
##  4 Mcdonalds  Gril~      750     280        31      10       0.5         155
##  5 Mcdonalds  Cris~      920     410        45      12       0.5         120
##  6 Mcdonalds  Big ~      540     250        28      10       1            80
##  7 Mcdonalds  Chee~      300     100        12       5       0.5          40
##  8 Mcdonalds  Clas~      510     210        24       4       0            65
##  9 Mcdonalds  Doub~      430     190        21      11       1            85
## 10 Mcdonalds  Doub~      770     400        45      21       2.5         175
## # ... with 47 more rows, and 9 more variables: sodium <dbl>, total_carb <dbl>,
## #   fiber <dbl>, sugar <dbl>, protein <dbl>, vit_a <dbl>, vit_c <dbl>,
## #   calcium <dbl>, salad <chr>
#filtering restaraunt information via name
dairy_queen <- fastfood %>%
  filter(restaurant == "Dairy Queen")
dairy_queen
## # A tibble: 42 x 17
##    restaurant item  calories cal_fat total_fat sat_fat trans_fat cholesterol
##    <chr>      <chr>    <dbl>   <dbl>     <dbl>   <dbl>     <dbl>       <dbl>
##  1 Dairy Que~ 1/2 ~     1000     660        74      26         2         170
##  2 Dairy Que~ 1/2 ~      800     460        51      20         2         135
##  3 Dairy Que~ 1/4 ~      630     330        37      13         1          95
##  4 Dairy Que~ 1/4 ~      540     270        30      11         1          70
##  5 Dairy Que~ 1/4 ~      570     310        35      11         1          75
##  6 Dairy Que~ Orig~      400     160        18       9         1          65
##  7 Dairy Que~ Orig~      630     310        34      18         2         125
##  8 Dairy Que~ 4 Pi~     1030     480        53       9         1          80
##  9 Dairy Que~ 6 Pi~     1260     590        66      11         1         120
## 10 Dairy Que~ Baco~      420     240        26      11         1          60
## # ... with 32 more rows, and 9 more variables: sodium <dbl>, total_carb <dbl>,
## #   fiber <dbl>, sugar <dbl>, protein <dbl>, vit_a <dbl>, vit_c <dbl>,
## #   calcium <dbl>, salad <chr>

Exercise 1

Make a plot (or plots) to visualize the distributions of the amount of calories from fat of the options from these two restaurants. How do their centers, shapes, and spreads compare?

x1 <- mcdonalds$cal_fat
x2 <- dairy_queen$cal_fat

summary(x1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    50.0   160.0   240.0   285.6   320.0  1270.0

‘Graphing citation: https://www.r-bloggers.com/2012/10/adding-measures-of-central-tendency-to-histograms-in-r/’

# McDonalds fat calories

hist(x1,
     col = "peachpuff",
     border = "black", 
     prob = TRUE, # show densities instead of frequencies
     xlab = "calories",
     main = "McDonalds' Fat Calories",
     lwd = 2)

# thickness of lin
hist(x2,
     col = "peachpuff",
     border = "black", 
     prob = TRUE, # show densities instead of frequencies
     xlab = "calories",
     main = "Dairy Queen Fat Calories",
     lwd = 2)

Answer to question 1:

These datum have different distributions. While they both tend to skew right, the McDonald’s plot does so more extremely, while the skewness of the DQ plot favors the center.

dqmean <- mean(dairy_queen$cal_fat)
dqstd <- sd(dairy_queen$cal_fat)
mcd_mean <- mean(mcdonalds$cal_fat)
mcd_std <- mean(mcdonalds$cal_fat)
library(ggplot2)
ggplot(data = dairy_queen, aes(x = cal_fat)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqstd), col = "green")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Exercise 2

Based on the this plot, does it appear that the data follow a nearly normal distribution? > Yes, it appears this data somewhat follows a normal distribution.

Evaluating the normal distribution

Below is a QQ plot

ggplot(data = dairy_queen, aes(sample = cal_fat)) + 
  geom_line(stat = "qq")

sim_norm <- rnorm(n = nrow(dairy_queen), mean = dqmean, sd = dqstd)
sim_norm
##  [1]  114.66729  310.09268  442.56909  315.06549  410.65596   93.80603
##  [7]  440.62706  158.72589  402.10043  119.03274  133.98377  366.53149
## [13] -232.67158  357.12501  469.09034  518.72800   88.60428  398.60715
## [19]  461.07955  132.71959  323.28978  230.70975  395.67408  100.60892
## [25]  107.51827  176.23780  210.17885   77.04213  377.37179   64.41452
## [31]   34.55038  382.11210  317.46534  240.50662  541.01741  226.84458
## [37]  349.16764  127.70771  386.70136  254.74305  405.38533  432.58581

Exercise 3

Make a normal probability plot of sim_norm. Do all of the points fall on the line? How does this plot compare to the probability plot for the real data? (Since sim_norm is not a data frame, it can be put directly into the sample argument and the data argument can be dropped.) > Not all the points of this normal plot fall onto the line, although most do. It has a similar shape to the plot of the real data, but it is not exact.

qqnorm(sim_norm,
       ylab = "Sample",
       xlab = "Theoretical",
       main = "DQ Calories from fat",)
qqline(sim_norm)

8 plotted simulations of the normal data

qqnormsim(sample = cal_fat, data = dairy_queen)

Exercise 4

Does the normal probability plot for the calories from fat look similar to the plots created for the simulated data? That is, do the plots provide evidence that the female heights are nearly normal? > Yes, the normal plot for the fat calories does look similar to the simulated plots. Because we can observe a similar cluster of data in the middle amongst all 9 plots, it is safe to say the data is nearly normal distributed.

Exercise 5

Using the same technique, determine whether or not the calories from McDonald’s menu appear to come from a normal distribution. > Yes, based on the simulation data, we can arrive at the same conclusions mentioned in the previous question regarding Mcdonalds’ calories from fat.

sim_norm2 <- rnorm(n = nrow(mcdonalds), mean = dqmean, sd = dqstd)

qqnorm(sim_norm2,
       ylab = "Sample",
       xlab = "Theoretical",
       main = "Mcdonald's Calories from fat",)
qqline(sim_norm2)

qqnormsim(sample = cal_fat, data = mcdonalds)

# compliment
compliment <- 1 - pnorm(q=600, mean = dqmean, sd = dqstd)
compliment
## [1] 0.01501523
# Theoretical probability
dairy_queen %>%
  filter(cal_fat > 600) %>%
  summarise(percent = n() / nrow(dairy_queen))
## # A tibble: 1 x 1
##   percent
##     <dbl>
## 1  0.0476

Exercise 6

Write out two probability questions that you would like to answer about any of the restaurants in this dataset. Calculate those probabilities using both the theoretical normal distribution as well as the empirical distribution (four probabilities in all). Which one had a closer agreement between the two methods? > What is the probability fat from calories is greater than 350 from McDonalds’ menu? What about being greater than 900 from DQ’s menu? > Findings: After performing the calculations below, we can see there is a considerably closer agreement for DQ menu items being greater than 900.

# Empirical
E1 <- 1 - pnorm(q = 350, mean = mcd_mean, sd = mcd_std)
E1
## [1] 0.4108224
# Theoretical
T1 <- mcdonalds %>%
  filter(cal_fat > 350) %>%
  summarise(percent = n() / nrow(mcdonalds))
T1
## # A tibble: 1 x 1
##   percent
##     <dbl>
## 1   0.211
# Difference
diff1 <- abs(E1 - T1)
diff1
##     percent
## 1 0.2002961

Question II:: > What is the probability fat from calories is greater than than 900 from Dairy Queen’s menu?

# Empirical
E2 <- 1 - pnorm(q = 900, mean = dqmean, sd = dqstd)
E2
## [1] 2.186778e-05
# Theoretical

T2 <- dairy_queen %>%
  filter(cal_fat > 900) %>%
  summarise(percent = n() / nrow(dairy_queen))
T2
## # A tibble: 1 x 1
##   percent
##     <dbl>
## 1       0
# Difference
diff2 <- abs(E2 - T2)
diff2
##        percent
## 1 2.186778e-05
dq <- data.frame(item = c(dairy_queen$item),
                 fat_calories = c(dairy_queen$cal_fat))
dq <- dq[order(dq$item),]
view(dq)

mcd <- data.frame(item = c(mcdonalds$item),
                 fat_calories = c(mcdonalds$cal_fat))
mcd <- mcd[order(mcd$item),]
view(mcd)

Exercise 6:

Now let’s consider some of the other variables in the dataset. Out of all the different restaurants, which ones’ distribution is the closest to normal for sodium? > Arby’s data is closest to the normal distribution

# Normal plot sodium Chick Fil A 

chick_fil_a <- fastfood %>%
  filter(restaurant == "Chick Fil-A")
view(chick_fil_a)
Chick_fil_sodi <- chick_fil_a$sodium
Chick_sodi_mean <- mean(chick_fil_a$sodium)
Chick_sodi_std <- sd(chick_fil_a$sodium)

ggplot(data = chick_fil_a, aes(sample = Chick_fil_sodi)) + 
  geom_line(stat = "qq")

# Normal plot histogram Chick Fil A
ggplot(data = chick_fil_a, aes(x = Chick_fil_sodi)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = Chick_sodi_mean, sd = Chick_sodi_std), col = "red")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Normal plot sodium Sonic
sonic <- fastfood %>%
  filter(restaurant == "Sonic")
Sonic_sodi <- sonic$sodium
Sonic_sodi_mean <- mean(sonic$sodium)
Sonic_sodi_std <- sd(sonic$sodium)

ggplot(data = sonic, aes(sample = Sonic_sodi)) + 
  geom_line(stat = "qq")

# Normal plot histogram Sonic
ggplot(data = sonic, aes(x = Sonic_sodi)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = Sonic_sodi_mean, sd = Sonic_sodi_std), col = "blue")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Normal plot sodium Arbys
arbys <- fastfood %>%
  filter(restaurant == "Arbys")
arbys_sodi <- arbys$sodium
arbys_sodi_mean <- mean(arbys$sodium)
arbys_sodi_std <- sd(arbys$sodium)

ggplot(data = arbys, aes(sample = arbys_sodi)) + 
  geom_line(stat = "qq")

# Normal plot histogram ARBYS
ggplot(data = arbys, aes(x = arbys_sodi)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = arbys_sodi_mean, sd = arbys_sodi_std), col = "green")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Normal plot sodium BK
burger_king <- fastfood %>%
  filter(restaurant == "Burger King ")
burger_king_sodi <- burger_king$sodium
burger_king_sodi_mean <- mean(burger_king$sodium)
burger_king_sodi_std <- sd(burger_king$sodium)

ggplot(data = burger_king, aes(sample = burger_king_sodi)) + 
  geom_line(stat = "qq")

# # Normal plot sodium histogram BK
# ggplot(data = burger_king, aes(x = burger_king_sodi)) +
#         geom_blank() +
#         geom_histogram(aes(y = ..density..)) +
#         stat_function(fun = dnorm, args = c(mean = burger_king_sodi_mean, sd = burger_king_sodi_std), col = "white")
# Normal plot SUBWAY
subway <- fastfood %>%
  filter(restaurant == "Subway")
subway_sodi <- subway$sodium
subway_sodi_mean <- mean(subway$sodium)
subway_sodi_std <- sd(subway_sodi)

ggplot(data = subway, aes(sample = subway_sodi)) + 
  geom_line(stat = "qq")

# Normal plot histogram SUBWAY
ggplot(data = subway, aes(x = subway_sodi)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = subway_sodi_mean, sd = subway_sodi_std), col = "purple")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Normal distribution of sodium: TACO BELL
tbell <- fastfood %>%
  filter(restaurant == "Taco Bell")
tbell_sodi <- tbell$sodium
tbell_sodi_mean <- mean(tbell$sodium)
tbell_sodi_std <- sd(tbell_sodi)

ggplot(data = tbell, aes(sample = tbell_sodi)) + 
  geom_line(stat = "qq")

# Normal plot histogram TACO BELL
ggplot(data = tbell, aes(x = tbell_sodi)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = tbell_sodi_mean, sd = tbell_sodi_std), col = "blue")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Normal distribution for sodium DAIRY QUEEN
dq_sodi <- dairy_queen$sodium
dq_sodi_mean <- mean(dairy_queen$sodium)
dq_sodi_std <- sd(dairy_queen$sodium)

ggplot(data = dairy_queen, aes(sample = dq_sodi)) + 
  geom_line(stat = "qq")

# Normal plot hihstogram DAIRY QUEEN
ggplot(data = dairy_queen, aes(x = dq_sodi)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = dq_sodi_mean, sd = dq_sodi_std), col = "tomato")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Normal distribution for sodium McDonalds
Mcdon_sodi <- mcdonalds$sodium
Mcdon_sodi_mean <- mean(mcdonalds$sodium)
Mcdon_sodi_std <- sd(mcdonalds$sodium)

ggplot(data = mcdonalds, aes(sample = Mcdon_sodi)) + 
  geom_line(stat = "qq")

# Normal plot histogram Mcdonalds

ggplot(data = mcdonalds, aes(x = Mcdon_sodi)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = Mcdon_sodi_mean, sd = Mcdon_sodi_std), col = "green")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Exercise 8

Note that some of the normal probability plots for sodium distributions seem to have a stepwise pattern. why do you think this might be the case? > I think this is because variations of items may have similar amounts of sodium. For instance, it is likely that the many variations of chicken sandwhiches that chick fil a offers have similar amounts of sodium to each other.

Exercise 9

As you can see, normal probability plots can be used both to assess normality and visualize skewness. Make a normal probability plot for the total carbohydrates from a restaurant of your choice. Based on this normal probability plot, is this variable left skewed, symmetric, or right skewed? Use a histogram to confirm your findings. > From the plots below, we can conclude this variable is right skewed.

# Normal distribution for carbohydrates McDonalds
Mcdon_carbo <- mcdonalds$total_carb
Mcdon_carbo_mean <- mean(mcdonalds$total_carb)
Mcdon_carbo_std <- sd(mcdonalds$total_carb)

ggplot(data = mcdonalds, aes(sample = Mcdon_carbo)) + 
  geom_line(stat = "qq")

# Normal distribution carbs HISTOGRAM McDonalds
ggplot(data = mcdonalds, aes(x = Mcdon_carbo)) +
        geom_blank() +
        geom_histogram(aes(y = ..density..)) +
        stat_function(fun = dnorm, args = c(mean = Mcdon_carbo_mean, sd = Mcdon_carbo_std), col = "hot pink")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

LS0tDQp0aXRsZTogIkRhdGEgNjA2OiBMYWIgIzQiDQphdXRob3I6ICJKb2UgQ29ubm9sbHkiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydA0KLS0tDQoNCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkob3BlbmludHJvKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KYGBgDQoNCmBgYHtyfQ0KZGF0YSgiZmFzdGZvb2QiLCBwYWNrYWdlID0gJ29wZW5pbnRybycpDQp2aWV3KGZhc3Rmb29kKQ0KYGBgDQpgYGB7cn0NCiNmaWx0ZXJpbmcgcmVzdGFyYXVudCBpbmZvcm1hdGlvbiB2aWEgbmFtZQ0KbWNkb25hbGRzIDwtIGZhc3Rmb29kICU+JQ0KICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiTWNkb25hbGRzIikNCm1jZG9uYWxkcw0KYGBgDQpgYGB7cn0NCiNmaWx0ZXJpbmcgcmVzdGFyYXVudCBpbmZvcm1hdGlvbiB2aWEgbmFtZQ0KZGFpcnlfcXVlZW4gPC0gZmFzdGZvb2QgJT4lDQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJEYWlyeSBRdWVlbiIpDQpkYWlyeV9xdWVlbg0KDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDENCg0KTWFrZSBhIHBsb3QgKG9yIHBsb3RzKSB0byB2aXN1YWxpemUgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgdGhlIGFtb3VudCBvZiBjYWxvcmllcyBmcm9tIGZhdCBvZiB0aGUgb3B0aW9ucyBmcm9tIHRoZXNlIHR3byByZXN0YXVyYW50cy4gSG93IGRvIHRoZWlyIGNlbnRlcnMsIHNoYXBlcywgYW5kIHNwcmVhZHMgY29tcGFyZT8NCg0KYGBge3IgY29kZS1jaHVuay1sYWJlbH0NCngxIDwtIG1jZG9uYWxkcyRjYWxfZmF0DQp4MiA8LSBkYWlyeV9xdWVlbiRjYWxfZmF0DQoNCnN1bW1hcnkoeDEpDQpgYGANCidHcmFwaGluZyBjaXRhdGlvbjogaHR0cHM6Ly93d3cuci1ibG9nZ2Vycy5jb20vMjAxMi8xMC9hZGRpbmctbWVhc3VyZXMtb2YtY2VudHJhbC10ZW5kZW5jeS10by1oaXN0b2dyYW1zLWluLXIvJw0KDQoNCmBgYHtyfQ0KIyBNY0RvbmFsZHMgZmF0IGNhbG9yaWVzDQoNCmhpc3QoeDEsDQogICAgIGNvbCA9ICJwZWFjaHB1ZmYiLA0KICAgICBib3JkZXIgPSAiYmxhY2siLCANCiAgICAgcHJvYiA9IFRSVUUsICMgc2hvdyBkZW5zaXRpZXMgaW5zdGVhZCBvZiBmcmVxdWVuY2llcw0KICAgICB4bGFiID0gImNhbG9yaWVzIiwNCiAgICAgbWFpbiA9ICJNY0RvbmFsZHMnIEZhdCBDYWxvcmllcyIsDQogICAgIGx3ZCA9IDIpDQoNCiMgdGhpY2tuZXNzIG9mIGxpbg0KYGBgDQoNCmBgYHtyfQ0KaGlzdCh4MiwNCiAgICAgY29sID0gInBlYWNocHVmZiIsDQogICAgIGJvcmRlciA9ICJibGFjayIsIA0KICAgICBwcm9iID0gVFJVRSwgIyBzaG93IGRlbnNpdGllcyBpbnN0ZWFkIG9mIGZyZXF1ZW5jaWVzDQogICAgIHhsYWIgPSAiY2Fsb3JpZXMiLA0KICAgICBtYWluID0gIkRhaXJ5IFF1ZWVuIEZhdCBDYWxvcmllcyIsDQogICAgIGx3ZCA9IDIpDQpgYGANCg0KIyMjIEFuc3dlciB0byBxdWVzdGlvbiAxOg0KPiBUaGVzZSBkYXR1bSBoYXZlIGRpZmZlcmVudCBkaXN0cmlidXRpb25zLiBXaGlsZSB0aGV5IGJvdGggdGVuZCB0byBza2V3IHJpZ2h0LCB0aGUgTWNEb25hbGQncyBwbG90IGRvZXMgc28gbW9yZSBleHRyZW1lbHksIHdoaWxlIHRoZSBza2V3bmVzcyBvZiB0aGUgRFEgcGxvdCBmYXZvcnMgdGhlIGNlbnRlci4gDQoNCmBgYHtyfQ0KZHFtZWFuIDwtIG1lYW4oZGFpcnlfcXVlZW4kY2FsX2ZhdCkNCmRxc3RkIDwtIHNkKGRhaXJ5X3F1ZWVuJGNhbF9mYXQpDQpgYGANCg0KYGBge3J9DQptY2RfbWVhbiA8LSBtZWFuKG1jZG9uYWxkcyRjYWxfZmF0KQ0KbWNkX3N0ZCA8LSBtZWFuKG1jZG9uYWxkcyRjYWxfZmF0KQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHggPSBjYWxfZmF0KSkgKw0KICAgICAgICBnZW9tX2JsYW5rKCkgKw0KICAgICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKw0KICAgICAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gYyhtZWFuID0gZHFtZWFuLCBzZCA9IGRxc3RkKSwgY29sID0gImdyZWVuIikNCmBgYA0KDQojIyMgRXhlcmNpc2UgMg0KQmFzZWQgb24gdGhlIHRoaXMgcGxvdCwgZG9lcyBpdCBhcHBlYXIgdGhhdCB0aGUgZGF0YSBmb2xsb3cgYSBuZWFybHkgbm9ybWFsIGRpc3RyaWJ1dGlvbj8NCj4gWWVzLCBpdCBhcHBlYXJzIHRoaXMgZGF0YSBzb21ld2hhdCBmb2xsb3dzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KIyMjIEV2YWx1YXRpbmcgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gDQojIEJlbG93IGlzIGEgUVEgcGxvdA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGRhaXJ5X3F1ZWVuLCBhZXMoc2FtcGxlID0gY2FsX2ZhdCkpICsgDQogIGdlb21fbGluZShzdGF0ID0gInFxIikNCmBgYA0KDQpgYGB7cn0NCnNpbV9ub3JtIDwtIHJub3JtKG4gPSBucm93KGRhaXJ5X3F1ZWVuKSwgbWVhbiA9IGRxbWVhbiwgc2QgPSBkcXN0ZCkNCnNpbV9ub3JtDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDMNCk1ha2UgYSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBvZiBzaW1fbm9ybS4gRG8gYWxsIG9mIHRoZSBwb2ludHMgZmFsbCBvbiB0aGUgbGluZT8gSG93IGRvZXMgdGhpcyBwbG90IGNvbXBhcmUgdG8gdGhlIHByb2JhYmlsaXR5IHBsb3QgZm9yIHRoZSByZWFsIGRhdGE/IChTaW5jZSBzaW1fbm9ybSBpcyBub3QgYSBkYXRhIGZyYW1lLCBpdCBjYW4gYmUgcHV0IGRpcmVjdGx5IGludG8gdGhlIHNhbXBsZSBhcmd1bWVudCBhbmQgdGhlIGRhdGEgYXJndW1lbnQgY2FuIGJlIGRyb3BwZWQuKQ0KPiBOb3QgYWxsIHRoZSBwb2ludHMgb2YgdGhpcyBub3JtYWwgcGxvdCBmYWxsIG9udG8gdGhlIGxpbmUsIGFsdGhvdWdoIG1vc3QgZG8uIEl0IGhhcyBhIHNpbWlsYXIgc2hhcGUgdG8gdGhlIHBsb3Qgb2YgdGhlIHJlYWwgZGF0YSwgYnV0IGl0IGlzIG5vdCBleGFjdC4NCg0KYGBge3J9DQpxcW5vcm0oc2ltX25vcm0sDQogICAgICAgeWxhYiA9ICJTYW1wbGUiLA0KICAgICAgIHhsYWIgPSAiVGhlb3JldGljYWwiLA0KICAgICAgIG1haW4gPSAiRFEgQ2Fsb3JpZXMgZnJvbSBmYXQiLCkNCnFxbGluZShzaW1fbm9ybSkNCmBgYA0KOCBwbG90dGVkIHNpbXVsYXRpb25zIG9mIHRoZSBub3JtYWwgZGF0YQ0KYGBge3J9DQpxcW5vcm1zaW0oc2FtcGxlID0gY2FsX2ZhdCwgZGF0YSA9IGRhaXJ5X3F1ZWVuKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSA0DQpEb2VzIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBmb3IgdGhlIGNhbG9yaWVzIGZyb20gZmF0IGxvb2sgc2ltaWxhciB0byB0aGUgcGxvdHMgY3JlYXRlZCBmb3IgdGhlIHNpbXVsYXRlZCBkYXRhPyBUaGF0IGlzLCBkbyB0aGUgcGxvdHMgcHJvdmlkZSBldmlkZW5jZSB0aGF0IHRoZSBmZW1hbGUgaGVpZ2h0cyBhcmUgbmVhcmx5IG5vcm1hbD8NCj4gWWVzLCB0aGUgbm9ybWFsIHBsb3QgZm9yIHRoZSBmYXQgY2Fsb3JpZXMgZG9lcyBsb29rIHNpbWlsYXIgdG8gdGhlIHNpbXVsYXRlZCBwbG90cy4gQmVjYXVzZSB3ZSBjYW4gb2JzZXJ2ZSBhIHNpbWlsYXIgY2x1c3RlciBvZiBkYXRhIGluIHRoZSBtaWRkbGUgYW1vbmdzdCBhbGwgOSBwbG90cywgaXQgaXMgc2FmZSB0byBzYXkgdGhlIGRhdGEgaXMgbmVhcmx5IG5vcm1hbCBkaXN0cmlidXRlZC4gDQoNCg0KIyMjIEV4ZXJjaXNlIDUNClVzaW5nIHRoZSBzYW1lIHRlY2huaXF1ZSwgZGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90IHRoZSBjYWxvcmllcyBmcm9tIE1jRG9uYWxk4oCZcyBtZW51IGFwcGVhciB0byBjb21lIGZyb20gYSBub3JtYWwgZGlzdHJpYnV0aW9uLg0KPiBZZXMsIGJhc2VkIG9uIHRoZSBzaW11bGF0aW9uIGRhdGEsIHdlIGNhbiBhcnJpdmUgYXQgdGhlIHNhbWUgY29uY2x1c2lvbnMgbWVudGlvbmVkIGluIHRoZSBwcmV2aW91cyBxdWVzdGlvbiByZWdhcmRpbmcgTWNkb25hbGRzJyBjYWxvcmllcyBmcm9tIGZhdC4NCg0KYGBge3J9DQpzaW1fbm9ybTIgPC0gcm5vcm0obiA9IG5yb3cobWNkb25hbGRzKSwgbWVhbiA9IGRxbWVhbiwgc2QgPSBkcXN0ZCkNCg0KcXFub3JtKHNpbV9ub3JtMiwNCiAgICAgICB5bGFiID0gIlNhbXBsZSIsDQogICAgICAgeGxhYiA9ICJUaGVvcmV0aWNhbCIsDQogICAgICAgbWFpbiA9ICJNY2RvbmFsZCdzIENhbG9yaWVzIGZyb20gZmF0IiwpDQpxcWxpbmUoc2ltX25vcm0yKQ0KDQpgYGANCg0KYGBge3J9DQpxcW5vcm1zaW0oc2FtcGxlID0gY2FsX2ZhdCwgZGF0YSA9IG1jZG9uYWxkcykNCmBgYA0KDQpgYGB7cn0NCiMgY29tcGxpbWVudA0KY29tcGxpbWVudCA8LSAxIC0gcG5vcm0ocT02MDAsIG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzdGQpDQpjb21wbGltZW50DQoNCmBgYA0KDQpgYGB7cn0NCiMgVGhlb3JldGljYWwgcHJvYmFiaWxpdHkNCmRhaXJ5X3F1ZWVuICU+JQ0KICBmaWx0ZXIoY2FsX2ZhdCA+IDYwMCkgJT4lDQogIHN1bW1hcmlzZShwZXJjZW50ID0gbigpIC8gbnJvdyhkYWlyeV9xdWVlbikpDQoNCmBgYA0KDQojIyMgRXhlcmNpc2UgNg0KV3JpdGUgb3V0IHR3byBwcm9iYWJpbGl0eSBxdWVzdGlvbnMgdGhhdCB5b3Ugd291bGQgbGlrZSB0byBhbnN3ZXIgYWJvdXQgYW55IG9mIHRoZSByZXN0YXVyYW50cyBpbiB0aGlzIGRhdGFzZXQuIENhbGN1bGF0ZSB0aG9zZSBwcm9iYWJpbGl0aWVzIHVzaW5nIGJvdGggdGhlIHRoZW9yZXRpY2FsIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgd2VsbCBhcyB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiAoZm91ciBwcm9iYWJpbGl0aWVzIGluIGFsbCkuIFdoaWNoIG9uZSBoYWQgYSBjbG9zZXIgYWdyZWVtZW50IGJldHdlZW4gdGhlIHR3byBtZXRob2RzPw0KPiBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBmYXQgZnJvbSBjYWxvcmllcyBpcyBncmVhdGVyIHRoYW4gMzUwIGZyb20gTWNEb25hbGRzJyBtZW51PyBXaGF0IGFib3V0IGJlaW5nIGdyZWF0ZXIgdGhhbiA5MDAgZnJvbSBEUSdzIG1lbnU/DQo+IEZpbmRpbmdzOiBBZnRlciBwZXJmb3JtaW5nIHRoZSBjYWxjdWxhdGlvbnMgYmVsb3csIHdlIGNhbiBzZWUgdGhlcmUgaXMgYSBjb25zaWRlcmFibHkgY2xvc2VyIGFncmVlbWVudCBmb3IgRFEgbWVudSBpdGVtcyBiZWluZyBncmVhdGVyIHRoYW4gOTAwLg0KDQpgYGB7cn0NCiMgRW1waXJpY2FsDQpFMSA8LSAxIC0gcG5vcm0ocSA9IDM1MCwgbWVhbiA9IG1jZF9tZWFuLCBzZCA9IG1jZF9zdGQpDQpFMQ0KYGBgDQpgYGB7cn0NCiMgVGhlb3JldGljYWwNClQxIDwtIG1jZG9uYWxkcyAlPiUNCiAgZmlsdGVyKGNhbF9mYXQgPiAzNTApICU+JQ0KICBzdW1tYXJpc2UocGVyY2VudCA9IG4oKSAvIG5yb3cobWNkb25hbGRzKSkNClQxDQpgYGANCmBgYHtyfQ0KIyBEaWZmZXJlbmNlDQpkaWZmMSA8LSBhYnMoRTEgLSBUMSkNCmRpZmYxDQoNCmBgYA0KUXVlc3Rpb24gSUk6Og0KPiBXaGF0IGlzIHRoZSBwcm9iYWJpbGl0eSBmYXQgZnJvbSBjYWxvcmllcyBpcyBncmVhdGVyIHRoYW4gdGhhbiA5MDAgZnJvbSBEYWlyeSBRdWVlbidzIG1lbnU/DQoNCmBgYHtyfQ0KIyBFbXBpcmljYWwNCkUyIDwtIDEgLSBwbm9ybShxID0gOTAwLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc3RkKQ0KRTINCmBgYA0KYGBge3J9DQojIFRoZW9yZXRpY2FsDQoNClQyIDwtIGRhaXJ5X3F1ZWVuICU+JQ0KICBmaWx0ZXIoY2FsX2ZhdCA+IDkwMCkgJT4lDQogIHN1bW1hcmlzZShwZXJjZW50ID0gbigpIC8gbnJvdyhkYWlyeV9xdWVlbikpDQpUMg0KYGBgDQoNCmBgYHtyfQ0KIyBEaWZmZXJlbmNlDQpkaWZmMiA8LSBhYnMoRTIgLSBUMikNCmRpZmYyDQpgYGANCg0KYGBge3J9DQpkcSA8LSBkYXRhLmZyYW1lKGl0ZW0gPSBjKGRhaXJ5X3F1ZWVuJGl0ZW0pLA0KICAgICAgICAgICAgICAgICBmYXRfY2Fsb3JpZXMgPSBjKGRhaXJ5X3F1ZWVuJGNhbF9mYXQpKQ0KZHEgPC0gZHFbb3JkZXIoZHEkaXRlbSksXQ0KdmlldyhkcSkNCg0KbWNkIDwtIGRhdGEuZnJhbWUoaXRlbSA9IGMobWNkb25hbGRzJGl0ZW0pLA0KICAgICAgICAgICAgICAgICBmYXRfY2Fsb3JpZXMgPSBjKG1jZG9uYWxkcyRjYWxfZmF0KSkNCm1jZCA8LSBtY2Rbb3JkZXIobWNkJGl0ZW0pLF0NCnZpZXcobWNkKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSA2Og0KTm93IGxldOKAmXMgY29uc2lkZXIgc29tZSBvZiB0aGUgb3RoZXIgdmFyaWFibGVzIGluIHRoZSBkYXRhc2V0LiBPdXQgb2YgYWxsIHRoZSBkaWZmZXJlbnQgcmVzdGF1cmFudHMsIHdoaWNoIG9uZXPigJkgZGlzdHJpYnV0aW9uIGlzIHRoZSBjbG9zZXN0IHRvIG5vcm1hbCBmb3Igc29kaXVtPw0KPiBBcmJ5J3MgZGF0YSBpcyBjbG9zZXN0IHRvIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uDQoNCmBgYHtyfQ0KIyBOb3JtYWwgcGxvdCBzb2RpdW0gQ2hpY2sgRmlsIEEgDQoNCmNoaWNrX2ZpbF9hIDwtIGZhc3Rmb29kICU+JQ0KICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiQ2hpY2sgRmlsLUEiKQ0KdmlldyhjaGlja19maWxfYSkNCkNoaWNrX2ZpbF9zb2RpIDwtIGNoaWNrX2ZpbF9hJHNvZGl1bQ0KQ2hpY2tfc29kaV9tZWFuIDwtIG1lYW4oY2hpY2tfZmlsX2Ekc29kaXVtKQ0KQ2hpY2tfc29kaV9zdGQgPC0gc2QoY2hpY2tfZmlsX2Ekc29kaXVtKQ0KDQpnZ3Bsb3QoZGF0YSA9IGNoaWNrX2ZpbF9hLCBhZXMoc2FtcGxlID0gQ2hpY2tfZmlsX3NvZGkpKSArIA0KICBnZW9tX2xpbmUoc3RhdCA9ICJxcSIpDQpgYGANCmBgYHtyfQ0KIyBOb3JtYWwgcGxvdCBoaXN0b2dyYW0gQ2hpY2sgRmlsIEENCmdncGxvdChkYXRhID0gY2hpY2tfZmlsX2EsIGFlcyh4ID0gQ2hpY2tfZmlsX3NvZGkpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArDQogICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBDaGlja19zb2RpX21lYW4sIHNkID0gQ2hpY2tfc29kaV9zdGQpLCBjb2wgPSAicmVkIikNCmBgYA0KDQpgYGB7cn0NCiMgTm9ybWFsIHBsb3Qgc29kaXVtIFNvbmljDQpzb25pYyA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIlNvbmljIikNClNvbmljX3NvZGkgPC0gc29uaWMkc29kaXVtDQpTb25pY19zb2RpX21lYW4gPC0gbWVhbihzb25pYyRzb2RpdW0pDQpTb25pY19zb2RpX3N0ZCA8LSBzZChzb25pYyRzb2RpdW0pDQoNCmdncGxvdChkYXRhID0gc29uaWMsIGFlcyhzYW1wbGUgPSBTb25pY19zb2RpKSkgKyANCiAgZ2VvbV9saW5lKHN0YXQgPSAicXEiKQ0KYGBgDQpgYGB7cn0NCiMgTm9ybWFsIHBsb3QgaGlzdG9ncmFtIFNvbmljDQpnZ3Bsb3QoZGF0YSA9IHNvbmljLCBhZXMoeCA9IFNvbmljX3NvZGkpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArDQogICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBTb25pY19zb2RpX21lYW4sIHNkID0gU29uaWNfc29kaV9zdGQpLCBjb2wgPSAiYmx1ZSIpDQoNCmBgYA0KDQpgYGB7cn0NCiMgTm9ybWFsIHBsb3Qgc29kaXVtIEFyYnlzDQphcmJ5cyA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkFyYnlzIikNCmFyYnlzX3NvZGkgPC0gYXJieXMkc29kaXVtDQphcmJ5c19zb2RpX21lYW4gPC0gbWVhbihhcmJ5cyRzb2RpdW0pDQphcmJ5c19zb2RpX3N0ZCA8LSBzZChhcmJ5cyRzb2RpdW0pDQoNCmdncGxvdChkYXRhID0gYXJieXMsIGFlcyhzYW1wbGUgPSBhcmJ5c19zb2RpKSkgKyANCiAgZ2VvbV9saW5lKHN0YXQgPSAicXEiKQ0KYGBgDQpgYGB7cn0NCiMgTm9ybWFsIHBsb3QgaGlzdG9ncmFtIEFSQllTDQpnZ3Bsb3QoZGF0YSA9IGFyYnlzLCBhZXMoeCA9IGFyYnlzX3NvZGkpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArDQogICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBhcmJ5c19zb2RpX21lYW4sIHNkID0gYXJieXNfc29kaV9zdGQpLCBjb2wgPSAiZ3JlZW4iKQ0KYGBgDQoNCg0KYGBge3J9DQojIE5vcm1hbCBwbG90IHNvZGl1bSBCSw0KYnVyZ2VyX2tpbmcgPC0gZmFzdGZvb2QgJT4lDQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJCdXJnZXIgS2luZwkiKQ0KYnVyZ2VyX2tpbmdfc29kaSA8LSBidXJnZXJfa2luZyRzb2RpdW0NCmJ1cmdlcl9raW5nX3NvZGlfbWVhbiA8LSBtZWFuKGJ1cmdlcl9raW5nJHNvZGl1bSkNCmJ1cmdlcl9raW5nX3NvZGlfc3RkIDwtIHNkKGJ1cmdlcl9raW5nJHNvZGl1bSkNCg0KZ2dwbG90KGRhdGEgPSBidXJnZXJfa2luZywgYWVzKHNhbXBsZSA9IGJ1cmdlcl9raW5nX3NvZGkpKSArIA0KICBnZW9tX2xpbmUoc3RhdCA9ICJxcSIpDQpgYGANCg0KYGBge3J9DQojICMgTm9ybWFsIHBsb3Qgc29kaXVtIGhpc3RvZ3JhbSBCSw0KIyBnZ3Bsb3QoZGF0YSA9IGJ1cmdlcl9raW5nLCBhZXMoeCA9IGJ1cmdlcl9raW5nX3NvZGkpKSArDQojICAgICAgICAgZ2VvbV9ibGFuaygpICsNCiMgICAgICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKw0KIyAgICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBidXJnZXJfa2luZ19zb2RpX21lYW4sIHNkID0gYnVyZ2VyX2tpbmdfc29kaV9zdGQpLCBjb2wgPSAid2hpdGUiKQ0KDQpgYGANCg0KYGBge3J9DQojIE5vcm1hbCBwbG90IFNVQldBWQ0Kc3Vid2F5IDwtIGZhc3Rmb29kICU+JQ0KICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiU3Vid2F5IikNCnN1YndheV9zb2RpIDwtIHN1YndheSRzb2RpdW0NCnN1YndheV9zb2RpX21lYW4gPC0gbWVhbihzdWJ3YXkkc29kaXVtKQ0Kc3Vid2F5X3NvZGlfc3RkIDwtIHNkKHN1YndheV9zb2RpKQ0KDQpnZ3Bsb3QoZGF0YSA9IHN1YndheSwgYWVzKHNhbXBsZSA9IHN1YndheV9zb2RpKSkgKyANCiAgZ2VvbV9saW5lKHN0YXQgPSAicXEiKQ0KYGBgDQpgYGB7cn0NCiMgTm9ybWFsIHBsb3QgaGlzdG9ncmFtIFNVQldBWQ0KZ2dwbG90KGRhdGEgPSBzdWJ3YXksIGFlcyh4ID0gc3Vid2F5X3NvZGkpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArDQogICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBzdWJ3YXlfc29kaV9tZWFuLCBzZCA9IHN1YndheV9zb2RpX3N0ZCksIGNvbCA9ICJwdXJwbGUiKQ0KDQpgYGANCg0KYGBge3J9DQojIE5vcm1hbCBkaXN0cmlidXRpb24gb2Ygc29kaXVtOiBUQUNPIEJFTEwNCnRiZWxsIDwtIGZhc3Rmb29kICU+JQ0KICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiVGFjbyBCZWxsIikNCnRiZWxsX3NvZGkgPC0gdGJlbGwkc29kaXVtDQp0YmVsbF9zb2RpX21lYW4gPC0gbWVhbih0YmVsbCRzb2RpdW0pDQp0YmVsbF9zb2RpX3N0ZCA8LSBzZCh0YmVsbF9zb2RpKQ0KDQpnZ3Bsb3QoZGF0YSA9IHRiZWxsLCBhZXMoc2FtcGxlID0gdGJlbGxfc29kaSkpICsgDQogIGdlb21fbGluZShzdGF0ID0gInFxIikNCmBgYA0KDQpgYGB7cn0NCiMgTm9ybWFsIHBsb3QgaGlzdG9ncmFtIFRBQ08gQkVMTA0KZ2dwbG90KGRhdGEgPSB0YmVsbCwgYWVzKHggPSB0YmVsbF9zb2RpKSkgKw0KICAgICAgICBnZW9tX2JsYW5rKCkgKw0KICAgICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKw0KICAgICAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gYyhtZWFuID0gdGJlbGxfc29kaV9tZWFuLCBzZCA9IHRiZWxsX3NvZGlfc3RkKSwgY29sID0gImJsdWUiKQ0KDQpgYGANCg0KYGBge3J9DQojIE5vcm1hbCBkaXN0cmlidXRpb24gZm9yIHNvZGl1bSBEQUlSWSBRVUVFTg0KZHFfc29kaSA8LSBkYWlyeV9xdWVlbiRzb2RpdW0NCmRxX3NvZGlfbWVhbiA8LSBtZWFuKGRhaXJ5X3F1ZWVuJHNvZGl1bSkNCmRxX3NvZGlfc3RkIDwtIHNkKGRhaXJ5X3F1ZWVuJHNvZGl1bSkNCg0KZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHNhbXBsZSA9IGRxX3NvZGkpKSArIA0KICBnZW9tX2xpbmUoc3RhdCA9ICJxcSIpDQoNCmBgYA0KDQpgYGB7cn0NCiMgTm9ybWFsIHBsb3QgaGloc3RvZ3JhbSBEQUlSWSBRVUVFTg0KZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHggPSBkcV9zb2RpKSkgKw0KICAgICAgICBnZW9tX2JsYW5rKCkgKw0KICAgICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSkgKw0KICAgICAgICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gYyhtZWFuID0gZHFfc29kaV9tZWFuLCBzZCA9IGRxX3NvZGlfc3RkKSwgY29sID0gInRvbWF0byIpDQpgYGANCmBgYHtyfQ0KIyBOb3JtYWwgZGlzdHJpYnV0aW9uIGZvciBzb2RpdW0gTWNEb25hbGRzDQpNY2Rvbl9zb2RpIDwtIG1jZG9uYWxkcyRzb2RpdW0NCk1jZG9uX3NvZGlfbWVhbiA8LSBtZWFuKG1jZG9uYWxkcyRzb2RpdW0pDQpNY2Rvbl9zb2RpX3N0ZCA8LSBzZChtY2RvbmFsZHMkc29kaXVtKQ0KDQpnZ3Bsb3QoZGF0YSA9IG1jZG9uYWxkcywgYWVzKHNhbXBsZSA9IE1jZG9uX3NvZGkpKSArIA0KICBnZW9tX2xpbmUoc3RhdCA9ICJxcSIpDQpgYGANCg0KYGBge3J9DQojIE5vcm1hbCBwbG90IGhpc3RvZ3JhbSBNY2RvbmFsZHMNCg0KZ2dwbG90KGRhdGEgPSBtY2RvbmFsZHMsIGFlcyh4ID0gTWNkb25fc29kaSkpICsNCiAgICAgICAgZ2VvbV9ibGFuaygpICsNCiAgICAgICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLikpICsNCiAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IE1jZG9uX3NvZGlfbWVhbiwgc2QgPSBNY2Rvbl9zb2RpX3N0ZCksIGNvbCA9ICJncmVlbiIpDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDgNCk5vdGUgdGhhdCBzb21lIG9mIHRoZSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdHMgZm9yIHNvZGl1bSBkaXN0cmlidXRpb25zIHNlZW0gdG8gaGF2ZSBhIHN0ZXB3aXNlIHBhdHRlcm4uIHdoeSBkbyB5b3UgdGhpbmsgdGhpcyBtaWdodCBiZSB0aGUgY2FzZT8NCj4gSSB0aGluayB0aGlzIGlzIGJlY2F1c2UgdmFyaWF0aW9ucyBvZiBpdGVtcyBtYXkgaGF2ZSBzaW1pbGFyIGFtb3VudHMgb2Ygc29kaXVtLiBGb3IgaW5zdGFuY2UsIGl0IGlzIGxpa2VseSB0aGF0IHRoZSBtYW55IHZhcmlhdGlvbnMgb2YgY2hpY2tlbiBzYW5kd2hpY2hlcyB0aGF0IGNoaWNrIGZpbCBhIG9mZmVycyBoYXZlIHNpbWlsYXIgYW1vdW50cyBvZiBzb2RpdW0gdG8gZWFjaCBvdGhlci4gDQoNCiMjIyBFeGVyY2lzZSA5DQpBcyB5b3UgY2FuIHNlZSwgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3RzIGNhbiBiZSB1c2VkIGJvdGggdG8gYXNzZXNzIG5vcm1hbGl0eSBhbmQgdmlzdWFsaXplIHNrZXduZXNzLiBNYWtlIGEgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QgZm9yIHRoZSB0b3RhbCBjYXJib2h5ZHJhdGVzIGZyb20gYSByZXN0YXVyYW50IG9mIHlvdXIgY2hvaWNlLiBCYXNlZCBvbiB0aGlzIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90LCBpcyB0aGlzIHZhcmlhYmxlIGxlZnQgc2tld2VkLCBzeW1tZXRyaWMsIG9yIHJpZ2h0IHNrZXdlZD8gVXNlIGEgaGlzdG9ncmFtIHRvIGNvbmZpcm0geW91ciBmaW5kaW5ncy4NCj4gRnJvbSB0aGUgcGxvdHMgYmVsb3csIHdlIGNhbiBjb25jbHVkZSB0aGlzIHZhcmlhYmxlIGlzIHJpZ2h0IHNrZXdlZC4NCg0KYGBge3J9DQojIE5vcm1hbCBkaXN0cmlidXRpb24gZm9yIGNhcmJvaHlkcmF0ZXMgTWNEb25hbGRzDQpNY2Rvbl9jYXJibyA8LSBtY2RvbmFsZHMkdG90YWxfY2FyYg0KTWNkb25fY2FyYm9fbWVhbiA8LSBtZWFuKG1jZG9uYWxkcyR0b3RhbF9jYXJiKQ0KTWNkb25fY2FyYm9fc3RkIDwtIHNkKG1jZG9uYWxkcyR0b3RhbF9jYXJiKQ0KDQpnZ3Bsb3QoZGF0YSA9IG1jZG9uYWxkcywgYWVzKHNhbXBsZSA9IE1jZG9uX2NhcmJvKSkgKyANCiAgZ2VvbV9saW5lKHN0YXQgPSAicXEiKQ0KYGBgDQpgYGB7cn0NCiMgTm9ybWFsIGRpc3RyaWJ1dGlvbiBjYXJicyBISVNUT0dSQU0gTWNEb25hbGRzDQpnZ3Bsb3QoZGF0YSA9IG1jZG9uYWxkcywgYWVzKHggPSBNY2Rvbl9jYXJibykpICsNCiAgICAgICAgZ2VvbV9ibGFuaygpICsNCiAgICAgICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLikpICsNCiAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IE1jZG9uX2NhcmJvX21lYW4sIHNkID0gTWNkb25fY2FyYm9fc3RkKSwgY29sID0gImhvdCBwaW5rIikNCmBgYA==