library(tidyverse)
library(openintro)
library(infer)
Exercise 1
The cases are about 13583 school aged children. Remember that you can answer this question by viewing the data in the data viewer or by using the following command:
Exercise 2
- How many observations are we missing weights from?
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 29.94 56.25 64.41 67.91 76.20 180.99 1004
yrbss%>%
filter(is.na(weight))%>%
nrow()
## [1] 1004
1004 cases are missing weights.
yrbss <- yrbss %>%
mutate(physical_3plus = ifelse(yrbss$physically_active_7d > 2, "yes", "no"))
Exercise 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?
They look very similar. I was expecting people who were physical 3 times a week to weigh less on average but the medians look similar as well as the IQR.
yrbss$physical_3plus<-as.factor(yrbss$physical_3plus)
yrb_plot<-yrbss%>%
filter(!is.na(weight),!is.na(physical_3plus))
p<-ggplot(yrb_plot, aes(x=physical_3plus,y=weight))+
geom_boxplot()
p

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
## <fct> <dbl>
## 1 no 66.7
## 2 yes 68.4
## 3 <NA> 69.9
Exercise 4
- Are all conditions necessary for inference satisfied? Comment on each. You can compute the group sizes with the
summarize command above by defining a new variable with the definition n()
CONDITIONS FOR INFERENCE:
Independence:
it was a SRS and the two groups are not linked, necessarily one who excersizes 3 times a week plus cannot be in the group that doesn’t.
Size:
the groups are less than 10% of the total population of kids who excersize and those who don’t
in the study…
#create new variable n
yrbss<- yrbss %>%
mutate(n = ifelse(yrbss$physically_active_7d > 2, "yes", "no"))
yrbss$n<-as.factor(yrbss$n)
view(yrbss)
yrbss%>%
count(n)
## Storing counts in `nn`, as `n` already present in input
## i Use `name = "new_name"` to pick a new name.
## # A tibble: 3 x 2
## n nn
## <fct> <int>
## 1 no 4404
## 2 yes 8906
## 3 <NA> 273
Exercise 5
Hypothesis test:
H_0: the difference in the means between physical 3 plus and less than 3 are equal (mean1-mean2)=0 H_A: the weights are diffferent !=0
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`.

ggplot(data = null_dist, aes(x = stat)) +
geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Exercise 6
How many of these null permutations have a difference of at least obs_stat?
obs_diff_val<-obs_diff$stat[1]
null_list<-as.list(null_dist$stat)
null_abs<-lapply(null_list, FUN=function(x){abs(x)})
null_dist%>%
summarise(mean= mean(stat, na.rm=TRUE))
## # A tibble: 1 x 1
## mean
## <dbl>
## 1 0.0153
null_dist%>%
filter(stat>obs_diff_val)
## # A tibble: 0 x 2
## # ... with 2 variables: replicate <int>, stat <dbl>
none of the values are greater than the obs_diff_val
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
Exercise 7
Construct and record a confidence interval for the difference between the weights of those who exercise at least three times a week and those who don’t, and interpret this interval in context of the data.
# number of groups
n_1<-8406
n_2<-4408
x_bar_diff<-1.78
T_score<-pt(.025,4407,lower.tail = FALSE)*2
#get sigmas of samples
sigma_1<-yrbss %>%
group_by(physical_3plus) %>%
summarise(sd = sd(weight, na.rm = TRUE))%>%
filter(physical_3plus=="yes")%>%
select(sd)%>%
as.double()
## `summarise()` ungrouping output (override with `.groups` argument)
sigma_2<-yrbss %>%
group_by(physical_3plus) %>%
summarise(sd = sd(weight, na.rm = TRUE))%>%
filter(physical_3plus=="no")%>%
select(sd)%>%
as.double()
## `summarise()` ungrouping output (override with `.groups` argument)
SE<-sqrt((sigma_1^2 /n_1)+(sigma_2^2/n_2))
bot<-x_bar_diff-T_score*SE
top<-x_bar_diff+T_score*SE
cat("the 95% confidence interval for comparing the differnece between the means of these two independent samples is ",bot,"to",top)
## the 95% confidence interval for comparing the differnece between the means of these two independent samples is 1.465649 to 2.094351
I am not sure I fully understand the role of the null distribution that we calculated. This is a little backwards than I thought it would work but, maybe we can say, since H_0: there is NO difference bewteen the two groups falls OUTSIDE our 95% confidence interval, we can REJECT the null hypothesis.
Exercise 8
Calculate a 95% confidence interval for the average height in meters (height) and interpret it in context.
Explore height
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 1.270 1.600 1.680 1.691 1.780 2.110 1004
height<-yrbss%>%
filter(!is.na(height))%>%
select(height)
n<-nrow(height)
df<-n-1
height<-height$height
x_bar<-mean(height)
sigma<-sd(height)
SE<-sigma/sqrt(n)
t_star<-qt(.025,df=df)
#confidence interval
bot<-x_bar-abs(t_star*SE)
top<-x_bar+abs(t_star*SE)
cat("the 95% confidence interval is ",bot," to ",top)
## the 95% confidence interval is 1.689411 to 1.693071
t_star<-abs(qt(.05,df=df))
# the rest is the same
x_bar<-mean(height)
sigma<-sd(height)
SE<-sigma/sqrt(n)
bot_1<-x_bar-abs(t_star*SE)
top_1<-x_bar+abs(t_star*SE)
cat("the 90% confidence interval is ",bot_1," to ",top_1)
## the 90% confidence interval is 1.689705 to 1.692777
The difference is so slight, could this be due to the really tight standard error due to the sample size?
yrbss<-as.data.frame(yrbss)
ggplot(yrbss, aes(x=height))+
geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 1004 rows containing non-finite values (stat_bin).

Looking at the histogram. there is a huge peak at what appears to be the sample mean. This could cause the dramatic tightening of the confidence interval.
Exercise 10
Conduct a hypothesis test evaluating whether the average height is DIFFERENT for those who exercise at least three times a week and those who dont.
obs_diff <- yrbss %>%
specify(height ~ physical_3plus) %>%
calculate(stat = "diff in means", order = c("yes", "no"))
## Warning: Removed 1219 rows containing missing values.
hypothesis test:
H_0: the difference in the height for the two groups is zero
(mean_diff=0)
H_A: the difference in heights is NOT zero
(mean_diff!=0)
#physically active count
n_1<-yrbss%>%
filter(physical_3plus=="yes")%>%
nrow()
n_2<-yrbss%>%
filter(physical_3plus=="no")%>%
nrow()
#difference in mean height
obs_diff <- yrbss %>%
specify(height ~ physical_3plus) %>%
calculate(stat = "diff in means", order = c("yes", "no"))
## Warning: Removed 1219 rows containing missing values.
null<-0
#sd for physically active
sigma_1<-yrbss %>%
group_by(physical_3plus) %>%
summarise(sd = sd(height, na.rm = TRUE))%>%
filter(physical_3plus=="yes")%>%
select(sd)%>%
as.double()
## `summarise()` ungrouping output (override with `.groups` argument)
#sd for not physically active
sigma_2<-yrbss %>%
group_by(physical_3plus) %>%
summarise(sd = sd(height, na.rm = TRUE))%>%
filter(physical_3plus=="no")%>%
select(sd)%>%
as.double()
## `summarise()` ungrouping output (override with `.groups` argument)
#standard error
SE<-sqrt((sigma_1^2 /n_1)+(sigma_2^2/n_2))
T_score<-abs(qt(.025,4407))
bot<-x_bar_diff-T_score*SE
top<-x_bar_diff+T_score*SE
cat("the 95% confidence interval for the difference in mean height between physically active and non physically active is ",bot,"to",top)
## the 95% confidence interval for the difference in mean height between physically active and non physically active is 1.77628 to 1.78372
The null value falls outside this range so we can REJECT the null hypothesis that there is no difference in the mean height between physically active and non physically active subjects.
Exercise 11
Now, a non-inference task: Determine the number of different options there are in the dataset for the hours_tv_per_school_day there are.
yrbss%>%
filter(!is.na(hours_tv_per_school_day))%>%
select(hours_tv_per_school_day)%>%
unique()
## hours_tv_per_school_day
## 1 5+
## 4 2
## 5 3
## 10 do not watch
## 12 <1
## 14 4
## 19 1
Exercise 12
Come up with a research question evaluating the relationship between height or weight and sleep. Formulate the question in a way that it can be answered using a hypothesis test and/or a confidence interval. Report the statistical results, and also provide an explanation in plain language. Be sure to check all assumptions, state your α level, and conclude in context.
Exploring data:
yrbss$hours_tv_per_school_day<-as.factor(yrbss$hours_tv_per_school_day)
yrb_plot<-yrbss%>%
filter(!is.na(weight),!is.na(hours_tv_per_school_day))
p<-ggplot(yrb_plot, aes(x=hours_tv_per_school_day,y=weight))+
geom_boxplot()
p

looking at the box plots, it looks like there is no major difference between weight and how much TV one watches.
I would like to do an ANOVA test on this data:
CHECKS:
Normality:
the sample sizes are large enough that the skew can be overlooked.
Homogeneity of variance:
the IQR for the categories looks similar across groups.
##
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
desc<-describeBy(yrbss$weight,yrbss$hours_tv_per_school_day,mat=TRUE)
print(desc,row.names=FALSE)
## item group1 vars n mean sd median trimmed mad min
## 1 <1 1 2021 66.48461 15.70216 63.50 64.68001 13.44718 34.02
## 2 1 1 1667 67.37800 16.37220 64.41 65.69415 14.79635 34.02
## 3 2 1 2548 67.78624 16.42145 64.41 66.06289 14.79635 36.29
## 4 3 1 1995 69.03978 17.35373 65.77 67.15432 14.79635 37.65
## 5 4 1 976 68.90626 18.02983 65.77 67.02081 16.81268 34.93
## 6 5+ 1 1430 70.20328 19.25428 66.23 67.80165 16.13069 29.94
## 7 do not watch 1 1671 66.26614 15.75067 63.50 64.52085 13.44718 31.75
## max range skew kurtosis se
## 163.30 129.28 1.304176 2.665420 0.3492821
## 158.76 124.74 1.137777 1.955114 0.4009952
## 145.15 108.86 1.094115 1.497159 0.3253208
## 160.12 122.47 1.252392 2.329786 0.3885271
## 158.76 123.83 1.166745 1.828749 0.5771208
## 180.99 151.05 1.318850 2.351653 0.5091658
## 158.76 127.01 1.258166 2.409482 0.3853104
perform ANOVA test:
aov.out<-aov(weight ~ hours_tv_per_school_day, data=yrbss)
summary(aov.out)
## Df Sum Sq Mean Sq F value Pr(>F)
## hours_tv_per_school_day 6 20160 3360 11.83 2.8e-13 ***
## Residuals 12301 3492964 284
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 1275 observations deleted due to missingness
The p-value is very small so it looks like there is some effect, but we cannot yet say which group.
My guess would be that the high mean weight of the 7+ hours of tv group is the culprit.
NEXT STEPS:
we want to do a t test of each pair, with a Bonferroni adjustment to the alpha.
I will look at the difference in mean between the 5+ group and the 3 hour group (in the middle of the hours watched.)
#T_score<-(x_bar_middle-x_bar_lower) - null / SE (for comparisons)
n_five<-1430
n_three<-1995
x_bar_five<-70.20328
x_bar_three<-67.78624
#from the residuals
MSE<-284
null<-0
SE<-sqrt((MSE/n_five)+(MSE/n_three))
T_score<-((x_bar_five-x_bar_three)-null)/SE
df=12301
k<-7
K<-(k*(k-1))/2
a<-.05
(a_star<-a/K)
## [1] 0.002380952
use R to get the area under the curve of the t-distribution
p_value<-2*pt(T_score,df=df,lower.tail = FALSE)
recall we are using the MODIFIED significance level a*
## [1] 0.002380952
## [1] 3.50588e-05
since the p-value is LOWER than the a_star, we can reject the null hypothesis, and say that the difference between the means of 5+ hours of tv and 3 is statistically significant.
LS0tDQp0aXRsZTogIkluZmVyZW5jZSBmb3IgbnVtZXJpY2FsIGRhdGEiDQphdXRob3I6ICJKYWNrIFdyaWdodCINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDoNCiAgb3BlbmludHJvOjpsYWJfcmVwb3J0OiBkZWZhdWx0DQogIG9wZW5pbnRybzo6cGRmOiBkZWZhdWx0DQotLS0NCg0KYGBge3IgbG9hZC1wYWNrYWdlcywgbWVzc2FnZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShvcGVuaW50cm8pDQpsaWJyYXJ5KGluZmVyKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSAxDQoNClRoZSBjYXNlcyBhcmUgYWJvdXQgMTM1ODMgc2Nob29sIGFnZWQgY2hpbGRyZW4uDQpSZW1lbWJlciB0aGF0IHlvdSBjYW4gYW5zd2VyIHRoaXMgcXVlc3Rpb24gYnkgdmlld2luZyB0aGUgZGF0YSBpbiB0aGUgZGF0YSB2aWV3ZXIgb3INCmJ5IHVzaW5nIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoNCg0KYGBge3J9DQpkYXRhKHlyYnNzKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSAyDQoNCjEuICBIb3cgbWFueSBvYnNlcnZhdGlvbnMgYXJlIHdlIG1pc3Npbmcgd2VpZ2h0cyBmcm9tPw0KDQpgYGB7cn0NCnN1bW1hcnkoeXJic3Mkd2VpZ2h0KQ0KeXJic3MlPiUNCiAgZmlsdGVyKGlzLm5hKHdlaWdodCkpJT4lDQogIG5yb3coKQ0KYGBgDQoxMDA0IGNhc2VzIGFyZSBtaXNzaW5nIHdlaWdodHMuDQoNCmBgYHtyIGNyZWF0ZSBuZXcgdmFyfQ0KeXJic3MgPC0geXJic3MgJT4lIA0KICBtdXRhdGUocGh5c2ljYWxfM3BsdXMgPSBpZmVsc2UoeXJic3MkcGh5c2ljYWxseV9hY3RpdmVfN2QgPiAyLCAieWVzIiwgIm5vIikpDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDMNCg0KDQoxLiAgTWFrZSBhIHNpZGUtYnktc2lkZSBib3hwbG90IG9mIGBwaHlzaWNhbF8zcGx1c2AgYW5kIGB3ZWlnaHRgLiBJcyB0aGVyZSBhIA0KcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlc2UgdHdvIHZhcmlhYmxlcz8gV2hhdCBkaWQgeW91IGV4cGVjdCBhbmQgd2h5Pw0KDQpUaGV5IGxvb2sgdmVyeSBzaW1pbGFyLiBJIHdhcyBleHBlY3RpbmcgcGVvcGxlIHdobyB3ZXJlIHBoeXNpY2FsIDMgdGltZXMgYSB3ZWVrIHRvIHdlaWdoIGxlc3Mgb24gYXZlcmFnZSBidXQgdGhlIG1lZGlhbnMgbG9vayBzaW1pbGFyIGFzIHdlbGwgYXMgdGhlIElRUi4NCg0KYGBge3J9DQp5cmJzcyRwaHlzaWNhbF8zcGx1czwtYXMuZmFjdG9yKHlyYnNzJHBoeXNpY2FsXzNwbHVzKQ0KeXJiX3Bsb3Q8LXlyYnNzJT4lDQogIGZpbHRlcighaXMubmEod2VpZ2h0KSwhaXMubmEocGh5c2ljYWxfM3BsdXMpKQ0KcDwtZ2dwbG90KHlyYl9wbG90LCBhZXMoeD1waHlzaWNhbF8zcGx1cyx5PXdlaWdodCkpKw0KICBnZW9tX2JveHBsb3QoKQ0KcA0KDQpgYGANCg0KDQpgYGB7cn0NCnlyYnNzICU+JQ0KICBncm91cF9ieShwaHlzaWNhbF8zcGx1cykgJT4lDQogIHN1bW1hcmlzZShtZWFuX3dlaWdodCA9IG1lYW4od2VpZ2h0LCBuYS5ybSA9IFRSVUUpKQ0KDQpgYGANCg0KDQojIyMgRXhlcmNpc2UgNA0KDQoxLiAgQXJlIGFsbCBjb25kaXRpb25zIG5lY2Vzc2FyeSBmb3IgaW5mZXJlbmNlIHNhdGlzZmllZD8gQ29tbWVudCBvbiBlYWNoLiBZb3UgY2FuIA0KY29tcHV0ZSB0aGUgZ3JvdXAgc2l6ZXMgd2l0aCB0aGUgYHN1bW1hcml6ZWAgY29tbWFuZCBhYm92ZSBieSBkZWZpbmluZyBhIG5ldyB2YXJpYWJsZQ0Kd2l0aCB0aGUgZGVmaW5pdGlvbiBgbigpYA0KDQpDT05ESVRJT05TIEZPUiBJTkZFUkVOQ0U6DQoNCkluZGVwZW5kZW5jZToNCg0KaXQgd2FzIGEgU1JTIGFuZCB0aGUgdHdvIGdyb3VwcyBhcmUgbm90IGxpbmtlZCwgbmVjZXNzYXJpbHkgb25lIHdobyBleGNlcnNpemVzIDMgdGltZXMgYSB3ZWVrIHBsdXMgY2Fubm90IGJlIGluIHRoZSBncm91cCB0aGF0IGRvZXNuJ3QuDQoNClNpemU6DQoNCnRoZSBncm91cHMgYXJlIGxlc3MgdGhhbiAxMCUgb2YgdGhlIHRvdGFsIHBvcHVsYXRpb24gb2Yga2lkcyB3aG8gZXhjZXJzaXplIGFuZCB0aG9zZSB3aG8gZG9uJ3QNCg0KaW4gdGhlIHN0dWR5Li4uDQoNCmBgYHtyfQ0KI2NyZWF0ZSBuZXcgdmFyaWFibGUgbg0KDQp5cmJzczwtIHlyYnNzICU+JSANCiAgbXV0YXRlKG4gPSBpZmVsc2UoeXJic3MkcGh5c2ljYWxseV9hY3RpdmVfN2QgPiAyLCAieWVzIiwgIm5vIikpDQoNCnlyYnNzJG48LWFzLmZhY3Rvcih5cmJzcyRuKQ0KDQp2aWV3KHlyYnNzKQ0KeXJic3MlPiUNCiBjb3VudChuKQ0KDQoNCg0KDQpgYGANCg0KDQojIyMgRXhlcmNpc2UgNQ0KDQpIeXBvdGhlc2lzIHRlc3Q6DQoNCkhfMDogdGhlIGRpZmZlcmVuY2UgaW4gdGhlIG1lYW5zIGJldHdlZW4gcGh5c2ljYWwgMyBwbHVzIGFuZCBsZXNzIHRoYW4gMyBhcmUgZXF1YWwgKG1lYW4xLW1lYW4yKT0wDQpIX0E6IHRoZSB3ZWlnaHRzIGFyZSBkaWZmZmVyZW50ICE9MA0KDQpgYGB7cn0NCm9ic19kaWZmIDwtIHlyYnNzICU+JQ0KICBzcGVjaWZ5KHdlaWdodCB+IHBoeXNpY2FsXzNwbHVzKSAlPiUNCiAgY2FsY3VsYXRlKHN0YXQgPSAiZGlmZiBpbiBtZWFucyIsIG9yZGVyID0gYygieWVzIiwgIm5vIikpDQoNCmBgYA0KDQoNCg0KYGBge3J9DQpudWxsX2Rpc3QgPC0geXJic3MgJT4lDQogIHNwZWNpZnkod2VpZ2h0IH4gcGh5c2ljYWxfM3BsdXMpICU+JQ0KICBoeXBvdGhlc2l6ZShudWxsID0gImluZGVwZW5kZW5jZSIpICU+JQ0KICBnZW5lcmF0ZShyZXBzID0gMTAwMCwgdHlwZSA9ICJwZXJtdXRlIikgJT4lDQogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoInllcyIsICJubyIpKQ0KDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IG51bGxfZGlzdCwgYWVzKHggPSBzdGF0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbSgpDQpgYGANCg0KDQpgYGB7cn0NCmdncGxvdChkYXRhID0gbnVsbF9kaXN0LCBhZXMoeCA9IHN0YXQpKSArDQogIGdlb21faGlzdG9ncmFtKCkNCmBgYA0KDQoNCg0KIyMjIEV4ZXJjaXNlIDYNCg0KMS4NCg0KSG93IG1hbnkgb2YgdGhlc2UgbnVsbCBwZXJtdXRhdGlvbnMgaGF2ZSBhIGRpZmZlcmVuY2Ugb2YgYXQgbGVhc3Qgb2JzX3N0YXQ/DQoNCmBgYHtyfQ0Kb2JzX2RpZmZfdmFsPC1vYnNfZGlmZiRzdGF0WzFdDQoNCm51bGxfbGlzdDwtYXMubGlzdChudWxsX2Rpc3Qkc3RhdCkNCm51bGxfYWJzPC1sYXBwbHkobnVsbF9saXN0LCBGVU49ZnVuY3Rpb24oeCl7YWJzKHgpfSkNCg0KbnVsbF9kaXN0JT4lDQogIHN1bW1hcmlzZShtZWFuPSBtZWFuKHN0YXQsIG5hLnJtPVRSVUUpKQ0KDQpudWxsX2Rpc3QlPiUNCiAgZmlsdGVyKHN0YXQ+b2JzX2RpZmZfdmFsKQ0KDQpgYGANCg0Kbm9uZSBvZiB0aGUgdmFsdWVzIGFyZSBncmVhdGVyIHRoYW4gdGhlIG9ic19kaWZmX3ZhbA0KDQpgYGB7cn0NCm51bGxfZGlzdCAlPiUNCiAgZ2V0X3BfdmFsdWUob2JzX3N0YXQgPSBvYnNfZGlmZiwgZGlyZWN0aW9uID0gInR3b19zaWRlZCIpDQoNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSA3DQoNCjEuDQoNCkNvbnN0cnVjdCBhbmQgcmVjb3JkIGEgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgd2VpZ2h0cyBvZiB0aG9zZSB3aG8gZXhlcmNpc2UgYXQgbGVhc3QgdGhyZWUgdGltZXMgYSB3ZWVrIGFuZCB0aG9zZSB3aG8gZG9u4oCZdCwgYW5kIGludGVycHJldCB0aGlzIGludGVydmFsIGluIGNvbnRleHQgb2YgdGhlIGRhdGEuDQoNCmBgYHtyfQ0KIyBudW1iZXIgb2YgZ3JvdXBzDQpuXzE8LTg0MDYNCm5fMjwtNDQwOA0KDQp4X2Jhcl9kaWZmPC0xLjc4DQpUX3Njb3JlPC1wdCguMDI1LDQ0MDcsbG93ZXIudGFpbCA9IEZBTFNFKSoyDQoNCiNnZXQgc2lnbWFzIG9mIHNhbXBsZXMNCnNpZ21hXzE8LXlyYnNzICU+JQ0KICBncm91cF9ieShwaHlzaWNhbF8zcGx1cykgJT4lDQogIHN1bW1hcmlzZShzZCA9IHNkKHdlaWdodCwgbmEucm0gPSBUUlVFKSklPiUNCiAgZmlsdGVyKHBoeXNpY2FsXzNwbHVzPT0ieWVzIiklPiUNCiAgc2VsZWN0KHNkKSU+JQ0KICBhcy5kb3VibGUoKQ0Kc2lnbWFfMjwteXJic3MgJT4lDQogIGdyb3VwX2J5KHBoeXNpY2FsXzNwbHVzKSAlPiUNCiAgc3VtbWFyaXNlKHNkID0gc2Qod2VpZ2h0LCBuYS5ybSA9IFRSVUUpKSU+JQ0KICBmaWx0ZXIocGh5c2ljYWxfM3BsdXM9PSJubyIpJT4lDQogIHNlbGVjdChzZCklPiUNCiAgYXMuZG91YmxlKCkNCg0KU0U8LXNxcnQoKHNpZ21hXzFeMiAvbl8xKSsoc2lnbWFfMl4yL25fMikpDQoNCmJvdDwteF9iYXJfZGlmZi1UX3Njb3JlKlNFDQp0b3A8LXhfYmFyX2RpZmYrVF9zY29yZSpTRQ0KDQpjYXQoInRoZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgY29tcGFyaW5nIHRoZSBkaWZmZXJuZWNlIGJldHdlZW4gdGhlIG1lYW5zIG9mIHRoZXNlIHR3byBpbmRlcGVuZGVudCBzYW1wbGVzIGlzICIsYm90LCJ0byIsdG9wKQ0KDQpgYGANCg0KDQpJIGFtIG5vdCBzdXJlIEkgZnVsbHkgdW5kZXJzdGFuZCB0aGUgcm9sZSBvZiB0aGUgbnVsbCBkaXN0cmlidXRpb24gdGhhdCB3ZSBjYWxjdWxhdGVkLiBUaGlzIGlzIGEgbGl0dGxlIGJhY2t3YXJkcyB0aGFuIEkgdGhvdWdodCBpdCB3b3VsZCB3b3JrIGJ1dCwgbWF5YmUgd2UgY2FuIHNheSwgc2luY2UgSF8wOiB0aGVyZSBpcyBOTyBkaWZmZXJlbmNlIGJld3RlZW4gdGhlIHR3byBncm91cHMgZmFsbHMgT1VUU0lERSBvdXIgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwsIHdlIGNhbiBSRUpFQ1QgdGhlIG51bGwgaHlwb3RoZXNpcy4gDQoNCiMjIyBFeGVyY2lzZSA4DQoNCjEuDQoNCkNhbGN1bGF0ZSBhIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgYXZlcmFnZSBoZWlnaHQgaW4gbWV0ZXJzIChoZWlnaHQpIGFuZCBpbnRlcnByZXQgaXQgaW4gY29udGV4dC4NCg0KRXhwbG9yZSBoZWlnaHQNCmBgYHtyfQ0Kc3VtbWFyeSh5cmJzcyRoZWlnaHQpDQpoZWlnaHQ8LXlyYnNzJT4lDQogIGZpbHRlcighaXMubmEoaGVpZ2h0KSklPiUNCiAgc2VsZWN0KGhlaWdodCkNCg0KbjwtbnJvdyhoZWlnaHQpDQpkZjwtbi0xDQpoZWlnaHQ8LWhlaWdodCRoZWlnaHQNCg0KDQp4X2JhcjwtbWVhbihoZWlnaHQpDQpzaWdtYTwtc2QoaGVpZ2h0KQ0KU0U8LXNpZ21hL3NxcnQobikNCnRfc3RhcjwtcXQoLjAyNSxkZj1kZikNCg0KI2NvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KYm90PC14X2Jhci1hYnModF9zdGFyKlNFKQ0KdG9wPC14X2JhcithYnModF9zdGFyKlNFKQ0KDQpjYXQoInRoZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBpcyAiLGJvdCwiIHRvICIsdG9wKQ0KDQpgYGANCg0KDQpgYGB7cn0NCnRfc3RhcjwtYWJzKHF0KC4wNSxkZj1kZikpDQojIHRoZSByZXN0IGlzIHRoZSBzYW1lDQp4X2JhcjwtbWVhbihoZWlnaHQpDQpzaWdtYTwtc2QoaGVpZ2h0KQ0KU0U8LXNpZ21hL3NxcnQobikNCmJvdF8xPC14X2Jhci1hYnModF9zdGFyKlNFKQ0KdG9wXzE8LXhfYmFyK2Ficyh0X3N0YXIqU0UpDQoNCmNhdCgidGhlIDkwJSBjb25maWRlbmNlIGludGVydmFsIGlzICIsYm90XzEsIiB0byAiLHRvcF8xKQ0KYGBgDQoNClRoZSBkaWZmZXJlbmNlIGlzIHNvIHNsaWdodCwgY291bGQgdGhpcyBiZSBkdWUgdG8gdGhlIHJlYWxseSB0aWdodCBzdGFuZGFyZCBlcnJvciBkdWUgdG8gdGhlIHNhbXBsZSBzaXplPw0KDQoNCmBgYHtyfQ0KeXJic3M8LWFzLmRhdGEuZnJhbWUoeXJic3MpDQpnZ3Bsb3QoeXJic3MsIGFlcyh4PWhlaWdodCkpKw0KICBnZW9tX2hpc3RvZ3JhbSgpDQoNCmBgYA0KDQpMb29raW5nIGF0IHRoZSBoaXN0b2dyYW0uIHRoZXJlIGlzIGEgaHVnZSBwZWFrIGF0IHdoYXQgYXBwZWFycyB0byBiZSB0aGUgc2FtcGxlIG1lYW4uIFRoaXMgY291bGQgY2F1c2UgdGhlIGRyYW1hdGljIHRpZ2h0ZW5pbmcgb2YgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCg0KIyMjIEV4ZXJjaXNlIDEwDQoNCkNvbmR1Y3QgYSBoeXBvdGhlc2lzIHRlc3QgZXZhbHVhdGluZyB3aGV0aGVyIHRoZSBhdmVyYWdlIGhlaWdodCBpcyBESUZGRVJFTlQgZm9yIHRob3NlIHdobyBleGVyY2lzZSBhdCBsZWFzdCB0aHJlZSB0aW1lcyBhIHdlZWsgYW5kIHRob3NlIHdobyBkb250Lg0KDQpgYGB7cn0NCm9ic19kaWZmIDwtIHlyYnNzICU+JQ0KICBzcGVjaWZ5KGhlaWdodCB+IHBoeXNpY2FsXzNwbHVzKSAlPiUNCiAgY2FsY3VsYXRlKHN0YXQgPSAiZGlmZiBpbiBtZWFucyIsIG9yZGVyID0gYygieWVzIiwgIm5vIikpDQpgYGANCg0KaHlwb3RoZXNpcyB0ZXN0Og0KDQpIXzA6IHRoZSBkaWZmZXJlbmNlIGluIHRoZSBoZWlnaHQgZm9yIHRoZSB0d28gZ3JvdXBzIGlzIHplcm8gDQoNCihtZWFuX2RpZmY9MCkNCg0KSF9BOiB0aGUgZGlmZmVyZW5jZSBpbiBoZWlnaHRzIGlzIE5PVCB6ZXJvIA0KDQoobWVhbl9kaWZmIT0wKQ0KDQpgYGB7cn0NCiNwaHlzaWNhbGx5IGFjdGl2ZSBjb3VudA0Kbl8xPC15cmJzcyU+JQ0KICBmaWx0ZXIocGh5c2ljYWxfM3BsdXM9PSJ5ZXMiKSU+JQ0KICBucm93KCkNCm5fMjwteXJic3MlPiUNCiAgZmlsdGVyKHBoeXNpY2FsXzNwbHVzPT0ibm8iKSU+JQ0KICBucm93KCkNCiNkaWZmZXJlbmNlIGluIG1lYW4gaGVpZ2h0DQpvYnNfZGlmZiA8LSB5cmJzcyAlPiUNCiAgc3BlY2lmeShoZWlnaHQgfiBwaHlzaWNhbF8zcGx1cykgJT4lDQogIGNhbGN1bGF0ZShzdGF0ID0gImRpZmYgaW4gbWVhbnMiLCBvcmRlciA9IGMoInllcyIsICJubyIpKQ0KbnVsbDwtMA0KI3NkIGZvciBwaHlzaWNhbGx5IGFjdGl2ZQ0Kc2lnbWFfMTwteXJic3MgJT4lDQogIGdyb3VwX2J5KHBoeXNpY2FsXzNwbHVzKSAlPiUNCiAgc3VtbWFyaXNlKHNkID0gc2QoaGVpZ2h0LCBuYS5ybSA9IFRSVUUpKSU+JQ0KICBmaWx0ZXIocGh5c2ljYWxfM3BsdXM9PSJ5ZXMiKSU+JQ0KICBzZWxlY3Qoc2QpJT4lDQogIGFzLmRvdWJsZSgpDQojc2QgZm9yIG5vdCBwaHlzaWNhbGx5IGFjdGl2ZQ0Kc2lnbWFfMjwteXJic3MgJT4lDQogIGdyb3VwX2J5KHBoeXNpY2FsXzNwbHVzKSAlPiUNCiAgc3VtbWFyaXNlKHNkID0gc2QoaGVpZ2h0LCBuYS5ybSA9IFRSVUUpKSU+JQ0KICBmaWx0ZXIocGh5c2ljYWxfM3BsdXM9PSJubyIpJT4lDQogIHNlbGVjdChzZCklPiUNCiAgYXMuZG91YmxlKCkNCiNzdGFuZGFyZCBlcnJvcg0KU0U8LXNxcnQoKHNpZ21hXzFeMiAvbl8xKSsoc2lnbWFfMl4yL25fMikpDQpUX3Njb3JlPC1hYnMocXQoLjAyNSw0NDA3KSkNCg0KYm90PC14X2Jhcl9kaWZmLVRfc2NvcmUqU0UNCnRvcDwteF9iYXJfZGlmZitUX3Njb3JlKlNFDQoNCmNhdCgidGhlIDk1JSBjb25maWRlbmNlIGludGVydmFsIGZvciB0aGUgZGlmZmVyZW5jZSBpbiBtZWFuIGhlaWdodCBiZXR3ZWVuIHBoeXNpY2FsbHkgYWN0aXZlIGFuZCBub24gcGh5c2ljYWxseSBhY3RpdmUgaXMgIixib3QsInRvIix0b3ApDQoNCmBgYA0KDQpUaGUgbnVsbCB2YWx1ZSBmYWxscyBvdXRzaWRlIHRoaXMgcmFuZ2Ugc28gd2UgY2FuIFJFSkVDVCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlcmUgaXMgbm8gZGlmZmVyZW5jZSBpbiB0aGUgbWVhbiBoZWlnaHQgYmV0d2VlbiBwaHlzaWNhbGx5IGFjdGl2ZSBhbmQgbm9uIHBoeXNpY2FsbHkgYWN0aXZlIHN1YmplY3RzLg0KDQojIyMgRXhlcmNpc2UgMTENCg0KMS4NCg0KTm93LCBhIG5vbi1pbmZlcmVuY2UgdGFzazogRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZGlmZmVyZW50IG9wdGlvbnMgdGhlcmUgYXJlIGluIHRoZSBkYXRhc2V0IGZvciB0aGUgaG91cnNfdHZfcGVyX3NjaG9vbF9kYXkgdGhlcmUgYXJlLg0KDQpgYGB7cn0NCnlyYnNzJT4lDQogIGZpbHRlcighaXMubmEoaG91cnNfdHZfcGVyX3NjaG9vbF9kYXkpKSU+JQ0KICBzZWxlY3QoaG91cnNfdHZfcGVyX3NjaG9vbF9kYXkpJT4lDQogIHVuaXF1ZSgpDQpgYGANCg0KDQoNCiMjIyBFeGVyY2lzZSAxMg0KDQoxLg0KDQpDb21lIHVwIHdpdGggYSByZXNlYXJjaCBxdWVzdGlvbiBldmFsdWF0aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBoZWlnaHQgb3Igd2VpZ2h0IGFuZCBzbGVlcC4gRm9ybXVsYXRlIHRoZSBxdWVzdGlvbiBpbiBhIHdheSB0aGF0IGl0IGNhbiBiZSBhbnN3ZXJlZCB1c2luZyBhIGh5cG90aGVzaXMgdGVzdCBhbmQvb3IgYSBjb25maWRlbmNlIGludGVydmFsLiBSZXBvcnQgdGhlIHN0YXRpc3RpY2FsIHJlc3VsdHMsIGFuZCBhbHNvIHByb3ZpZGUgYW4gZXhwbGFuYXRpb24gaW4gcGxhaW4gbGFuZ3VhZ2UuIEJlIHN1cmUgdG8gY2hlY2sgYWxsIGFzc3VtcHRpb25zLCBzdGF0ZSB5b3VyIM6xIGxldmVsLCBhbmQgY29uY2x1ZGUgaW4gY29udGV4dC4NCg0KDQpFeHBsb3JpbmcgZGF0YToNCg0KYGBge3J9DQoNCnlyYnNzJGhvdXJzX3R2X3Blcl9zY2hvb2xfZGF5PC1hcy5mYWN0b3IoeXJic3MkaG91cnNfdHZfcGVyX3NjaG9vbF9kYXkpDQp5cmJfcGxvdDwteXJic3MlPiUNCiAgZmlsdGVyKCFpcy5uYSh3ZWlnaHQpLCFpcy5uYShob3Vyc190dl9wZXJfc2Nob29sX2RheSkpDQpwPC1nZ3Bsb3QoeXJiX3Bsb3QsIGFlcyh4PWhvdXJzX3R2X3Blcl9zY2hvb2xfZGF5LHk9d2VpZ2h0KSkrDQogIGdlb21fYm94cGxvdCgpDQpwDQpgYGANCg0KDQpsb29raW5nIGF0IHRoZSBib3ggcGxvdHMsIGl0IGxvb2tzIGxpa2UgdGhlcmUgaXMgbm8gbWFqb3IgZGlmZmVyZW5jZSBiZXR3ZWVuIHdlaWdodCBhbmQgaG93IG11Y2ggVFYgb25lIHdhdGNoZXMuIA0KDQpJIHdvdWxkIGxpa2UgdG8gZG8gYW4gQU5PVkEgdGVzdCBvbiB0aGlzIGRhdGE6DQoNCkNIRUNLUzoNCg0KTm9ybWFsaXR5Og0KDQp0aGUgc2FtcGxlIHNpemVzIGFyZSBsYXJnZSBlbm91Z2ggdGhhdCB0aGUgc2tldyBjYW4gYmUgb3Zlcmxvb2tlZC4NCg0KSG9tb2dlbmVpdHkgb2YgdmFyaWFuY2U6DQoNCnRoZSBJUVIgZm9yIHRoZSBjYXRlZ29yaWVzIGxvb2tzIHNpbWlsYXIgYWNyb3NzIGdyb3Vwcy4gDQoNCmBgYHtyfQ0KbGlicmFyeShwc3ljaCkNCmRlc2M8LWRlc2NyaWJlQnkoeXJic3Mkd2VpZ2h0LHlyYnNzJGhvdXJzX3R2X3Blcl9zY2hvb2xfZGF5LG1hdD1UUlVFKQ0KDQpwcmludChkZXNjLHJvdy5uYW1lcz1GQUxTRSkNCmBgYA0KDQoNCnBlcmZvcm0gQU5PVkEgdGVzdDoNCg0KYGBge3J9DQphb3Yub3V0PC1hb3Yod2VpZ2h0IH4gaG91cnNfdHZfcGVyX3NjaG9vbF9kYXksIGRhdGE9eXJic3MpDQoNCnN1bW1hcnkoYW92Lm91dCkNCg0KYGBgDQoNCg0KVGhlIHAtdmFsdWUgaXMgdmVyeSBzbWFsbCBzbyBpdCBsb29rcyBsaWtlIHRoZXJlIGlzIHNvbWUgZWZmZWN0LCBidXQgd2UgY2Fubm90IHlldCBzYXkgd2hpY2ggZ3JvdXAuDQoNCk15IGd1ZXNzIHdvdWxkIGJlIHRoYXQgdGhlIGhpZ2ggbWVhbiB3ZWlnaHQgb2YgdGhlIDcrIGhvdXJzIG9mIHR2IGdyb3VwIGlzIHRoZSBjdWxwcml0LiANCg0KTkVYVCBTVEVQUzoNCg0Kd2Ugd2FudCB0byBkbyBhIHQgdGVzdCBvZiBlYWNoIHBhaXIsIHdpdGggYSBCb25mZXJyb25pIGFkanVzdG1lbnQgdG8gdGhlIGFscGhhLg0KDQpJIHdpbGwgbG9vayBhdCB0aGUgZGlmZmVyZW5jZSBpbiBtZWFuIGJldHdlZW4gdGhlIDUrIGdyb3VwIGFuZCB0aGUgMyBob3VyIGdyb3VwIChpbiB0aGUgbWlkZGxlIG9mIHRoZSBob3VycyB3YXRjaGVkLikNCmBgYHtyfQ0KI1Rfc2NvcmU8LSh4X2Jhcl9taWRkbGUteF9iYXJfbG93ZXIpIC0gbnVsbCAvIFNFIChmb3IgY29tcGFyaXNvbnMpDQpuX2ZpdmU8LTE0MzANCm5fdGhyZWU8LTE5OTUNCnhfYmFyX2ZpdmU8LTcwLjIwMzI4DQp4X2Jhcl90aHJlZTwtNjcuNzg2MjQJDQojZnJvbSB0aGUgcmVzaWR1YWxzDQpNU0U8LTI4NA0KbnVsbDwtMA0KU0U8LXNxcnQoKE1TRS9uX2ZpdmUpKyhNU0Uvbl90aHJlZSkpDQpUX3Njb3JlPC0oKHhfYmFyX2ZpdmUteF9iYXJfdGhyZWUpLW51bGwpL1NFDQpkZj0xMjMwMQ0KazwtNw0KSzwtKGsqKGstMSkpLzINCmE8LS4wNQ0KKGFfc3RhcjwtYS9LKQ0KYGBgDQoNCg0KdXNlIFIgdG8gZ2V0IHRoZSBhcmVhIHVuZGVyIHRoZSBjdXJ2ZSBvZiB0aGUgdC1kaXN0cmlidXRpb24NCg0KYGBge3J9DQpwX3ZhbHVlPC0yKnB0KFRfc2NvcmUsZGY9ZGYsbG93ZXIudGFpbCA9IEZBTFNFKQ0KYGBgDQoNCg0KcmVjYWxsIHdlIGFyZSB1c2luZyB0aGUgTU9ESUZJRUQgc2lnbmlmaWNhbmNlIGxldmVsIGEqDQoNCmBgYHtyfQ0KcHJpbnQoYV9zdGFyKQ0KcHJpbnQocF92YWx1ZSkNCmBgYA0Kc2luY2UgdGhlIHAtdmFsdWUgaXMgTE9XRVIgdGhhbiB0aGUgYV9zdGFyLCB3ZSBjYW4gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMsIGFuZCBzYXkgdGhhdCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtZWFucyBvZiA1KyBob3VycyBvZiB0diBhbmQgMyBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiA=