library(tidyverse)
library(openintro)
knitr::kable(head(fastfood))
Mcdonalds |
Artisan Grilled Chicken Sandwich |
380 |
60 |
7 |
2 |
0.0 |
95 |
1110 |
44 |
3 |
11 |
37 |
4 |
20 |
20 |
Other |
Mcdonalds |
Single Bacon Smokehouse Burger |
840 |
410 |
45 |
17 |
1.5 |
130 |
1580 |
62 |
2 |
18 |
46 |
6 |
20 |
20 |
Other |
Mcdonalds |
Double Bacon Smokehouse Burger |
1130 |
600 |
67 |
27 |
3.0 |
220 |
1920 |
63 |
3 |
18 |
70 |
10 |
20 |
50 |
Other |
Mcdonalds |
Grilled Bacon Smokehouse Chicken Sandwich |
750 |
280 |
31 |
10 |
0.5 |
155 |
1940 |
62 |
2 |
18 |
55 |
6 |
25 |
20 |
Other |
Mcdonalds |
Crispy Bacon Smokehouse Chicken Sandwich |
920 |
410 |
45 |
12 |
0.5 |
120 |
1980 |
81 |
4 |
18 |
46 |
6 |
20 |
20 |
Other |
Mcdonalds |
Big Mac |
540 |
250 |
28 |
10 |
1.0 |
80 |
950 |
46 |
3 |
9 |
25 |
10 |
2 |
15 |
Other |
mcdonalds <- fastfood %>%
filter(restaurant == "Mcdonalds")
dairy_queen <- fastfood %>%
filter(restaurant == "Dairy Queen")
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?
ggplot(data = mcdonalds, aes(x = cal_fat)) +
geom_blank() +
geom_histogram(color="blue")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggplot(data = dairy_queen, aes(x = cal_fat)) +
geom_blank() +
geom_histogram(color="green")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Both plots are unimodal, the Dairy Queen histogram is slightly right-skewed whereas the McDonalds is right-skewed. The Dairy Queen one appears almost normal.
Exercise 2
Based on the this plot, does it appear that the data follow a nearly normal distribution?
dqmean <- mean(dairy_queen$cal_fat)
dqsd <- sd(dairy_queen$cal_fat)
ggplot(data = dairy_queen, aes(x = cal_fat)) +
geom_blank() +
geom_histogram(aes(y = ..density..), color="green") +
stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqsd), col = "tomato")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Based on this plot, we can say that this distribution is nearly normal.
ggplot(data = dairy_queen, aes(sample = cal_fat)) +
geom_line(stat = "qq", color="dark green")

sim_norm <- rnorm(n = nrow(dairy_queen), mean = dqmean, sd = dqsd)
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 dataframe, it can be put directly into the sample argument and the data argument can be dropped.)
Looks very similar
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 distribution is nearly normal?
Yes
Exercise 5
Using the same technique, determine whether or not the calories from McDonald’s menu appear to come from a normal distribution.
mcmean <- mean(mcdonalds$cal_fat)
mcsd <- sd(mcdonalds$cal_fat)
ggplot(data = mcdonalds, aes(x = cal_fat)) +
geom_blank() +
geom_histogram(aes(y = ..density..), color="blue") +
stat_function(fun = dnorm, args = c(mean = mcmean, sd = mcsd), col = "tomato")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.


Line does not seem to follow the same slope, does not appear normal.
1 - pnorm(q = 600, mean = dqmean, sd = dqsd)
## [1] 0.01501523
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?
a) What is the percentage of McDonald’s menu that is over 600 calories from fat?
1 - pnorm(q = 600, mean = mcmean, sd = mcsd)
## [1] 0.07733771
8% of McDonald’s menu is over 600 calories from fat.
sum(mcdonalds$cal_fat > 600) / length(mcdonalds$cal_fat)
## [1] 0.07017544
7%
b) What is the pecentage of McDonald’s menu that is over 600 calories?
mcmean2 <- mean(mcdonalds$calories)
mcsd2 <- sd(mcdonalds$calories)
1 - pnorm(q = 600, mean = mcmean2, sd = mcsd2)
## [1] 0.5391331
54% of the theoretical normal.
sum(mcdonalds$calories > 600) / length(mcdonalds$calories)
## [1] 0.4210526
42% of the real data.
Calories from fat are closer than overall calories.
Exercise 7
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?
restaurants <- fastfood %>%
group_by(restaurant) %>%
select(restaurant, sodium) %>%
summarise( avg = mean(sodium), sd_sodium= sd(sodium), .groups = "drop_last")
datar <- fastfood%>%
filter(restaurant == "Arbys")
dmean = restaurants$avg[1]
dsd = restaurants$sd_sodium[1]
qqnormsim(sample = sodium, data = datar)

datar <- fastfood%>%
filter(restaurant == "Burger King")
dmean = restaurants$avg[2]
dsd = restaurants$sd_sodium[2]
qqnormsim(sample = sodium, data = datar)

datar <- fastfood%>%
filter(restaurant == "Chick Fil-A")
qqnormsim(sample = sodium, data = datar)

datar <- fastfood%>%
filter(restaurant == "Sonic")
qqnormsim(sample = sodium, data = datar)

datar <- fastfood%>%
filter(restaurant == "Subway")
qqnormsim(sample = sodium, data = datar)

datar <- fastfood%>%
filter(restaurant == "Taco Bell")
qqnormsim(sample = sodium, data = datar)

I would say Taco Bell
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 would say the distributions are right or left-skewed.
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
datar <- fastfood%>%
filter(restaurant == "Taco Bell")
qqnormsim(sample = total_carb, data = datar)

Based on this, I would say the histogram is almost normal and slightly right skewed.
dmean <- mean(datar$total_carb)
dsd <- sd(datar$total_carb)
ggplot(data = mcdonalds, aes(x = total_carb)) +
geom_blank() +
geom_histogram(aes(y = ..density..), color="blue") +
stat_function(fun = dnorm, args = c(mean = dmean, sd = dsd), col = "tomato")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

It appears the conclusions were correct. …
LS0tDQp0aXRsZTogIkRTNjA2IC0gTGFiIDQiDQphdXRob3I6ICJHZW9yZ2UgQ3J1eiINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0DQotLS0NCg0KYGBge3IgbG9hZC1wYWNrYWdlcywgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShvcGVuaW50cm8pDQprbml0cjo6a2FibGUoaGVhZChmYXN0Zm9vZCkpDQpgYGANCg0KDQpgYGB7cn0NCm1jZG9uYWxkcyA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIk1jZG9uYWxkcyIpDQpkYWlyeV9xdWVlbiA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkRhaXJ5IFF1ZWVuIikNCmBgYA0KDQojIyMgRXhlcmNpc2UgMQ0KDQpNYWtlIGEgcGxvdCAob3IgcGxvdHMpIHRvIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9ucyBvZiB0aGUgYW1vdW50IG9mIGNhbG9yaWVzIGZyb20gZmF0IG9mIHRoZSBvcHRpb25zIGZyb20gdGhlc2UgdHdvIHJlc3RhdXJhbnRzLiBIb3cgZG8gdGhlaXIgY2VudGVycywgc2hhcGVzLCBhbmQgc3ByZWFkcyBjb21wYXJlPw0KDQpgYGB7ciBjb2RlLWNodW5rLWxhYmVsfQ0KZ2dwbG90KGRhdGEgPSBtY2RvbmFsZHMsIGFlcyh4ID0gY2FsX2ZhdCkpICsNCiAgICAgICAgZ2VvbV9ibGFuaygpICsNCiAgICAgICAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsdWUiKSANCmBgYA0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gZGFpcnlfcXVlZW4sIGFlcyh4ID0gY2FsX2ZhdCkpICsNCiAgICAgICAgZ2VvbV9ibGFuaygpICsNCiAgICAgICAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImdyZWVuIikgDQpgYGANCg0KQm90aCBwbG90cyBhcmUgdW5pbW9kYWwsIHRoZSBEYWlyeSBRdWVlbiBoaXN0b2dyYW0gaXMgc2xpZ2h0bHkgcmlnaHQtc2tld2VkIHdoZXJlYXMgdGhlIE1jRG9uYWxkcyBpcyByaWdodC1za2V3ZWQuICBUaGUgRGFpcnkgUXVlZW4gb25lIGFwcGVhcnMgYWxtb3N0IG5vcm1hbC4gDQoNCiMjIyBFeGVyY2lzZSAyDQoNCkJhc2VkIG9uIHRoZSB0aGlzIHBsb3QsIGRvZXMgaXQgYXBwZWFyIHRoYXQgdGhlIGRhdGEgZm9sbG93IGEgbmVhcmx5IG5vcm1hbCBkaXN0cmlidXRpb24/DQoNCmBgYHtyfQ0KZHFtZWFuIDwtIG1lYW4oZGFpcnlfcXVlZW4kY2FsX2ZhdCkNCmRxc2QgICA8LSBzZChkYWlyeV9xdWVlbiRjYWxfZmF0KQ0KDQpnZ3Bsb3QoZGF0YSA9IGRhaXJ5X3F1ZWVuLCBhZXMoeCA9IGNhbF9mYXQpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pLCBjb2xvcj0iZ3JlZW4iKSArDQogICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzZCksIGNvbCA9ICJ0b21hdG8iKQ0KYGBgDQoNCioqQmFzZWQgb24gdGhpcyBwbG90LCB3ZSBjYW4gc2F5IHRoYXQgdGhpcyBkaXN0cmlidXRpb24gaXMgbmVhcmx5IG5vcm1hbC4qKg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gZGFpcnlfcXVlZW4sIGFlcyhzYW1wbGUgPSBjYWxfZmF0KSkgKyANCiAgZ2VvbV9saW5lKHN0YXQgPSAicXEiLCBjb2xvcj0iZGFyayBncmVlbiIpDQpgYGANCg0KYGBge3J9DQpzaW1fbm9ybSA8LSBybm9ybShuID0gbnJvdyhkYWlyeV9xdWVlbiksIG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzZCkNCmBgYA0KDQojIyMgRXhlcmNpc2UgMw0KTWFrZSBhIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IG9mIHNpbV9ub3JtLiBEbyBhbGwgb2YgdGhlIHBvaW50cyBmYWxsIG9uIHRoZSBsaW5lPyBIb3cgZG9lcyB0aGlzIHBsb3QgY29tcGFyZSB0byB0aGUgcHJvYmFiaWxpdHkgcGxvdCBmb3IgdGhlIHJlYWwgZGF0YT8gKFNpbmNlIHNpbV9ub3JtIGlzIG5vdCBhIGRhdGFmcmFtZSwgaXQgY2FuIGJlIHB1dCBkaXJlY3RseSBpbnRvIHRoZSBzYW1wbGUgYXJndW1lbnQgYW5kIHRoZSBkYXRhIGFyZ3VtZW50IGNhbiBiZSBkcm9wcGVkLikNCg0KKipMb29rcyB2ZXJ5IHNpbWlsYXIqKg0KDQpgYGB7cn0NCnFxbm9ybXNpbShzYW1wbGUgPSBjYWxfZmF0LCBkYXRhID0gZGFpcnlfcXVlZW4pDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDQNCkRvZXMgdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgY2Fsb3JpZXMgZnJvbSBmYXQgbG9vayBzaW1pbGFyIHRvIHRoZSBwbG90cyBjcmVhdGVkIGZvciB0aGUgc2ltdWxhdGVkIGRhdGE/IFRoYXQgaXMsIGRvIHRoZSBwbG90cyBwcm92aWRlIGV2aWRlbmNlIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBpcyBuZWFybHkgbm9ybWFsPw0KDQoqKlllcyoqDQoNCiMjIyBFeGVyY2lzZSA1DQpVc2luZyB0aGUgc2FtZSB0ZWNobmlxdWUsIGRldGVybWluZSB3aGV0aGVyIG9yIG5vdCB0aGUgY2Fsb3JpZXMgZnJvbSBNY0RvbmFsZOKAmXMgbWVudSBhcHBlYXIgdG8gY29tZSBmcm9tIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCmBgYHtyfQ0KbWNtZWFuIDwtIG1lYW4obWNkb25hbGRzJGNhbF9mYXQpDQptY3NkICAgPC0gc2QobWNkb25hbGRzJGNhbF9mYXQpDQoNCmdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoeCA9IGNhbF9mYXQpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pLCBjb2xvcj0iYmx1ZSIpICsNCiAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IG1jbWVhbiwgc2QgPSBtY3NkKSwgY29sID0gInRvbWF0byIpDQpgYGANCg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KcXFub3Jtc2ltKHNhbXBsZSA9IGNhbF9mYXQsIGRhdGEgPSBtY2RvbmFsZHMpDQoNCmBgYA0KDQpMaW5lIGRvZXMgbm90IHNlZW0gdG8gZm9sbG93IHRoZSBzYW1lIHNsb3BlLCBkb2VzIG5vdCBhcHBlYXIgbm9ybWFsLiANCg0KYGBge3J9DQoxIC0gcG5vcm0ocSA9IDYwMCwgbWVhbiA9IGRxbWVhbiwgc2QgPSBkcXNkKQ0KDQpgYGANCg0KYGBge3J9DQpkYWlyeV9xdWVlbiAlPiUgDQogIGZpbHRlcihjYWxfZmF0ID4gNjAwKSAlPiUNCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBuKCkgLyBucm93KGRhaXJ5X3F1ZWVuKSkNCmBgYA0KDQojIyMgRXhlcmNpc2UgNg0KDQpXcml0ZSBvdXQgdHdvIHByb2JhYmlsaXR5IHF1ZXN0aW9ucyB0aGF0IHlvdSB3b3VsZCBsaWtlIHRvIGFuc3dlciBhYm91dCBhbnkgb2YgdGhlIHJlc3RhdXJhbnRzIGluIHRoaXMgZGF0YXNldC4gQ2FsY3VsYXRlIHRob3NlIHByb2JhYmlsaXRpZXMgdXNpbmcgYm90aCB0aGUgdGhlb3JldGljYWwgbm9ybWFsIGRpc3RyaWJ1dGlvbiBhcyB3ZWxsIGFzIHRoZSBlbXBpcmljYWwgZGlzdHJpYnV0aW9uIChmb3VyIHByb2JhYmlsaXRpZXMgaW4gYWxsKS4gV2hpY2ggb25lIGhhZCBhIGNsb3NlciBhZ3JlZW1lbnQgYmV0d2VlbiB0aGUgdHdvIG1ldGhvZHM/DQoNCioqYSkgV2hhdCBpcyB0aGUgcGVyY2VudGFnZSBvZiBNY0RvbmFsZCdzIG1lbnUgdGhhdCBpcyBvdmVyIDYwMCBjYWxvcmllcyBmcm9tIGZhdD8qKg0KDQpgYGB7cn0NCjEgLSBwbm9ybShxID0gNjAwLCBtZWFuID0gbWNtZWFuLCBzZCA9IG1jc2QpDQpgYGANCg0KOCUgb2YgTWNEb25hbGQncyBtZW51IGlzIG92ZXIgNjAwIGNhbG9yaWVzIGZyb20gZmF0Lg0KDQpgYGB7cn0NCnN1bShtY2RvbmFsZHMkY2FsX2ZhdCA+IDYwMCkgLyBsZW5ndGgobWNkb25hbGRzJGNhbF9mYXQpDQpgYGANCg0KNyUNCg0KKipiKSBXaGF0IGlzIHRoZSBwZWNlbnRhZ2Ugb2YgTWNEb25hbGQncyBtZW51IHRoYXQgaXMgb3ZlciA2MDAgY2Fsb3JpZXM/ICoqDQoNCmBgYHtyfQ0KDQptY21lYW4yIDwtIG1lYW4obWNkb25hbGRzJGNhbG9yaWVzKQ0KbWNzZDIgICA8LSBzZChtY2RvbmFsZHMkY2Fsb3JpZXMpDQoNCjEgLSBwbm9ybShxID0gNjAwLCBtZWFuID0gbWNtZWFuMiwgc2QgPSBtY3NkMikNCg0KYGBgDQoNCjU0JSBvZiB0aGUgdGhlb3JldGljYWwgbm9ybWFsLiANCg0KYGBge3J9DQpzdW0obWNkb25hbGRzJGNhbG9yaWVzID4gNjAwKSAvIGxlbmd0aChtY2RvbmFsZHMkY2Fsb3JpZXMpDQpgYGANCg0KNDIlIG9mIHRoZSByZWFsIGRhdGEuDQoNCioqQ2Fsb3JpZXMgZnJvbSBmYXQgYXJlIGNsb3NlciB0aGFuIG92ZXJhbGwgY2Fsb3JpZXMuKioNCg0KIyMjIEV4ZXJjaXNlIDcNCk5vdyBsZXTigJlzIGNvbnNpZGVyIHNvbWUgb2YgdGhlIG90aGVyIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldC4gT3V0IG9mIGFsbCB0aGUgZGlmZmVyZW50IHJlc3RhdXJhbnRzLCB3aGljaCBvbmVz4oCZIGRpc3RyaWJ1dGlvbiBpcyB0aGUgY2xvc2VzdCB0byBub3JtYWwgZm9yIHNvZGl1bT8NCg0KYGBge3J9DQpyZXN0YXVyYW50cyA8LSBmYXN0Zm9vZCAlPiUgDQogIGdyb3VwX2J5KHJlc3RhdXJhbnQpICU+JQ0KICBzZWxlY3QocmVzdGF1cmFudCwgc29kaXVtKSAlPiUgDQogIHN1bW1hcmlzZSggYXZnID0gbWVhbihzb2RpdW0pLCBzZF9zb2RpdW09IHNkKHNvZGl1bSksIC5ncm91cHMgPSAiZHJvcF9sYXN0IikNCmBgYA0KDQpgYGB7cn0NCmRhdGFyIDwtIGZhc3Rmb29kJT4lDQogICAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkFyYnlzIikNCmRtZWFuID0gcmVzdGF1cmFudHMkYXZnWzFdDQpkc2QgPSByZXN0YXVyYW50cyRzZF9zb2RpdW1bMV0NCg0KcXFub3Jtc2ltKHNhbXBsZSA9IHNvZGl1bSwgZGF0YSA9IGRhdGFyKQ0KDQpgYGANCg0KYGBge3J9DQpkYXRhciA8LSBmYXN0Zm9vZCU+JQ0KICAgIGZpbHRlcihyZXN0YXVyYW50ID09ICJCdXJnZXIgS2luZyIpDQogIA0KZG1lYW4gPSByZXN0YXVyYW50cyRhdmdbMl0NCmRzZCA9IHJlc3RhdXJhbnRzJHNkX3NvZGl1bVsyXQ0KDQpxcW5vcm1zaW0oc2FtcGxlID0gc29kaXVtLCBkYXRhID0gZGF0YXIpDQoNCmBgYA0KDQpgYGB7cn0NCmRhdGFyIDwtIGZhc3Rmb29kJT4lDQogICAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkNoaWNrIEZpbC1BIikNCiAgDQpxcW5vcm1zaW0oc2FtcGxlID0gc29kaXVtLCBkYXRhID0gZGF0YXIpDQoNCmBgYA0KDQpgYGB7cn0NCmRhdGFyIDwtIGZhc3Rmb29kJT4lDQogICAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIlNvbmljIikNCiAgDQpxcW5vcm1zaW0oc2FtcGxlID0gc29kaXVtLCBkYXRhID0gZGF0YXIpDQoNCmBgYA0KDQpgYGB7cn0NCmRhdGFyIDwtIGZhc3Rmb29kJT4lDQogICAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIlN1YndheSIpDQogIA0KcXFub3Jtc2ltKHNhbXBsZSA9IHNvZGl1bSwgZGF0YSA9IGRhdGFyKQ0KDQpgYGANCg0KYGBge3J9DQpkYXRhciA8LSBmYXN0Zm9vZCU+JQ0KICAgIGZpbHRlcihyZXN0YXVyYW50ID09ICJUYWNvIEJlbGwiKQ0KICANCnFxbm9ybXNpbShzYW1wbGUgPSBzb2RpdW0sIGRhdGEgPSBkYXRhcikNCg0KYGBgDQoNCkkgd291bGQgc2F5IFRhY28gQmVsbA0KDQojIyMgRXhlcmNpc2UgOA0KTm90ZSB0aGF0IHNvbWUgb2YgdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBmb3Igc29kaXVtIGRpc3RyaWJ1dGlvbnMgc2VlbSB0byBoYXZlIGEgc3RlcHdpc2UgcGF0dGVybi4gd2h5IGRvIHlvdSB0aGluayB0aGlzIG1pZ2h0IGJlIHRoZSBjYXNlPw0KDQoqKkkgd291bGQgc2F5IHRoZSBkaXN0cmlidXRpb25zIGFyZSByaWdodCBvciBsZWZ0LXNrZXdlZC4qKg0KDQojIyMgRXhlcmNpc2UgOQ0KQXMgeW91IGNhbiBzZWUsIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBjYW4gYmUgdXNlZCBib3RoIHRvIGFzc2VzcyBub3JtYWxpdHkgYW5kIHZpc3VhbGl6ZSBza2V3bmVzcy4gTWFrZSBhIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90IGZvciB0aGUgdG90YWwgY2FyYm9oeWRyYXRlcyBmcm9tIGEgcmVzdGF1cmFudCBvZiB5b3VyIGNob2ljZS4gQmFzZWQgb24gdGhpcyBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCwgaXMgdGhpcyB2YXJpYWJsZSBsZWZ0IHNrZXdlZCwgc3ltbWV0cmljLCBvciByaWdodCBza2V3ZWQ/DQpVc2UgYSBoaXN0b2dyYW0gdG8gY29uZmlybSB5b3VyIGZpbmRpbmdzDQoNCmBgYHtyfQ0KZGF0YXIgPC0gZmFzdGZvb2QlPiUNCiAgICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiVGFjbyBCZWxsIikNCiAgDQpxcW5vcm1zaW0oc2FtcGxlID0gdG90YWxfY2FyYiwgZGF0YSA9IGRhdGFyKQ0KYGBgDQoNCkJhc2VkIG9uIHRoaXMsIEkgd291bGQgc2F5IHRoZSBoaXN0b2dyYW0gaXMgYWxtb3N0IG5vcm1hbCBhbmQgc2xpZ2h0bHkgcmlnaHQgc2tld2VkLg0KDQpgYGB7cn0NCmRtZWFuIDwtIG1lYW4oZGF0YXIkdG90YWxfY2FyYikNCmRzZCAgIDwtIHNkKGRhdGFyJHRvdGFsX2NhcmIpDQoNCmdncGxvdChkYXRhID0gbWNkb25hbGRzLCBhZXMoeCA9IHRvdGFsX2NhcmIpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pLCBjb2xvcj0iYmx1ZSIpICsNCiAgICAgICAgc3RhdF9mdW5jdGlvbihmdW4gPSBkbm9ybSwgYXJncyA9IGMobWVhbiA9IGRtZWFuLCBzZCA9IGRzZCksIGNvbCA9ICJ0b21hdG8iKQ0KYGBgDQoNCkl0IGFwcGVhcnMgdGhlIGNvbmNsdXNpb25zIHdlcmUgY29ycmVjdC4NCi4uLg0KDQo=