Group Details
- Student1: Meihui Lee (S3176428)
- Student2: Daniel Tay (S3089145)
Executive Statement
In recent months supermarket giants Woolworths and Coles have been cutting prices to fend off challenger Aldi. Our initial assumption is that due to both supermarkets having similar purchasing power and financial strength, there will be no overall difference between its prices.
The objective of this investigation is to determine which, Woolworths or Coles, is cheaper, based on statistical evidence.
Using the Simple Random Sampling method we collected samples from a full list of items obtained from the Woolworths website using a data scraper. The data population is defined to only exact matched items on regular prices. With a sample size of 100 (>30), referring to the Central Limit Theorem we assume our sampling distribution to be approximately normally distributed.
With descriptive statistics and box plots we made observations and performed hypothesis testing to determine if there is a statistically significant difference between item prices. The sample mean difference between item prices in Woolworths against Coles was found to be -0.1889 (SD = 0.7635). The paired-samples t-test found the p-value to be 0.015, which is less than our significance level of 0.05. The 95% Confidence Interval [-0.340, -0.037] does not capture our null hypothesis value of 0.
The investigation found a statistically significant mean difference between prices in Woolworths and Coles. Woolworths prices are found to be significantly cheaper compared to Coles.
Load Packages and Data
library(readr)
library(dplyr)
library(DT)
library(car)
library(granova)
Price_War_Samples <- read_csv("~/Dropbox/RMIT - Master of Analytics/Intro to Stats/Assignment 3 - Price Wars/Price Wars/Excel All Files/Price War Samples.csv")
Data Collection:
To ensure every item has an equal chance of being selected, a full list of items was obtained from the Woolworths website using a data miner application. We limit these items to consumables, excluding items that we think do not behave the same way as regular food and groceries. This will be our population.
The list is sorted, cleaned, compiled into Excel and ordered. We use the RANDBETWEEN function in Excel to randomly generate numbers to pick items from the ordered list. We define an accurate match to be of exact name, size and weight. If an item picked does not have an accurate match in Coles, we skip over the item. The item is excluded from our population.
Current prices are obtained from respective websites on 2017/MAY/10.
An extract of the sample is shown as following:
datatable(Price_War_Samples, options = list(
initComplete = JS("
function(settings, json) {
$(this.api().table().header()).css({
'background-color': '#000',
'color': '#fff'
});
}")
))
Note:
Skips in the Sample No indicate where an accurate match could not be found in Coles. 195 random numbers were generated to achieve a sample size of 100 accurately matched items between Woolworths and Coles.
Var is the price difference between the two supermarkets, Woolworths against Coles, where a negative variance indicates Woolworths is cheaper than Coles and vice versa.
Summary Statistics
We begin the investigation by analysing the descriptive statistics of both sample results from Woolworths and Coles:
Woolworths
Price_War_Samples %>% summarise (Min = min(Woolworths,na.rm = TRUE),
Q1 = quantile(Woolworths,probs = .25,na.rm = TRUE),
Median = median(Woolworths, na.rm = TRUE),
Q3 = quantile(Woolworths,probs = .75,na.rm = TRUE),
Max = max(Woolworths,na.rm = TRUE),
Mean = mean(Woolworths, na.rm = TRUE),
SD = sd(Woolworths, na.rm = TRUE),
Range = Max - Min, na.rm = TRUE,
n = n(),
Missing = sum(is.na(Woolworths)))
Coles
Price_War_Samples %>% summarise (Min = min(Coles,na.rm = TRUE),
Q1 = quantile(Coles,probs = .25,na.rm = TRUE),
Median = median(Coles, na.rm = TRUE),
Q3 = quantile(Coles,probs = .75,na.rm = TRUE),
Max = max(Coles,na.rm = TRUE),
Mean = mean(Coles, na.rm = TRUE),
SD = sd(Coles, na.rm = TRUE),
Range = Max - Min, na.rm = TRUE,
n = n(),
Missing = sum(is.na(Coles)))
We visualise using a side-by-side box plot of the prices:
boxplot(
Price_War_Samples$Woolworths,
Price_War_Samples$Coles,
ylab = "Item Price",
xlab = "Supermarket",
col=c("green", "red"))
axis(1, at = 1:2, labels = c("Woolworths", "Coles"))

Observation:
Based on the sample mean (4.7546 v 4.9435) it appears that Woolworths is slightly cheaper than Coles.
Woolworths has a larger standard deviation (4.012 v 3.919) and a larger range (37.31 v 35.72) compared to Coles.
Referring to the summary statistics and box plot, item prices in Woolworths and Coles show very slight differences. The hypothesis test will help us consider whether this difference is statistically significant.
Hypothesis Test
We reject the one sample t-test as we do not have a population mean. We reject the two sample t-test as our samples are matched, ie. not independent.
Based on our strict matching rules where items are accurately matched between both supermarkets, each price observation is said to be dependent. Hence we choose the paired samples t-test, also known as the dependent samples t-test.
We use the paired-samples t-test to determine if the mean price difference between Woolworths and Coles can be considered statistically significant. Based on our sample size of 100 (>30) we can assume our data to be normally distributed. We set the significance level at 0.05. The statistical hypotheses:
\[H_0: \mu_\Delta = 0\] \[H_A: \mu_\Delta \neq 0\]
We calculate the descriptive statistics for the mean difference between Woolworths and Coles:
Price_War_Samples %>% summarise (Min = min(Var,na.rm = TRUE),
Q1 = quantile(Var,probs = .25,na.rm = TRUE),
Median = median(Var, na.rm = TRUE),
Q3 = quantile(Var,probs = .75,na.rm = TRUE),
Max = max(Var,na.rm = TRUE),
Mean = mean(Var, na.rm = TRUE),
SD = sd(Var, na.rm = TRUE),
n = n(),
Missing = sum(is.na(Var)))
boxplot (Price_War_Samples$Var,
ylab = "Prices",
xlab = "Price Variance (Woolworths v Coles)",
col=c("yellow"))

NA
Observation:
- It appears that Woolworths is cheaper than Coles on a mean of 0.1889. We note though that the price variance ranges from being $2.10 cheaper to $4.06 more expensive.
Although we have a sample size >30 we still look at the Q-Q plot to check normality of the differences:
qqPlot(Price_War_Samples$Var, dist="norm")

The Q-Q plot above shows that apart from a few outliers the majority of our sample follows a normal distribution.
We calculate the paired sample t-test using the t.test() function in R:
t.test(Price_War_Samples$Woolworths, Price_War_Samples$Coles,
paired = TRUE,
conf.level = 0.95,
alternative = "two.sided")
Paired t-test
data: Price_War_Samples$Woolworths and Price_War_Samples$Coles
t = -2.4743, df = 99, p-value = 0.01505
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-0.34038615 -0.03741385
sample estimates:
mean of the differences
-0.1889
We visualise the mean difference using a scatter plot. The plot reports the mean difference and confidence intervals from the paired samples t-test:
granova.ds(
data.frame(Price_War_Samples$Woolworths, Price_War_Samples$Coles),
xlab = "Woolworths",
ylab = "Coles"
)
Summary Stats
n 100.000
mean(x) 4.755
mean(y) 4.944
mean(D=x-y) -0.189
SD(D) 0.763
ES(D) -0.247
r(x,y) 0.982
r(x+y,d) 0.123
LL 95%CI -0.340
UL 95%CI -0.037
t(D-bar) -2.474
df.t 99.000
pval.t 0.015

Interpretation
We use a paired-samples t-test to test for a significant mean difference between item prices in Woolworths against Coles. The mean difference was found to be -0.1889 (SD = 0.7635).
The paired-samples t-test found the following:
- p-value of 0.015 is less than our significance level of 0.05
- The null hypothesis value of 0 is not captured in our 95% Confidence Interval [-0.340, -0.037]
The results above found a statistically significant mean difference between prices in Woolworths and Coles. Woolworths prices are found to be significantly cheaper compared to Coles.
Discussion
Based on our findings, the initial assumption that no overall price difference between the two supermarkets appears to be incorrect. Looking at the Dependent Sample Assessment Plot we see that the majority of samples indicate Woolworths being cheaper. However, these plots (where Woolworths was cheaper) are very close to the identity line. This indicates that Woolworths prices are just slightly cheaper than Coles. In the few instances where Coles is cheaper, the difference is more significant.
When we look back at the descriptive statistics for the mean difference, the Max of differences (Coles being cheaper than Woolworths) is $4.06 where else the Min of differences (Woolworths being cheaper than Coles) is just $2.10. These observations indicate a possibility of each supermarket having a different pricing strategy. Woolworths seem more likely to give slight better prices on its overall products compared to Coles but Coles is more likely to give a larger saving to its customers on fewer products.
Having obtained a full list of items from the Woolworths website we are confident of the Simple Random Sampling method, where every item in Woolworths had an equal chance of being selected. We trust this to be the most effective probability-based sampling method.
We note though that comparing only regular priced items in this investigation is a limitation, noting that special discount prices offered by each supermarket could significantly change our findings of whether Woolworths or Coles is cheaper. However due to these special discount prices varying from week to week, pricing data would have to be collected over a significant number of weeks. Due to time constraints we were unable to do so thus unable to fairly compare the impact of these special discount prices.
For better results we should definitely take into account the impact of special discount prices. Future investigations could also focus on specific categories of items to provide a targeted insight.
LS0tCnRpdGxlOiAiTUFUSDEzMjQgQXNzaWdubWVudCAzIgpzdWJ0aXRsZTogIlN1cGVybWFya2V0IFByaWNlIFdhcnMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIEdyb3VwIERldGFpbHMKCiogU3R1ZGVudDE6IE1laWh1aSBMZWUgKFMzMTc2NDI4KQoqIFN0dWRlbnQyOiBEYW5pZWwgVGF5IChTMzA4OTE0NSkKCiMjIEV4ZWN1dGl2ZSBTdGF0ZW1lbnQKCkluIHJlY2VudCBtb250aHMgc3VwZXJtYXJrZXQgZ2lhbnRzIFdvb2x3b3J0aHMgYW5kIENvbGVzIGhhdmUgYmVlbiBjdXR0aW5nIHByaWNlcyB0byBmZW5kIG9mZiBjaGFsbGVuZ2VyIEFsZGkuIE91ciBpbml0aWFsIGFzc3VtcHRpb24gaXMgdGhhdCBkdWUgdG8gYm90aCBzdXBlcm1hcmtldHMgaGF2aW5nIHNpbWlsYXIgcHVyY2hhc2luZyBwb3dlciBhbmQgZmluYW5jaWFsIHN0cmVuZ3RoLCB0aGVyZSB3aWxsIGJlIG5vIG92ZXJhbGwgZGlmZmVyZW5jZSBiZXR3ZWVuIGl0cyBwcmljZXMuCgpUaGUgb2JqZWN0aXZlIG9mIHRoaXMgaW52ZXN0aWdhdGlvbiBpcyB0byBkZXRlcm1pbmUgd2hpY2gsIFdvb2x3b3J0aHMgb3IgQ29sZXMsIGlzIGNoZWFwZXIsIGJhc2VkIG9uIHN0YXRpc3RpY2FsIGV2aWRlbmNlLgoKVXNpbmcgdGhlIFNpbXBsZSBSYW5kb20gU2FtcGxpbmcgbWV0aG9kIHdlIGNvbGxlY3RlZCBzYW1wbGVzIGZyb20gYSBmdWxsIGxpc3Qgb2YgaXRlbXMgb2J0YWluZWQgZnJvbSB0aGUgV29vbHdvcnRocyB3ZWJzaXRlIHVzaW5nIGEgZGF0YSBzY3JhcGVyLiBUaGUgZGF0YSBwb3B1bGF0aW9uIGlzIGRlZmluZWQgdG8gb25seSBleGFjdCBtYXRjaGVkIGl0ZW1zIG9uIHJlZ3VsYXIgcHJpY2VzLiBXaXRoIGEgc2FtcGxlIHNpemUgb2YgMTAwICg+MzApLCByZWZlcnJpbmcgdG8gdGhlIENlbnRyYWwgTGltaXQgVGhlb3JlbSB3ZSBhc3N1bWUgb3VyIHNhbXBsaW5nIGRpc3RyaWJ1dGlvbiB0byBiZSBhcHByb3hpbWF0ZWx5IG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgoKV2l0aCBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGFuZCBib3ggcGxvdHMgd2UgbWFkZSBvYnNlcnZhdGlvbnMgYW5kIHBlcmZvcm1lZCBoeXBvdGhlc2lzIHRlc3RpbmcgdG8gZGV0ZXJtaW5lIGlmIHRoZXJlIGlzIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gaXRlbSBwcmljZXMuIFRoZSBzYW1wbGUgbWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gaXRlbSBwcmljZXMgaW4gV29vbHdvcnRocyBhZ2FpbnN0IENvbGVzIHdhcyBmb3VuZCB0byBiZSAtMC4xODg5IChTRCA9IDAuNzYzNSkuIFRoZSBwYWlyZWQtc2FtcGxlcyB0LXRlc3QgZm91bmQgdGhlIHAtdmFsdWUgdG8gYmUgMC4wMTUsIHdoaWNoIGlzIGxlc3MgdGhhbiBvdXIgc2lnbmlmaWNhbmNlIGxldmVsIG9mIDAuMDUuIFRoZSA5NSUgQ29uZmlkZW5jZSBJbnRlcnZhbCBbLTAuMzQwLCAtMC4wMzddIGRvZXMgbm90IGNhcHR1cmUgb3VyIG51bGwgaHlwb3RoZXNpcyB2YWx1ZSBvZiAwLgoKVGhlIGludmVzdGlnYXRpb24gZm91bmQgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IG1lYW4gZGlmZmVyZW5jZSBiZXR3ZWVuIHByaWNlcyBpbiBXb29sd29ydGhzIGFuZCBDb2xlcy4gV29vbHdvcnRocyBwcmljZXMgYXJlIGZvdW5kIHRvIGJlIHNpZ25pZmljYW50bHkgY2hlYXBlciBjb21wYXJlZCB0byBDb2xlcy4KCiMjIExvYWQgUGFja2FnZXMgYW5kIERhdGEKCmBgYHtyfQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KERUKQpsaWJyYXJ5KGNhcikKbGlicmFyeShncmFub3ZhKQoKUHJpY2VfV2FyX1NhbXBsZXMgPC0gcmVhZF9jc3YoIn4vRHJvcGJveC9STUlUIC0gTWFzdGVyIG9mIEFuYWx5dGljcy9JbnRybyB0byBTdGF0cy9Bc3NpZ25tZW50IDMgLSBQcmljZSBXYXJzL1ByaWNlIFdhcnMvRXhjZWwgQWxsIEZpbGVzL1ByaWNlIFdhciBTYW1wbGVzLmNzdiIpCgpgYGAKCkRhdGEgQ29sbGVjdGlvbjoKCjEuIFRvIGVuc3VyZSBldmVyeSBpdGVtIGhhcyBhbiBlcXVhbCBjaGFuY2Ugb2YgYmVpbmcgc2VsZWN0ZWQsIGEgZnVsbCBsaXN0IG9mIGl0ZW1zIHdhcyBvYnRhaW5lZCBmcm9tIHRoZSBXb29sd29ydGhzIHdlYnNpdGUgdXNpbmcgYSBkYXRhIG1pbmVyIGFwcGxpY2F0aW9uLiBXZSBsaW1pdCB0aGVzZSBpdGVtcyB0byBjb25zdW1hYmxlcywgZXhjbHVkaW5nIGl0ZW1zIHRoYXQgd2UgdGhpbmsgZG8gbm90IGJlaGF2ZSB0aGUgc2FtZSB3YXkgYXMgcmVndWxhciBmb29kIGFuZCBncm9jZXJpZXMuIFRoaXMgd2lsbCBiZSBvdXIgcG9wdWxhdGlvbi4gCgoyLiBUaGUgbGlzdCBpcyBzb3J0ZWQsIGNsZWFuZWQsIGNvbXBpbGVkIGludG8gRXhjZWwgYW5kIG9yZGVyZWQuIFdlIHVzZSB0aGUgUkFOREJFVFdFRU4gZnVuY3Rpb24gaW4gRXhjZWwgdG8gcmFuZG9tbHkgZ2VuZXJhdGUgbnVtYmVycyB0byBwaWNrIGl0ZW1zIGZyb20gdGhlIG9yZGVyZWQgbGlzdC4gV2UgZGVmaW5lIGFuIGFjY3VyYXRlIG1hdGNoIHRvIGJlIG9mIGV4YWN0IG5hbWUsIHNpemUgYW5kIHdlaWdodC4gSWYgYW4gaXRlbSBwaWNrZWQgZG9lcyBub3QgaGF2ZSBhbiBhY2N1cmF0ZSBtYXRjaCBpbiBDb2xlcywgd2Ugc2tpcCBvdmVyIHRoZSBpdGVtLiBUaGUgaXRlbSBpcyBleGNsdWRlZCBmcm9tIG91ciBwb3B1bGF0aW9uLgoKMy4gQ3VycmVudCBwcmljZXMgYXJlIG9idGFpbmVkIGZyb20gcmVzcGVjdGl2ZSB3ZWJzaXRlcyBvbiAyMDE3L01BWS8xMC4KCkFuIGV4dHJhY3Qgb2YgdGhlIHNhbXBsZSBpcyBzaG93biBhcyBmb2xsb3dpbmc6CgpgYGB7cn0KCmRhdGF0YWJsZShQcmljZV9XYXJfU2FtcGxlcywgb3B0aW9ucyA9IGxpc3QoCiAgaW5pdENvbXBsZXRlID0gSlMoIgogICAgZnVuY3Rpb24oc2V0dGluZ3MsIGpzb24pIHsKICAgICAgJCh0aGlzLmFwaSgpLnRhYmxlKCkuaGVhZGVyKCkpLmNzcyh7CiAgICAgICAgJ2JhY2tncm91bmQtY29sb3InOiAnIzAwMCcsCiAgICAgICAgJ2NvbG9yJzogJyNmZmYnCiAgICAgIH0pOwogICAgfSIpCikpCgpgYGAKCk5vdGU6CgoxLiBTa2lwcyBpbiB0aGUgU2FtcGxlIE5vIGluZGljYXRlIHdoZXJlIGFuIGFjY3VyYXRlIG1hdGNoIGNvdWxkIG5vdCBiZSBmb3VuZCBpbiBDb2xlcy4gMTk1IHJhbmRvbSBudW1iZXJzIHdlcmUgZ2VuZXJhdGVkIHRvIGFjaGlldmUgYSBzYW1wbGUgc2l6ZSBvZiAxMDAgYWNjdXJhdGVseSBtYXRjaGVkIGl0ZW1zIGJldHdlZW4gV29vbHdvcnRocyBhbmQgQ29sZXMuCgoyLiBWYXIgaXMgdGhlIHByaWNlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIHN1cGVybWFya2V0cywgV29vbHdvcnRocyBhZ2FpbnN0IENvbGVzLCB3aGVyZSBhIG5lZ2F0aXZlIHZhcmlhbmNlIGluZGljYXRlcyBXb29sd29ydGhzIGlzIGNoZWFwZXIgdGhhbiBDb2xlcyBhbmQgdmljZSB2ZXJzYS4KCiMjIFN1bW1hcnkgU3RhdGlzdGljcwoKV2UgYmVnaW4gdGhlIGludmVzdGlnYXRpb24gYnkgYW5hbHlzaW5nIHRoZSBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIG9mIGJvdGggc2FtcGxlIHJlc3VsdHMgZnJvbSBXb29sd29ydGhzIGFuZCBDb2xlczoKCldvb2x3b3J0aHMKCmBgYHtyfQoKUHJpY2VfV2FyX1NhbXBsZXMgJT4lIHN1bW1hcmlzZSAgICAgICAgICAgICAgICAgIChNaW4gPSBtaW4oV29vbHdvcnRocyxuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFExID0gcXVhbnRpbGUoV29vbHdvcnRocyxwcm9icyA9IC4yNSxuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lZGlhbiA9IG1lZGlhbihXb29sd29ydGhzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFEzID0gcXVhbnRpbGUoV29vbHdvcnRocyxwcm9icyA9IC43NSxuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1heCA9IG1heChXb29sd29ydGhzLG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVhbiA9IG1lYW4oV29vbHdvcnRocywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRCA9IHNkKFdvb2x3b3J0aHMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmFuZ2UgPSBNYXggLSBNaW4sIG5hLnJtID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pc3NpbmcgPSBzdW0oaXMubmEoV29vbHdvcnRocykpKQpgYGAKCkNvbGVzCgpgYGB7cn0KClByaWNlX1dhcl9TYW1wbGVzICU+JSBzdW1tYXJpc2UgICAgICAgICAgICAgICAgICAoTWluID0gbWluKENvbGVzLG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUTEgPSBxdWFudGlsZShDb2xlcyxwcm9icyA9IC4yNSxuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lZGlhbiA9IG1lZGlhbihDb2xlcywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRMyA9IHF1YW50aWxlKENvbGVzLHByb2JzID0gLjc1LG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF4ID0gbWF4KENvbGVzLG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVhbiA9IG1lYW4oQ29sZXMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0QgPSBzZChDb2xlcywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSYW5nZSA9IE1heCAtIE1pbiwgbmEucm0gPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBuKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWlzc2luZyA9IHN1bShpcy5uYShDb2xlcykpKQoKYGBgCgpXZSB2aXN1YWxpc2UgdXNpbmcgYSBzaWRlLWJ5LXNpZGUgYm94IHBsb3Qgb2YgdGhlIHByaWNlczoKCmBgYHtyfQoKYm94cGxvdCgKICBQcmljZV9XYXJfU2FtcGxlcyRXb29sd29ydGhzLAogIFByaWNlX1dhcl9TYW1wbGVzJENvbGVzLAogIHlsYWIgPSAiSXRlbSBQcmljZSIsCiAgeGxhYiA9ICJTdXBlcm1hcmtldCIsCiAgY29sPWMoImdyZWVuIiwgInJlZCIpKQpheGlzKDEsIGF0ID0gMToyLCBsYWJlbHMgPSBjKCJXb29sd29ydGhzIiwgIkNvbGVzIikpCgpgYGAKCk9ic2VydmF0aW9uOgoKMS4gQmFzZWQgb24gdGhlIHNhbXBsZSBtZWFuICg0Ljc1NDYgdiA0Ljk0MzUpIGl0IGFwcGVhcnMgdGhhdCBXb29sd29ydGhzIGlzIHNsaWdodGx5IGNoZWFwZXIgdGhhbiBDb2xlcy4KCjIuIFdvb2x3b3J0aHMgaGFzIGEgbGFyZ2VyIHN0YW5kYXJkIGRldmlhdGlvbiAoNC4wMTIgdiAzLjkxOSkgYW5kIGEgbGFyZ2VyIHJhbmdlICgzNy4zMSB2IDM1LjcyKSBjb21wYXJlZCB0byBDb2xlcy4KClJlZmVycmluZyB0byB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzIGFuZCBib3ggcGxvdCwgaXRlbSBwcmljZXMgaW4gV29vbHdvcnRocyBhbmQgQ29sZXMgc2hvdyB2ZXJ5IHNsaWdodCBkaWZmZXJlbmNlcy4gVGhlIGh5cG90aGVzaXMgdGVzdCB3aWxsIGhlbHAgdXMgY29uc2lkZXIgd2hldGhlciB0aGlzIGRpZmZlcmVuY2UgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gCgojIyBIeXBvdGhlc2lzIFRlc3QKCldlIHJlamVjdCB0aGUgb25lIHNhbXBsZSB0LXRlc3QgYXMgd2UgZG8gbm90IGhhdmUgYSBwb3B1bGF0aW9uIG1lYW4uIFdlIHJlamVjdCB0aGUgdHdvIHNhbXBsZSB0LXRlc3QgYXMgb3VyIHNhbXBsZXMgYXJlIG1hdGNoZWQsIGllLiBub3QgaW5kZXBlbmRlbnQuCgpCYXNlZCBvbiBvdXIgc3RyaWN0IG1hdGNoaW5nIHJ1bGVzIHdoZXJlIGl0ZW1zIGFyZSBhY2N1cmF0ZWx5IG1hdGNoZWQgYmV0d2VlbiBib3RoIHN1cGVybWFya2V0cywgZWFjaCBwcmljZSBvYnNlcnZhdGlvbiBpcyBzYWlkIHRvIGJlIGRlcGVuZGVudC4gSGVuY2Ugd2UgY2hvb3NlIHRoZSAqKnBhaXJlZCBzYW1wbGVzIHQtdGVzdCwgYWxzbyBrbm93biBhcyB0aGUgZGVwZW5kZW50IHNhbXBsZXMgdC10ZXN0KiouIAoKV2UgdXNlIHRoZSBwYWlyZWQtc2FtcGxlcyB0LXRlc3QgdG8gZGV0ZXJtaW5lIGlmIHRoZSBtZWFuIHByaWNlIGRpZmZlcmVuY2UgYmV0d2VlbiBXb29sd29ydGhzIGFuZCBDb2xlcyBjYW4gYmUgY29uc2lkZXJlZCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBCYXNlZCBvbiBvdXIgc2FtcGxlIHNpemUgb2YgMTAwICg+MzApIHdlIGNhbiBhc3N1bWUgb3VyIGRhdGEgdG8gYmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIFdlIHNldCB0aGUgc2lnbmlmaWNhbmNlIGxldmVsIGF0IDAuMDUuIFRoZSBzdGF0aXN0aWNhbCBoeXBvdGhlc2VzOgoKJCRIXzA6IFxtdV9cRGVsdGEgPSAwJCQKJCRIX0E6IFxtdV9cRGVsdGEgXG5lcSAwJCQKCldlIGNhbGN1bGF0ZSB0aGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBmb3IgdGhlIG1lYW4gZGlmZmVyZW5jZSBiZXR3ZWVuIFdvb2x3b3J0aHMgYW5kIENvbGVzOgoKYGBge3J9CgoKUHJpY2VfV2FyX1NhbXBsZXMgJT4lIHN1bW1hcmlzZSAgICAgICAgICAgICAgICAgIChNaW4gPSBtaW4oVmFyLG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUTEgPSBxdWFudGlsZShWYXIscHJvYnMgPSAuMjUsbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWRpYW4gPSBtZWRpYW4oVmFyLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFEzID0gcXVhbnRpbGUoVmFyLHByb2JzID0gLjc1LG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF4ID0gbWF4KFZhcixuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW4gPSBtZWFuKFZhciwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRCA9IHNkKFZhciwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pc3NpbmcgPSBzdW0oaXMubmEoVmFyKSkpCgoKYGBgCmBgYHtyfQoKYm94cGxvdCAgIChQcmljZV9XYXJfU2FtcGxlcyRWYXIsCiAgICAgICAgICAgeWxhYiA9ICJQcmljZXMiLAogICAgICAgICAgIHhsYWIgPSAiUHJpY2UgVmFyaWFuY2UgKFdvb2x3b3J0aHMgdiBDb2xlcykiLAogICAgICAgICAgIGNvbD1jKCJ5ZWxsb3ciKSkgICAKICAgIApgYGAKCk9ic2VydmF0aW9uOgoKMS4gSXQgYXBwZWFycyB0aGF0IFdvb2x3b3J0aHMgaXMgY2hlYXBlciB0aGFuIENvbGVzIG9uIGEgbWVhbiBvZiAwLjE4ODkuIFdlIG5vdGUgdGhvdWdoIHRoYXQgdGhlIHByaWNlIHZhcmlhbmNlIHJhbmdlcyBmcm9tIGJlaW5nICQyLjEwIGNoZWFwZXIgdG8gJDQuMDYgbW9yZSBleHBlbnNpdmUuCgpBbHRob3VnaCB3ZSBoYXZlIGEgc2FtcGxlIHNpemUgPjMwIHdlIHN0aWxsIGxvb2sgYXQgdGhlIFEtUSBwbG90IHRvIGNoZWNrIG5vcm1hbGl0eSBvZiB0aGUgZGlmZmVyZW5jZXM6CgpgYGB7cn0KCnFxUGxvdChQcmljZV9XYXJfU2FtcGxlcyRWYXIsIGRpc3Q9Im5vcm0iKQoKYGBgCgpUaGUgUS1RIHBsb3QgYWJvdmUgc2hvd3MgdGhhdCBhcGFydCBmcm9tIGEgZmV3IG91dGxpZXJzIHRoZSBtYWpvcml0eSBvZiBvdXIgc2FtcGxlIGZvbGxvd3MgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiAKCldlIGNhbGN1bGF0ZSB0aGUgcGFpcmVkIHNhbXBsZSB0LXRlc3QgdXNpbmcgdGhlIHQudGVzdCgpIGZ1bmN0aW9uIGluIFI6CgpgYGB7cn0KCnQudGVzdChQcmljZV9XYXJfU2FtcGxlcyRXb29sd29ydGhzLCBQcmljZV9XYXJfU2FtcGxlcyRDb2xlcywKICAgICAgIHBhaXJlZCA9IFRSVUUsCiAgICAgICBjb25mLmxldmVsID0gMC45NSwKICAgICAgIGFsdGVybmF0aXZlID0gInR3by5zaWRlZCIpCgpgYGAKCldlIHZpc3VhbGlzZSB0aGUgbWVhbiBkaWZmZXJlbmNlIHVzaW5nIGEgc2NhdHRlciBwbG90LiBUaGUgcGxvdCByZXBvcnRzIHRoZSBtZWFuIGRpZmZlcmVuY2UgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZyb20gdGhlIHBhaXJlZCBzYW1wbGVzIHQtdGVzdDoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuaGVpZ2h0PTksIGZpZy53aWR0aD05fQoKZ3Jhbm92YS5kcygKICBkYXRhLmZyYW1lKFByaWNlX1dhcl9TYW1wbGVzJFdvb2x3b3J0aHMsIFByaWNlX1dhcl9TYW1wbGVzJENvbGVzKSwKICB4bGFiID0gIldvb2x3b3J0aHMiLAogIHlsYWIgPSAiQ29sZXMiCiAgKQoKYGBgCgojIyBJbnRlcnByZXRhdGlvbgoKV2UgdXNlIGEgcGFpcmVkLXNhbXBsZXMgdC10ZXN0IHRvIHRlc3QgZm9yIGEgc2lnbmlmaWNhbnQgbWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gaXRlbSBwcmljZXMgaW4gV29vbHdvcnRocyBhZ2FpbnN0IENvbGVzLiBUaGUgbWVhbiBkaWZmZXJlbmNlIHdhcyBmb3VuZCB0byBiZSAtMC4xODg5IChTRCA9IDAuNzYzNSkuIAoKVGhlIHBhaXJlZC1zYW1wbGVzIHQtdGVzdCBmb3VuZCB0aGUgZm9sbG93aW5nOgoKYSkgcC12YWx1ZSBvZiAwLjAxNSBpcyBsZXNzIHRoYW4gb3VyIHNpZ25pZmljYW5jZSBsZXZlbCBvZiAwLjA1CmIpIFRoZSBudWxsIGh5cG90aGVzaXMgdmFsdWUgb2YgMCBpcyBub3QgY2FwdHVyZWQgaW4gb3VyIDk1JSBDb25maWRlbmNlIEludGVydmFsIFstMC4zNDAsIC0wLjAzN10KClRoZSByZXN1bHRzIGFib3ZlIGZvdW5kIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBtZWFuIGRpZmZlcmVuY2UgYmV0d2VlbiBwcmljZXMgaW4gV29vbHdvcnRocyBhbmQgQ29sZXMuIFdvb2x3b3J0aHMgcHJpY2VzIGFyZSBmb3VuZCB0byBiZSBzaWduaWZpY2FudGx5IGNoZWFwZXIgY29tcGFyZWQgdG8gQ29sZXMuCgojIyBEaXNjdXNzaW9uIAoKQmFzZWQgb24gb3VyIGZpbmRpbmdzLCB0aGUgaW5pdGlhbCBhc3N1bXB0aW9uIHRoYXQgbm8gb3ZlcmFsbCBwcmljZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBzdXBlcm1hcmtldHMgYXBwZWFycyB0byBiZSBpbmNvcnJlY3QuIExvb2tpbmcgYXQgdGhlIERlcGVuZGVudCBTYW1wbGUgQXNzZXNzbWVudCBQbG90IHdlIHNlZSB0aGF0IHRoZSBtYWpvcml0eSBvZiBzYW1wbGVzIGluZGljYXRlIFdvb2x3b3J0aHMgYmVpbmcgY2hlYXBlci4gSG93ZXZlciwgdGhlc2UgcGxvdHMgKHdoZXJlIFdvb2x3b3J0aHMgd2FzIGNoZWFwZXIpIGFyZSB2ZXJ5IGNsb3NlIHRvIHRoZSBpZGVudGl0eSBsaW5lLiBUaGlzIGluZGljYXRlcyB0aGF0ICBXb29sd29ydGhzIHByaWNlcyBhcmUganVzdCBzbGlnaHRseSBjaGVhcGVyIHRoYW4gQ29sZXMuIEluIHRoZSBmZXcgaW5zdGFuY2VzIHdoZXJlIENvbGVzIGlzIGNoZWFwZXIsIHRoZSBkaWZmZXJlbmNlIGlzIG1vcmUgc2lnbmlmaWNhbnQuIAoKV2hlbiB3ZSBsb29rIGJhY2sgYXQgdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIHRoZSBtZWFuIGRpZmZlcmVuY2UsIHRoZSBNYXggb2YgZGlmZmVyZW5jZXMgKENvbGVzIGJlaW5nIGNoZWFwZXIgdGhhbiBXb29sd29ydGhzKSBpcyAkNC4wNiB3aGVyZSBlbHNlIHRoZSBNaW4gb2YgZGlmZmVyZW5jZXMgKFdvb2x3b3J0aHMgYmVpbmcgY2hlYXBlciB0aGFuIENvbGVzKSBpcyBqdXN0ICQyLjEwLiBUaGVzZSBvYnNlcnZhdGlvbnMgaW5kaWNhdGUgYSBwb3NzaWJpbGl0eSBvZiBlYWNoIHN1cGVybWFya2V0IGhhdmluZyBhIGRpZmZlcmVudCBwcmljaW5nIHN0cmF0ZWd5LiBXb29sd29ydGhzIHNlZW0gbW9yZSBsaWtlbHkgdG8gZ2l2ZSBzbGlnaHQgYmV0dGVyIHByaWNlcyBvbiBpdHMgb3ZlcmFsbCBwcm9kdWN0cyBjb21wYXJlZCB0byBDb2xlcyBidXQgQ29sZXMgaXMgbW9yZSBsaWtlbHkgdG8gZ2l2ZSBhIGxhcmdlciBzYXZpbmcgdG8gaXRzIGN1c3RvbWVycyBvbiBmZXdlciBwcm9kdWN0cy4gIAoKSGF2aW5nIG9idGFpbmVkIGEgZnVsbCBsaXN0IG9mIGl0ZW1zIGZyb20gdGhlIFdvb2x3b3J0aHMgd2Vic2l0ZSB3ZSBhcmUgY29uZmlkZW50IG9mIHRoZSBTaW1wbGUgUmFuZG9tIFNhbXBsaW5nIG1ldGhvZCwgd2hlcmUgZXZlcnkgaXRlbSBpbiBXb29sd29ydGhzIGhhZCBhbiBlcXVhbCBjaGFuY2Ugb2YgYmVpbmcgc2VsZWN0ZWQuIFdlIHRydXN0IHRoaXMgdG8gYmUgdGhlIG1vc3QgZWZmZWN0aXZlIHByb2JhYmlsaXR5LWJhc2VkIHNhbXBsaW5nIG1ldGhvZC4KCldlIG5vdGUgdGhvdWdoIHRoYXQgY29tcGFyaW5nIG9ubHkgcmVndWxhciBwcmljZWQgaXRlbXMgaW4gdGhpcyBpbnZlc3RpZ2F0aW9uIGlzIGEgbGltaXRhdGlvbiwgbm90aW5nIHRoYXQgc3BlY2lhbCBkaXNjb3VudCBwcmljZXMgb2ZmZXJlZCBieSBlYWNoIHN1cGVybWFya2V0IGNvdWxkIHNpZ25pZmljYW50bHkgY2hhbmdlIG91ciBmaW5kaW5ncyBvZiB3aGV0aGVyIFdvb2x3b3J0aHMgb3IgQ29sZXMgaXMgY2hlYXBlci4gSG93ZXZlciBkdWUgdG8gdGhlc2Ugc3BlY2lhbCBkaXNjb3VudCBwcmljZXMgdmFyeWluZyBmcm9tIHdlZWsgdG8gd2VlaywgcHJpY2luZyBkYXRhIHdvdWxkIGhhdmUgdG8gYmUgY29sbGVjdGVkIG92ZXIgYSBzaWduaWZpY2FudCBudW1iZXIgb2Ygd2Vla3MuIER1ZSB0byB0aW1lIGNvbnN0cmFpbnRzIHdlIHdlcmUgdW5hYmxlIHRvIGRvIHNvIHRodXMgdW5hYmxlIHRvIGZhaXJseSBjb21wYXJlIHRoZSBpbXBhY3Qgb2YgdGhlc2Ugc3BlY2lhbCBkaXNjb3VudCBwcmljZXMuCgpGb3IgYmV0dGVyIHJlc3VsdHMgd2Ugc2hvdWxkIGRlZmluaXRlbHkgdGFrZSBpbnRvIGFjY291bnQgdGhlIGltcGFjdCBvZiBzcGVjaWFsIGRpc2NvdW50IHByaWNlcy4gRnV0dXJlIGludmVzdGlnYXRpb25zIGNvdWxkIGFsc28gZm9jdXMgb24gc3BlY2lmaWMgY2F0ZWdvcmllcyBvZiBpdGVtcyB0byBwcm92aWRlIGEgdGFyZ2V0ZWQgaW5zaWdodC4gCgoKCg==