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?
Each set is unimodal and right skewed (the tail runs to the right). With that said, the frequency histogram(s) highlight a number of unique differences between the distributions - McDonald’s has a higher minimum, maximum and mean / center for fat calories, and the McDonald’s x axis increases in increments of 200 cals while the Dairy Queen one increases in increments of 100 cals.
mcdonalds <- fastfood %>%
filter(restaurant == "Mcdonalds")
dairy_queen <- fastfood %>%
filter(restaurant == "Dairy Queen")
summary(mcdonalds$cal_fat)
hist(mcdonalds$cal_fat)
summary(dairy_queen$cal_fat)
hist(dairy_queen$cal_fat)
Exercise 2
Based on the plot (below), does it appear that the data follow a nearly normal distribution?
Yes but not exactly. It appears that the data follow a nearly normal distribution, it’s just that the peaks are much higher and more spread our as they approach 0 (in density), and there’s an errant high density to the far right. With that said, there is a central peak ~220 cal_fat and the distribution does approach 0 (in density) near the min and max cal_fat values so the case can be made that it is a 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..)) +
stat_function(fun = dnorm, args = c(mean = dqmean, sd = dqsd), col = "tomato")
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.)
No, all of the points do not fall on the line. The probability plots for the simulated v real data are similar but not the same. The real data has a lesser slope from -2 to -1 and a greater slope from 1 to 2. Other than that nuance, the plots are very similar.
#Construct a normal probability (Q-Q) plot
ggplot(data = dairy_queen, aes(sample = cal_fat)) +
geom_line(stat = "qq")
#Simulate data from a normal distribution
sim_norm <- rnorm(n = nrow(dairy_queen), mean = dqmean, sd = dqsd)
#Plot the simulated data
ggplot(data = NULL, aes(sample = sim_norm)) +
geom_line(stat = "qq")
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 cal_fat are nearly normal?
Per lab text: A data set that is nearly normal will result in a probability plot where the points closely follow a diagonal line. Any deviations from normality lead to deviations of these points from that line.
The Dairy Queen cal_fat data (plotted below) is nearly normal. It closely follows a diagonal line and is incredibly similar to the plots generated by qqnormsim (ie. sim 7).
qqnormsim(sample = cal_fat, data = dairy_queen)
Exercise 5
Using the same technique, determine whether or not the calories from McDonald’s menu appear to come from a normal distribution.
The Dairy Queen cal_fat data (plotted below) is nearly normal. Although the slope is rather small near the beginning and rather larger later on, it does form a diagonal line and closely mimics a couple of the simulated plots up until these higher values (ie. sim 1 or 3).
qqnormsim(sample = cal_fat, data = mcdonalds)
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?
Question 1: What is the probability that a randomly chosen Arby’s product has more than 30g’s of protein?
#Arby's >30gs protein calculations:
arbys <- fastfood %>%
filter(restaurant == "Arbys")
a_mean <- mean(arbys$protein)
a_sd <- sd(arbys$protein)
1 - pnorm(q = 30, mean = a_mean, sd = a_sd)
arbys %>%
filter(protein > 30) %>%
summarise(percent = n() / nrow(arbys))
Question 2: What is the probability that a randomly chosen product from any of these fast food restaurants is less than 300 calories?
#< 300 cals calculations:
ff_mean <- mean(fastfood$calories)
ff_sd <- sd(fastfood$calories)
pnorm(q = 300, mean = ff_mean, sd = ff_sd)
fastfood %>%
filter(calories < 300) %>%
summarise(percent = n() / nrow(fastfood))
Although the calculated probabilities varied slightly for both calculations, those for probability that a randomly chosen product from any of these fast food restaurants was less than 300 calories were in closer agreement.
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?
Based on the plots below, Burger King and Chick Fil-A had the distributions closest to normal for sodium.
#Arbys sodium plot
arbys <- fastfood %>%
filter(restaurant == "Arbys")
qqnorm(arbys$sodium, main = "Arbys")
#Burger King sodium plot
bk <- fastfood %>%
filter(restaurant == "Burger King")
qqnorm(bk$sodium, main = "Burger King")
#Chick Fil-A sodium plot **
cfa <- fastfood %>%
filter(restaurant == "Chick Fil-A")
qqnorm(cfa$sodium, main = "Chick Fil-A")
#Dairy Queen sodium plot
dq <- fastfood %>%
filter(restaurant == "Dairy Queen")
qqnorm(dq$sodium, main = "Dairy Queen")
#McDonald's sodium plot
mcd <- fastfood %>%
filter(restaurant == "Mcdonalds")
qqnorm(mcd$sodium, main = "McDonald's")
#Sonic sodium plot
s <- fastfood %>%
filter(restaurant == "Sonic")
qqnorm(s$sodium, main = "Sonic")
#Subway sodium plot
sw <- fastfood %>%
filter(restaurant == "Subway")
qqnorm(sw$sodium, main = "Subway")
#Taco Bell sodium plot
tb <- fastfood %>%
filter(restaurant == "Taco Bell")
qqnorm(tb$sodium, main = "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?
The stepwise pattern may emerge with these distributions for sodium across a number of fast food chains because these restaurants typically offer an array of products (ie. french fries, soft drinks, sandwiches, salads) and the sodium content across these different food groups can vary quite a bit (ie. high in french fries or fried food and low in salads –> thus leading to different levels within the distribution.)
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.
Based on the normal probability plot (below), this variable (total carbohydrates) is right skewed and the histogram confirms this with data being concentrated on the left with a tail running to the right.
#Normal plot for total carbohydrates from Dairy Queen
qqnorm(dq$total_carb, main = "Dairy Queen Carbs")
qqline(dq$total_carb)
#Use a histogram to confirm.
hist(dq$total_carb)
LS0tDQp0aXRsZTogIkRBVEEgNjA2IExhYiA0Ig0KYXV0aG9yOiAiTWFnbnVzIFNrb25iZXJnIg0Kb3V0cHV0Og0KICBvcGVuaW50cm86OmxhYl9yZXBvcnQ6IGRlZmF1bHQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgaW5jbHVkZXM6DQogICAgICBpbl9oZWFkZXI6IGhlYWRlci5odG1sDQogICAgY3NzOiAuL2xhYi5jc3MNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgZWNobyA9IEZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGV2YWwgPSBUUlVFLCByZXN1bHRzID0gRkFMU0UsIGZpZy5zaG93ID0gImhpZGUiLCBtZXNzYWdlID0gRkFMU0UpDQpgYGANCg0KDQpgYGB7ciBsb2FkLXBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KG9wZW5pbnRybykNCg0KYGBgDQoNCiMjIyBFeGVyY2lzZSAxICAgDQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQoNCk1ha2UgYSBwbG90IChvciBwbG90cykgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBhbW91bnQgb2YgY2Fsb3JpZXMgZnJvbSBmYXQgb2YgdGhlIG9wdGlvbnMgZnJvbSB0aGVzZSB0d28gcmVzdGF1cmFudHMuIEhvdyBkbyB0aGVpciBjZW50ZXJzLCBzaGFwZXMsIGFuZCBzcHJlYWRzIGNvbXBhcmU/DQoNCjwvZGl2PiBcaGZpbGxcYnJlYWsNCg0KRWFjaCBzZXQgaXMgdW5pbW9kYWwgYW5kIHJpZ2h0IHNrZXdlZCAodGhlIHRhaWwgcnVucyB0byB0aGUgcmlnaHQpLiBXaXRoIHRoYXQgc2FpZCwgdGhlIGZyZXF1ZW5jeSBoaXN0b2dyYW0ocykgaGlnaGxpZ2h0IGEgbnVtYmVyIG9mIHVuaXF1ZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBkaXN0cmlidXRpb25zIC0gTWNEb25hbGQncyBoYXMgYSBoaWdoZXIgbWluaW11bSwgbWF4aW11bSBhbmQgbWVhbiAvIGNlbnRlciBmb3IgZmF0IGNhbG9yaWVzLCAqYW5kKiB0aGUgTWNEb25hbGQncyB4IGF4aXMgaW5jcmVhc2VzIGluIGluY3JlbWVudHMgb2YgMjAwIGNhbHMgd2hpbGUgdGhlIERhaXJ5IFF1ZWVuIG9uZSBpbmNyZWFzZXMgaW4gaW5jcmVtZW50cyBvZiAxMDAgY2Fscy4gDQoNCmBgYHtyfQ0KDQptY2RvbmFsZHMgPC0gZmFzdGZvb2QgJT4lDQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJNY2RvbmFsZHMiKQ0KZGFpcnlfcXVlZW4gPC0gZmFzdGZvb2QgJT4lDQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJEYWlyeSBRdWVlbiIpDQoNCnN1bW1hcnkobWNkb25hbGRzJGNhbF9mYXQpDQpoaXN0KG1jZG9uYWxkcyRjYWxfZmF0KQ0KDQpzdW1tYXJ5KGRhaXJ5X3F1ZWVuJGNhbF9mYXQpDQpoaXN0KGRhaXJ5X3F1ZWVuJGNhbF9mYXQpDQoNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSAyDQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQoNCkJhc2VkIG9uIHRoZSBwbG90IChiZWxvdyksIGRvZXMgaXQgYXBwZWFyIHRoYXQgdGhlIGRhdGEgZm9sbG93IGEgbmVhcmx5IG5vcm1hbCBkaXN0cmlidXRpb24/DQoNCjwvZGl2PiBcaGZpbGxcYnJlYWsNCg0KWWVzICpidXQqIG5vdCBleGFjdGx5LiBJdCBhcHBlYXJzIHRoYXQgdGhlIGRhdGEgZm9sbG93IGEgbmVhcmx5IG5vcm1hbCBkaXN0cmlidXRpb24sIGl0J3MganVzdCB0aGF0IHRoZSBwZWFrcyBhcmUgbXVjaCBoaWdoZXIgYW5kIG1vcmUgc3ByZWFkIG91ciBhcyB0aGV5IGFwcHJvYWNoIDAgKGluIGRlbnNpdHkpLCBhbmQgdGhlcmUncyBhbiBlcnJhbnQgaGlnaCBkZW5zaXR5IHRvIHRoZSBmYXIgcmlnaHQuIFdpdGggdGhhdCBzYWlkLCB0aGVyZSBpcyBhIGNlbnRyYWwgcGVhayB+MjIwIGNhbF9mYXQgYW5kIHRoZSBkaXN0cmlidXRpb24gZG9lcyBhcHByb2FjaCAwIChpbiBkZW5zaXR5KSBuZWFyIHRoZSBtaW4gYW5kIG1heCBjYWxfZmF0IHZhbHVlcyBzbyB0aGUgY2FzZSBjYW4gYmUgbWFkZSB0aGF0IGl0IGlzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KYGBge3J9DQoNCmRxbWVhbiA9IG1lYW4oZGFpcnlfcXVlZW4kY2FsX2ZhdCkNCmRxc2QgPSBzZChkYWlyeV9xdWVlbiRjYWxfZmF0KQ0KDQpnZ3Bsb3QoZGF0YSA9IGRhaXJ5X3F1ZWVuLCBhZXMoeCA9IGNhbF9mYXQpKSArDQogICAgICAgIGdlb21fYmxhbmsoKSArDQogICAgICAgIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pKSArDQogICAgICAgIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIGFyZ3MgPSBjKG1lYW4gPSBkcW1lYW4sIHNkID0gZHFzZCksIGNvbCA9ICJ0b21hdG8iKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSAzDQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQoNCk1ha2UgYSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBvZiBzaW1fbm9ybS4gRG8gYWxsIG9mIHRoZSBwb2ludHMgZmFsbCBvbiB0aGUgbGluZT8gSG93IGRvZXMgdGhpcyBwbG90IGNvbXBhcmUgdG8gdGhlIHByb2JhYmlsaXR5IHBsb3QgZm9yIHRoZSByZWFsIGRhdGE/IChTaW5jZSBzaW1fbm9ybSBpcyBub3QgYSBkYXRhZnJhbWUsIGl0IGNhbiBiZSBwdXQgZGlyZWN0bHkgaW50byB0aGUgc2FtcGxlIGFyZ3VtZW50IGFuZCB0aGUgZGF0YSBhcmd1bWVudCBjYW4gYmUgZHJvcHBlZC4pDQoNCjwvZGl2PiBcaGZpbGxcYnJlYWsNCg0KTm8sIGFsbCBvZiB0aGUgcG9pbnRzIGRvIG5vdCBmYWxsIG9uIHRoZSBsaW5lLiBUaGUgcHJvYmFiaWxpdHkgcGxvdHMgZm9yIHRoZSBzaW11bGF0ZWQgdiByZWFsIGRhdGEgYXJlIHNpbWlsYXIgYnV0IG5vdCB0aGUgc2FtZS4gVGhlIHJlYWwgZGF0YSBoYXMgYSBsZXNzZXIgc2xvcGUgZnJvbSAtMiB0byAtMSBhbmQgYSBncmVhdGVyIHNsb3BlIGZyb20gMSB0byAyLiBPdGhlciB0aGFuIHRoYXQgbnVhbmNlLCB0aGUgcGxvdHMgYXJlIHZlcnkgc2ltaWxhci4NCg0KYGBge3J9DQojQ29uc3RydWN0IGEgbm9ybWFsIHByb2JhYmlsaXR5IChRLVEpIHBsb3QNCmdncGxvdChkYXRhID0gZGFpcnlfcXVlZW4sIGFlcyhzYW1wbGUgPSBjYWxfZmF0KSkgKyANCiAgZ2VvbV9saW5lKHN0YXQgPSAicXEiKQ0KDQojU2ltdWxhdGUgZGF0YSBmcm9tIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbg0Kc2ltX25vcm0gPC0gcm5vcm0obiA9IG5yb3coZGFpcnlfcXVlZW4pLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpDQoNCiNQbG90IHRoZSBzaW11bGF0ZWQgZGF0YQ0KZ2dwbG90KGRhdGEgPSBOVUxMLCBhZXMoc2FtcGxlID0gc2ltX25vcm0pKSArDQogIGdlb21fbGluZShzdGF0ID0gInFxIikNCg0KYGBgDQoNCg0KIyMjIEV4ZXJjaXNlIDQNCg0KPHN0eWxlPg0KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJibHVlIj4NCg0KRG9lcyB0aGUgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QgZm9yIHRoZSBjYWxvcmllcyBmcm9tIGZhdCBsb29rIHNpbWlsYXIgdG8gdGhlIHBsb3RzIGNyZWF0ZWQgZm9yIHRoZSBzaW11bGF0ZWQgZGF0YT8gVGhhdCBpcywgZG8gdGhlIHBsb3RzIHByb3ZpZGUgZXZpZGVuY2UgdGhhdCB0aGUgY2FsX2ZhdCBhcmUgbmVhcmx5IG5vcm1hbD8NCg0KPC9kaXY+IFxoZmlsbFxicmVhaw0KDQpQZXIgbGFiIHRleHQ6ICpBIGRhdGEgc2V0IHRoYXQgaXMgbmVhcmx5IG5vcm1hbCB3aWxsIHJlc3VsdCBpbiBhIHByb2JhYmlsaXR5IHBsb3Qgd2hlcmUgdGhlIHBvaW50cyBjbG9zZWx5IGZvbGxvdyBhIGRpYWdvbmFsIGxpbmUuIEFueSBkZXZpYXRpb25zIGZyb20gbm9ybWFsaXR5IGxlYWQgdG8gZGV2aWF0aW9ucyBvZiB0aGVzZSBwb2ludHMgZnJvbSB0aGF0IGxpbmUuKg0KDQpUaGUgRGFpcnkgUXVlZW4gY2FsX2ZhdCBkYXRhIChwbG90dGVkIGJlbG93KSBpcyBuZWFybHkgbm9ybWFsLiBJdCBjbG9zZWx5IGZvbGxvd3MgYSBkaWFnb25hbCBsaW5lIGFuZCBpcyBpbmNyZWRpYmx5IHNpbWlsYXIgdG8gdGhlIHBsb3RzIGdlbmVyYXRlZCBieSBxcW5vcm1zaW0gKGllLiBzaW0gNykuDQoNCmBgYHtyfQ0KcXFub3Jtc2ltKHNhbXBsZSA9IGNhbF9mYXQsIGRhdGEgPSBkYWlyeV9xdWVlbikNCmBgYA0KDQojIyMgRXhlcmNpc2UgNQ0KDQo8c3R5bGU+DQpkaXYuYmx1ZSB7IGJhY2tncm91bmQtY29sb3I6I2U2ZjBmZjsgYm9yZGVyLXJhZGl1czogNXB4OyBwYWRkaW5nOiAyMHB4O30NCjwvc3R5bGU+DQo8ZGl2IGNsYXNzID0gImJsdWUiPg0KDQpVc2luZyB0aGUgc2FtZSB0ZWNobmlxdWUsIGRldGVybWluZSB3aGV0aGVyIG9yIG5vdCB0aGUgY2Fsb3JpZXMgZnJvbSBNY0RvbmFsZOKAmXMgbWVudSBhcHBlYXIgdG8gY29tZSBmcm9tIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbi4NCg0KPC9kaXY+IFxoZmlsbFxicmVhaw0KDQpUaGUgRGFpcnkgUXVlZW4gY2FsX2ZhdCBkYXRhIChwbG90dGVkIGJlbG93KSBpcyBuZWFybHkgbm9ybWFsLiBBbHRob3VnaCB0aGUgc2xvcGUgaXMgcmF0aGVyIHNtYWxsIG5lYXIgdGhlIGJlZ2lubmluZyBhbmQgcmF0aGVyIGxhcmdlciBsYXRlciBvbiwgaXQgZG9lcyBmb3JtIGEgZGlhZ29uYWwgbGluZSBhbmQgY2xvc2VseSBtaW1pY3MgYSBjb3VwbGUgb2YgdGhlIHNpbXVsYXRlZCBwbG90cyB1cCB1bnRpbCB0aGVzZSBoaWdoZXIgdmFsdWVzIChpZS4gc2ltIDEgb3IgMykuDQoNCmBgYHtyfQ0KcXFub3Jtc2ltKHNhbXBsZSA9IGNhbF9mYXQsIGRhdGEgPSBtY2RvbmFsZHMpDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDYNCg0KPHN0eWxlPg0KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJibHVlIj4NCg0KV3JpdGUgb3V0IHR3byBwcm9iYWJpbGl0eSBxdWVzdGlvbnMgdGhhdCB5b3Ugd291bGQgbGlrZSB0byBhbnN3ZXIgYWJvdXQgYW55IG9mIHRoZSByZXN0YXVyYW50cyBpbiB0aGlzIGRhdGFzZXQuIENhbGN1bGF0ZSB0aG9zZSBwcm9iYWJpbGl0aWVzIHVzaW5nIGJvdGggdGhlIHRoZW9yZXRpY2FsIG5vcm1hbCBkaXN0cmlidXRpb24gYXMgd2VsbCBhcyB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiAoZm91ciBwcm9iYWJpbGl0aWVzIGluIGFsbCkuIFdoaWNoIG9uZSBoYWQgYSBjbG9zZXIgYWdyZWVtZW50IGJldHdlZW4gdGhlIHR3byBtZXRob2RzPw0KDQo8L2Rpdj4gXGhmaWxsXGJyZWFrDQoNCioqUXVlc3Rpb24gMTogKiogV2hhdCBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCBhIHJhbmRvbWx5IGNob3NlbiBBcmJ5J3MgcHJvZHVjdCBoYXMgbW9yZSB0aGFuIDMwZydzIG9mIHByb3RlaW4/DQoNCmBgYHtyfQ0KDQojQXJieSdzID4zMGdzIHByb3RlaW4gY2FsY3VsYXRpb25zOiANCmFyYnlzIDwtIGZhc3Rmb29kICU+JQ0KICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiQXJieXMiKQ0KDQphX21lYW4gPC0gbWVhbihhcmJ5cyRwcm90ZWluKQ0KYV9zZCA8LSBzZChhcmJ5cyRwcm90ZWluKQ0KDQoxIC0gcG5vcm0ocSA9IDMwLCBtZWFuID0gYV9tZWFuLCBzZCA9IGFfc2QpDQoNCmFyYnlzICU+JSANCiAgZmlsdGVyKHByb3RlaW4gPiAzMCkgJT4lDQogIHN1bW1hcmlzZShwZXJjZW50ID0gbigpIC8gbnJvdyhhcmJ5cykpDQoNCmBgYA0KDQoqKlF1ZXN0aW9uIDI6ICoqIFdoYXQgaXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgYSByYW5kb21seSBjaG9zZW4gcHJvZHVjdCBmcm9tIGFueSBvZiB0aGVzZSBmYXN0IGZvb2QgcmVzdGF1cmFudHMgaXMgbGVzcyB0aGFuIDMwMCBjYWxvcmllcz8NCg0KYGBge3J9DQojPCAzMDAgY2FscyBjYWxjdWxhdGlvbnM6IA0KDQpmZl9tZWFuIDwtIG1lYW4oZmFzdGZvb2QkY2Fsb3JpZXMpDQpmZl9zZCA8LSBzZChmYXN0Zm9vZCRjYWxvcmllcykNCg0KcG5vcm0ocSA9IDMwMCwgbWVhbiA9IGZmX21lYW4sIHNkID0gZmZfc2QpDQoNCmZhc3Rmb29kICU+JSANCiAgZmlsdGVyKGNhbG9yaWVzIDwgMzAwKSAlPiUNCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBuKCkgLyBucm93KGZhc3Rmb29kKSkNCg0KYGBgDQoNCkFsdGhvdWdoIHRoZSBjYWxjdWxhdGVkIHByb2JhYmlsaXRpZXMgdmFyaWVkICpzbGlnaHRseSogZm9yIGJvdGggY2FsY3VsYXRpb25zLCB0aG9zZSBmb3IgcHJvYmFiaWxpdHkgdGhhdCBhIHJhbmRvbWx5IGNob3NlbiBwcm9kdWN0IGZyb20gYW55IG9mIHRoZXNlIGZhc3QgZm9vZCByZXN0YXVyYW50cyB3YXMgbGVzcyB0aGFuIDMwMCBjYWxvcmllcyB3ZXJlIGluIGNsb3NlciBhZ3JlZW1lbnQuIA0KDQoNCiMjIyBFeGVyY2lzZSA3DQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQoNCk5vdyBsZXTigJlzIGNvbnNpZGVyIHNvbWUgb2YgdGhlIG90aGVyIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldC4gT3V0IG9mIGFsbCB0aGUgZGlmZmVyZW50IHJlc3RhdXJhbnRzLCB3aGljaCBvbmVz4oCZIGRpc3RyaWJ1dGlvbiBpcyB0aGUgY2xvc2VzdCB0byBub3JtYWwgZm9yIHNvZGl1bT8NCg0KPC9kaXY+IFxoZmlsbFxicmVhaw0KDQpCYXNlZCBvbiB0aGUgcGxvdHMgYmVsb3csICoqQnVyZ2VyIEtpbmcgYW5kIENoaWNrIEZpbC1BKiogaGFkIHRoZSBkaXN0cmlidXRpb25zIGNsb3Nlc3QgdG8gbm9ybWFsIGZvciBzb2RpdW0uDQoNCmBgYHtyfQ0KI0FyYnlzIHNvZGl1bSBwbG90DQphcmJ5cyA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkFyYnlzIikNCg0KcXFub3JtKGFyYnlzJHNvZGl1bSwgbWFpbiA9ICJBcmJ5cyIpDQoNCiNCdXJnZXIgS2luZyBzb2RpdW0gcGxvdA0KYmsgPC0gZmFzdGZvb2QgJT4lDQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJCdXJnZXIgS2luZyIpDQoNCnFxbm9ybShiayRzb2RpdW0sIG1haW4gPSAiQnVyZ2VyIEtpbmciKQ0KDQojQ2hpY2sgRmlsLUEgc29kaXVtIHBsb3QgKioNCmNmYSA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkNoaWNrIEZpbC1BIikNCg0KcXFub3JtKGNmYSRzb2RpdW0sIG1haW4gPSAiQ2hpY2sgRmlsLUEiKQ0KDQojRGFpcnkgUXVlZW4gc29kaXVtIHBsb3QNCmRxIDwtIGZhc3Rmb29kICU+JQ0KICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiRGFpcnkgUXVlZW4iKQ0KDQpxcW5vcm0oZHEkc29kaXVtLCBtYWluID0gIkRhaXJ5IFF1ZWVuIikNCg0KI01jRG9uYWxkJ3Mgc29kaXVtIHBsb3QNCm1jZCA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIk1jZG9uYWxkcyIpDQoNCnFxbm9ybShtY2Qkc29kaXVtLCBtYWluID0gIk1jRG9uYWxkJ3MiKQ0KDQojU29uaWMgc29kaXVtIHBsb3QNCnMgPC0gZmFzdGZvb2QgJT4lDQogIGZpbHRlcihyZXN0YXVyYW50ID09ICJTb25pYyIpDQoNCnFxbm9ybShzJHNvZGl1bSwgbWFpbiA9ICJTb25pYyIpDQoNCiNTdWJ3YXkgc29kaXVtIHBsb3QNCnN3IDwtIGZhc3Rmb29kICU+JQ0KICBmaWx0ZXIocmVzdGF1cmFudCA9PSAiU3Vid2F5IikNCg0KcXFub3JtKHN3JHNvZGl1bSwgbWFpbiA9ICJTdWJ3YXkiKQ0KDQojVGFjbyBCZWxsIHNvZGl1bSBwbG90DQp0YiA8LSBmYXN0Zm9vZCAlPiUNCiAgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIlRhY28gQmVsbCIpDQoNCnFxbm9ybSh0YiRzb2RpdW0sIG1haW4gPSAiVGFjbyBCZWxsIikNCg0KYGBgDQoNCg0KIyMjIEV4ZXJjaXNlIDgNCg0KPHN0eWxlPg0KZGl2LmJsdWUgeyBiYWNrZ3JvdW5kLWNvbG9yOiNlNmYwZmY7IGJvcmRlci1yYWRpdXM6IDVweDsgcGFkZGluZzogMjBweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJibHVlIj4NCg0KTm90ZSB0aGF0IHNvbWUgb2YgdGhlIG5vcm1hbCBwcm9iYWJpbGl0eSBwbG90cyBmb3Igc29kaXVtIGRpc3RyaWJ1dGlvbnMgc2VlbSB0byBoYXZlIGEgc3RlcHdpc2UgcGF0dGVybi4gd2h5IGRvIHlvdSB0aGluayB0aGlzIG1pZ2h0IGJlIHRoZSBjYXNlPw0KDQo8L2Rpdj4gXGhmaWxsXGJyZWFrDQoNCioqVGhlIHN0ZXB3aXNlIHBhdHRlcm4gbWF5IGVtZXJnZSB3aXRoIHRoZXNlIGRpc3RyaWJ1dGlvbnMgZm9yIHNvZGl1bSBhY3Jvc3MgYSBudW1iZXIgb2YgZmFzdCBmb29kIGNoYWlucyBiZWNhdXNlIHRoZXNlIHJlc3RhdXJhbnRzIHR5cGljYWxseSBvZmZlciBhbiBhcnJheSBvZiBwcm9kdWN0cyAoaWUuIGZyZW5jaCBmcmllcywgc29mdCBkcmlua3MsIHNhbmR3aWNoZXMsIHNhbGFkcykgYW5kIHRoZSBzb2RpdW0gY29udGVudCBhY3Jvc3MgdGhlc2UgZGlmZmVyZW50IGZvb2QgZ3JvdXBzIGNhbiB2YXJ5IHF1aXRlIGEgYml0IChpZS4gaGlnaCBpbiBmcmVuY2ggZnJpZXMgb3IgZnJpZWQgZm9vZCBhbmQgbG93IGluIHNhbGFkcyAtLT4gdGh1cyBsZWFkaW5nIHRvIGRpZmZlcmVudCBsZXZlbHMgd2l0aGluIHRoZSBkaXN0cmlidXRpb24uKSoqDQoNCiMjIyBFeGVyY2lzZSA5DQoNCjxzdHlsZT4NCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojZTZmMGZmOyBib3JkZXItcmFkaXVzOiA1cHg7IHBhZGRpbmc6IDIwcHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYmx1ZSI+DQoNCkFzIHlvdSBjYW4gc2VlLCBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdHMgY2FuIGJlIHVzZWQgYm90aCB0byBhc3Nlc3Mgbm9ybWFsaXR5IGFuZCB2aXN1YWxpemUgc2tld25lc3MuIE1ha2UgYSBub3JtYWwgcHJvYmFiaWxpdHkgcGxvdCBmb3IgdGhlIHRvdGFsIGNhcmJvaHlkcmF0ZXMgZnJvbSBhIHJlc3RhdXJhbnQgb2YgeW91ciBjaG9pY2UuIEJhc2VkIG9uIHRoaXMgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QsIGlzIHRoaXMgdmFyaWFibGUgbGVmdCBza2V3ZWQsIHN5bW1ldHJpYywgb3IgcmlnaHQgc2tld2VkPyAqVXNlIGEgaGlzdG9ncmFtIHRvIGNvbmZpcm0geW91ciBmaW5kaW5ncy4qDQoNCjwvZGl2PiBcaGZpbGxcYnJlYWsNCg0KKipCYXNlZCBvbiB0aGUgbm9ybWFsIHByb2JhYmlsaXR5IHBsb3QgKGJlbG93KSwgdGhpcyB2YXJpYWJsZSAodG90YWwgY2FyYm9oeWRyYXRlcykgaXMgcmlnaHQgc2tld2VkIGFuZCB0aGUgaGlzdG9ncmFtIGNvbmZpcm1zIHRoaXMgd2l0aCBkYXRhIGJlaW5nIGNvbmNlbnRyYXRlZCBvbiB0aGUgbGVmdCB3aXRoIGEgdGFpbCBydW5uaW5nIHRvIHRoZSByaWdodC4qKg0KDQpgYGB7cn0NCiNOb3JtYWwgcGxvdCBmb3IgdG90YWwgY2FyYm9oeWRyYXRlcyBmcm9tIERhaXJ5IFF1ZWVuDQpxcW5vcm0oZHEkdG90YWxfY2FyYiwgbWFpbiA9ICJEYWlyeSBRdWVlbiBDYXJicyIpDQpxcWxpbmUoZHEkdG90YWxfY2FyYikNCg0KI1VzZSBhIGhpc3RvZ3JhbSB0byBjb25maXJtLg0KaGlzdChkcSR0b3RhbF9jYXJiKQ0KYGBgDQo=