setwd("~/Desktop/MastersSem_1/1. Applied Analytics/Assignment4")
library(readr)
library(tidyr)
library(dplyr)
library(Hmisc)
library(dplyr)
library(car)
library(knitr)
library(ggplot2)
library(outliers)
library(caret)
library(editrules)

Question 1

Introduction

Length of hospital Stay (LOS) or Average Length of Stay (ALOS) is an important indicator of the use of medical services that is used to assess the efficiency of hospital management, patient quality of care, and functional evaluation. Stratified sampling has been ultilised to collect the ALOS from different Peer Group. Then we implemented hypothesis testing for gathering statistical evidence from samples and we would focus on two sample t-test. A sample of 30021 observations were gathered and analysed as follows.

Problem Statement

The average is calculated as the number of bed days for overnight stays divided by the number of overnight stays and is reported for selected conditions and procedures. It was thought that the mean value of the average of length of stay (ALOS) in a hospital was 4.5 days. We carry out this analysis to find out if this mean was correct.

Data Preprocessing

hospital <- read.csv("Assignment4A.csv", fileEncoding="latin1", stringsAsFactors = FALSE)
hospital_tidy <- hospital %>% select("Average.length.of.stay..days.")
colnames(hospital_tidy)[colnames(hospital_tidy)=="Average.length.of.stay..days."] <- "ALOS"
hospital_tidy$ALOStay <- hospital_tidy$ALOS %>% as.numeric(hospital_tidy$ALOS)
knitr::kable(head(hospital_tidy))
ALOS ALOStay
3.9 3.9
3.3 3.3
3.1 3.1
2.5 2.5
2.6 2.6
2.7 2.7

Summary

h<-hospital_tidy %>% summarise(Min = min(hospital_tidy$ALOStay,na.rm = TRUE),
                          Q1 = quantile(hospital_tidy$ALOStay,probs=.25,na.rm=TRUE),
                          Median = median(hospital_tidy$ALOStay, na.rm = TRUE),
                          Max = max(hospital_tidy$ALOStay,na.rm = TRUE),
                          Mean = mean(hospital_tidy$ALOStay, na.rm = TRUE),
                          SD = sd(hospital_tidy$ALOStay, na.rm = TRUE),
                          n = n(),
                          Missing = sum(is.na(hospital_tidy$ALOStay)))
knitr::kable(head(h))
Min Q1 Median Max Mean SD n Missing
1 2.5 3.4 13.9 3.956307 1.989426 30021 19770

Tidy Data

(19770/30021)*100
[1] 65.8539

Since the amount of missing data is large relative to the size of the data set (i.e. 66%). Hence, we need to replace the missing values in order not to bias the analysis. Since the data is skewed, we used the median value of the data to replace the missing values.

hospital_tidy$ALOStay[is.na(hospital_tidy$ALOStay)] <- median(hospital_tidy$ALOStay, na.rm = TRUE)

Descriptive Statistics and Visualizations

h_new<-hospital_tidy %>% summarise(Min = min(hospital_tidy$ALOStay,na.rm = TRUE),
                          Q1 = quantile(hospital_tidy$ALOStay,probs=.25,na.rm=TRUE),
                          Median = median(hospital_tidy$ALOStay, na.rm = TRUE),
                          Max = max(hospital_tidy$ALOStay,na.rm = TRUE),
                          Mean = mean(hospital_tidy$ALOStay, na.rm = TRUE),
                          SD = sd(hospital_tidy$ALOStay, na.rm = TRUE),
                          n = n(),
                          Missing = sum(is.na(hospital_tidy$ALOStay)))
knitr::kable(head(h_new))
Min Q1 Median Max Mean SD n Missing
1 3.4 3.4 13.9 3.589957 1.192034 30021 0
hist(hospital_tidy$ALOStay, xlab = "Average of Length of Stay (in days)", 
     main = "Histogram of Average of Length of Stay (ALOS)", breaks=50)

The distribution appears to be rightly skewed. However, we have a large dataset (i.e. n>30), therefore, normality can be assumed by invoking the Central Limit Theorem (CLT). So, we are safe to continue with the two-tailed, one-sample t-test.

Hypothesis Testing

A two-tailed, one-sample t-test was used to determine if the average of length of stay (ALOS) were significantly different from the previously assumed average of length of stay (ALOS) of 4.5 days.

Assumptions:

  • Unknown population standard deviation.
  • Large sample used (n>30) so normality can be assumed.
  • Population homogeneity of variance.

Statistical Hypothesis:

  • \(H_0 : \mu = 4.5\)days
  • \(H_A : \mu \neq 4.5\)days
t.test(hospital_tidy$ALOStay, mu = 4.5, alternative="two.sided")

    One Sample t-test

data:  hospital_tidy$ALOStay
t = -132.28, df = 30020, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 4.5
95 percent confidence interval:
 3.576472 3.603442
sample estimates:
mean of x 
 3.589957 

Results and Analysis

Our decision should be to reject \(H_0 : \mu = 4.5\)days. The analysis are as follows:

  • t(30020) = -132.28.
  • p < 0.05.
  • 95% CI of the average of length of stay (ALOS) 95% CI [3.58 3.60], which did not capture \(H_0 : \mu = 4.5\)days.

The results of the one-sample t-test were therefore statistically significant. This meant that the mean of average of length of stay (ALOS) was statistically significantly lower than the population mean of average of length of stay (ALOS).

Question 2

Introduction

The performance of a student in an exam depends on how well they are prepared with their studies. But there can be other factors which can affect their grades in an exam. Knowing these factors may help get a better understanding of how well a student can perform in an exam.

One such factor is if a student attend tutorial classes. We have gathered a dataset of the 1290 students on their grades before and after attending tutorial classes. We analyse these datasets and apply statistical tests and techniques to determine if the students scores improved after attending tutorial classes.

Problem Statement

We want to determine if tutorial class can help improve the scores in the exams by students. In this investigation, we ultilised the paired-samples t-test was used to test for a significant mean difference between scores before and after tutorial.

Data

performance <- read.csv("Assignment4b.csv")
performance_new <- performance %>% select(Score.after.tutorial,Score.before.tutorial)
knitr::kable(head(performance_new))
Score.after.tutorial Score.before.tutorial
42 50
38 13
43 27
37 44
35 35
41 55

Descriptive Statistics and Visualizations

p_before<-performance %>% summarise(Min = min(performance$Score.before.tutorial,na.rm = TRUE),
                          Q1=quantile(performance$Score.before.tutorial,probs=.25,na.rm=TRUE),
                          Median = median(performance$Score.before.tutorial, na.rm = TRUE),
                          Max = max(performance$Score.before.tutorial,na.rm = TRUE),
                          Mean = mean(performance$Score.before.tutorial, na.rm = TRUE),
                          SD = sd(performance$Score.before.tutorial, na.rm = TRUE),
                          n = n(),
                          Missing = sum(is.na(performance$Score.before.tutorial)))
knitr::kable(head(p_before))
Min Q1 Median Max Mean SD n Missing
13 27 37 55 35.82093 10.53833 1290 0
p_after<-performance %>% summarise(Min = min(performance$Score.after.tutorial,na.rm = TRUE),
                          Q1 = quantile(performance$Score.after.tutorial,probs=.25,na.rm=TRUE),
                          Median = median(performance$Score.after.tutorial, na.rm = TRUE),
                          Max = max(performance$Score.after.tutorial,na.rm = TRUE),
                          Mean = mean(performance$Score.after.tutorial, na.rm = TRUE),
                          SD = sd(performance$Score.after.tutorial, na.rm = TRUE),
                          n = n(),
                          Missing = sum(is.na(performance$Score.after.tutorial)))
knitr::kable(head(p_after))
Min Q1 Median Max Mean SD n Missing
33 37 41 55 41.17132 4.952305 1290 0

Paired Samples Visualisation

boxplot(performance$Score.before.tutorial,performance$Score.after.tutorial, ylab = "Scores",
  xlab = "Time")
axis(1, at = 1:2, labels = c("Before", "After"))

performance <- performance %>% select(Score.after.tutorial, Score.before.tutorial) %>% mutate(Difference = Score.after.tutorial - Score.before.tutorial)
knitr::kable(head(performance,3))
Score.after.tutorial Score.before.tutorial Difference
42 50 -8
38 13 25
43 27 16

We can then calculate the descriptive statistics for the mean difference, difference.

p_difference<-performance %>% summarise(Min = min(performance$Difference,na.rm = TRUE),
                          Q1 = quantile(performance$Difference,probs=.25,na.rm=TRUE),
                          Median = median(performance$Difference, na.rm = TRUE),
                          Max = max(performance$Difference,na.rm = TRUE),
                          Mean = mean(performance$Difference, na.rm = TRUE),
                          SD = sd(performance$Difference, na.rm = TRUE),
                          n = n(),
                          Missing = sum(is.na(performance$Difference)))
knitr::kable(head(p_difference))
Min Q1 Median Max Mean SD n Missing
-14 0 0 31 5.350388 10.03793 1290 0

Normality Check

qqPlot(performance$Difference, dist="norm", ylab="Mean Difference")
[1]  8 83

The differences does not appear to be normally distributed. However, we have a large dataset (i.i n>30), therefore, normality can be assumed by invoking the Central Limit Theorem (CLT). So, we are safe to continue with the paired-samples t-test.

Hypothesis Testing

A paired-samples t-test was used to test for a significant mean difference between scores before and after tutorial. The population mean of these differences is denoted as \(\mu_{\Delta}\)

The statistical hypotheses for the paired-samples t-test are as follows:

  • \(H_0 : \mu_{\Delta}=0\)
  • \(H_A : \mu_{\Delta} \neq 0\)
t.test(performance$Score.after.tutorial, performance$Score.before.tutorial,
       paired = TRUE,
       alternative = "two.sided")

    Paired t-test

data:  performance$Score.after.tutorial and performance$Score.before.tutorial
t = 19.144, df = 1289, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 4.802104 5.898671
sample estimates:
mean of the differences 
               5.350388 

Results and Analysis

Our decision should be to reject \(H_0 : \mu_{\Delta}=0\). The analysis are as follows:

  • t(1289) = 19.144
  • p < 0.05.
  • 95% CI of the estimated population difference [4.802104 5.898671] which did not capture \(H_0 : \mu_{\Delta}=0\).

The results of the paired-samples t-test were statistically significant which meant that there is statistically significant difference between scores before tutorial and score after tutorials. The student’s scores were found to be significantly improved after attending in tutorial classes. Hence, it is shown that tutorials are quite important in improving student scores.

Reference

LS0tCnRpdGxlOiAiTUFUSDEzMjQgU2VtZXN0ZXIgMSwgMjAyMCIKYXV0aG9yOiAiUm95IFdvbmcgS2hlciBZdW5nIChTMzgzNTM1MikiCnN1YnRpdGxlOiBBc3NpZ25tZW50IDQKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IAogICAgdG9jOiB0cnVlCi0tLQoKCmBgYHtyfQpzZXR3ZCgifi9EZXNrdG9wL01hc3RlcnNTZW1fMS8xLiBBcHBsaWVkIEFuYWx5dGljcy9Bc3NpZ25tZW50NCIpCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KEhtaXNjKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGNhcikKbGlicmFyeShrbml0cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KG91dGxpZXJzKQpsaWJyYXJ5KGNhcmV0KQpsaWJyYXJ5KGVkaXRydWxlcykKYGBgCgpcbmV3cGFnZQoKIyBRdWVzdGlvbiAxCgojIyBJbnRyb2R1Y3Rpb24KCkxlbmd0aCBvZiBob3NwaXRhbCBTdGF5IChMT1MpIG9yIEF2ZXJhZ2UgTGVuZ3RoIG9mIFN0YXkgKEFMT1MpIGlzIGFuIGltcG9ydGFudCBpbmRpY2F0b3Igb2YgdGhlIHVzZSBvZiBtZWRpY2FsIHNlcnZpY2VzIHRoYXQgaXMgdXNlZCB0byBhc3Nlc3MgdGhlIGVmZmljaWVuY3kgb2YgaG9zcGl0YWwgbWFuYWdlbWVudCwgcGF0aWVudCBxdWFsaXR5IG9mIGNhcmUsIGFuZCBmdW5jdGlvbmFsIGV2YWx1YXRpb24uIFN0cmF0aWZpZWQgc2FtcGxpbmcgaGFzIGJlZW4gdWx0aWxpc2VkIHRvIGNvbGxlY3QgdGhlIEFMT1MgZnJvbSBkaWZmZXJlbnQgUGVlciBHcm91cC4gVGhlbiB3ZSBpbXBsZW1lbnRlZCBoeXBvdGhlc2lzIHRlc3RpbmcgZm9yIGdhdGhlcmluZyBzdGF0aXN0aWNhbCBldmlkZW5jZSBmcm9tIHNhbXBsZXMgYW5kIHdlIHdvdWxkIGZvY3VzIG9uIHR3byBzYW1wbGUgdC10ZXN0LiBBIHNhbXBsZSBvZiAzMDAyMSBvYnNlcnZhdGlvbnMgd2VyZSBnYXRoZXJlZCBhbmQgYW5hbHlzZWQgYXMgZm9sbG93cy4KCiMjIFByb2JsZW0gU3RhdGVtZW50CgpUaGUgYXZlcmFnZSBpcyBjYWxjdWxhdGVkIGFzIHRoZSBudW1iZXIgb2YgYmVkIGRheXMgZm9yIG92ZXJuaWdodCBzdGF5cyBkaXZpZGVkIGJ5IHRoZSBudW1iZXIgb2Ygb3Zlcm5pZ2h0IHN0YXlzIGFuZCBpcyByZXBvcnRlZCBmb3Igc2VsZWN0ZWQgY29uZGl0aW9ucyBhbmQgcHJvY2VkdXJlcy4gSXQgd2FzIHRob3VnaHQgdGhhdCB0aGUgbWVhbiB2YWx1ZSBvZiB0aGUgYXZlcmFnZSBvZiBsZW5ndGggb2Ygc3RheSAoQUxPUykgaW4gYSBob3NwaXRhbCB3YXMgNC41IGRheXMuIFdlIGNhcnJ5IG91dCB0aGlzIGFuYWx5c2lzIHRvIGZpbmQgb3V0IGlmIHRoaXMgbWVhbiB3YXMgY29ycmVjdC4gCgojIyBEYXRhIFByZXByb2Nlc3NpbmcKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpob3NwaXRhbCA8LSByZWFkLmNzdigiQXNzaWdubWVudDRBLmNzdiIsIGZpbGVFbmNvZGluZz0ibGF0aW4xIiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQpob3NwaXRhbF90aWR5IDwtIGhvc3BpdGFsICU+JSBzZWxlY3QoIkF2ZXJhZ2UubGVuZ3RoLm9mLnN0YXkuLmRheXMuIikKY29sbmFtZXMoaG9zcGl0YWxfdGlkeSlbY29sbmFtZXMoaG9zcGl0YWxfdGlkeSk9PSJBdmVyYWdlLmxlbmd0aC5vZi5zdGF5Li5kYXlzLiJdIDwtICJBTE9TIgpob3NwaXRhbF90aWR5JEFMT1N0YXkgPC0gaG9zcGl0YWxfdGlkeSRBTE9TICU+JSBhcy5udW1lcmljKGhvc3BpdGFsX3RpZHkkQUxPUykKa25pdHI6OmthYmxlKGhlYWQoaG9zcGl0YWxfdGlkeSkpCmBgYAoKXG5ld3BhZ2UKIyMjIFN1bW1hcnkKCmBgYHtyfQpoPC1ob3NwaXRhbF90aWR5ICU+JSBzdW1tYXJpc2UoTWluID0gbWluKGhvc3BpdGFsX3RpZHkkQUxPU3RheSxuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFExID0gcXVhbnRpbGUoaG9zcGl0YWxfdGlkeSRBTE9TdGF5LHByb2JzPS4yNSxuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBNZWRpYW4gPSBtZWRpYW4oaG9zcGl0YWxfdGlkeSRBTE9TdGF5LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1heCA9IG1heChob3NwaXRhbF90aWR5JEFMT1N0YXksbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBNZWFuID0gbWVhbihob3NwaXRhbF90aWR5JEFMT1N0YXksIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgU0QgPSBzZChob3NwaXRhbF90aWR5JEFMT1N0YXksIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbiA9IG4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBNaXNzaW5nID0gc3VtKGlzLm5hKGhvc3BpdGFsX3RpZHkkQUxPU3RheSkpKQprbml0cjo6a2FibGUoaGVhZChoKSkKYGBgCgojIyMgVGlkeSBEYXRhCgpgYGB7cn0KKDE5NzcwLzMwMDIxKSoxMDAKYGBgCgpTaW5jZSB0aGUgYW1vdW50IG9mIG1pc3NpbmcgZGF0YSBpcyBsYXJnZSByZWxhdGl2ZSB0byB0aGUgc2l6ZSBvZiB0aGUgZGF0YSBzZXQgKGkuZS4gNjYlKS4gSGVuY2UsIHdlIG5lZWQgdG8gcmVwbGFjZSB0aGUgbWlzc2luZyB2YWx1ZXMgaW4gb3JkZXIgbm90IHRvIGJpYXMgdGhlIGFuYWx5c2lzLiBTaW5jZSB0aGUgZGF0YSBpcyBza2V3ZWQsIHdlIHVzZWQgdGhlIG1lZGlhbiB2YWx1ZSBvZiB0aGUgZGF0YSB0byByZXBsYWNlIHRoZSBtaXNzaW5nIHZhbHVlcy4KCgpgYGB7cn0KaG9zcGl0YWxfdGlkeSRBTE9TdGF5W2lzLm5hKGhvc3BpdGFsX3RpZHkkQUxPU3RheSldIDwtIG1lZGlhbihob3NwaXRhbF90aWR5JEFMT1N0YXksIG5hLnJtID0gVFJVRSkKYGBgCgoKXG5ld3BhZ2UKIyMgRGVzY3JpcHRpdmUgU3RhdGlzdGljcyBhbmQgVmlzdWFsaXphdGlvbnMKCmBgYHtyfQpoX25ldzwtaG9zcGl0YWxfdGlkeSAlPiUgc3VtbWFyaXNlKE1pbiA9IG1pbihob3NwaXRhbF90aWR5JEFMT1N0YXksbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBRMSA9IHF1YW50aWxlKGhvc3BpdGFsX3RpZHkkQUxPU3RheSxwcm9icz0uMjUsbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTWVkaWFuID0gbWVkaWFuKGhvc3BpdGFsX3RpZHkkQUxPU3RheSwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBNYXggPSBtYXgoaG9zcGl0YWxfdGlkeSRBTE9TdGF5LG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTWVhbiA9IG1lYW4oaG9zcGl0YWxfdGlkeSRBTE9TdGF5LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFNEID0gc2QoaG9zcGl0YWxfdGlkeSRBTE9TdGF5LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBuKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTWlzc2luZyA9IHN1bShpcy5uYShob3NwaXRhbF90aWR5JEFMT1N0YXkpKSkKa25pdHI6OmthYmxlKGhlYWQoaF9uZXcpKQpgYGAKCgpgYGB7cn0KaGlzdChob3NwaXRhbF90aWR5JEFMT1N0YXksIHhsYWIgPSAiQXZlcmFnZSBvZiBMZW5ndGggb2YgU3RheSAoaW4gZGF5cykiLCAKICAgICBtYWluID0gIkhpc3RvZ3JhbSBvZiBBdmVyYWdlIG9mIExlbmd0aCBvZiBTdGF5IChBTE9TKSIsIGJyZWFrcz01MCkKYGBgCgpUaGUgZGlzdHJpYnV0aW9uIGFwcGVhcnMgdG8gYmUgcmlnaHRseSBza2V3ZWQuIEhvd2V2ZXIsIHdlIGhhdmUgYSBsYXJnZSBkYXRhc2V0IChpLmUuIG4+MzApLCB0aGVyZWZvcmUsIG5vcm1hbGl0eSBjYW4gYmUgYXNzdW1lZCBieSBpbnZva2luZyB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtIChDTFQpLiBTbywgd2UgYXJlIHNhZmUgdG8gY29udGludWUgd2l0aCB0aGUgdHdvLXRhaWxlZCwgb25lLXNhbXBsZSB0LXRlc3QuCgoKCgojIyBIeXBvdGhlc2lzIFRlc3RpbmcKCkEgdHdvLXRhaWxlZCwgb25lLXNhbXBsZSB0LXRlc3Qgd2FzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIHRoZSBhdmVyYWdlIG9mIGxlbmd0aCBvZiBzdGF5IChBTE9TKSB3ZXJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGZyb20gdGhlIHByZXZpb3VzbHkgYXNzdW1lZCBhdmVyYWdlIG9mIGxlbmd0aCBvZiBzdGF5IChBTE9TKSBvZiA0LjUgZGF5cy4KCkFzc3VtcHRpb25zOgoKKiBVbmtub3duIHBvcHVsYXRpb24gc3RhbmRhcmQgZGV2aWF0aW9uLgoqIExhcmdlIHNhbXBsZSB1c2VkIChuPjMwKSBzbyBub3JtYWxpdHkgY2FuIGJlIGFzc3VtZWQuCiogUG9wdWxhdGlvbiBob21vZ2VuZWl0eSBvZiB2YXJpYW5jZS4KCgpTdGF0aXN0aWNhbCBIeXBvdGhlc2lzOgoKKiAkSF8wIDogXG11ID0gNC41JGRheXMKKiAkSF9BIDogXG11IFxuZXEgNC41JGRheXMKCgpgYGB7cn0KdC50ZXN0KGhvc3BpdGFsX3RpZHkkQUxPU3RheSwgbXUgPSA0LjUsIGFsdGVybmF0aXZlPSJ0d28uc2lkZWQiKQpgYGAKCiMjIFJlc3VsdHMgYW5kIEFuYWx5c2lzCgpPdXIgZGVjaXNpb24gc2hvdWxkIGJlIHRvIHJlamVjdCAkSF8wIDogXG11ID0gNC41JGRheXMuICBUaGUgYW5hbHlzaXMgYXJlIGFzIGZvbGxvd3M6CgoqIHQoMzAwMjApID0gLTEzMi4yOC4KKiBwIDwgMC4wNS4gCiogOTUlIENJIG9mIHRoZSBhdmVyYWdlIG9mIGxlbmd0aCBvZiBzdGF5IChBTE9TKSA5NSUgQ0kgWzMuNTggMy42MF0sIHdoaWNoIGRpZCBub3QgY2FwdHVyZSAkSF8wIDogXG11ID0gNC41JGRheXMuIAoKVGhlIHJlc3VsdHMgb2YgdGhlIG9uZS1zYW1wbGUgdC10ZXN0IHdlcmUgdGhlcmVmb3JlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuIFRoaXMgbWVhbnQgdGhhdCB0aGUgbWVhbiBvZiBhdmVyYWdlIG9mIGxlbmd0aCBvZiBzdGF5IChBTE9TKSB3YXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudGx5IGxvd2VyIHRoYW4gdGhlIHBvcHVsYXRpb24gbWVhbiBvZiBhdmVyYWdlIG9mIGxlbmd0aCBvZiBzdGF5IChBTE9TKS4KClxuZXdwYWdlCgojIFF1ZXN0aW9uIDIKCiMjIEludHJvZHVjdGlvbgoKVGhlIHBlcmZvcm1hbmNlIG9mIGEgc3R1ZGVudCBpbiBhbiBleGFtIGRlcGVuZHMgb24gaG93IHdlbGwgdGhleSBhcmUgcHJlcGFyZWQgd2l0aCB0aGVpciBzdHVkaWVzLiBCdXQgdGhlcmUgY2FuIGJlIG90aGVyIGZhY3RvcnMgd2hpY2ggY2FuIGFmZmVjdCB0aGVpciBncmFkZXMgaW4gYW4gZXhhbS4gS25vd2luZyB0aGVzZSBmYWN0b3JzIG1heSBoZWxwIGdldCBhIGJldHRlciB1bmRlcnN0YW5kaW5nIG9mIGhvdyB3ZWxsIGEgc3R1ZGVudCBjYW4gcGVyZm9ybSBpbiBhbiBleGFtLgoKT25lIHN1Y2ggZmFjdG9yIGlzIGlmIGEgc3R1ZGVudCBhdHRlbmQgdHV0b3JpYWwgY2xhc3Nlcy4gV2UgaGF2ZSBnYXRoZXJlZCBhIGRhdGFzZXQgb2YgdGhlIDEyOTAgc3R1ZGVudHMgb24gdGhlaXIgZ3JhZGVzIGJlZm9yZSBhbmQgYWZ0ZXIgYXR0ZW5kaW5nIHR1dG9yaWFsIGNsYXNzZXMuIFdlIGFuYWx5c2UgdGhlc2UgZGF0YXNldHMgYW5kIGFwcGx5IHN0YXRpc3RpY2FsIHRlc3RzIGFuZCB0ZWNobmlxdWVzIHRvIGRldGVybWluZSBpZiB0aGUgc3R1ZGVudHMgc2NvcmVzIGltcHJvdmVkIGFmdGVyIGF0dGVuZGluZyB0dXRvcmlhbCBjbGFzc2VzLgoKIyMgUHJvYmxlbSBTdGF0ZW1lbnQKCldlIHdhbnQgdG8gZGV0ZXJtaW5lIGlmIHR1dG9yaWFsIGNsYXNzIGNhbiBoZWxwIGltcHJvdmUgdGhlIHNjb3JlcyBpbiB0aGUgZXhhbXMgYnkgc3R1ZGVudHMuIEluIHRoaXMgaW52ZXN0aWdhdGlvbiwgd2UgdWx0aWxpc2VkIHRoZSBwYWlyZWQtc2FtcGxlcyB0LXRlc3Qgd2FzIHVzZWQgdG8gdGVzdCBmb3IgYSBzaWduaWZpY2FudCBtZWFuIGRpZmZlcmVuY2UgYmV0d2VlbiBzY29yZXMgYmVmb3JlIGFuZCBhZnRlciB0dXRvcmlhbC4KCiMjIERhdGEKCmBgYHtyfQpwZXJmb3JtYW5jZSA8LSByZWFkLmNzdigiQXNzaWdubWVudDRiLmNzdiIpCnBlcmZvcm1hbmNlX25ldyA8LSBwZXJmb3JtYW5jZSAlPiUgc2VsZWN0KFNjb3JlLmFmdGVyLnR1dG9yaWFsLFNjb3JlLmJlZm9yZS50dXRvcmlhbCkKa25pdHI6OmthYmxlKGhlYWQocGVyZm9ybWFuY2VfbmV3KSkKYGBgCgpcbmV3cGFnZQojIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzIGFuZCBWaXN1YWxpemF0aW9ucwoKYGBge3J9CnBfYmVmb3JlPC1wZXJmb3JtYW5jZSAlPiUgc3VtbWFyaXNlKE1pbiA9IG1pbihwZXJmb3JtYW5jZSRTY29yZS5iZWZvcmUudHV0b3JpYWwsbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBRMT1xdWFudGlsZShwZXJmb3JtYW5jZSRTY29yZS5iZWZvcmUudHV0b3JpYWwscHJvYnM9LjI1LG5hLnJtPVRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1lZGlhbiA9IG1lZGlhbihwZXJmb3JtYW5jZSRTY29yZS5iZWZvcmUudHV0b3JpYWwsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTWF4ID0gbWF4KHBlcmZvcm1hbmNlJFNjb3JlLmJlZm9yZS50dXRvcmlhbCxuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW4gPSBtZWFuKHBlcmZvcm1hbmNlJFNjb3JlLmJlZm9yZS50dXRvcmlhbCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBTRCA9IHNkKHBlcmZvcm1hbmNlJFNjb3JlLmJlZm9yZS50dXRvcmlhbCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1pc3NpbmcgPSBzdW0oaXMubmEocGVyZm9ybWFuY2UkU2NvcmUuYmVmb3JlLnR1dG9yaWFsKSkpCmtuaXRyOjprYWJsZShoZWFkKHBfYmVmb3JlKSkKYGBgCgoKYGBge3J9CnBfYWZ0ZXI8LXBlcmZvcm1hbmNlICU+JSBzdW1tYXJpc2UoTWluID0gbWluKHBlcmZvcm1hbmNlJFNjb3JlLmFmdGVyLnR1dG9yaWFsLG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgUTEgPSBxdWFudGlsZShwZXJmb3JtYW5jZSRTY29yZS5hZnRlci50dXRvcmlhbCxwcm9icz0uMjUsbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTWVkaWFuID0gbWVkaWFuKHBlcmZvcm1hbmNlJFNjb3JlLmFmdGVyLnR1dG9yaWFsLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1heCA9IG1heChwZXJmb3JtYW5jZSRTY29yZS5hZnRlci50dXRvcmlhbCxuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW4gPSBtZWFuKHBlcmZvcm1hbmNlJFNjb3JlLmFmdGVyLnR1dG9yaWFsLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFNEID0gc2QocGVyZm9ybWFuY2UkU2NvcmUuYWZ0ZXIudHV0b3JpYWwsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbiA9IG4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBNaXNzaW5nID0gc3VtKGlzLm5hKHBlcmZvcm1hbmNlJFNjb3JlLmFmdGVyLnR1dG9yaWFsKSkpCmtuaXRyOjprYWJsZShoZWFkKHBfYWZ0ZXIpKQpgYGAKClxuZXdwYWdlCgojIyMgUGFpcmVkIFNhbXBsZXMgVmlzdWFsaXNhdGlvbgoKCmBgYHtyfQpib3hwbG90KHBlcmZvcm1hbmNlJFNjb3JlLmJlZm9yZS50dXRvcmlhbCxwZXJmb3JtYW5jZSRTY29yZS5hZnRlci50dXRvcmlhbCwgeWxhYiA9ICJTY29yZXMiLAogIHhsYWIgPSAiVGltZSIpCmF4aXMoMSwgYXQgPSAxOjIsIGxhYmVscyA9IGMoIkJlZm9yZSIsICJBZnRlciIpKQpgYGAKCgpgYGB7cn0KcGVyZm9ybWFuY2UgPC0gcGVyZm9ybWFuY2UgJT4lIHNlbGVjdChTY29yZS5hZnRlci50dXRvcmlhbCwgU2NvcmUuYmVmb3JlLnR1dG9yaWFsKSAlPiUgbXV0YXRlKERpZmZlcmVuY2UgPSBTY29yZS5hZnRlci50dXRvcmlhbCAtIFNjb3JlLmJlZm9yZS50dXRvcmlhbCkKa25pdHI6OmthYmxlKGhlYWQocGVyZm9ybWFuY2UsMykpCmBgYAoKV2UgY2FuIHRoZW4gY2FsY3VsYXRlIHRoZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGZvciB0aGUgbWVhbiBkaWZmZXJlbmNlLCBkaWZmZXJlbmNlLgoKCmBgYHtyfQpwX2RpZmZlcmVuY2U8LXBlcmZvcm1hbmNlICU+JSBzdW1tYXJpc2UoTWluID0gbWluKHBlcmZvcm1hbmNlJERpZmZlcmVuY2UsbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBRMSA9IHF1YW50aWxlKHBlcmZvcm1hbmNlJERpZmZlcmVuY2UscHJvYnM9LjI1LG5hLnJtPVRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1lZGlhbiA9IG1lZGlhbihwZXJmb3JtYW5jZSREaWZmZXJlbmNlLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1heCA9IG1heChwZXJmb3JtYW5jZSREaWZmZXJlbmNlLG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTWVhbiA9IG1lYW4ocGVyZm9ybWFuY2UkRGlmZmVyZW5jZSwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBTRCA9IHNkKHBlcmZvcm1hbmNlJERpZmZlcmVuY2UsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbiA9IG4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBNaXNzaW5nID0gc3VtKGlzLm5hKHBlcmZvcm1hbmNlJERpZmZlcmVuY2UpKSkKa25pdHI6OmthYmxlKGhlYWQocF9kaWZmZXJlbmNlKSkKYGBgCgoKIyMgTm9ybWFsaXR5IENoZWNrCgpgYGB7cn0KcXFQbG90KHBlcmZvcm1hbmNlJERpZmZlcmVuY2UsIGRpc3Q9Im5vcm0iLCB5bGFiPSJNZWFuIERpZmZlcmVuY2UiKQpgYGAKClRoZSBkaWZmZXJlbmNlcyBkb2VzIG5vdCBhcHBlYXIgdG8gYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIEhvd2V2ZXIsIHdlIGhhdmUgYSBsYXJnZSBkYXRhc2V0IChpLmkgbj4zMCksIHRoZXJlZm9yZSwgbm9ybWFsaXR5IGNhbiBiZSBhc3N1bWVkIGJ5IGludm9raW5nIHRoZSBDZW50cmFsIExpbWl0IFRoZW9yZW0gKENMVCkuIFNvLCB3ZSBhcmUgc2FmZSB0byBjb250aW51ZSB3aXRoIHRoZSBwYWlyZWQtc2FtcGxlcyB0LXRlc3QuCgojIyBIeXBvdGhlc2lzIFRlc3RpbmcKCkEgcGFpcmVkLXNhbXBsZXMgdC10ZXN0IHdhcyB1c2VkIHRvIHRlc3QgZm9yIGEgc2lnbmlmaWNhbnQgbWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gc2NvcmVzIGJlZm9yZSBhbmQgYWZ0ZXIgdHV0b3JpYWwuIFRoZSBwb3B1bGF0aW9uIG1lYW4gb2YgdGhlc2UgZGlmZmVyZW5jZXMgaXMgZGVub3RlZCBhcyAkXG11X3tcRGVsdGF9JAoKClRoZSBzdGF0aXN0aWNhbCBoeXBvdGhlc2VzIGZvciB0aGUgcGFpcmVkLXNhbXBsZXMgdC10ZXN0IGFyZSBhcyBmb2xsb3dzOgoKKiAkSF8wIDogXG11X3tcRGVsdGF9PTAkCiogJEhfQSA6IFxtdV97XERlbHRhfSBcbmVxIDAkCgpgYGB7cn0KdC50ZXN0KHBlcmZvcm1hbmNlJFNjb3JlLmFmdGVyLnR1dG9yaWFsLCBwZXJmb3JtYW5jZSRTY29yZS5iZWZvcmUudHV0b3JpYWwsCiAgICAgICBwYWlyZWQgPSBUUlVFLAogICAgICAgYWx0ZXJuYXRpdmUgPSAidHdvLnNpZGVkIikKYGBgCgojIyBSZXN1bHRzIGFuZCBBbmFseXNpcwoKT3VyIGRlY2lzaW9uIHNob3VsZCBiZSB0byByZWplY3QgJEhfMCA6IFxtdV97XERlbHRhfT0wJC4gVGhlIGFuYWx5c2lzIGFyZSBhcyBmb2xsb3dzOgoKKiB0KDEyODkpID0gMTkuMTQ0CiogcCA8IDAuMDUuCiogOTUlIENJIG9mIHRoZSBlc3RpbWF0ZWQgcG9wdWxhdGlvbiBkaWZmZXJlbmNlIFs0LjgwMjEwNCA1Ljg5ODY3MV0gd2hpY2ggZGlkIG5vdCBjYXB0dXJlICRIXzAgOiBcbXVfe1xEZWx0YX09MCQuIAoKVGhlIHJlc3VsdHMgb2YgdGhlIHBhaXJlZC1zYW1wbGVzIHQtdGVzdCB3ZXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgd2hpY2ggbWVhbnQgdGhhdCB0aGVyZSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2UgYmV0d2VlbiBzY29yZXMgYmVmb3JlIHR1dG9yaWFsIGFuZCBzY29yZSBhZnRlciB0dXRvcmlhbHMuIFRoZSBzdHVkZW50J3Mgc2NvcmVzIHdlcmUgZm91bmQgdG8gYmUgc2lnbmlmaWNhbnRseSBpbXByb3ZlZCBhZnRlciAgYXR0ZW5kaW5nIGluIHR1dG9yaWFsIGNsYXNzZXMuIEhlbmNlLCBpdCBpcyBzaG93biB0aGF0IHR1dG9yaWFscyBhcmUgcXVpdGUgaW1wb3J0YW50IGluIGltcHJvdmluZyBzdHVkZW50IHNjb3Jlcy4KCgpcbmV3cGFnZQoKIyBSZWZlcmVuY2UKCgoqIHtodHRwczovL3d3dy5haWh3Lmdvdi5hdS9yZXBvcnRzLWRhdGEvbXlob3NwaXRhbHMvc2VjdG9ycy9hZG1pdHRlZC0gcGF0aWVudHN9Cioge2h0dHBzOi8vYXN0cmFsLXRoZW9yeS0xNTc1MTAuYXBwc3BvdC5jb20vc2VjdXJlZC9NQVRIMTMyNF9Nb2R1bGVfMDcuaHRtbCN0aGVfb25lLXNhbXBsZV8odCktdGVzdF9pbl9yfQoKCg==