#Inference for Numerical Data
library(tidyverse)
library(openintro)
library(infer)
data(yrbss)
Exercise 1
What are the cases in this data set? How many cases are there in our sample? Individual Youth behavior. There are 13,583 cases in our sample. Each case represents an individual student’s behavior and demographic info.
## Rows: 13,583
## Columns: 13
## $ age <int> 14, 14, 15, 15, 15, 15, 15, 14, 15, 15, 15...
## $ gender <chr> "female", "female", "female", "female", "f...
## $ grade <chr> "9", "9", "9", "9", "9", "9", "9", "9", "9...
## $ hispanic <chr> "not", "not", "hispanic", "not", "not", "n...
## $ race <chr> "Black or African American", "Black or Afr...
## $ height <dbl> NA, NA, 1.73, 1.60, 1.50, 1.57, 1.65, 1.88...
## $ weight <dbl> NA, NA, 84.37, 55.79, 46.72, 67.13, 131.54...
## $ helmet_12m <chr> "never", "never", "never", "never", "did n...
## $ text_while_driving_30d <chr> "0", NA, "30", "0", "did not drive", "did ...
## $ physically_active_7d <int> 4, 2, 7, 0, 2, 1, 4, 4, 5, 0, 0, 0, 4, 7, ...
## $ hours_tv_per_school_day <chr> "5+", "5+", "5+", "2", "3", "5+", "5+", "5...
## $ strength_training_7d <int> 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 3, 0, 0, 7, ...
## $ school_night_hours_sleep <chr> "8", "6", "<5", "6", "9", "8", "9", "6", "...
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 29.94 56.25 64.41 67.91 76.20 180.99 1004
Exercise 2
How many observations are we missing weights from? We’re missing 1,004.
yrbss <- yrbss %>%
mutate(physical_3plus = ifelse(yrbss$physically_active_7d > 2, "yes", "no"))
Excercise 3
Make a side-by-side boxplot of physical_3plus and weight. Is there a relationship between these two variables? What did you expect and why?
boxplot(yrbss$weight ~ yrbss$physical_3plus, col="orange", main="Distribution of Physical Activity and Weight", ylab="Weight", xlab="Physical Activity")

There appears to be minimal change based on the physical activity. The mean weight of the “yes” is slightly higher than the “no” and it appears to be a more normalized distribution. I expected the mean weight of the “no” to be higher based on the physical activity.
yrbss %>%
group_by(physical_3plus) %>%
summarise(mean_weight = mean(weight, na.rm = TRUE))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 3 x 2
## physical_3plus mean_weight
## <chr> <dbl>
## 1 no 66.7
## 2 yes 68.4
## 3 <NA> 69.9
###Exercise 4 The conditions we need for inference on one proportion are: Random: The data comes from a random or randomized experiment. Normal: The sampling distribution of p^ needs to be approximately normal — needs at least 10 expected successes and 10 expected failures. Independent: Individual observations need to be independent.
###Exercise 5 H0: There’s no statistical difference in weight due to exercise. H1: The average weights are different between those who exercise at least 3 times a week.
obs_diff <- yrbss %>%
specify(weight ~ physical_3plus) %>%
calculate(stat = "diff in means", order = c("yes", "no"))
## Warning: Removed 1219 rows containing missing values.
null_dist <- yrbss %>%
specify(weight ~ physical_3plus) %>%
hypothesize(null = "independence") %>%
generate(reps = 1000, type = "permute") %>%
calculate(stat = "diff in means", order = c("yes", "no"))
## Warning: Removed 1219 rows containing missing values.
ggplot(data = null_dist, aes(x = stat)) +
geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Exercise 6
null_dist %>%
filter(stat >= obs_diff)
## # A tibble: 0 x 2
## # ... with 2 variables: replicate <int>, stat <dbl>
We found no permutation with a difference with at least obs_stat.
null_dist %>%
get_p_value(obs_stat = obs_diff, direction = "two_sided")
## Warning: Please be cautious in reporting a p-value of 0. This result is an
## approximation based on the number of `reps` chosen in the `generate()` step. See
## `?get_p_value()` for more information.
## # A tibble: 1 x 1
## p_value
## <dbl>
## 1 0
What this warning means is that, although the result in calculations is 0, p-value is an approximation and not the real zero. As the number of repetitions grow, the p-value becomes increasingly small or approaches 0.
Exercise 7
p1 <- yrbss %>%
filter(physical_3plus == "yes") %>%
summarise(mean_weight = mean(weight, na.rm = TRUE),
total = n())
p2 <- yrbss %>%
filter(physical_3plus == "no") %>%
summarise(mean_weight = mean(weight, na.rm = TRUE),
total = n())
n <- 13583 - 1004
prop1 <- p1$total/n
prop2 <- p2$total/n
mean_diff <- p1$mean_weight - p2$mean_weight
se <- ( ((prop1 * (1 - prop1)) / n) + ((prop2 * (1 - prop2)) / n)) ** 0.5
z <- 1.96
me <-z * se
ci_95 <- c(mean_diff - me, mean_diff + me)
ci_95
## [1] 1.763068 1.786101
The 95% confidence interval of the difference between those who exercise regularly and those who do not is between 1.76 and 1.79kg. This means that there is a difference between those who exercise and those who do not and we should reject the null hypothesis.
Exercise 8
z = 1.96
mean_height <- mean(yrbss$height, na.rm = TRUE)
sd_height <- sd(yrbss$height, na.rm = TRUE)
total_height <- yrbss %>%
filter(!is.na(height)) %>%
summarise(n = n())
total_height <- total_height$n
ci_low <- mean_height - (z * (sd_height/sqrt(total_height)))
ci_high <- mean_height + (z * (sd_height/sqrt(total_height)))
ci_95 <- c(ci_low, ci_high)
ci_95
## [1] 1.689411 1.693071
The 95% confidence interval is between 1.6894 and 1.6930
Exercise 9
z = 1.64
#mean_height <- mean(yrbss$height, na.rm = TRUE)
#sd_height <- sd(yrbss$height, na.rm = TRUE)
#total_height <- yrbss %>%
# filter(!is.na(height)) %>%
# summarise(n = n())
#total_height <- total_height$n
ci_low <- mean_height - (z * (sd_height/sqrt(total_height)))
ci_high <- mean_height + (z * (sd_height/sqrt(total_height)))
ci_90 <- c(ci_low, ci_high)
ci_90
## [1] 1.689710 1.692772
The 90% confidence interval is more narrow: 1.6897 and 1.6927
Exercise 10
H0 = There’s no statistical difference in height between those who exercise regularly and those who don’t.
H1 = There is a difference in height between the two groups.
boxplot(yrbss$height ~ yrbss$physical_3plus, col="orange", main="Distribution of Physical Activity and Height", ylab="Height", xlab="Physical Activity")

There appears to be a difference in height between the two groups.
yrbss %>%
group_by(physical_3plus) %>%
summarise(mean_height = mean(height, na.rm = TRUE))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 3 x 2
## physical_3plus mean_height
## <chr> <dbl>
## 1 no 1.67
## 2 yes 1.70
## 3 <NA> 1.71
obs_diff_ht <- yrbss %>%
specify(height ~ physical_3plus) %>%
calculate(stat = "diff in means", order = c("yes", "no"))
## Warning: Removed 1219 rows containing missing values.
null_dist_ht <- yrbss %>%
specify(height ~ physical_3plus) %>%
hypothesize(null = "independence") %>%
generate(reps = 1000, type = "permute") %>%
calculate(stat = "diff in means", order = c("yes", "no"))
## Warning: Removed 1219 rows containing missing values.
null_dist_ht %>%
get_p_value(obs_stat = obs_diff_ht, direction = "two_sided")
## Warning: Please be cautious in reporting a p-value of 0. This result is an
## approximation based on the number of `reps` chosen in the `generate()` step. See
## `?get_p_value()` for more information.
## # A tibble: 1 x 1
## p_value
## <dbl>
## 1 0
What this warning means is that, although the result in calculations is 0, p-value is an approximation and not the real zero. As the number of repetitions grow, the p-value becomes increasingly small or approaches 0.
p1 <- yrbss %>%
filter(physical_3plus == "yes") %>%
summarise(mean_height = mean(height, na.rm = TRUE),
total = n())
p2 <- yrbss %>%
filter(physical_3plus == "no") %>%
summarise(mean_height = mean(height, na.rm = TRUE),
total = n())
n <- 12364
prop1 <- p1$total/n
prop2 <- p2$total/n
mean_diff <- p1$mean_height - p2$mean_height
se <- ( ((prop1 * (1 - prop1)) / n) + ((prop2 * (1 - prop2)) / n)) ** 0.5
z <- 1.96
me <-z * se
ci_95 <- c(mean_diff - me, mean_diff + me)
ci_95
## [1] 0.02605665 0.04919512
The 95% confidence interval of the difference between those who exercise regularly and those who do not is between 0.02 and 0.05. This means that there is a difference between those who exercise and those who do not and we should reject the null hypothesis.
Exercise 11
yrbss %>%
group_by(hours_tv_per_school_day) %>%
summarise(n = n(), .groups="drop_last")
## # A tibble: 8 x 2
## hours_tv_per_school_day n
## <chr> <int>
## 1 <1 2168
## 2 1 1750
## 3 2 2705
## 4 3 2139
## 5 4 1048
## 6 5+ 1595
## 7 do not watch 1840
## 8 <NA> 338
7 options, unless we count NA, then 8.
Exercise 12
Research question: Is there evidence that students weight is affected by the sleep time?
H0: There is no relationship between weight and sleep for students. H1: There is a relationship between weight and sleep.
α Level: .05 (95% confident)
yrbss <- yrbss %>%
mutate(sleep_7plus = ifelse(yrbss$school_night_hours_sleep > 6, "yes", "no"))
boxplot(yrbss$weight ~ yrbss$sleep_7plus, col="orange", main="Distribution of Good night sleep and Weight", ylab="Weight", xlab="Good night sleep")

The boxplot points to a slight difference in weight.
weight_no <- yrbss %>%
filter(sleep_7plus == "no") %>%
summarise(w_avg = mean(weight, na.rm = TRUE),
w_sd = sd(weight, na.rm=TRUE),
total = n())
weight_yes <- yrbss %>%
filter(sleep_7plus == "yes") %>%
summarise(w_avg = mean(weight, na.rm = TRUE),
w_sd = sd(weight, na.rm=TRUE),
total = n())
mean_diff <- weight_no$w_avg - weight_yes$w_avg
se <-
sqrt(
((weight_no$w_avg**2) / weight_no$total) +
((weight_yes$w_avg**2) / weight_yes$total))
ci_low <- mean_diff - 1.96 * se
ci_high <- mean_diff + 1.96 * se
ci_95 <- c(ci_low, ci_high)
ci_95
## [1] -0.9169308 3.9251705
Because the CI is between -0.92 and 3.92 we will accept the null hypothesis that there is no relationship between weight and sleep. These results are somewhat surprising. …
LS0tDQp0aXRsZTogIkRTNjA2LUxhYjciDQphdXRob3I6ICJHZW9yZ2UgQ3J1eiINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0DQotLS0NCg0KI0luZmVyZW5jZSBmb3IgTnVtZXJpY2FsIERhdGENCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkob3BlbmludHJvKQ0KbGlicmFyeShpbmZlcikNCmRhdGEoeXJic3MpDQoNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSAxDQoqKldoYXQgYXJlIHRoZSBjYXNlcyBpbiB0aGlzIGRhdGEgc2V0PyBIb3cgbWFueSBjYXNlcyBhcmUgdGhlcmUgaW4gb3VyIHNhbXBsZT8qKg0KSW5kaXZpZHVhbCBZb3V0aCBiZWhhdmlvci4gIFRoZXJlIGFyZSAxMyw1ODMgY2FzZXMgaW4gb3VyIHNhbXBsZS4gRWFjaCBjYXNlIHJlcHJlc2VudHMgYW4gaW5kaXZpZHVhbCBzdHVkZW50J3MgYmVoYXZpb3IgYW5kIGRlbW9ncmFwaGljIGluZm8uDQoNCmBgYHtyIGNvZGUtY2h1bmstbGFiZWx9DQpnbGltcHNlKHlyYnNzKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeSh5cmJzcyR3ZWlnaHQpDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDINCioqSG93IG1hbnkgb2JzZXJ2YXRpb25zIGFyZSB3ZSBtaXNzaW5nIHdlaWdodHMgZnJvbT8qKg0KV2UncmUgbWlzc2luZyAxLDAwNC4NCg0KDQpgYGB7cn0NCnlyYnNzIDwtIHlyYnNzICU+JSANCiAgbXV0YXRlKHBoeXNpY2FsXzNwbHVzID0gaWZlbHNlKHlyYnNzJHBoeXNpY2FsbHlfYWN0aXZlXzdkID4gMiwgInllcyIsICJubyIpKQ0KYGBgDQoNCiMjIyBFeGNlcmNpc2UgMw0KKipNYWtlIGEgc2lkZS1ieS1zaWRlIGJveHBsb3Qgb2YgcGh5c2ljYWxfM3BsdXMgYW5kIHdlaWdodC4gSXMgdGhlcmUgYSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGVzZSB0d28gdmFyaWFibGVzPyBXaGF0IGRpZCB5b3UgZXhwZWN0IGFuZCB3aHk/KioNCg0KYGBge3J9DQpib3hwbG90KHlyYnNzJHdlaWdodCB+IHlyYnNzJHBoeXNpY2FsXzNwbHVzLCBjb2w9Im9yYW5nZSIsIG1haW49IkRpc3RyaWJ1dGlvbiBvZiBQaHlzaWNhbCBBY3Rpdml0eSBhbmQgV2VpZ2h0IiwgeWxhYj0iV2VpZ2h0IiwgeGxhYj0iUGh5c2ljYWwgQWN0aXZpdHkiKQ0KYGBgDQoNClRoZXJlIGFwcGVhcnMgdG8gYmUgbWluaW1hbCBjaGFuZ2UgYmFzZWQgb24gdGhlIHBoeXNpY2FsIGFjdGl2aXR5LiAgVGhlIG1lYW4gd2VpZ2h0IG9mIHRoZSAieWVzIiBpcyBzbGlnaHRseSBoaWdoZXIgdGhhbiB0aGUgIm5vIiBhbmQgaXQgYXBwZWFycyB0byBiZSBhIG1vcmUgbm9ybWFsaXplZCBkaXN0cmlidXRpb24uICBJIGV4cGVjdGVkIHRoZSBtZWFuIHdlaWdodCBvZiB0aGUgIm5vIiB0byBiZSBoaWdoZXIgYmFzZWQgb24gdGhlIHBoeXNpY2FsIGFjdGl2aXR5LiANCg0KYGBge3J9DQp5cmJzcyAlPiUNCiAgZ3JvdXBfYnkocGh5c2ljYWxfM3BsdXMpICU+JQ0KICBzdW1tYXJpc2UobWVhbl93ZWlnaHQgPSBtZWFuKHdlaWdodCwgbmEucm0gPSBUUlVFKSkNCmBgYA0KDQojIyNFeGVyY2lzZSA0DQpUaGUgY29uZGl0aW9ucyB3ZSBuZWVkIGZvciBpbmZlcmVuY2Ugb24gb25lIHByb3BvcnRpb24gYXJlOg0KUmFuZG9tOiBUaGUgZGF0YSBjb21lcyBmcm9tIGEgcmFuZG9tIG9yIHJhbmRvbWl6ZWQgZXhwZXJpbWVudC4NCk5vcm1hbDogVGhlIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiBvZiBwXiBuZWVkcyB0byBiZSBhcHByb3hpbWF0ZWx5IG5vcm1hbCDigJQgbmVlZHMgYXQgbGVhc3QgMTAgZXhwZWN0ZWQgc3VjY2Vzc2VzIGFuZCAxMCBleHBlY3RlZCBmYWlsdXJlcy4NCkluZGVwZW5kZW50OiBJbmRpdmlkdWFsIG9ic2VydmF0aW9ucyBuZWVkIHRvIGJlIGluZGVwZW5kZW50LiANCg0KIyMjRXhlcmNpc2UgNQ0KSDA6IFRoZXJlJ3Mgbm8gc3RhdGlzdGljYWwgZGlmZmVyZW5jZSBpbiB3ZWlnaHQgZHVlIHRvIGV4ZXJjaXNlLiANCkgxOiBUaGUgYXZlcmFnZSB3ZWlnaHRzIGFyZSBkaWZmZXJlbnQgYmV0d2VlbiB0aG9zZSB3aG8gZXhlcmNpc2UgYXQgbGVhc3QgMyB0aW1lcyBhIHdlZWsuIA0KDQoNCmBgYHtyfQ0Kb2JzX2RpZmYgPC0geXJic3MgJT4lDQogIHNwZWNpZnkod2VpZ2h0IH4gcGh5c2ljYWxfM3BsdXMpICU+JQ0KICBjYWxjdWxhdGUoc3RhdCA9ICJkaWZmIGluIG1lYW5zIiwgb3JkZXIgPSBjKCJ5ZXMiLCAibm8iKSkNCg0KbnVsbF9kaXN0IDwtIHlyYnNzICU+JQ0KICBzcGVjaWZ5KHdlaWdodCB+IHBoeXNpY2FsXzNwbHVzKSAlPiUNCiAgaHlwb3RoZXNpemUobnVsbCA9ICJpbmRlcGVuZGVuY2UiKSAlPiUNCiAgZ2VuZXJhdGUocmVwcyA9IDEwMDAsIHR5cGUgPSAicGVybXV0ZSIpICU+JQ0KICBjYWxjdWxhdGUoc3RhdCA9ICJkaWZmIGluIG1lYW5zIiwgb3JkZXIgPSBjKCJ5ZXMiLCAibm8iKSkNCg0KZ2dwbG90KGRhdGEgPSBudWxsX2Rpc3QsIGFlcyh4ID0gc3RhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSA2DQoNCmBgYHtyfQ0KbnVsbF9kaXN0ICU+JQ0KICBmaWx0ZXIoc3RhdCA+PSBvYnNfZGlmZikNCmBgYA0KV2UgZm91bmQgbm8gcGVybXV0YXRpb24gd2l0aCBhIGRpZmZlcmVuY2Ugd2l0aCBhdCBsZWFzdCBvYnNfc3RhdC4NCg0KYGBge3J9DQpudWxsX2Rpc3QgJT4lDQogIGdldF9wX3ZhbHVlKG9ic19zdGF0ID0gb2JzX2RpZmYsIGRpcmVjdGlvbiA9ICJ0d29fc2lkZWQiKQ0KYGBgDQoNCldoYXQgdGhpcyB3YXJuaW5nIG1lYW5zIGlzIHRoYXQsIGFsdGhvdWdoIHRoZSByZXN1bHQgaW4gY2FsY3VsYXRpb25zIGlzIDAsIHAtdmFsdWUgaXMgYW4gKmFwcHJveGltYXRpb24qIGFuZCBub3QgdGhlIHJlYWwgemVyby4gIEFzIHRoZSBudW1iZXIgb2YgcmVwZXRpdGlvbnMgZ3JvdywgdGhlIHAtdmFsdWUgYmVjb21lcyBpbmNyZWFzaW5nbHkgc21hbGwgb3IgYXBwcm9hY2hlcyAwLg0KDQoNCiMjIyBFeGVyY2lzZSA3DQoNCmBgYHtyfQ0KDQpwMSA8LSB5cmJzcyAlPiUNCiAgICBmaWx0ZXIocGh5c2ljYWxfM3BsdXMgPT0gInllcyIpICU+JQ0KICAgIHN1bW1hcmlzZShtZWFuX3dlaWdodCA9IG1lYW4od2VpZ2h0LCBuYS5ybSA9IFRSVUUpLCANCiAgICAgICAgICAgICAgdG90YWwgPSBuKCkpDQpwMiA8LSB5cmJzcyAlPiUNCiAgZmlsdGVyKHBoeXNpY2FsXzNwbHVzID09ICJubyIpICU+JQ0KICAgIHN1bW1hcmlzZShtZWFuX3dlaWdodCA9IG1lYW4od2VpZ2h0LCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICB0b3RhbCA9IG4oKSkNCg0KbiA8LSAxMzU4MyAtIDEwMDQNCg0KcHJvcDEgPC0gcDEkdG90YWwvbg0KcHJvcDIgPC0gcDIkdG90YWwvbg0KDQptZWFuX2RpZmYgPC0gcDEkbWVhbl93ZWlnaHQgLSBwMiRtZWFuX3dlaWdodA0KDQpzZSA8LSAoICgocHJvcDEgKiAoMSAtIHByb3AxKSkgLyBuKSArICAoKHByb3AyICogKDEgLSBwcm9wMikpIC8gbikpICoqIDAuNQ0KeiA8LSAxLjk2DQoNCm1lIDwteiAqIHNlDQoNCmNpXzk1IDwtIGMobWVhbl9kaWZmIC0gbWUsIG1lYW5fZGlmZiArIG1lKQ0KDQpjaV85NQ0KDQpgYGANClRoZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBvZiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRob3NlIHdobyBleGVyY2lzZSByZWd1bGFybHkgYW5kIHRob3NlIHdobyBkbyBub3QgaXMgYmV0d2VlbiAxLjc2IGFuZCAxLjc5a2cuICBUaGlzIG1lYW5zIHRoYXQgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGhvc2Ugd2hvIGV4ZXJjaXNlIGFuZCB0aG9zZSB3aG8gZG8gbm90IGFuZCB3ZSBzaG91bGQgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMuDQoNCiMjIyBFeGVyY2lzZSA4DQoNCmBgYHtyfQ0KDQp6ID0gMS45Ng0KbWVhbl9oZWlnaHQgPC0gbWVhbih5cmJzcyRoZWlnaHQsIG5hLnJtID0gVFJVRSkNCnNkX2hlaWdodCA8LSBzZCh5cmJzcyRoZWlnaHQsIG5hLnJtID0gVFJVRSkNCnRvdGFsX2hlaWdodCA8LSB5cmJzcyAlPiUgDQogIGZpbHRlcighaXMubmEoaGVpZ2h0KSkgJT4lDQogIHN1bW1hcmlzZShuID0gbigpKQ0KDQp0b3RhbF9oZWlnaHQgPC0gdG90YWxfaGVpZ2h0JG4NCg0KY2lfbG93IDwtIG1lYW5faGVpZ2h0IC0gKHogKiAoc2RfaGVpZ2h0L3NxcnQodG90YWxfaGVpZ2h0KSkpDQpjaV9oaWdoIDwtIG1lYW5faGVpZ2h0ICsgKHogKiAoc2RfaGVpZ2h0L3NxcnQodG90YWxfaGVpZ2h0KSkpDQoNCmNpXzk1IDwtIGMoY2lfbG93LCBjaV9oaWdoKQ0KY2lfOTUNCmBgYA0KDQpUaGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgYmV0d2VlbiAxLjY4OTQgYW5kIDEuNjkzMA0KDQojIyMgRXhlcmNpc2UgOQ0KDQpgYGB7cn0NCnogPSAxLjY0DQojbWVhbl9oZWlnaHQgPC0gbWVhbih5cmJzcyRoZWlnaHQsIG5hLnJtID0gVFJVRSkNCiNzZF9oZWlnaHQgPC0gc2QoeXJic3MkaGVpZ2h0LCBuYS5ybSA9IFRSVUUpDQojdG90YWxfaGVpZ2h0IDwtIHlyYnNzICU+JSANCiMgIGZpbHRlcighaXMubmEoaGVpZ2h0KSkgJT4lDQojICBzdW1tYXJpc2UobiA9IG4oKSkNCg0KI3RvdGFsX2hlaWdodCA8LSB0b3RhbF9oZWlnaHQkbg0KDQpjaV9sb3cgPC0gbWVhbl9oZWlnaHQgLSAoeiAqIChzZF9oZWlnaHQvc3FydCh0b3RhbF9oZWlnaHQpKSkNCmNpX2hpZ2ggPC0gbWVhbl9oZWlnaHQgKyAoeiAqIChzZF9oZWlnaHQvc3FydCh0b3RhbF9oZWlnaHQpKSkNCg0KY2lfOTAgPC0gYyhjaV9sb3csIGNpX2hpZ2gpDQpjaV85MA0KYGBgDQoNClRoZSA5MCUgY29uZmlkZW5jZSBpbnRlcnZhbCBpcyBtb3JlIG5hcnJvdzogMS42ODk3IGFuZCAxLjY5MjcNCg0KIyMjIEV4ZXJjaXNlIDEwDQoNCkgwID0gVGhlcmUncyBubyBzdGF0aXN0aWNhbCBkaWZmZXJlbmNlIGluIGhlaWdodCBiZXR3ZWVuIHRob3NlIHdobyBleGVyY2lzZSByZWd1bGFybHkgYW5kIHRob3NlIHdobyBkb24ndC4NCg0KSDEgPSBUaGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4gaGVpZ2h0IGJldHdlZW4gdGhlIHR3byBncm91cHMuIA0KDQoNCmBgYHtyfQ0KDQpib3hwbG90KHlyYnNzJGhlaWdodCB+IHlyYnNzJHBoeXNpY2FsXzNwbHVzLCBjb2w9Im9yYW5nZSIsIG1haW49IkRpc3RyaWJ1dGlvbiBvZiBQaHlzaWNhbCBBY3Rpdml0eSBhbmQgSGVpZ2h0IiwgeWxhYj0iSGVpZ2h0IiwgeGxhYj0iUGh5c2ljYWwgQWN0aXZpdHkiKQ0KYGBgDQoNClRoZXJlIGFwcGVhcnMgdG8gYmUgYSBkaWZmZXJlbmNlIGluIGhlaWdodCBiZXR3ZWVuIHRoZSB0d28gZ3JvdXBzLiANCmBgYHtyfQ0KeXJic3MgJT4lDQogIGdyb3VwX2J5KHBoeXNpY2FsXzNwbHVzKSAlPiUNCiAgc3VtbWFyaXNlKG1lYW5faGVpZ2h0ID0gbWVhbihoZWlnaHQsIG5hLnJtID0gVFJVRSkpDQpgYGANCg0KYGBge3J9DQpvYnNfZGlmZl9odCA8LSB5cmJzcyAlPiUNCiAgc3BlY2lmeShoZWlnaHQgfiBwaHlzaWNhbF8zcGx1cykgJT4lDQogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoInllcyIsICJubyIpKQ0KDQpudWxsX2Rpc3RfaHQgPC0geXJic3MgJT4lDQogIHNwZWNpZnkoaGVpZ2h0IH4gcGh5c2ljYWxfM3BsdXMpICU+JQ0KICBoeXBvdGhlc2l6ZShudWxsID0gImluZGVwZW5kZW5jZSIpICU+JQ0KICBnZW5lcmF0ZShyZXBzID0gMTAwMCwgdHlwZSA9ICJwZXJtdXRlIikgJT4lDQogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoInllcyIsICJubyIpKQ0KDQpudWxsX2Rpc3RfaHQgJT4lDQogIGdldF9wX3ZhbHVlKG9ic19zdGF0ID0gb2JzX2RpZmZfaHQsIGRpcmVjdGlvbiA9ICJ0d29fc2lkZWQiKQ0KDQpgYGANCg0KDQpXaGF0IHRoaXMgd2FybmluZyBtZWFucyBpcyB0aGF0LCBhbHRob3VnaCB0aGUgcmVzdWx0IGluIGNhbGN1bGF0aW9ucyBpcyAwLCBwLXZhbHVlIGlzIGFuICphcHByb3hpbWF0aW9uKiBhbmQgbm90IHRoZSByZWFsIHplcm8uICBBcyB0aGUgbnVtYmVyIG9mIHJlcGV0aXRpb25zIGdyb3csIHRoZSBwLXZhbHVlIGJlY29tZXMgaW5jcmVhc2luZ2x5IHNtYWxsIG9yIGFwcHJvYWNoZXMgMC4NCg0KYGBge3J9DQoNCnAxIDwtIHlyYnNzICU+JQ0KICAgIGZpbHRlcihwaHlzaWNhbF8zcGx1cyA9PSAieWVzIikgJT4lDQogICAgc3VtbWFyaXNlKG1lYW5faGVpZ2h0ID0gbWVhbihoZWlnaHQsIG5hLnJtID0gVFJVRSksIA0KICAgICAgICAgICAgICB0b3RhbCA9IG4oKSkNCnAyIDwtIHlyYnNzICU+JQ0KICBmaWx0ZXIocGh5c2ljYWxfM3BsdXMgPT0gIm5vIikgJT4lDQogICAgc3VtbWFyaXNlKG1lYW5faGVpZ2h0ID0gbWVhbihoZWlnaHQsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgIHRvdGFsID0gbigpKQ0KDQpuIDwtIDEyMzY0DQoNCnByb3AxIDwtIHAxJHRvdGFsL24NCnByb3AyIDwtIHAyJHRvdGFsL24NCg0KbWVhbl9kaWZmIDwtIHAxJG1lYW5faGVpZ2h0IC0gcDIkbWVhbl9oZWlnaHQNCg0Kc2UgPC0gKCAoKHByb3AxICogKDEgLSBwcm9wMSkpIC8gbikgKyAgKChwcm9wMiAqICgxIC0gcHJvcDIpKSAvIG4pKSAqKiAwLjUNCnogPC0gMS45Ng0KDQptZSA8LXogKiBzZQ0KDQpjaV85NSA8LSBjKG1lYW5fZGlmZiAtIG1lLCBtZWFuX2RpZmYgKyBtZSkNCg0KY2lfOTUNCmBgYA0KDQpUaGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgb2YgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aG9zZSB3aG8gZXhlcmNpc2UgcmVndWxhcmx5IGFuZCB0aG9zZSB3aG8gZG8gbm90IGlzIGJldHdlZW4gMC4wMiBhbmQgMC4wNS4gIFRoaXMgbWVhbnMgdGhhdCB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgYmV0d2VlbiB0aG9zZSB3aG8gZXhlcmNpc2UgYW5kIHRob3NlIHdobyBkbyBub3QgYW5kIHdlIHNob3VsZCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcy4NCg0KDQojIyMgRXhlcmNpc2UgMTENCg0KYGBge3J9DQoNCnlyYnNzICU+JSANCiAgZ3JvdXBfYnkoaG91cnNfdHZfcGVyX3NjaG9vbF9kYXkpICU+JSANCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHM9ImRyb3BfbGFzdCIpDQoNCmBgYA0KDQo3IG9wdGlvbnMsIHVubGVzcyB3ZSBjb3VudCBOQSwgdGhlbiA4Lg0KDQoNCiMjIyBFeGVyY2lzZSAxMg0KDQpSZXNlYXJjaCBxdWVzdGlvbjogSXMgdGhlcmUgZXZpZGVuY2UgdGhhdCBzdHVkZW50cyB3ZWlnaHQgaXMgYWZmZWN0ZWQgYnkgdGhlIHNsZWVwIHRpbWU/DQoNCkgwOiBUaGVyZSBpcyBubyByZWxhdGlvbnNoaXAgYmV0d2VlbiB3ZWlnaHQgYW5kIHNsZWVwIGZvciBzdHVkZW50cy4NCkgxOiBUaGVyZSBpcyBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHdlaWdodCBhbmQgc2xlZXAuIA0KDQrOsSBMZXZlbDogLjA1ICg5NSUgY29uZmlkZW50KQ0KDQoNCmBgYHtyfQ0KDQp5cmJzcyA8LSB5cmJzcyAlPiUgDQogIG11dGF0ZShzbGVlcF83cGx1cyA9IGlmZWxzZSh5cmJzcyRzY2hvb2xfbmlnaHRfaG91cnNfc2xlZXAgPiA2LCAieWVzIiwgIm5vIikpDQoNCmJveHBsb3QoeXJic3Mkd2VpZ2h0IH4geXJic3Mkc2xlZXBfN3BsdXMsIGNvbD0ib3JhbmdlIiwgbWFpbj0iRGlzdHJpYnV0aW9uIG9mIEdvb2QgbmlnaHQgc2xlZXAgYW5kIFdlaWdodCIsIHlsYWI9IldlaWdodCIsIHhsYWI9Ikdvb2QgbmlnaHQgc2xlZXAiKQ0KYGBgDQoNClRoZSBib3hwbG90IHBvaW50cyB0byBhIHNsaWdodCBkaWZmZXJlbmNlIGluIHdlaWdodC4NCg0KYGBge3J9DQp3ZWlnaHRfbm8gPC0geXJic3MgJT4lIA0KICAgIGZpbHRlcihzbGVlcF83cGx1cyA9PSAibm8iKSAlPiUNCiAgICBzdW1tYXJpc2Uod19hdmcgPSBtZWFuKHdlaWdodCwgbmEucm0gPSBUUlVFKSwgDQogICAgICAgICAgICAgIHdfc2QgPSBzZCh3ZWlnaHQsIG5hLnJtPVRSVUUpLA0KICAgICAgICAgICAgICB0b3RhbCA9IG4oKSkNCg0Kd2VpZ2h0X3llcyA8LSB5cmJzcyAlPiUgDQogICAgZmlsdGVyKHNsZWVwXzdwbHVzID09ICJ5ZXMiKSAlPiUNCiAgICBzdW1tYXJpc2Uod19hdmcgPSBtZWFuKHdlaWdodCwgbmEucm0gPSBUUlVFKSwgDQogICAgICAgICAgICAgIHdfc2QgPSBzZCh3ZWlnaHQsIG5hLnJtPVRSVUUpLA0KICAgICAgICAgICAgICB0b3RhbCA9IG4oKSkNCg0KbWVhbl9kaWZmIDwtIHdlaWdodF9ubyR3X2F2ZyAtIHdlaWdodF95ZXMkd19hdmcNCg0Kc2UgPC0gDQogIHNxcnQoDQogICgod2VpZ2h0X25vJHdfYXZnKioyKSAvIHdlaWdodF9ubyR0b3RhbCkgKw0KICAoKHdlaWdodF95ZXMkd19hdmcqKjIpIC8gd2VpZ2h0X3llcyR0b3RhbCkpDQoNCmNpX2xvdyA8LSBtZWFuX2RpZmYgLSAxLjk2ICogc2UNCmNpX2hpZ2ggPC0gbWVhbl9kaWZmICsgMS45NiAqIHNlDQoNCmNpXzk1IDwtIGMoY2lfbG93LCBjaV9oaWdoKQ0KDQpjaV85NQ0KYGBgDQoNCkJlY2F1c2UgdGhlIENJIGlzIGJldHdlZW4gLTAuOTIgYW5kIDMuOTIgd2Ugd2lsbCBhY2NlcHQgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZXJlIGlzIG5vIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHdlaWdodCBhbmQgc2xlZXAuICBUaGVzZSByZXN1bHRzIGFyZSBzb21ld2hhdCBzdXJwcmlzaW5nLiANCi4uLg0KDQoNCg==