Student Details
Student Name (s3868685)
Problem Statement
The dataset contains 3 variables for two cities of Melbourne and
Sydney, of 3 months of the year that are Dec2021-Jan 2022 and Feb-2022,
collected from: Data Source: http://www.bom.gov.au/climate/data/stations/ http://www.bom.gov.au/climate/data/index.shtml?bookmark=136
Variables selected in the dataset:
1- Solar exposure: The Daily global solar exposure is the total solar
energy for a day falling on a horizontal surface. It is measured from
midnight to midnight. The values are usually highest in clear sun
conditions during the summer and lowest during winter or very cloudy
days and
2- Maximum temperature: It is the highest temperature recorded in the
24 hours from 9 am.
The objective of this statistical analysis is to see the variation
between the solar exposure and maximum temperatures observed for both
cities Melbourne and Sydney. It is interesting to see the variations in
both variables for cities which are located at different geographical
locations and have different weathers.
Load Packages
# This is a chunk where you can load the necessary packages required to reproduce the report
library(colorspace)
library(dplyr)
library(evaluate)
library(epitools)
library(forcats)
library(ggplot2)
library(grid)
library(gridExtra)
library(Hmisc)
library(htmlwidgets)
library(knitr)
library(lattice)
library(lubridate)
library(magrittr)
library(MVN)
library(outliers)
library(Rcpp)
library(readr)
library(readxl)
library(rmarkdown)
library(sp)
library(stringr)
library(tibble)
library(tidyr)
library(tidyselect)
library(tidyverse)
library(validate)
Data
Import the climate data and prepare it for analysis. Show your
code.
# This is a chunk for your Data section.
#Importing datasets
Climate_Melb <- read_csv("C:/Users/praam/OneDrive - RMIT University/Data-Applied Analytics/Climate Data Melbourne.csv")
Rows: 90 Columns: 7── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (1): Day
dbl (6): Station number, Year, Month, Maximum Temperature, Solar Exposure, Wind speed
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Climate_Syd <- read_csv("C:/Users/praam/OneDrive - RMIT University/Data-Applied Analytics/Climate Data Sydney.csv")
New names:Rows: 90 Columns: 8── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (1): Day
dbl (6): Station number, Year, Month, Maximum Temperature, Solar Exposure, maximum wind speed
lgl (1): ...6
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#Scanning/Checking the header of imported datasets
head(Climate_Melb)
head(Climate_Syd)
#Renaming column names for dataset imported
Climate_Melb <- Climate_Melb %>% rename_at('Station number', ~'Station')
Climate_Melb <- Climate_Melb %>% rename_at('Maximum Temperature', ~'Temperature')
Climate_Melb <- Climate_Melb %>% rename_at('Solar Exposure', ~'Solar_expo')
Climate_Melb <- Climate_Melb %>% rename_at('Wind speed', ~'Wind_speed')
#Deleting the blank column and ensuring that both cities data sets have same variable names
Climate_Syd <- Climate_Syd[, c(-6)]
colnames(Climate_Syd) <- c(colnames(Climate_Melb))
# replace Station numbers with City names
Climate_Melb$Station <- as.character(Climate_Melb$Station)
Climate_Melb['Station'][Climate_Melb['Station'] == 86282] <- "Melbourne"
Climate_Syd$Station <- as.character(Climate_Syd$Station)
Climate_Syd['Station'][Climate_Syd['Station'] == 66212] <- "Sydney"
#Extracting day number from day character and creating additional date column
Climate_Melb$Day <- as.numeric(str_replace_all(Climate_Melb$Day, pattern = "[a-z]", replacement = ""))
Climate_Syd$Day <- as.numeric(str_replace_all(Climate_Syd$Day, pattern = "[a-z]", replacement = ""))
#Rearranging column variables and shifting of newly added date column after station number
Climate_Melb<- Climate_Melb %>% mutate(Date = make_date(Year, Month, Day),.after = "Station")
Climate_Syd<- Climate_Syd %>% mutate(Date = make_date(Year, Month, Day),.after = "Station")
head(Climate_Melb)
head(Climate_Syd)
#Data type conversions
Climate_Melb$Year <- factor(Climate_Melb$Year)
Climate_Melb$Month <- factor(Climate_Melb$Month)
Climate_Melb$Day <- factor(Climate_Melb$Day)
Climate_Syd$Year <- factor(Climate_Syd$Year)
Climate_Syd$Month <- factor(Climate_Syd$Month)
Climate_Syd$Day <- factor(Climate_Syd$Day)
#Merging of both data cities/ station number datasets
Climate_cities <- as.data.frame(bind_rows(Climate_Melb, Climate_Syd))
Climate_cities$Station<- factor(Climate_cities$Station)
head(Climate_cities)
# Select specific variables from the data and store them in a new data frame
#Creating a subset of dataset with Station name, Date, Max temperature and solar exposure for Melbourne
Melb <- Climate_Melb[,c(-3,-4,-5,-8)] %>% as.data.frame(Melb)
#Creating a subset of dataset with Station name, Date, Max temperature and solar exposure for Sydney
Syd <- Climate_Syd[,c(-3,-4,-5,-8)] %>% as.data.frame(Syd)
#On investigating the imported data it is observed that there is one NA value which can alter the results and hence will be replaced by mean of temperatures for Sydney
Syd$Temperature <- impute(Syd$Temperature, fun = mean)
#Creating a subset of dataset with Station name, Date, Max temperature and solar exposure for both cities
Cities <- table(Climate_cities$Solar_expo, Climate_cities$Temperature)
Summary Statistics
Calculate descriptive statistics (i.e., mean, median, standard
deviation, first and third quartile, interquartile range, minimum and
maximum values) of the selected variable grouped by city.
# This is a chunk for your Summary Statistics section.
#Summary statistic of Temperature variable grouped by city
City_Temp <- Climate_cities %>% group_by(Station) %>% summarise(Min = min(Temperature,na.rm = TRUE),
Q1 = quantile(Temperature,probs = .25,na.rm = TRUE),
Median = median(Temperature, na.rm = TRUE),
Q3 = quantile(Temperature,probs = .75,na.rm = TRUE),
Max = max(Temperature,na.rm = TRUE),
Mean = mean(Temperature, na.rm = TRUE),
SD = sd(Temperature, na.rm = TRUE),
n = n(),
Missing = sum(is.na(Temperature)))
City_Temp
#On investigating the summary it is observed that there is one NA value which can alter the results and hence will be replaced by mean of temperatures for Sydney
Climate_cities$Temperature <- impute(Climate_cities$Temperature, fun = mean)
#Rerun the summary statistic after NA replacement with median
City_Temp <- Climate_cities %>% group_by(Station) %>% summarise(Min = min(Temperature,na.rm = TRUE),
Q1 = quantile(Temperature,probs = .25,na.rm = TRUE),
Median = median(Temperature, na.rm = TRUE),
Q3 = quantile(Temperature,probs = .75,na.rm = TRUE),
Max = max(Temperature,na.rm = TRUE),
Mean = mean(Temperature, na.rm = TRUE),
SD = sd(Temperature, na.rm = TRUE),
n = n(),
Missing = sum(is.na(Temperature)))
#Summary statistic of Max. temperature variables grouped by city
City_Temp
City_Temp_Melb <- City_Temp %>% filter(City_Temp$Station == "Melbourne")
City_Temp_Syd <- City_Temp %>% filter(City_Temp$Station == "Sydney")
#Summary statistic of Solar exposure variable grouped by city
City_Solar_expo <- Climate_cities %>% group_by(Station) %>% summarise(Min = min(Solar_expo,na.rm = TRUE),
Q1 = quantile(Solar_expo,probs = .25,na.rm = TRUE),
Median = median(Solar_expo, na.rm = TRUE),
Q3 = quantile(Solar_expo,probs = .75,na.rm = TRUE),
Max = max(Solar_expo,na.rm = TRUE),
Mean = mean(Solar_expo, na.rm = TRUE),
SD = sd(Solar_expo, na.rm = TRUE),
n = n(),
Missing = sum(is.na(Solar_expo)))
City_Solar_expo
City_Solar_Melb <- City_Solar_expo %>% filter(City_Solar_expo$Station == "Melbourne")
City_Solar_Syd <- City_Solar_expo %>% filter(City_Solar_expo$Station == "Sydney")
Distribution Fitting
Compare the empirical distribution of selected variable to a normal
distribution separately in Melbourne and in Sydney. You need to do this
visually by plotting the histogram with normal distribution overlay.
Show your code.
# This is a chunk for your Distribution Fitting section.
#Plotting histogram for City temperatures to observe behavior/pattern of temperatures across cities
par(mfrow = c(2, 2))
#Histogram with normal distribution overlay for Melbourne temperature variable
x <- rnorm(1000, mean= 0, sd =1)
x1<-rnorm(n=City_Temp_Melb$n,mean = City_Temp_Melb$Mean, sd = City_Temp_Melb$SD)
hist(x1, freq= FALSE, xlim=c(10, 50), breaks=15)
curve(dnorm(x,mean(x1),sd(x1)), add= TRUE)
abline(v=mean(x1),col='red',lw=2)
#Histogram with normal distribution overlay for Sydney temperature variable
x2<-rnorm(n=City_Temp_Syd$n,mean = City_Temp_Syd$Mean, sd = City_Temp_Syd$SD)
hist(x2, freq= FALSE, xlim=c(10, 50),breaks=15)
curve(dnorm(x,mean(x2),sd(x2)), add= TRUE)
abline(v=mean(x2),col='red',lw=2)
#Histogram with normal distribution overlay for Melbourne solar exposure variable)
x3<-rnorm(n=City_Solar_Melb$n,mean = City_Solar_Melb$Mean, sd = City_Solar_Melb$SD)
hist(x3, freq= FALSE, xlim=c(0, 40),breaks=15)
curve(dnorm(x,mean(x3),sd(x3)), add= TRUE)
abline(v=mean(x3),col='red',lw=2)
#Histogram with normal distribution overlay for Sydney solar exposure variable
x4<-rnorm(n=City_Solar_Syd$n,mean = City_Solar_Syd$Mean, sd = City_Solar_Syd$SD)
hist(x4, freq= FALSE, xlim=c(0, 40),breaks=15)
curve(dnorm(x,mean(x4),sd(x4)), add= TRUE)
abline(v=mean(x4),col='red',lw=2)

Interpretation
Going back to your problem statement, what insight has been gained
from the investigation?
After plotting the respective variables histograms along with normal
distribution curves and analyzing empirical data, following can be
inferred, for the months of Dec-22 to Feb-23
Melbourne temperatures The melbourne max. temperatures are
generally more spread or unevenly distributed. There are more variations
in daily max. temperaure which is reflected by density plot.
Sydney temperatures When compared to Melbourne temperatures,
Sydney temperatures are more evenly distributed. There are less
variations, which is also reflected in high density plot.
Also, difference, between min and max. temperatures is less for
Sydney than Melbourne daily temperatures.
Melbourne Solar exposure Solar exposure in Melbourne case seems
to be evenly distributed across normal distribution curve indicating
uniform distribution.
Sydney Solar exposure Solar exposure in Sydney seems to be more
uniform across normal distribution curve indicating more
consistency/less weather predictability. On comparison between solar
exposure of both cities Melbourne and Sydney, there doesn’t seems to be
more difference and distribution. This is also indicated by similar Mean
values. However, there are days which have more solar exposure than
remaining days, in case of Melbourne than Sydney which is also reflected
by Median values of solar exposure of both cities.
LS0tDQp0aXRsZTogIk1BVEgxMzI0IEFzc2lnbm1lbnQgMSINCnN1YnRpdGxlOiBTdGF0aXN0aWNhbCBhbmFseXNpcyBvZiBDbGltYXRlIGRhdGENCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojIyBTdHVkZW50IERldGFpbHMNCg0KDQpTdHVkZW50IE5hbWUgKHMzODY4Njg1KQ0KDQojIyBQcm9ibGVtIFN0YXRlbWVudA0KDQpUaGUgZGF0YXNldCBjb250YWlucyAzIHZhcmlhYmxlcyBmb3IgdHdvIGNpdGllcyBvZiBNZWxib3VybmUgYW5kIFN5ZG5leSwgb2YgMyBtb250aHMgb2YgdGhlIHllYXIgdGhhdCBhcmUgRGVjMjAyMS1KYW4gMjAyMiBhbmQgRmViLTIwMjIsIGNvbGxlY3RlZCBmcm9tOiANCkRhdGEgU291cmNlOiBodHRwOi8vd3d3LmJvbS5nb3YuYXUvY2xpbWF0ZS9kYXRhL3N0YXRpb25zLw0KaHR0cDovL3d3dy5ib20uZ292LmF1L2NsaW1hdGUvZGF0YS9pbmRleC5zaHRtbD9ib29rbWFyaz0xMzYNCg0KVmFyaWFibGVzIHNlbGVjdGVkIGluIHRoZSBkYXRhc2V0Og0KDQoxLSBTb2xhciBleHBvc3VyZTogVGhlIERhaWx5IGdsb2JhbCBzb2xhciBleHBvc3VyZSBpcyB0aGUgdG90YWwgc29sYXIgZW5lcmd5IGZvciBhIGRheSBmYWxsaW5nIG9uIGEgaG9yaXpvbnRhbCBzdXJmYWNlLiBJdCBpcyBtZWFzdXJlZCBmcm9tIG1pZG5pZ2h0IHRvIG1pZG5pZ2h0LiBUaGUgdmFsdWVzIGFyZSB1c3VhbGx5IGhpZ2hlc3QgaW4gY2xlYXIgc3VuIGNvbmRpdGlvbnMgZHVyaW5nIHRoZSBzdW1tZXIgYW5kIGxvd2VzdCBkdXJpbmcgd2ludGVyIG9yIHZlcnkgY2xvdWR5IGRheXMgYW5kDQoNCjItIE1heGltdW0gdGVtcGVyYXR1cmU6IEl0IGlzIHRoZSBoaWdoZXN0IHRlbXBlcmF0dXJlIHJlY29yZGVkIGluIHRoZSAyNCBob3VycyBmcm9tIDkgYW0uDQoNClRoZSBvYmplY3RpdmUgb2YgdGhpcyBzdGF0aXN0aWNhbCBhbmFseXNpcyBpcyB0byBzZWUgdGhlIHZhcmlhdGlvbiBiZXR3ZWVuIHRoZSBzb2xhciBleHBvc3VyZSBhbmQgbWF4aW11bSB0ZW1wZXJhdHVyZXMgb2JzZXJ2ZWQgZm9yIGJvdGggY2l0aWVzIE1lbGJvdXJuZSBhbmQgU3lkbmV5LiBJdCBpcyBpbnRlcmVzdGluZyB0byBzZWUgdGhlIHZhcmlhdGlvbnMgaW4gYm90aCB2YXJpYWJsZXMgZm9yIGNpdGllcyB3aGljaCBhcmUgbG9jYXRlZCBhdCBkaWZmZXJlbnQgZ2VvZ3JhcGhpY2FsIGxvY2F0aW9ucyBhbmQgaGF2ZSBkaWZmZXJlbnQgd2VhdGhlcnMuIA0KDQojIyBMb2FkIFBhY2thZ2VzDQoNCmBgYHtyfQ0KIyBUaGlzIGlzIGEgY2h1bmsgd2hlcmUgeW91IGNhbiBsb2FkIHRoZSBuZWNlc3NhcnkgcGFja2FnZXMgcmVxdWlyZWQgdG8gcmVwcm9kdWNlIHRoZSByZXBvcnQNCmxpYnJhcnkoY29sb3JzcGFjZSkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGV2YWx1YXRlKQ0KbGlicmFyeShlcGl0b29scykNCmxpYnJhcnkoZm9yY2F0cykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ3JpZCkNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShIbWlzYykNCmxpYnJhcnkoaHRtbHdpZGdldHMpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShsYXR0aWNlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KG1hZ3JpdHRyKQ0KbGlicmFyeShNVk4pDQpsaWJyYXJ5KG91dGxpZXJzKQ0KbGlicmFyeShSY3BwKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShybWFya2Rvd24pDQpsaWJyYXJ5KHNwKQ0KbGlicmFyeShzdHJpbmdyKQ0KbGlicmFyeSh0aWJibGUpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeSh0aWR5c2VsZWN0KQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHZhbGlkYXRlKQ0KYGBgDQoNCiMjIERhdGENCg0KSW1wb3J0IHRoZSBjbGltYXRlIGRhdGEgYW5kIHByZXBhcmUgaXQgZm9yIGFuYWx5c2lzLiBTaG93IHlvdXIgY29kZS4NCg0KYGBge3J9DQojIFRoaXMgaXMgYSBjaHVuayBmb3IgeW91ciBEYXRhIHNlY3Rpb24uIA0KDQojSW1wb3J0aW5nIGRhdGFzZXRzDQpDbGltYXRlX01lbGIgPC0gcmVhZF9jc3YoIkM6L1VzZXJzL3ByYWFtL09uZURyaXZlIC0gUk1JVCBVbml2ZXJzaXR5L0RhdGEtQXBwbGllZCBBbmFseXRpY3MvQ2xpbWF0ZSBEYXRhIE1lbGJvdXJuZS5jc3YiKQ0KQ2xpbWF0ZV9TeWQgPC0gcmVhZF9jc3YoIkM6L1VzZXJzL3ByYWFtL09uZURyaXZlIC0gUk1JVCBVbml2ZXJzaXR5L0RhdGEtQXBwbGllZCBBbmFseXRpY3MvQ2xpbWF0ZSBEYXRhIFN5ZG5leS5jc3YiKQ0KDQojU2Nhbm5pbmcvQ2hlY2tpbmcgdGhlIGhlYWRlciBvZiBpbXBvcnRlZCBkYXRhc2V0cw0KaGVhZChDbGltYXRlX01lbGIpDQpoZWFkKENsaW1hdGVfU3lkKQ0KDQojUmVuYW1pbmcgY29sdW1uIG5hbWVzIGZvciBkYXRhc2V0IGltcG9ydGVkDQpDbGltYXRlX01lbGIgPC0gQ2xpbWF0ZV9NZWxiICU+JSByZW5hbWVfYXQoJ1N0YXRpb24gbnVtYmVyJywgfidTdGF0aW9uJykNCkNsaW1hdGVfTWVsYiA8LSBDbGltYXRlX01lbGIgJT4lIHJlbmFtZV9hdCgnTWF4aW11bSBUZW1wZXJhdHVyZScsIH4nVGVtcGVyYXR1cmUnKQ0KQ2xpbWF0ZV9NZWxiIDwtIENsaW1hdGVfTWVsYiAlPiUgcmVuYW1lX2F0KCdTb2xhciBFeHBvc3VyZScsIH4nU29sYXJfZXhwbycpDQpDbGltYXRlX01lbGIgPC0gQ2xpbWF0ZV9NZWxiICU+JSByZW5hbWVfYXQoJ1dpbmQgc3BlZWQnLCB+J1dpbmRfc3BlZWQnKQ0KDQojRGVsZXRpbmcgdGhlIGJsYW5rIGNvbHVtbiBhbmQgZW5zdXJpbmcgdGhhdCBib3RoIGNpdGllcyBkYXRhIHNldHMgaGF2ZSBzYW1lIHZhcmlhYmxlIG5hbWVzIA0KQ2xpbWF0ZV9TeWQgPC0gQ2xpbWF0ZV9TeWRbLCBjKC02KV0NCmNvbG5hbWVzKENsaW1hdGVfU3lkKSA8LSBjKGNvbG5hbWVzKENsaW1hdGVfTWVsYikpDQoNCiMgcmVwbGFjZSBTdGF0aW9uIG51bWJlcnMgd2l0aCBDaXR5IG5hbWVzDQpDbGltYXRlX01lbGIkU3RhdGlvbiA8LSBhcy5jaGFyYWN0ZXIoQ2xpbWF0ZV9NZWxiJFN0YXRpb24pDQpDbGltYXRlX01lbGJbJ1N0YXRpb24nXVtDbGltYXRlX01lbGJbJ1N0YXRpb24nXSA9PSA4NjI4Ml0gPC0gIk1lbGJvdXJuZSINCg0KQ2xpbWF0ZV9TeWQkU3RhdGlvbiA8LSBhcy5jaGFyYWN0ZXIoQ2xpbWF0ZV9TeWQkU3RhdGlvbikNCkNsaW1hdGVfU3lkWydTdGF0aW9uJ11bQ2xpbWF0ZV9TeWRbJ1N0YXRpb24nXSA9PSA2NjIxMl0gPC0gIlN5ZG5leSINCg0KI0V4dHJhY3RpbmcgZGF5IG51bWJlciBmcm9tIGRheSBjaGFyYWN0ZXIgYW5kIGNyZWF0aW5nIGFkZGl0aW9uYWwgZGF0ZSBjb2x1bW4gDQpDbGltYXRlX01lbGIkRGF5IDwtIGFzLm51bWVyaWMoc3RyX3JlcGxhY2VfYWxsKENsaW1hdGVfTWVsYiREYXksIHBhdHRlcm4gPSAiW2Etel0iLCByZXBsYWNlbWVudCA9ICIiKSkNCkNsaW1hdGVfU3lkJERheSA8LSBhcy5udW1lcmljKHN0cl9yZXBsYWNlX2FsbChDbGltYXRlX1N5ZCREYXksIHBhdHRlcm4gPSAiW2Etel0iLCByZXBsYWNlbWVudCA9ICIiKSkNCg0KI1JlYXJyYW5naW5nIGNvbHVtbiB2YXJpYWJsZXMgYW5kIHNoaWZ0aW5nIG9mIG5ld2x5IGFkZGVkIGRhdGUgY29sdW1uIGFmdGVyIHN0YXRpb24gbnVtYmVyDQpDbGltYXRlX01lbGI8LSBDbGltYXRlX01lbGIgJT4lIG11dGF0ZShEYXRlID0gbWFrZV9kYXRlKFllYXIsIE1vbnRoLCBEYXkpLC5hZnRlciA9ICJTdGF0aW9uIikgDQpDbGltYXRlX1N5ZDwtIENsaW1hdGVfU3lkICU+JSBtdXRhdGUoRGF0ZSA9IG1ha2VfZGF0ZShZZWFyLCBNb250aCwgRGF5KSwuYWZ0ZXIgPSAiU3RhdGlvbiIpDQoNCmhlYWQoQ2xpbWF0ZV9NZWxiKQ0KaGVhZChDbGltYXRlX1N5ZCkNCg0KI0RhdGEgdHlwZSBjb252ZXJzaW9ucw0KQ2xpbWF0ZV9NZWxiJFllYXIgPC0gZmFjdG9yKENsaW1hdGVfTWVsYiRZZWFyKQ0KQ2xpbWF0ZV9NZWxiJE1vbnRoIDwtIGZhY3RvcihDbGltYXRlX01lbGIkTW9udGgpDQpDbGltYXRlX01lbGIkRGF5IDwtIGZhY3RvcihDbGltYXRlX01lbGIkRGF5KQ0KDQpDbGltYXRlX1N5ZCRZZWFyIDwtIGZhY3RvcihDbGltYXRlX1N5ZCRZZWFyKQ0KQ2xpbWF0ZV9TeWQkTW9udGggPC0gZmFjdG9yKENsaW1hdGVfU3lkJE1vbnRoKQ0KQ2xpbWF0ZV9TeWQkRGF5IDwtIGZhY3RvcihDbGltYXRlX1N5ZCREYXkpDQoNCiNNZXJnaW5nIG9mIGJvdGggZGF0YSBjaXRpZXMvIHN0YXRpb24gbnVtYmVyIGRhdGFzZXRzDQpDbGltYXRlX2NpdGllcyA8LSBhcy5kYXRhLmZyYW1lKGJpbmRfcm93cyhDbGltYXRlX01lbGIsIENsaW1hdGVfU3lkKSkNCkNsaW1hdGVfY2l0aWVzJFN0YXRpb248LSBmYWN0b3IoQ2xpbWF0ZV9jaXRpZXMkU3RhdGlvbikNCmhlYWQoQ2xpbWF0ZV9jaXRpZXMpDQoNCiMgU2VsZWN0IHNwZWNpZmljIHZhcmlhYmxlcyBmcm9tIHRoZSBkYXRhIGFuZCBzdG9yZSB0aGVtIGluIGEgbmV3IGRhdGEgZnJhbWUNCg0KI0NyZWF0aW5nIGEgc3Vic2V0IG9mIGRhdGFzZXQgd2l0aCBTdGF0aW9uIG5hbWUsIERhdGUsIE1heCB0ZW1wZXJhdHVyZSBhbmQgc29sYXIgZXhwb3N1cmUgZm9yIE1lbGJvdXJuZQ0KDQpNZWxiIDwtIENsaW1hdGVfTWVsYlssYygtMywtNCwtNSwtOCldICU+JSBhcy5kYXRhLmZyYW1lKE1lbGIpDQoNCiNDcmVhdGluZyBhIHN1YnNldCBvZiBkYXRhc2V0IHdpdGggU3RhdGlvbiBuYW1lLCBEYXRlLCBNYXggdGVtcGVyYXR1cmUgYW5kIHNvbGFyIGV4cG9zdXJlIGZvciBTeWRuZXkNClN5ZCA8LSBDbGltYXRlX1N5ZFssYygtMywtNCwtNSwtOCldICU+JSBhcy5kYXRhLmZyYW1lKFN5ZCkNCg0KI09uIGludmVzdGlnYXRpbmcgdGhlIGltcG9ydGVkIGRhdGEgaXQgaXMgb2JzZXJ2ZWQgdGhhdCB0aGVyZSBpcyBvbmUgTkEgdmFsdWUgd2hpY2ggY2FuIGFsdGVyIHRoZSByZXN1bHRzIGFuZCBoZW5jZSB3aWxsIGJlIHJlcGxhY2VkIGJ5IG1lYW4gb2YgdGVtcGVyYXR1cmVzIGZvciBTeWRuZXkNClN5ZCRUZW1wZXJhdHVyZSA8LSBpbXB1dGUoU3lkJFRlbXBlcmF0dXJlLCBmdW4gPSBtZWFuKQ0KDQojQ3JlYXRpbmcgYSBzdWJzZXQgb2YgZGF0YXNldCB3aXRoIFN0YXRpb24gbmFtZSwgRGF0ZSwgTWF4IHRlbXBlcmF0dXJlIGFuZCBzb2xhciBleHBvc3VyZSBmb3IgYm90aCBjaXRpZXMNCg0KQ2l0aWVzIDwtIHRhYmxlKENsaW1hdGVfY2l0aWVzJFNvbGFyX2V4cG8sIENsaW1hdGVfY2l0aWVzJFRlbXBlcmF0dXJlKQ0KDQpgYGANCg0KDQojIyBTdW1tYXJ5IFN0YXRpc3RpY3MNCg0KDQpDYWxjdWxhdGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyAoaS5lLiwgbWVhbiwgbWVkaWFuLCBzdGFuZGFyZCBkZXZpYXRpb24sIGZpcnN0IGFuZCB0aGlyZCBxdWFydGlsZSwgaW50ZXJxdWFydGlsZSByYW5nZSwgbWluaW11bSBhbmQgbWF4aW11bSB2YWx1ZXMpIG9mIHRoZSBzZWxlY3RlZCB2YXJpYWJsZSBncm91cGVkIGJ5IGNpdHkuDQoNCmBgYHtyfQ0KIyBUaGlzIGlzIGEgY2h1bmsgZm9yIHlvdXIgU3VtbWFyeSBTdGF0aXN0aWNzIHNlY3Rpb24uIA0KDQojU3VtbWFyeSBzdGF0aXN0aWMgb2YgVGVtcGVyYXR1cmUgdmFyaWFibGUgZ3JvdXBlZCBieSBjaXR5IA0KQ2l0eV9UZW1wIDwtIENsaW1hdGVfY2l0aWVzICU+JSBncm91cF9ieShTdGF0aW9uKSAlPiUgc3VtbWFyaXNlKE1pbiA9IG1pbihUZW1wZXJhdHVyZSxuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRMSA9IHF1YW50aWxlKFRlbXBlcmF0dXJlLHByb2JzID0gLjI1LG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lZGlhbiA9IG1lZGlhbihUZW1wZXJhdHVyZSwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUTMgPSBxdWFudGlsZShUZW1wZXJhdHVyZSxwcm9icyA9IC43NSxuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXggPSBtYXgoVGVtcGVyYXR1cmUsbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVhbiA9IG1lYW4oVGVtcGVyYXR1cmUsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEID0gc2QoVGVtcGVyYXR1cmUsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBuKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pc3NpbmcgPSBzdW0oaXMubmEoVGVtcGVyYXR1cmUpKSkNCkNpdHlfVGVtcA0KDQojT24gaW52ZXN0aWdhdGluZyB0aGUgc3VtbWFyeSBpdCBpcyBvYnNlcnZlZCB0aGF0IHRoZXJlIGlzIG9uZSBOQSB2YWx1ZSB3aGljaCBjYW4gYWx0ZXIgdGhlIHJlc3VsdHMgYW5kIGhlbmNlIHdpbGwgYmUgcmVwbGFjZWQgYnkgbWVhbiBvZiB0ZW1wZXJhdHVyZXMgZm9yIFN5ZG5leQ0KDQpDbGltYXRlX2NpdGllcyRUZW1wZXJhdHVyZSA8LSBpbXB1dGUoQ2xpbWF0ZV9jaXRpZXMkVGVtcGVyYXR1cmUsIGZ1biA9IG1lYW4pDQoNCiNSZXJ1biB0aGUgc3VtbWFyeSBzdGF0aXN0aWMgYWZ0ZXIgTkEgcmVwbGFjZW1lbnQgd2l0aCBtZWRpYW4NCkNpdHlfVGVtcCA8LSBDbGltYXRlX2NpdGllcyAlPiUgZ3JvdXBfYnkoU3RhdGlvbikgJT4lIHN1bW1hcmlzZShNaW4gPSBtaW4oVGVtcGVyYXR1cmUsbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUTEgPSBxdWFudGlsZShUZW1wZXJhdHVyZSxwcm9icyA9IC4yNSxuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWRpYW4gPSBtZWRpYW4oVGVtcGVyYXR1cmUsIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFEzID0gcXVhbnRpbGUoVGVtcGVyYXR1cmUscHJvYnMgPSAuNzUsbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF4ID0gbWF4KFRlbXBlcmF0dXJlLG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW4gPSBtZWFuKFRlbXBlcmF0dXJlLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRCA9IHNkKFRlbXBlcmF0dXJlLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuID0gbigpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNaXNzaW5nID0gc3VtKGlzLm5hKFRlbXBlcmF0dXJlKSkpDQojU3VtbWFyeSBzdGF0aXN0aWMgb2YgTWF4LiB0ZW1wZXJhdHVyZSB2YXJpYWJsZXMgZ3JvdXBlZCBieSBjaXR5DQpDaXR5X1RlbXANCkNpdHlfVGVtcF9NZWxiIDwtIENpdHlfVGVtcCAlPiUgZmlsdGVyKENpdHlfVGVtcCRTdGF0aW9uID09ICJNZWxib3VybmUiKQ0KQ2l0eV9UZW1wX1N5ZCA8LSBDaXR5X1RlbXAgJT4lIGZpbHRlcihDaXR5X1RlbXAkU3RhdGlvbiA9PSAiU3lkbmV5IikNCg0KI1N1bW1hcnkgc3RhdGlzdGljIG9mIFNvbGFyIGV4cG9zdXJlIHZhcmlhYmxlIGdyb3VwZWQgYnkgY2l0eSANCkNpdHlfU29sYXJfZXhwbyA8LSBDbGltYXRlX2NpdGllcyAlPiUgZ3JvdXBfYnkoU3RhdGlvbikgJT4lIHN1bW1hcmlzZShNaW4gPSBtaW4oU29sYXJfZXhwbyxuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRMSA9IHF1YW50aWxlKFNvbGFyX2V4cG8scHJvYnMgPSAuMjUsbmEucm0gPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVkaWFuID0gbWVkaWFuKFNvbGFyX2V4cG8sIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFEzID0gcXVhbnRpbGUoU29sYXJfZXhwbyxwcm9icyA9IC43NSxuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXggPSBtYXgoU29sYXJfZXhwbyxuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWFuID0gbWVhbihTb2xhcl9leHBvLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRCA9IHNkKFNvbGFyX2V4cG8sIG5hLnJtID0gVFJVRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4gPSBuKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pc3NpbmcgPSBzdW0oaXMubmEoU29sYXJfZXhwbykpKQ0KQ2l0eV9Tb2xhcl9leHBvDQpDaXR5X1NvbGFyX01lbGIgPC0gQ2l0eV9Tb2xhcl9leHBvICU+JSBmaWx0ZXIoQ2l0eV9Tb2xhcl9leHBvJFN0YXRpb24gPT0gIk1lbGJvdXJuZSIpDQpDaXR5X1NvbGFyX1N5ZCA8LSBDaXR5X1NvbGFyX2V4cG8gJT4lIGZpbHRlcihDaXR5X1NvbGFyX2V4cG8kU3RhdGlvbiA9PSAiU3lkbmV5IikNCg0KYGBgDQoNCg0KIyMgRGlzdHJpYnV0aW9uIEZpdHRpbmcNCg0KQ29tcGFyZSB0aGUgZW1waXJpY2FsIGRpc3RyaWJ1dGlvbiBvZiBzZWxlY3RlZCB2YXJpYWJsZSB0byBhIG5vcm1hbCBkaXN0cmlidXRpb24gc2VwYXJhdGVseSBpbiBNZWxib3VybmUgYW5kIGluIFN5ZG5leS4gWW91IG5lZWQgdG8gZG8gdGhpcyB2aXN1YWxseSBieSBwbG90dGluZyB0aGUgaGlzdG9ncmFtIHdpdGggbm9ybWFsIGRpc3RyaWJ1dGlvbiBvdmVybGF5LiBTaG93IHlvdXIgY29kZS4NCg0KDQpgYGB7cn0NCiMgVGhpcyBpcyBhIGNodW5rIGZvciB5b3VyIERpc3RyaWJ1dGlvbiBGaXR0aW5nIHNlY3Rpb24uDQoNCiNQbG90dGluZyBoaXN0b2dyYW0gZm9yIENpdHkgdGVtcGVyYXR1cmVzIHRvIG9ic2VydmUgYmVoYXZpb3IvcGF0dGVybiBvZiB0ZW1wZXJhdHVyZXMgYWNyb3NzIGNpdGllcw0KDQpwYXIobWZyb3cgPSBjKDIsIDIpKQ0KI0hpc3RvZ3JhbSB3aXRoIG5vcm1hbCBkaXN0cmlidXRpb24gb3ZlcmxheSBmb3IgTWVsYm91cm5lIHRlbXBlcmF0dXJlIHZhcmlhYmxlDQp4IDwtIHJub3JtKDEwMDAsIG1lYW49IDAsIHNkID0xKQ0KeDE8LXJub3JtKG49Q2l0eV9UZW1wX01lbGIkbixtZWFuID0gQ2l0eV9UZW1wX01lbGIkTWVhbiwgc2QgPSBDaXR5X1RlbXBfTWVsYiRTRCkNCmhpc3QoeDEsIGZyZXE9IEZBTFNFLCB4bGltPWMoMTAsIDUwKSwgYnJlYWtzPTE1KQ0KY3VydmUoZG5vcm0oeCxtZWFuKHgxKSxzZCh4MSkpLCBhZGQ9IFRSVUUpDQphYmxpbmUodj1tZWFuKHgxKSxjb2w9J3JlZCcsbHc9MikNCg0KI0hpc3RvZ3JhbSB3aXRoIG5vcm1hbCBkaXN0cmlidXRpb24gb3ZlcmxheSBmb3IgU3lkbmV5IHRlbXBlcmF0dXJlIHZhcmlhYmxlDQp4Mjwtcm5vcm0obj1DaXR5X1RlbXBfU3lkJG4sbWVhbiA9IENpdHlfVGVtcF9TeWQkTWVhbiwgc2QgPSBDaXR5X1RlbXBfU3lkJFNEKQ0KaGlzdCh4MiwgZnJlcT0gRkFMU0UsIHhsaW09YygxMCwgNTApLGJyZWFrcz0xNSkNCmN1cnZlKGRub3JtKHgsbWVhbih4Miksc2QoeDIpKSwgYWRkPSBUUlVFKQ0KYWJsaW5lKHY9bWVhbih4MiksY29sPSdyZWQnLGx3PTIpDQoNCiNIaXN0b2dyYW0gd2l0aCBub3JtYWwgZGlzdHJpYnV0aW9uIG92ZXJsYXkgZm9yIE1lbGJvdXJuZSBzb2xhciBleHBvc3VyZSB2YXJpYWJsZSkNCngzPC1ybm9ybShuPUNpdHlfU29sYXJfTWVsYiRuLG1lYW4gPSBDaXR5X1NvbGFyX01lbGIkTWVhbiwgc2QgPSBDaXR5X1NvbGFyX01lbGIkU0QpDQpoaXN0KHgzLCBmcmVxPSBGQUxTRSwgeGxpbT1jKDAsIDQwKSxicmVha3M9MTUpDQpjdXJ2ZShkbm9ybSh4LG1lYW4oeDMpLHNkKHgzKSksIGFkZD0gVFJVRSkNCmFibGluZSh2PW1lYW4oeDMpLGNvbD0ncmVkJyxsdz0yKQ0KDQojSGlzdG9ncmFtIHdpdGggbm9ybWFsIGRpc3RyaWJ1dGlvbiBvdmVybGF5IGZvciBTeWRuZXkgc29sYXIgZXhwb3N1cmUgdmFyaWFibGUNCng0PC1ybm9ybShuPUNpdHlfU29sYXJfU3lkJG4sbWVhbiA9IENpdHlfU29sYXJfU3lkJE1lYW4sIHNkID0gQ2l0eV9Tb2xhcl9TeWQkU0QpDQpoaXN0KHg0LCBmcmVxPSBGQUxTRSwgeGxpbT1jKDAsIDQwKSxicmVha3M9MTUpDQpjdXJ2ZShkbm9ybSh4LG1lYW4oeDQpLHNkKHg0KSksIGFkZD0gVFJVRSkNCmFibGluZSh2PW1lYW4oeDQpLGNvbD0ncmVkJyxsdz0yKQ0KDQpgYGANCg0KIyMgSW50ZXJwcmV0YXRpb24NCg0KR29pbmcgYmFjayB0byB5b3VyIHByb2JsZW0gc3RhdGVtZW50LCB3aGF0IGluc2lnaHQgaGFzIGJlZW4gZ2FpbmVkIGZyb20gdGhlIGludmVzdGlnYXRpb24/IA0KDQpBZnRlciBwbG90dGluZyB0aGUgcmVzcGVjdGl2ZSB2YXJpYWJsZXMgaGlzdG9ncmFtcyBhbG9uZyB3aXRoIG5vcm1hbCBkaXN0cmlidXRpb24gY3VydmVzIGFuZCBhbmFseXppbmcgZW1waXJpY2FsIGRhdGEsIGZvbGxvd2luZyBjYW4gYmUgaW5mZXJyZWQsIGZvciB0aGUgbW9udGhzIG9mIERlYy0yMiB0byBGZWItMjMNCg0KMSkgTWVsYm91cm5lIHRlbXBlcmF0dXJlcw0KVGhlIG1lbGJvdXJuZSBtYXguIHRlbXBlcmF0dXJlcyBhcmUgZ2VuZXJhbGx5IG1vcmUgc3ByZWFkIG9yIHVuZXZlbmx5IGRpc3RyaWJ1dGVkLiBUaGVyZSBhcmUgbW9yZSB2YXJpYXRpb25zIGluIGRhaWx5IG1heC4gdGVtcGVyYXVyZSB3aGljaCBpcyByZWZsZWN0ZWQgYnkgZGVuc2l0eSBwbG90Lg0KDQoyKSBTeWRuZXkgdGVtcGVyYXR1cmVzDQpXaGVuIGNvbXBhcmVkIHRvIE1lbGJvdXJuZSB0ZW1wZXJhdHVyZXMsIFN5ZG5leSB0ZW1wZXJhdHVyZXMgYXJlIG1vcmUgZXZlbmx5IGRpc3RyaWJ1dGVkLiBUaGVyZSBhcmUgbGVzcyB2YXJpYXRpb25zLCB3aGljaCBpcyBhbHNvIHJlZmxlY3RlZCBpbiBoaWdoIGRlbnNpdHkgcGxvdC4gDQoNCkFsc28sIGRpZmZlcmVuY2UsIGJldHdlZW4gbWluIGFuZCBtYXguIHRlbXBlcmF0dXJlcyBpcyBsZXNzIGZvciBTeWRuZXkgdGhhbiBNZWxib3VybmUgZGFpbHkgdGVtcGVyYXR1cmVzLg0KDQozKSBNZWxib3VybmUgU29sYXIgZXhwb3N1cmUNClNvbGFyIGV4cG9zdXJlIGluIE1lbGJvdXJuZSBjYXNlIHNlZW1zIHRvIGJlIGV2ZW5seSBkaXN0cmlidXRlZCBhY3Jvc3Mgbm9ybWFsIGRpc3RyaWJ1dGlvbiBjdXJ2ZSBpbmRpY2F0aW5nIHVuaWZvcm0gZGlzdHJpYnV0aW9uLiANCg0KNCkgU3lkbmV5IFNvbGFyIGV4cG9zdXJlDQpTb2xhciBleHBvc3VyZSBpbiBTeWRuZXkgc2VlbXMgdG8gYmUgbW9yZSB1bmlmb3JtIGFjcm9zcyBub3JtYWwgZGlzdHJpYnV0aW9uIGN1cnZlIGluZGljYXRpbmcgbW9yZSBjb25zaXN0ZW5jeS9sZXNzIHdlYXRoZXIgcHJlZGljdGFiaWxpdHkuIE9uIGNvbXBhcmlzb24gYmV0d2VlbiBzb2xhciBleHBvc3VyZSBvZiBib3RoIGNpdGllcyBNZWxib3VybmUgYW5kIFN5ZG5leSwgdGhlcmUgZG9lc24ndCBzZWVtcyB0byBiZSBtb3JlIGRpZmZlcmVuY2UgYW5kIGRpc3RyaWJ1dGlvbi4gVGhpcyBpcyBhbHNvIGluZGljYXRlZCBieSBzaW1pbGFyIE1lYW4gIHZhbHVlcy4gSG93ZXZlciwgdGhlcmUgYXJlIGRheXMgd2hpY2ggaGF2ZSBtb3JlIHNvbGFyIGV4cG9zdXJlIHRoYW4gcmVtYWluaW5nIGRheXMsIGluIGNhc2Ugb2YgTWVsYm91cm5lIHRoYW4gU3lkbmV5IHdoaWNoIGlzIGFsc28gcmVmbGVjdGVkIGJ5IE1lZGlhbiB2YWx1ZXMgb2Ygc29sYXIgZXhwb3N1cmUgb2YgYm90aCBjaXRpZXMu