Required packages

library(readxl)
library(tidyr)
library(dplyr)
library(editrules)
library(outliers)
library(MVN)

Executive Summary

The datasets of regional population by gender and age in 2018-2019 were obtained from Australian Bureau of Statistics to gain more insights about gender ratio in regional areas in Victoria and how their population changed from 2018 to 2019.

The first two datasets were imported as xlsx. files for the population estimates by sex across Local Government Areas (LGA) in 2018 and filtered for Victorian region. The final dataset described the total population estimates across LGA in Victoria in 2018-2019. All of the imported datasets were then joined using LGA as key variables and checked for data structure. Data conversion was taken from character to numeric values. The merged dataset was untidy because column headers were not variables so that tidying data was carried out for gender columns with the estimated number of residents as values. Two new variables were created with mutate function to determine the population ratio by sex and the population growth between 2018-2019 for LGAs.

The tidy dataset was then scanned for missing values and special values for all numeric values. The obvious errors of numeric data were also scanned for the total population of 2018 and 2019 to ensure that there were no negative values in the variables. The outliers were detected for following variables: Estimated residents, Population ratio and Growth rate using boxplot. The location of these outliers was identified using z.scores method for univariate data. The data from total population of 2018 and 2019 was scanned for outliers as multivariate data using Mahalanobis distance approach and visualised by Chi-square Q-Q plot. Following this, since the outliers were decided not to eliminate from the dataset, data transformation was taken for these two variables using \(ln\) transformation to reduce the right skewness in the distributions. The final dataset was ready for further statistical analysis.

Data

First dataset

The Population Estimates by Age and Sex, Local Government Areas (ASGS 2018), 2018 .xls was collected from Australian Bureau of Statistics at https://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/3235.02018?OpenDocument&fbclid=IwAR0JOzaSa6clO2HYae-2ZbsdXZjNBuk5XK-Z5YEM0NhCuoCjW-fp8IkGbtQ, which measured the estimate of the residental population in Australia by age and gender corresponding to State and Local Government Areas at 30 June 2018.

The original dataset #1 was firstly imported with 7 skipped rows due to invalid headers and stored as pop_female for sheet named “Table 2”.

Since the study focused on total population by gender in Victoria, the S/T code under ASGS 2018 for Victoria (S/T code = 2) was filtered from the original dataset using filter().

The column names of vic_pop_female were then renamed using colnames().

Since the study would not consider the number of residents under Age group categories, only Total Female population per LGA was selected from vic_pop_female using select() and assigned into new object called data_female.

The data_female now contained four main variables:

  • S/T code [categorical]: State/Territory code
  • S/T name [character]: State/Territory name
  • LGA code [categorical]: code of Local Government Areas per State e.g 20110 for Alpine (S)
  • LGA Name [character]: name of Local Government Areas per State e.g Alpine
  • Total Female population [numeric]: the total of female residents from all age groups by LGA
pop_female <- read_excel("Population Estimates by Age and Sex, Local Government Areas (ASGS 2018), 2018 .xls", sheet = "Table 2", skip = 7)
New names:
* `` -> ...2
* `` -> ...3
* `` -> ...4
vic_pop_female <- pop_female %>% filter(`ASGS 2018` == 2) 
colnames(vic_pop_female) <- c("S/T code", "S/T name", "LGA code", "LGA name", "Age 0-4", "Age 5-9", "Age 10-14", "Age 15-19", "Age 20-24", "Age 25-29", "Age 30-34", "Age 35-39", "Age 40-44", "Age 45-49", "Age 50-54", "Age 55-59", "Age 60-64", "Age 65-69", "Age 70-74", "Age 75-79", "Age 80-84", "Age 85 and over", "Total Female population")
data_female <- vic_pop_female %>% select(`S/T code` , `S/T name`, `LGA code`, `LGA name`, `Total Female population`)
head(data_female)

Second dataset

The pop_male was also imported from Population Estimates by Age and Sex, Local Government Areas (ASGS 2018), 2018 .xls with sheet named “Table 1”.

Since the study focused on total population by gender in Victoria, the S/T code under ASGS 2018 for Victoria (S/T code = 2) was also filtered from pop_male using filter().

The column names of vic_pop_male were also renamed using colnames().

Since the study would not consider the number of residents under Age group categories, only Total Male population per LGA was selected from vic_pop_male using select() and assigned into new object called data_male.

The data_female now contained four main variables:

  • S/T code [categorical]: State/Territory code
  • S/T name [character]: State/Territory name
  • LGA code [categorical]: code of Local Government Areas per State e.g 20110 for Alpine (S)
  • LGA Name [character]: name of Local Government Areas per State e.g Alpine
  • Total Male population [numeric]: the total of female residents from all age groups by LGA
pop_male <- read_excel("Population Estimates by Age and Sex, Local Government Areas (ASGS 2018), 2018 .xls", sheet = "Table 1", skip = 7)
New names:
* `` -> ...2
* `` -> ...3
* `` -> ...4
vic_pop_male <- pop_male %>% filter(`ASGS 2018` == 2) 
colnames(vic_pop_male) <- c("S/T code", "S/T name", "LGA code", "LGA name", "Age 0-4", "Age 5-9", "Age 10-14", "Age 15-19", "Age 20-24", "Age 25-29", "Age 30-34", "Age 35-39", "Age 40-44", "Age 45-49", "Age 50-54", "Age 55-59", "Age 60-64", "Age 65-69", "Age 70-74", "Age 75-79", "Age 80-84", "Age 85 and over", "Total Male population")
data_male <- vic_pop_male %>% select(`S/T code` , `S/T name`, `LGA code`, `LGA name`, `Total Male population`)
head(data_male)

Third dataset

The Population Estimates by Local Government Area, 2018 to 2019 .xls was also obtained from Australian Bureau of Statistics at https://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/3218.02018-19?OpenDocument&fbclid=IwAR205_G_WwqXHZDy0SJxsXfJX_SbSNN4owAo_uYnsQ1ecqmhMsuTpaJ4xVw, which indicated the total population for 2018 and 2019 as well as proportion for different components of population change (natural increase, net overseas migration, net internal migration) by LGA across States.

The original dataset #2 was firstly imported with sheet named “Table 2” (Victoria) and 6 skipped rows due to invalid headers and stored as pop_vic.

The total population of Victoria by LGA in 2018 and 2019 were selected from the original dataset pop_vic using select() and assigned into new object new_pop_vicfor later merging datasets.

The column names of new_pop_vic was renamed and now includes three variables:

  • LGA code [categorical]: code of Local Government Areas in Victoria
  • LGA name[characer]: name of Local Government Areas in Victoria
  • 2018[numeric]: total population in 2018 by lGA
  • 2019[numeric]: total population in 2019 by lGA
pop_vic <- read_excel("Population Estimates by Local Government Area, 2018 to 2019 .xls", sheet = "Table 2", skip = 6)
New names:
* `` -> ...1
* `` -> ...2
* `` -> ...5
* `` -> ...7
* `` -> ...8
* … and 1 more problem
new_pop_vic <- pop_vic %>% select (c(1,2,3,4)) 
colnames(new_pop_vic) <- c("LGA code", "LGA name", "Total_2018", "Total_2019")
head(new_pop_vic)
NA

Merging datasets

The data_female and data_male were firstly merged using inner_join which used S/T code, S/T name,LGA code and LGA name as key variables and stored as data_gender.

  • Data_gender described the total population by gender across Local Government Areas in Victoria by 2018.
data_gender <- inner_join(data_female, data_male,by = c("S/T code", "S/T name", "LGA code", "LGA name"))
head(data_gender)

The final dataset pop_vic_gender was then created by merging data_gender and new_pop_vic using inner_join which used both LGA code and LGA name as key variables.

The final dataset now includes 8 variables:

  • S/T code [categorical]: State/Territory code
  • S/T name [character]: State/Territory name
  • LGA code [categorical]: code of Local Government Areas per State e.g 20110 for Alpine (S)
  • LGA Name [character]: name of Local Government Areas per State e.g Alpine
  • Total Female population [numeric]: the total of female residents by LGA
  • Total Male population [numeric]: the total of male residents by LGA
  • Total_2018[numeric]: total population in 2018 by lGA
  • Total_2019[numeric]: total population in 2019 by lGA
pop_vic_gender <- inner_join(data_gender, new_pop_vic, by = c("LGA code", "LGA name"))
head(pop_vic_gender)

Understand

The dimension of the dataset was checked using dim(), which resulted at 80 observations and 8 variables.

The structure of pop_vic_gender showed that all variables were in character type. Therefore, the conversion to numeric data type and factor were needed.

dim(pop_vic_gender)
[1] 80  8
str(pop_vic_gender)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   80 obs. of  8 variables:
 $ S/T code               : chr  "2" "2" "2" "2" ...
 $ S/T name               : chr  "Victoria" "Victoria" "Victoria" "Victoria" ...
 $ LGA code               : chr  "20110" "20260" "20570" "20660" ...
 $ LGA name               : chr  "Alpine (S)" "Ararat (RC)" "Ballarat (C)" "Banyule (C)" ...
 $ Total Female population: chr  "6391" "5468" "55293" "66536" ...
 $ Total Male population  : chr  "6339" "6327" "52032" "63701" ...
 $ Total_2018             : chr  "12730" "11795" "107324" "130250" ...
 $ Total_2019             : chr  "12814" "11845" "109505" "131631" ...
col.num <- c("S/T code", "Total Female population", "Total Male population", "Total_2018", "Total_2019")
pop_vic_gender[col.num] <- sapply(pop_vic_gender[col.num],as.numeric)
pop_vic_gender$`LGA code` <- as.factor(pop_vic_gender$`LGA code`)
str(pop_vic_gender)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   80 obs. of  8 variables:
 $ S/T code               : num  2 2 2 2 2 2 2 2 2 2 ...
 $ S/T name               : chr  "Victoria" "Victoria" "Victoria" "Victoria" ...
 $ LGA code               : Factor w/ 80 levels "20110","20260",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ LGA name               : chr  "Alpine (S)" "Ararat (RC)" "Ballarat (C)" "Banyule (C)" ...
 $ Total Female population: num  6391 5468 55293 66536 18021 ...
 $ Total Male population  : num  6339 6327 52032 63701 17306 ...
 $ Total_2018             : num  12730 11795 107324 130250 35326 ...
 $ Total_2019             : num  12814 11845 109505 131631 36320 ...

Tidy & Manipulate Data I

The pop_vic_gender dataset was untidy because Total Female population and Total Male population as column headers were not variables.

gather() was used to gather female and male columns into one single column named Gender and stored the values under Estimated residents column.

A tidy dataset was then stored as tidy_pop_gender.

tidy_pop_gender <- pop_vic_gender %>% gather(`Total Female population`, `Total Male population`,  key = "Gender", value = "Estimated residents")
head(tidy_pop_gender)
is.factor(tidy_pop_gender$Gender)
[1] FALSE
tidy_pop_gender$Gender <- as.factor(tidy_pop_gender$Gender)
tidy_pop_gender$Gender<- factor(tidy_pop_gender$Gender, level = c("Total Female population", "Total Male population"), labels = c("female", "male"))
tidy_pop_gender <- tidy_pop_gender[ , c(1,2,3,4,7,8,5,6)]
head(tidy_pop_gender)

Tidy & Manipulate Data II

The Population ratio was created to estimate the proportion of female and male residents by total population per Local Government Areas in Victoria by 2018.

The Growth rate was also mutated to determine the growth rate of population between 2018 and 2019 for every Local Government Areas in Victoria.

Growth rate = \(\frac{Present value - Past value}{Past value}*100\)
new_pop <- tidy_pop_gender %>% mutate("Population ratio" = round((`Estimated residents`/`Total_2018`)*100, 2), "Growth rate" = ((`Total_2019` - `Total_2018`)/`Total_2018`)*100)
head(new_pop)
new_pop %>% group_by(`Gender`) %>% summarise(avergage = mean(`Population ratio`, na.rm = TRUE))

Scan I

Scan for missing values

The missing values (NA) were scanned for all numeric values and output as the total number of missing values for each column using sum(is.na()).

The sapply() was used to apply sum(is.na()) in multiple columns for scanning.

There is no NA values detected in the dataset new_pop.

sapply(new_pop, function(x) sum(is.na(x)))
           S/T code            S/T name            LGA code            LGA name 
                  0                   0                   0                   0 
             Gender Estimated residents          Total_2018          Total_2019 
                  0                   0                   0                   0 
   Population ratio         Growth rate 
                  0                   0 

Scan for special values

The is.special function is created to check for special values that are either infinite values or Not a Number values (nan) in the dataset.

The special values were scanned for all numeric data in new_pop dataset and the output as the total number of special values for each columns using sum(is.special()).

The sapply() was also used to apply sum(is.special()) in multiple columns for scanning special values.

There is no special value detected in the dataset.

is.special <- function(x){
if (is.numeric(x)) (is.infinite(x) | is.nan(x))
}
sapply(new_pop, function(x) sum(is.special(x)))
           S/T code            S/T name            LGA code            LGA name 
                  0                   0                   0                   0 
             Gender Estimated residents          Total_2018          Total_2019 
                  0                   0                   0                   0 
   Population ratio         Growth rate 
                  0                   0 

Scan for obvivous errors

The data inconsistencies were checked for the dataset by generating a rule for numeric data. The rule is no negative numeric values in the total population of 2018 and 2019.

The rule was created using editset() and assigned it into rule.

The rule was then applied to the dataset using violatedEdits() to output logical values where TRUE is where inconsistencies are existed.

  • The output turned out to have no data inconsistencies in the dataset.
rule <- editset(c("Total_2018 > 0", "Total_2019 > 0"))
rule

Edit set:
num1 : 0 < Total_2018
num2 : 0 < Total_2019 
violatedEdits(rule, new_pop) 
      edit
record  num1  num2
   1   FALSE FALSE
   2   FALSE FALSE
   3   FALSE FALSE
   4   FALSE FALSE
   5   FALSE FALSE
   6   FALSE FALSE
   7   FALSE FALSE
   8   FALSE FALSE
   9   FALSE FALSE
   10  FALSE FALSE
   11  FALSE FALSE
   12  FALSE FALSE
   13  FALSE FALSE
   14  FALSE FALSE
   15  FALSE FALSE
   16  FALSE FALSE
   17  FALSE FALSE
   18  FALSE FALSE
   19  FALSE FALSE
   20  FALSE FALSE
   21  FALSE FALSE
   22  FALSE FALSE
   23  FALSE FALSE
   24  FALSE FALSE
   25  FALSE FALSE
   26  FALSE FALSE
   27  FALSE FALSE
   28  FALSE FALSE
   29  FALSE FALSE
   30  FALSE FALSE
   31  FALSE FALSE
   32  FALSE FALSE
   33  FALSE FALSE
   34  FALSE FALSE
   35  FALSE FALSE
   36  FALSE FALSE
   37  FALSE FALSE
   38  FALSE FALSE
   39  FALSE FALSE
   40  FALSE FALSE
   41  FALSE FALSE
   42  FALSE FALSE
   43  FALSE FALSE
   44  FALSE FALSE
   45  FALSE FALSE
   46  FALSE FALSE
   47  FALSE FALSE
   48  FALSE FALSE
   49  FALSE FALSE
   50  FALSE FALSE
   51  FALSE FALSE
   52  FALSE FALSE
   53  FALSE FALSE
   54  FALSE FALSE
   55  FALSE FALSE
   56  FALSE FALSE
   57  FALSE FALSE
   58  FALSE FALSE
   59  FALSE FALSE
   60  FALSE FALSE
   61  FALSE FALSE
   62  FALSE FALSE
   63  FALSE FALSE
   64  FALSE FALSE
   65  FALSE FALSE
   66  FALSE FALSE
   67  FALSE FALSE
   68  FALSE FALSE
   69  FALSE FALSE
   70  FALSE FALSE
   71  FALSE FALSE
   72  FALSE FALSE
   73  FALSE FALSE
   74  FALSE FALSE
   75  FALSE FALSE
   76  FALSE FALSE
   77  FALSE FALSE
   78  FALSE FALSE
   79  FALSE FALSE
   80  FALSE FALSE
   81  FALSE FALSE
   82  FALSE FALSE
   83  FALSE FALSE
   84  FALSE FALSE
   85  FALSE FALSE
   86  FALSE FALSE
   87  FALSE FALSE
   88  FALSE FALSE
   89  FALSE FALSE
   90  FALSE FALSE
   91  FALSE FALSE
   92  FALSE FALSE
   93  FALSE FALSE
   94  FALSE FALSE
   95  FALSE FALSE
   96  FALSE FALSE
   97  FALSE FALSE
   98  FALSE FALSE
   99  FALSE FALSE
   100 FALSE FALSE
   101 FALSE FALSE
   102 FALSE FALSE
   103 FALSE FALSE
   104 FALSE FALSE
   105 FALSE FALSE
   106 FALSE FALSE
   107 FALSE FALSE
   108 FALSE FALSE
   109 FALSE FALSE
   110 FALSE FALSE
   111 FALSE FALSE
   112 FALSE FALSE
   113 FALSE FALSE
   114 FALSE FALSE
   115 FALSE FALSE
   116 FALSE FALSE
   117 FALSE FALSE
   118 FALSE FALSE
   119 FALSE FALSE
   120 FALSE FALSE
   121 FALSE FALSE
   122 FALSE FALSE
   123 FALSE FALSE
   124 FALSE FALSE
   125 FALSE FALSE
   126 FALSE FALSE
   127 FALSE FALSE
   128 FALSE FALSE
   129 FALSE FALSE
   130 FALSE FALSE
   131 FALSE FALSE
   132 FALSE FALSE
   133 FALSE FALSE
   134 FALSE FALSE
   135 FALSE FALSE
   136 FALSE FALSE
   137 FALSE FALSE
   138 FALSE FALSE
   139 FALSE FALSE
   140 FALSE FALSE
   141 FALSE FALSE
   142 FALSE FALSE
   143 FALSE FALSE
   144 FALSE FALSE
   145 FALSE FALSE
   146 FALSE FALSE
   147 FALSE FALSE
   148 FALSE FALSE
   149 FALSE FALSE
   150 FALSE FALSE
   151 FALSE FALSE
   152 FALSE FALSE
   153 FALSE FALSE
   154 FALSE FALSE
   155 FALSE FALSE
   156 FALSE FALSE
   157 FALSE FALSE
   158 FALSE FALSE
   159 FALSE FALSE
   160 FALSE FALSE

Scan II

Scan for number and proportions of residents by gender

Boxplot was used to scan numeric values from Estimated residents and Population ratio columns for any potential outliers in the dataset.

There were two outliers recorded in the boxplot of Estimated residents which responded for more than 150,000 residents across LGAs in Victoria.

The outliers were then detected by Z-score method using scores(type = "z").

The summary of z scores showed that the minimum z-score is -1.0408 and the maximum is 3.395.

Since the absolute values of z score greater than 3 are considered as outliers, which(abs(z.scores)>3) was used to identify the location of outliers.

  • The observation in row 14 and 94 were considered as outliers.
  • It highlighted that the LGA named Casey in Victoria had the most outstanding population which is more 150,000 residents by gender living in the area.
  • Since this output might be interesting for future questions, these outliers would not be eliminated.
boxplot(new_pop$`Estimated residents`, main="Number of residents in Victoria (2018)", ylab = "Residents")

z.scores <- new_pop$`Estimated residents` %>%  scores(type = "z")
z.scores %>% summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.0408 -0.8383 -0.4571  0.0000  0.7009  3.3958 
which(abs(z.scores) >3 )
[1] 14 94
new_pop[c(14,94), ]
length (which( abs(z.scores) >3 ))
[1] 2

There were four outliers recorded in the boxplot of Population ratio which was ranging from either more than 52% or less than 48% of residents living across LGAs.

The outliers were then detected by Z-score method using scores(type = "z").

The summary of z scores showed that the minimum z-score2 is -4.6315 and the maximum is 4.638060.

Since the absolute values of z score greater than 3 are considered as outliers, which(abs(z.scores)>3) was used to identify the location of outliers.

  • The observation in row 80 and 160 were considered as outliers.
  • It highlighted that the LGA named Unicorporated in Victoria which had the proportions of female residents lower than 48% and the proportions of male residents higher than 52%.
  • Unicorpotated Vic are areas without local gorvernment (Travel Victoria) at https://www.travelvictoria.com.au/victoria/localgovernment/.
  • Since these outliers are also meaningful, they would also not be eliminated from the dataset.
boxplot(new_pop$`Population ratio`, main="Proportions of residents in Victoria (2018)", ylab = "percentage")

z.scores2 <- new_pop$`Population ratio` %>%  scores(type = "z")
z.scores2 %>% summary()
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
-4.631539 -0.594046  0.003261  0.000000  0.593007  4.638060 
which(abs(z.scores2) >3)
[1]  80 160
new_pop[c(80,160), ]

Scan for total population in 2018 and 2019

The total population in 2018 and 2019 across LGAs were subsetted from the dataset for scanning for multivariate data.

The Mahalanobis distance was used to detect multivariate outliers for the subset pop_sub dataset using mvn().

According to Chi-square Q-Q plot, there are 72 outliers dectected in the subset. These outliers would then be handled by transforming values.

pop_sub <- new_pop %>% select(`Total_2018`, `Total_2019`)
results <- mvn(data = pop_sub, multivariateOutlierMethod = "quan", showOutliers = TRUE)

The location of outliers were shown below:

results$multivariateOutliers

Boxplot was used to scan numeric values for Growth rate for any potential outliers in the dataset.

There were four outliers recorded in the boxplot of Estimated residents which indicated the growth rate of more than 4.0.

The outliers were then detected by Z-score method using scores(type = "z").

The summary of z scores showed that the minimum z-score is -1.7945 and the maximum is 3.1031.

Since the absolute values of z score greater than 3 are considered as outliers, which(abs(z.scores)>3) was used to identify the location of outliers.

  • The observation in row 76 and 156 were considered as outliers.
  • It highlighted that the LGA named Wyndham in Victoria had the highest growth rate of population from 2018 to 2019.
  • Since this output could bring interesting story for future analysis, these outliers would not be eliminated.
boxplot(new_pop$`Growth rate`, main = "Growth rate of LGAs in Victoria between 2018 and 2019")

z.scores3 <- new_pop$`Growth rate` %>%  scores(type = "z")
z.scores3 %>% summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.7945 -0.6311 -0.1422  0.0000  0.4218  3.1031 
which(abs(z.scores3) >3 )
[1]  76 156
new_pop[c(76,156), ]

Transform

The data distribution was checked for both Total_2018 and Total_2019 using hist().

Both of the distributions showed high right skewness in the variables. Therefore, \(ln\) transformation was taken into data transformation to reduce the skewness using log().

hist(new_pop$Total_2018, main = "Total population in 2018")

hist(new_pop$Total_2019, main = "Total population in 2019")

The distribution for Total_2018 and Total_2019 after \(ln\) transformation:

log_2018 <- log(new_pop$Total_2018)
hist(log_2018, main = "Log population in 2018")

log_2019 <- log(new_pop$Total_2019)
hist(log_2019, main = "Log population in 2019")

References

Australian Bureau of Statistics 2019, Population Estimates by Age and Sex, Local Government Areas (ASGS 2018), 2018, Australia’s statistic datasets, data file, Australian Government, Australian Bureau of Statistics, Melbourne, viewed 20 May 2020, https://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/3235.02018?OpenDocument.

Australian Bureau of Statistics 2019, Population Estimates by Local Government Area, 2018 to 2019 , Australia’s statistic datasets, data file, Australian Government, Australian Bureau of Statistics, Melbourne, viewed 20 May 2020, https://www.abs.gov.au/AUSSTATS/abs@.nsf/DetailsPage/3218.02018-19?OpenDocument&fbclid=IwAR205_G_WwqXHZDy0SJxsXfJX_SbSNN4owAo_uYnsQ1ecqmhMsuTpaJ4xVw.

Parker, B 2002, Planning Analysis: Calculating Growth Rates, University of Oregon, viewed 30 May 2020, https://pages.uoregon.edu/rgp/PPPM613/class8a.htm#:~:text=The%20annual%20percentage%20growth%20rate,N%2C%20the%20number%20of%20years.&text=In%201980%2C%20the%20population%20in%20Lane%20County%20was%20250%2C000.

Travel Victoria 2020, Local Government Areas, Travel Victoria, viewed 30 May 2020, https://www.travelvictoria.com.au/victoria/localgovernment/.



LS0tCnRpdGxlOiAiTUFUSDIzNDkgU2VtZXN0ZXIgMSwgMjAyMCIKYXV0aG9yOiAiVGhhbmggTmdvYyBNYWkgVHJhbiBhbmQgUzM4MzUzOTkiCnN1YnRpdGxlOiBBc3NpZ25tZW50IDIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKIyMgUmVxdWlyZWQgcGFja2FnZXMgCgpgYGB7cn0KbGlicmFyeShyZWFkeGwpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZWRpdHJ1bGVzKQpsaWJyYXJ5KG91dGxpZXJzKQpsaWJyYXJ5KE1WTikKYGBgCgoKIyMgRXhlY3V0aXZlIFN1bW1hcnkgCgpUaGUgZGF0YXNldHMgb2YgcmVnaW9uYWwgcG9wdWxhdGlvbiBieSBnZW5kZXIgYW5kIGFnZSBpbiAyMDE4LTIwMTkgd2VyZSBvYnRhaW5lZCBmcm9tIEF1c3RyYWxpYW4gQnVyZWF1IG9mIFN0YXRpc3RpY3MgdG8gZ2FpbiBtb3JlIGluc2lnaHRzIGFib3V0IGdlbmRlciByYXRpbyBpbiByZWdpb25hbCBhcmVhcyBpbiBWaWN0b3JpYSBhbmQgaG93IHRoZWlyIHBvcHVsYXRpb24gY2hhbmdlZCBmcm9tIDIwMTggdG8gMjAxOS4KClRoZSBmaXJzdCB0d28gZGF0YXNldHMgd2VyZSBpbXBvcnRlZCBhcyB4bHN4LiBmaWxlcyBmb3IgdGhlIHBvcHVsYXRpb24gZXN0aW1hdGVzIGJ5IHNleCBhY3Jvc3MgTG9jYWwgR292ZXJubWVudCBBcmVhcyAoTEdBKSBpbiAyMDE4IGFuZCBmaWx0ZXJlZCBmb3IgVmljdG9yaWFuIHJlZ2lvbi4gVGhlIGZpbmFsIGRhdGFzZXQgZGVzY3JpYmVkIHRoZSB0b3RhbCBwb3B1bGF0aW9uIGVzdGltYXRlcyBhY3Jvc3MgTEdBIGluIFZpY3RvcmlhIGluIDIwMTgtMjAxOS4gQWxsIG9mIHRoZSBpbXBvcnRlZCBkYXRhc2V0cyB3ZXJlIHRoZW4gam9pbmVkIHVzaW5nIExHQSBhcyBrZXkgdmFyaWFibGVzIGFuZCBjaGVja2VkIGZvciBkYXRhIHN0cnVjdHVyZS4gRGF0YSBjb252ZXJzaW9uIHdhcyB0YWtlbiBmcm9tIGNoYXJhY3RlciB0byBudW1lcmljIHZhbHVlcy4gVGhlIG1lcmdlZCBkYXRhc2V0IHdhcyB1bnRpZHkgYmVjYXVzZSBjb2x1bW4gaGVhZGVycyB3ZXJlIG5vdCB2YXJpYWJsZXMgc28gdGhhdCB0aWR5aW5nIGRhdGEgd2FzIGNhcnJpZWQgb3V0IGZvciBnZW5kZXIgY29sdW1ucyB3aXRoIHRoZSBlc3RpbWF0ZWQgbnVtYmVyIG9mIHJlc2lkZW50cyBhcyB2YWx1ZXMuICBUd28gbmV3IHZhcmlhYmxlcyB3ZXJlIGNyZWF0ZWQgd2l0aCBtdXRhdGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHRoZSBwb3B1bGF0aW9uIHJhdGlvIGJ5IHNleCBhbmQgdGhlIHBvcHVsYXRpb24gZ3Jvd3RoIGJldHdlZW4gMjAxOC0yMDE5IGZvciBMR0FzLiAKClRoZSB0aWR5IGRhdGFzZXQgd2FzIHRoZW4gc2Nhbm5lZCBmb3IgbWlzc2luZyB2YWx1ZXMgYW5kIHNwZWNpYWwgdmFsdWVzIGZvciBhbGwgbnVtZXJpYyB2YWx1ZXMuIFRoZSBvYnZpb3VzIGVycm9ycyBvZiBudW1lcmljIGRhdGEgd2VyZSBhbHNvIHNjYW5uZWQgZm9yIHRoZSB0b3RhbCBwb3B1bGF0aW9uIG9mIDIwMTggYW5kIDIwMTkgdG8gZW5zdXJlIHRoYXQgdGhlcmUgd2VyZSBubyBuZWdhdGl2ZSB2YWx1ZXMgaW4gdGhlIHZhcmlhYmxlcy4gVGhlIG91dGxpZXJzIHdlcmUgZGV0ZWN0ZWQgZm9yIGZvbGxvd2luZyB2YXJpYWJsZXM6IEVzdGltYXRlZCByZXNpZGVudHMsIFBvcHVsYXRpb24gcmF0aW8gYW5kIEdyb3d0aCByYXRlIHVzaW5nIGJveHBsb3QuIFRoZSBsb2NhdGlvbiBvZiB0aGVzZSBvdXRsaWVycyB3YXMgaWRlbnRpZmllZCB1c2luZyB6LnNjb3JlcyBtZXRob2QgZm9yIHVuaXZhcmlhdGUgZGF0YS4gVGhlIGRhdGEgZnJvbSB0b3RhbCBwb3B1bGF0aW9uIG9mIDIwMTggYW5kIDIwMTkgd2FzIHNjYW5uZWQgZm9yIG91dGxpZXJzIGFzIG11bHRpdmFyaWF0ZSBkYXRhIHVzaW5nIE1haGFsYW5vYmlzIGRpc3RhbmNlIGFwcHJvYWNoIGFuZCB2aXN1YWxpc2VkIGJ5IENoaS1zcXVhcmUgUS1RIHBsb3QuIEZvbGxvd2luZyB0aGlzLCBzaW5jZSB0aGUgb3V0bGllcnMgd2VyZSBkZWNpZGVkIG5vdCB0byBlbGltaW5hdGUgZnJvbSB0aGUgZGF0YXNldCwgZGF0YSB0cmFuc2Zvcm1hdGlvbiB3YXMgdGFrZW4gZm9yIHRoZXNlIHR3byB2YXJpYWJsZXMgdXNpbmcgJGxuJCB0cmFuc2Zvcm1hdGlvbiB0byByZWR1Y2UgdGhlIHJpZ2h0IHNrZXduZXNzIGluIHRoZSBkaXN0cmlidXRpb25zLiBUaGUgZmluYWwgZGF0YXNldCB3YXMgcmVhZHkgZm9yIGZ1cnRoZXIgc3RhdGlzdGljYWwgYW5hbHlzaXMuIAoKCiMjIERhdGEgCgojIyMgRmlyc3QgZGF0YXNldAoKVGhlIFBvcHVsYXRpb24gRXN0aW1hdGVzIGJ5IEFnZSBhbmQgU2V4LCBMb2NhbCBHb3Zlcm5tZW50IEFyZWFzIChBU0dTIDIwMTgpLCAyMDE4IC54bHMgd2FzIGNvbGxlY3RlZCBmcm9tIEF1c3RyYWxpYW4gQnVyZWF1IG9mIFN0YXRpc3RpY3MgYXQgaHR0cHM6Ly93d3cuYWJzLmdvdi5hdS9BVVNTVEFUUy9hYnNALm5zZi9EZXRhaWxzUGFnZS8zMjM1LjAyMDE4P09wZW5Eb2N1bWVudCZmYmNsaWQ9SXdBUjBKT3phU2E2Y2xPMkhZYWUtMlpic2RYWmpOQnVrNVhLLVo1WUVNME5oQ3VvQ2pXLWZwOElrR2J0USwgd2hpY2ggbWVhc3VyZWQgdGhlIGVzdGltYXRlIG9mIHRoZSByZXNpZGVudGFsIHBvcHVsYXRpb24gaW4gQXVzdHJhbGlhIGJ5IGFnZSBhbmQgZ2VuZGVyIGNvcnJlc3BvbmRpbmcgdG8gU3RhdGUgYW5kIExvY2FsIEdvdmVybm1lbnQgQXJlYXMgYXQgMzAgSnVuZSAyMDE4LgoKVGhlIG9yaWdpbmFsIGRhdGFzZXQgIzEgd2FzIGZpcnN0bHkgaW1wb3J0ZWQgd2l0aCA3IHNraXBwZWQgcm93cyBkdWUgdG8gaW52YWxpZCBoZWFkZXJzIGFuZCBzdG9yZWQgYXMgYHBvcF9mZW1hbGVgIGZvciBzaGVldCBuYW1lZCAiVGFibGUgMiIuICAKClNpbmNlIHRoZSBzdHVkeSBmb2N1c2VkIG9uIHRvdGFsIHBvcHVsYXRpb24gYnkgZ2VuZGVyIGluIFZpY3RvcmlhLCB0aGUgUy9UIGNvZGUgdW5kZXIgYEFTR1MgMjAxOGAgZm9yIFZpY3RvcmlhIChTL1QgY29kZSA9IDIpIHdhcyBmaWx0ZXJlZCBmcm9tIHRoZSBvcmlnaW5hbCBkYXRhc2V0IHVzaW5nIGBmaWx0ZXIoKWAuIAoKVGhlIGNvbHVtbiBuYW1lcyBvZiBgdmljX3BvcF9mZW1hbGVgIHdlcmUgdGhlbiByZW5hbWVkIHVzaW5nIGBjb2xuYW1lcygpYC4KClNpbmNlIHRoZSBzdHVkeSB3b3VsZCBub3QgY29uc2lkZXIgdGhlIG51bWJlciBvZiByZXNpZGVudHMgdW5kZXIgQWdlIGdyb3VwIGNhdGVnb3JpZXMsIG9ubHkgYFRvdGFsIEZlbWFsZSBwb3B1bGF0aW9uYCBwZXIgTEdBICB3YXMgc2VsZWN0ZWQgZnJvbSBgdmljX3BvcF9mZW1hbGVgIHVzaW5nIGBzZWxlY3QoKWAgYW5kIGFzc2lnbmVkIGludG8gbmV3IG9iamVjdCBjYWxsZWQgYGRhdGFfZmVtYWxlYC4gCgpUaGUgYGRhdGFfZmVtYWxlYCBub3cgY29udGFpbmVkIGZvdXIgbWFpbiB2YXJpYWJsZXM6CgoqIGBTL1QgY29kZWAgW2NhdGVnb3JpY2FsXTogU3RhdGUvVGVycml0b3J5IGNvZGUgCiogYFMvVCBuYW1lYCBbY2hhcmFjdGVyXTogU3RhdGUvVGVycml0b3J5IG5hbWUKKiBgTEdBIGNvZGVgIFtjYXRlZ29yaWNhbF06IGNvZGUgb2YgTG9jYWwgR292ZXJubWVudCBBcmVhcyBwZXIgU3RhdGUgZS5nIDIwMTEwIGZvciBBbHBpbmUgKFMpCiogYExHQSBOYW1lYCBbY2hhcmFjdGVyXTogbmFtZSBvZiBMb2NhbCBHb3Zlcm5tZW50IEFyZWFzIHBlciBTdGF0ZSBlLmcgQWxwaW5lCiogYFRvdGFsIEZlbWFsZSBwb3B1bGF0aW9uYCBbbnVtZXJpY106IHRoZSB0b3RhbCBvZiBmZW1hbGUgcmVzaWRlbnRzIGZyb20gYWxsIGFnZSBncm91cHMgYnkgTEdBIAoKYGBge3J9CnBvcF9mZW1hbGUgPC0gcmVhZF9leGNlbCgiUG9wdWxhdGlvbiBFc3RpbWF0ZXMgYnkgQWdlIGFuZCBTZXgsIExvY2FsIEdvdmVybm1lbnQgQXJlYXMgKEFTR1MgMjAxOCksIDIwMTggLnhscyIsIHNoZWV0ID0gIlRhYmxlIDIiLCBza2lwID0gNykKdmljX3BvcF9mZW1hbGUgPC0gcG9wX2ZlbWFsZSAlPiUgZmlsdGVyKGBBU0dTIDIwMThgID09IDIpIApjb2xuYW1lcyh2aWNfcG9wX2ZlbWFsZSkgPC0gYygiUy9UIGNvZGUiLCAiUy9UIG5hbWUiLCAiTEdBIGNvZGUiLCAiTEdBIG5hbWUiLCAiQWdlIDAtNCIsICJBZ2UgNS05IiwgIkFnZSAxMC0xNCIsICJBZ2UgMTUtMTkiLCAiQWdlIDIwLTI0IiwgIkFnZSAyNS0yOSIsICJBZ2UgMzAtMzQiLCAiQWdlIDM1LTM5IiwgIkFnZSA0MC00NCIsICJBZ2UgNDUtNDkiLCAiQWdlIDUwLTU0IiwgIkFnZSA1NS01OSIsICJBZ2UgNjAtNjQiLCAiQWdlIDY1LTY5IiwgIkFnZSA3MC03NCIsICJBZ2UgNzUtNzkiLCAiQWdlIDgwLTg0IiwgIkFnZSA4NSBhbmQgb3ZlciIsICJUb3RhbCBGZW1hbGUgcG9wdWxhdGlvbiIpCmBgYAoKCmBgYHtyfQpkYXRhX2ZlbWFsZSA8LSB2aWNfcG9wX2ZlbWFsZSAlPiUgc2VsZWN0KGBTL1QgY29kZWAgLCBgUy9UIG5hbWVgLCBgTEdBIGNvZGVgLCBgTEdBIG5hbWVgLCBgVG90YWwgRmVtYWxlIHBvcHVsYXRpb25gKQpoZWFkKGRhdGFfZmVtYWxlKQpgYGAKCgojIyMgU2Vjb25kIGRhdGFzZXQgCgpUaGUgYHBvcF9tYWxlYCB3YXMgYWxzbyBpbXBvcnRlZCBmcm9tIFBvcHVsYXRpb24gRXN0aW1hdGVzIGJ5IEFnZSBhbmQgU2V4LCBMb2NhbCBHb3Zlcm5tZW50IEFyZWFzIChBU0dTIDIwMTgpLCAyMDE4IC54bHMgd2l0aCBzaGVldCBuYW1lZCAiVGFibGUgMSIuIAoKU2luY2UgdGhlIHN0dWR5IGZvY3VzZWQgb24gdG90YWwgcG9wdWxhdGlvbiBieSBnZW5kZXIgaW4gVmljdG9yaWEsIHRoZSBTL1QgY29kZSB1bmRlciBgQVNHUyAyMDE4YCBmb3IgVmljdG9yaWEgKFMvVCBjb2RlID0gMikgd2FzIGFsc28gZmlsdGVyZWQgZnJvbSBgcG9wX21hbGVgIHVzaW5nIGBmaWx0ZXIoKWAuIAoKVGhlIGNvbHVtbiBuYW1lcyBvZiBgdmljX3BvcF9tYWxlYCB3ZXJlIGFsc28gcmVuYW1lZCB1c2luZyBgY29sbmFtZXMoKWAuCgpTaW5jZSB0aGUgc3R1ZHkgd291bGQgbm90IGNvbnNpZGVyIHRoZSBudW1iZXIgb2YgcmVzaWRlbnRzIHVuZGVyIEFnZSBncm91cCBjYXRlZ29yaWVzLCBvbmx5IGBUb3RhbCBNYWxlIHBvcHVsYXRpb25gIHBlciBMR0EgIHdhcyBzZWxlY3RlZCBmcm9tIGB2aWNfcG9wX21hbGVgIHVzaW5nIGBzZWxlY3QoKWAgYW5kIGFzc2lnbmVkIGludG8gbmV3IG9iamVjdCBjYWxsZWQgYGRhdGFfbWFsZWAuIAoKVGhlIGBkYXRhX2ZlbWFsZWAgbm93IGNvbnRhaW5lZCBmb3VyIG1haW4gdmFyaWFibGVzOgoKKiBgUy9UIGNvZGVgIFtjYXRlZ29yaWNhbF06IFN0YXRlL1RlcnJpdG9yeSBjb2RlIAoqIGBTL1QgbmFtZWAgW2NoYXJhY3Rlcl06IFN0YXRlL1RlcnJpdG9yeSBuYW1lCiogYExHQSBjb2RlYCBbY2F0ZWdvcmljYWxdOiBjb2RlIG9mIExvY2FsIEdvdmVybm1lbnQgQXJlYXMgcGVyIFN0YXRlIGUuZyAyMDExMCBmb3IgQWxwaW5lIChTKQoqIGBMR0EgTmFtZWAgW2NoYXJhY3Rlcl06IG5hbWUgb2YgTG9jYWwgR292ZXJubWVudCBBcmVhcyBwZXIgU3RhdGUgZS5nIEFscGluZQoqIGBUb3RhbCBNYWxlIHBvcHVsYXRpb25gIFtudW1lcmljXTogdGhlIHRvdGFsIG9mIGZlbWFsZSByZXNpZGVudHMgZnJvbSBhbGwgYWdlIGdyb3VwcyBieSBMR0EgCgpgYGB7cn0KcG9wX21hbGUgPC0gcmVhZF9leGNlbCgiUG9wdWxhdGlvbiBFc3RpbWF0ZXMgYnkgQWdlIGFuZCBTZXgsIExvY2FsIEdvdmVybm1lbnQgQXJlYXMgKEFTR1MgMjAxOCksIDIwMTggLnhscyIsIHNoZWV0ID0gIlRhYmxlIDEiLCBza2lwID0gNykKdmljX3BvcF9tYWxlIDwtIHBvcF9tYWxlICU+JSBmaWx0ZXIoYEFTR1MgMjAxOGAgPT0gMikgCmNvbG5hbWVzKHZpY19wb3BfbWFsZSkgPC0gYygiUy9UIGNvZGUiLCAiUy9UIG5hbWUiLCAiTEdBIGNvZGUiLCAiTEdBIG5hbWUiLCAiQWdlIDAtNCIsICJBZ2UgNS05IiwgIkFnZSAxMC0xNCIsICJBZ2UgMTUtMTkiLCAiQWdlIDIwLTI0IiwgIkFnZSAyNS0yOSIsICJBZ2UgMzAtMzQiLCAiQWdlIDM1LTM5IiwgIkFnZSA0MC00NCIsICJBZ2UgNDUtNDkiLCAiQWdlIDUwLTU0IiwgIkFnZSA1NS01OSIsICJBZ2UgNjAtNjQiLCAiQWdlIDY1LTY5IiwgIkFnZSA3MC03NCIsICJBZ2UgNzUtNzkiLCAiQWdlIDgwLTg0IiwgIkFnZSA4NSBhbmQgb3ZlciIsICJUb3RhbCBNYWxlIHBvcHVsYXRpb24iKQpgYGAKCgpgYGB7cn0KZGF0YV9tYWxlIDwtIHZpY19wb3BfbWFsZSAlPiUgc2VsZWN0KGBTL1QgY29kZWAgLCBgUy9UIG5hbWVgLCBgTEdBIGNvZGVgLCBgTEdBIG5hbWVgLCBgVG90YWwgTWFsZSBwb3B1bGF0aW9uYCkKaGVhZChkYXRhX21hbGUpCmBgYAoKIyMjIFRoaXJkIGRhdGFzZXQKClRoZSBQb3B1bGF0aW9uIEVzdGltYXRlcyBieSBMb2NhbCBHb3Zlcm5tZW50IEFyZWEsIDIwMTggdG8gMjAxOSAueGxzIHdhcyBhbHNvIG9idGFpbmVkIGZyb20gQXVzdHJhbGlhbiBCdXJlYXUgb2YgU3RhdGlzdGljcyBhdCBodHRwczovL3d3dy5hYnMuZ292LmF1L0FVU1NUQVRTL2Fic0AubnNmL0RldGFpbHNQYWdlLzMyMTguMDIwMTgtMTk/T3BlbkRvY3VtZW50JmZiY2xpZD1Jd0FSMjA1X0dfV3dxWEhaRHkwU0p4c1hmSlhfU2JTTk40b3dBb191WW5zUTFlY3FtaE1zdVRwYUo0eFZ3LCB3aGljaCBpbmRpY2F0ZWQgdGhlIHRvdGFsIHBvcHVsYXRpb24gZm9yIDIwMTggYW5kIDIwMTkgYXMgd2VsbCBhcyBwcm9wb3J0aW9uIGZvciBkaWZmZXJlbnQgY29tcG9uZW50cyBvZiBwb3B1bGF0aW9uIGNoYW5nZSAobmF0dXJhbCBpbmNyZWFzZSwgbmV0IG92ZXJzZWFzIG1pZ3JhdGlvbiwgbmV0IGludGVybmFsIG1pZ3JhdGlvbikgYnkgTEdBIGFjcm9zcyBTdGF0ZXMuCgpUaGUgb3JpZ2luYWwgZGF0YXNldCAjMiB3YXMgZmlyc3RseSBpbXBvcnRlZCB3aXRoIHNoZWV0IG5hbWVkICJUYWJsZSAyIiAoVmljdG9yaWEpIGFuZCA2IHNraXBwZWQgcm93cyBkdWUgdG8gaW52YWxpZCBoZWFkZXJzIGFuZCBzdG9yZWQgYXMgYHBvcF92aWNgLgoKVGhlIHRvdGFsIHBvcHVsYXRpb24gb2YgVmljdG9yaWEgYnkgTEdBIGluIDIwMTggYW5kIDIwMTkgd2VyZSBzZWxlY3RlZCBmcm9tIHRoZSBvcmlnaW5hbCBkYXRhc2V0IGBwb3BfdmljYCB1c2luZyBgc2VsZWN0KClgIGFuZCBhc3NpZ25lZCBpbnRvIG5ldyBvYmplY3QgYG5ld19wb3BfdmljYGZvciBsYXRlciBtZXJnaW5nIGRhdGFzZXRzLgoKVGhlIGNvbHVtbiBuYW1lcyBvZiBgbmV3X3BvcF92aWNgIHdhcyByZW5hbWVkIGFuZCBub3cgaW5jbHVkZXMgdGhyZWUgdmFyaWFibGVzOgoKKiBgTEdBIGNvZGVgIFtjYXRlZ29yaWNhbF06IGNvZGUgb2YgTG9jYWwgR292ZXJubWVudCBBcmVhcyBpbiBWaWN0b3JpYQoqIGBMR0EgbmFtZWBbY2hhcmFjZXJdOiBuYW1lIG9mIExvY2FsIEdvdmVybm1lbnQgQXJlYXMgaW4gVmljdG9yaWEKKiBgMjAxOGBbbnVtZXJpY106IHRvdGFsIHBvcHVsYXRpb24gaW4gMjAxOCBieSBsR0EKKiBgMjAxOWBbbnVtZXJpY106IHRvdGFsIHBvcHVsYXRpb24gaW4gMjAxOSBieSBsR0EKCgpgYGB7cn0KcG9wX3ZpYyA8LSByZWFkX2V4Y2VsKCJQb3B1bGF0aW9uIEVzdGltYXRlcyBieSBMb2NhbCBHb3Zlcm5tZW50IEFyZWEsIDIwMTggdG8gMjAxOSAueGxzIiwgc2hlZXQgPSAiVGFibGUgMiIsIHNraXAgPSA2KQpuZXdfcG9wX3ZpYyA8LSBwb3BfdmljICU+JSBzZWxlY3QgKGMoMSwyLDMsNCkpIApjb2xuYW1lcyhuZXdfcG9wX3ZpYykgPC0gYygiTEdBIGNvZGUiLCAiTEdBIG5hbWUiLCAiVG90YWxfMjAxOCIsICJUb3RhbF8yMDE5IikKaGVhZChuZXdfcG9wX3ZpYykKCmBgYAoKCiMjIyBNZXJnaW5nIGRhdGFzZXRzCgpUaGUgYGRhdGFfZmVtYWxlYCBhbmQgYGRhdGFfbWFsZWAgd2VyZSBmaXJzdGx5IG1lcmdlZCB1c2luZyBgaW5uZXJfam9pbmAgd2hpY2ggdXNlZCBgUy9UIGNvZGVgLCBgUy9UIG5hbWVgLGBMR0EgY29kZWAgYW5kIGBMR0EgbmFtZWAgYXMga2V5IHZhcmlhYmxlcyBhbmQgc3RvcmVkIGFzIGBkYXRhX2dlbmRlcmAuCgoqIGBEYXRhX2dlbmRlcmAgZGVzY3JpYmVkIHRoZSB0b3RhbCBwb3B1bGF0aW9uIGJ5IGdlbmRlciBhY3Jvc3MgTG9jYWwgR292ZXJubWVudCBBcmVhcyBpbiBWaWN0b3JpYSBieSAyMDE4LgoKYGBge3J9CmRhdGFfZ2VuZGVyIDwtIGlubmVyX2pvaW4oZGF0YV9mZW1hbGUsIGRhdGFfbWFsZSxieSA9IGMoIlMvVCBjb2RlIiwgIlMvVCBuYW1lIiwgIkxHQSBjb2RlIiwgIkxHQSBuYW1lIikpCmhlYWQoZGF0YV9nZW5kZXIpCmBgYAoKVGhlIGZpbmFsIGRhdGFzZXQgYHBvcF92aWNfZ2VuZGVyYCB3YXMgdGhlbiBjcmVhdGVkIGJ5IG1lcmdpbmcgYGRhdGFfZ2VuZGVyYCBhbmQgYG5ld19wb3BfdmljYCB1c2luZyBgaW5uZXJfam9pbmAgd2hpY2ggdXNlZCBib3RoIGBMR0EgY29kZWAgYW5kIGBMR0EgbmFtZWAgYXMga2V5IHZhcmlhYmxlcy4gCgpUaGUgZmluYWwgZGF0YXNldCBub3cgaW5jbHVkZXMgOCB2YXJpYWJsZXM6CgoqIGBTL1QgY29kZWAgW2NhdGVnb3JpY2FsXTogU3RhdGUvVGVycml0b3J5IGNvZGUgCiogYFMvVCBuYW1lYCBbY2hhcmFjdGVyXTogU3RhdGUvVGVycml0b3J5IG5hbWUKKiBgTEdBIGNvZGVgIFtjYXRlZ29yaWNhbF06IGNvZGUgb2YgTG9jYWwgR292ZXJubWVudCBBcmVhcyBwZXIgU3RhdGUgZS5nIDIwMTEwIGZvciBBbHBpbmUgKFMpCiogYExHQSBOYW1lYCBbY2hhcmFjdGVyXTogbmFtZSBvZiBMb2NhbCBHb3Zlcm5tZW50IEFyZWFzIHBlciBTdGF0ZSBlLmcgQWxwaW5lCiogYFRvdGFsIEZlbWFsZSBwb3B1bGF0aW9uYCBbbnVtZXJpY106IHRoZSB0b3RhbCBvZiBmZW1hbGUgcmVzaWRlbnRzIGJ5IExHQQoqIGBUb3RhbCBNYWxlIHBvcHVsYXRpb25gIFtudW1lcmljXTogdGhlIHRvdGFsIG9mIG1hbGUgcmVzaWRlbnRzIGJ5IExHQQoqIGBUb3RhbF8yMDE4YFtudW1lcmljXTogdG90YWwgcG9wdWxhdGlvbiBpbiAyMDE4IGJ5IGxHQQoqIGBUb3RhbF8yMDE5YFtudW1lcmljXTogdG90YWwgcG9wdWxhdGlvbiBpbiAyMDE5IGJ5IGxHQQoKYGBge3J9CnBvcF92aWNfZ2VuZGVyIDwtIGlubmVyX2pvaW4oZGF0YV9nZW5kZXIsIG5ld19wb3BfdmljLCBieSA9IGMoIkxHQSBjb2RlIiwgIkxHQSBuYW1lIikpCmhlYWQocG9wX3ZpY19nZW5kZXIpCmBgYAoKIyMgVW5kZXJzdGFuZCAKClRoZSBkaW1lbnNpb24gb2YgdGhlIGRhdGFzZXQgd2FzIGNoZWNrZWQgdXNpbmcgYGRpbSgpYCwgd2hpY2ggcmVzdWx0ZWQgYXQgODAgb2JzZXJ2YXRpb25zIGFuZCA4IHZhcmlhYmxlcy4KClRoZSBzdHJ1Y3R1cmUgb2YgYHBvcF92aWNfZ2VuZGVyYCBzaG93ZWQgdGhhdCBhbGwgdmFyaWFibGVzIHdlcmUgaW4gY2hhcmFjdGVyIHR5cGUuIFRoZXJlZm9yZSwgdGhlIGNvbnZlcnNpb24gdG8gbnVtZXJpYyBkYXRhIHR5cGUgYW5kIGZhY3RvciB3ZXJlIG5lZWRlZC4KCiogVGhlIGNvbnZlcnNpb24gb2YgbXVsdGlwbGUgY29sdW1ucyB0byBudW1lcmljIGRhdGEgdHlwZSB3YXMgZG9uZSBieSB1c2luZyBgc2FwcGx5YCB3aXRoIGBhcy5udW1lcmljYC4KKiBUaGUgY29udmVyc2lvbiBvZiBgTEdBIGNvZGVgIHRvIGZhY3RvciB2YXJpYWJsZSB3YXMgZG9uZSBieSB1c2luZyBgYXMuZmFjdG9yYCB3aXRob3V0IG9yZGVyZWQuCgoKYGBge3J9CmRpbShwb3BfdmljX2dlbmRlcikKc3RyKHBvcF92aWNfZ2VuZGVyKQoKY29sLm51bSA8LSBjKCJTL1QgY29kZSIsICJUb3RhbCBGZW1hbGUgcG9wdWxhdGlvbiIsICJUb3RhbCBNYWxlIHBvcHVsYXRpb24iLCAiVG90YWxfMjAxOCIsICJUb3RhbF8yMDE5IikKcG9wX3ZpY19nZW5kZXJbY29sLm51bV0gPC0gc2FwcGx5KHBvcF92aWNfZ2VuZGVyW2NvbC5udW1dLGFzLm51bWVyaWMpCnBvcF92aWNfZ2VuZGVyJGBMR0EgY29kZWAgPC0gYXMuZmFjdG9yKHBvcF92aWNfZ2VuZGVyJGBMR0EgY29kZWApCmBgYAoKCmBgYHtyfQpzdHIocG9wX3ZpY19nZW5kZXIpCgpgYGAKCgojIwlUaWR5ICYgTWFuaXB1bGF0ZSBEYXRhIEkgCgpUaGUgYHBvcF92aWNfZ2VuZGVyYCBkYXRhc2V0IHdhcyB1bnRpZHkgYmVjYXVzZSBgVG90YWwgRmVtYWxlIHBvcHVsYXRpb25gIGFuZCBgVG90YWwgTWFsZSBwb3B1bGF0aW9uYCBhcyBjb2x1bW4gaGVhZGVycyB3ZXJlIG5vdCB2YXJpYWJsZXMuIAoKYGdhdGhlcigpYCB3YXMgdXNlZCB0byBnYXRoZXIgZmVtYWxlIGFuZCBtYWxlIGNvbHVtbnMgaW50byBvbmUgc2luZ2xlIGNvbHVtbiBuYW1lZCBgR2VuZGVyYCBhbmQgc3RvcmVkIHRoZSB2YWx1ZXMgdW5kZXIgYEVzdGltYXRlZCByZXNpZGVudHNgIGNvbHVtbi4KCiogYEdlbmRlcmAgd2FzIHRoZW4gY2hlY2sgd2hldGhlciBpdCB3YXMgYSBmYWN0b3IgdmFyaWFibGUgdXNpbmcgYGlzLmZhY3RvcigpYC4KICAgICsgU2luY2UgdGhlIHZhcmlhYmxlIHdhcyBub3QgYSBmYWN0b3IsIHRoZSBjb252ZXJzaW9uIGZyb20gY2hhcmFjdGVyIHRvIGZhY3RvciB3YXMgdGFrZW4gYnkgdXNpbmcgYGFzLmZhY3RvcmAuCiAgICArIFRoZSBsZXZlbHMgb2YgYEdlbmRlcmAgd2FzIGNsYXNzaWZpZWQgdXNpbmcgYGZhY3RvcmAgd2l0aCBsYWJlbHMuCgoqIGBFc3RpbWF0ZWQgcmVzaWRlbnRzYCBzaG93ZWQgdGhlIG51bWJlciBvZiByZXNpZGVudHMgYnkgZ2VuZGVyIGZvciBlYWNoIExvY2FsIEdvdmVybm1lbnQgQXJlYXMgb24gVmljdG9yaWEgYnkgMjAxOC4gCgpBIHRpZHkgZGF0YXNldCB3YXMgdGhlbiBzdG9yZWQgYXMgYHRpZHlfcG9wX2dlbmRlcmAuCgoqIFRoZSBjb2x1bW5zIG9mIHRoZSB0aWR5IGRhdGFzZXQgd2VyZSByZWFycmFuZ2VkIHdpdGggYEdlbmRlcmAgYW5kIGBFc3RpbWF0ZWQgcmVzaWRlbnRzYCBiZWZvcmUgYFRvdGFsXzIwMThgIGFuZCBgVG90YWxfMjAxOWAuCgoKCmBgYHtyfQp0aWR5X3BvcF9nZW5kZXIgPC0gcG9wX3ZpY19nZW5kZXIgJT4lIGdhdGhlcihgVG90YWwgRmVtYWxlIHBvcHVsYXRpb25gLCBgVG90YWwgTWFsZSBwb3B1bGF0aW9uYCwgIGtleSA9ICJHZW5kZXIiLCB2YWx1ZSA9ICJFc3RpbWF0ZWQgcmVzaWRlbnRzIikKaGVhZCh0aWR5X3BvcF9nZW5kZXIpCmBgYAoKCmBgYHtyfQppcy5mYWN0b3IodGlkeV9wb3BfZ2VuZGVyJEdlbmRlcikKdGlkeV9wb3BfZ2VuZGVyJEdlbmRlciA8LSBhcy5mYWN0b3IodGlkeV9wb3BfZ2VuZGVyJEdlbmRlcikKdGlkeV9wb3BfZ2VuZGVyJEdlbmRlcjwtIGZhY3Rvcih0aWR5X3BvcF9nZW5kZXIkR2VuZGVyLCBsZXZlbCA9IGMoIlRvdGFsIEZlbWFsZSBwb3B1bGF0aW9uIiwgIlRvdGFsIE1hbGUgcG9wdWxhdGlvbiIpLCBsYWJlbHMgPSBjKCJmZW1hbGUiLCAibWFsZSIpKQpgYGAKCgpgYGB7cn0KdGlkeV9wb3BfZ2VuZGVyIDwtIHRpZHlfcG9wX2dlbmRlclsgLCBjKDEsMiwzLDQsNyw4LDUsNildCmBgYAoKYGBge3J9CmhlYWQodGlkeV9wb3BfZ2VuZGVyKQpgYGAKCiMjCVRpZHkgJiBNYW5pcHVsYXRlIERhdGEgSUkgCgpUaGUgYFBvcHVsYXRpb24gcmF0aW9gIHdhcyBjcmVhdGVkIHRvIGVzdGltYXRlIHRoZSBwcm9wb3J0aW9uIG9mIGZlbWFsZSBhbmQgbWFsZSByZXNpZGVudHMgYnkgdG90YWwgcG9wdWxhdGlvbiBwZXIgTG9jYWwgR292ZXJubWVudCBBcmVhcyBpbiBWaWN0b3JpYSBieSAyMDE4LiAKCiogUG9wdWxhdGlvbiByYXRpbyBjYWxjdWxhdGVkIGJ5IGRpdmlkaW5nIHRoZSBgRXN0aW1hdGVkIHJlc2lkZW50c2Agd2l0aCB0b3RhbCBwb3B1bGF0aW9uIGluIGAyMDE4YCBhbmQgY29udmVydGluZyBpbnRvIHByb3BvcnRpb25zLgoKKiBUaGUgcmF0aW8gaW5kaWNhdGVkIHRoYXQgdGhlcmUgd2VyZSBoaWdoZXIgbWVhbiBwcm9wb3J0aW9ucyBvZiBmZW1hbGUgcmVzaWRlbnRzIGFjcm9zcyBMR0EgaW4gVmljdG9yaWEgYnkgMjAxOCB1c2luZyBgZ3JvdXBfYnkoKWAgYW5kIGBzdW1tYXJpc2UoKWAuIAoKVGhlIGBHcm93dGggcmF0ZWAgd2FzIGFsc28gbXV0YXRlZCB0byBkZXRlcm1pbmUgdGhlIGdyb3d0aCByYXRlIG9mIHBvcHVsYXRpb24gYmV0d2VlbiAyMDE4IGFuZCAyMDE5IGZvciBldmVyeSBMb2NhbCBHb3Zlcm5tZW50IEFyZWFzIGluIFZpY3RvcmlhLgoKKiBHcm93dGggcmF0ZSBjYWxjdWxhdGVkIGJ5IGZvbGxvd2luZyB3aXRoIHRoZSBlcXVhdGlvbiBzb3VyY2VkIGZyb20gW1VuaXZlcnNpdHkgb2YgT3JlZ29uXShodHRwczovL3BhZ2VzLnVvcmVnb24uZWR1L3JncC9QUFBNNjEzL2NsYXNzOGEuaHRtIzp+OnRleHQ9VGhlJTIwYW5udWFsJTIwcGVyY2VudGFnZSUyMGdyb3d0aCUyMHJhdGUsTiUyQyUyMHRoZSUyMG51bWJlciUyMG9mJTIweWVhcnMuJnRleHQ9SW4lMjAxOTgwJTJDJTIwdGhlJTIwcG9wdWxhdGlvbiUyMGluJTIwTGFuZSUyMENvdW50eSUyMHdhcyUyMDI1MCUyQzAwMCkuCgo8Y2VudGVyPiBHcm93dGggcmF0ZSA9ICRcZnJhY3tQcmVzZW50IHZhbHVlIC0gUGFzdCB2YWx1ZX17UGFzdCB2YWx1ZX0qMTAwJCAKPC9jZW50ZXI+CgoKKiBUaGlzIGdyb3d0aCByYXRlIHZhbHVlIHdvdWxkIGJlIHVzZWZ1bCBmb3IgcHJlZGljdGluZyBmdXR1cmUgcG9wdWxhdGlvbiBpbiBkaWZmZXJlbnQgTEdBcyB1c2luZyBhbiBleHBvbmVudGlhbCBncm93dGggbW9kZWwuCgpgYGB7ciBlY2hvPVRSVUV9Cm5ld19wb3AgPC0gdGlkeV9wb3BfZ2VuZGVyICU+JSBtdXRhdGUoIlBvcHVsYXRpb24gcmF0aW8iID0gcm91bmQoKGBFc3RpbWF0ZWQgcmVzaWRlbnRzYC9gVG90YWxfMjAxOGApKjEwMCwgMiksICJHcm93dGggcmF0ZSIgPSAoKGBUb3RhbF8yMDE5YCAtIGBUb3RhbF8yMDE4YCkvYFRvdGFsXzIwMThgKSoxMDApCmhlYWQobmV3X3BvcCkKYGBgCgoKYGBge3IgZWNobz1UUlVFfQpuZXdfcG9wICU+JSBncm91cF9ieShgR2VuZGVyYCkgJT4lIHN1bW1hcmlzZShhdmVyZ2FnZSA9IG1lYW4oYFBvcHVsYXRpb24gcmF0aW9gLCBuYS5ybSA9IFRSVUUpKQpgYGAKCgojIwlTY2FuIEkgCgojIyMgU2NhbiBmb3IgbWlzc2luZyB2YWx1ZXMKClRoZSBtaXNzaW5nIHZhbHVlcyAoTkEpIHdlcmUgc2Nhbm5lZCBmb3IgYWxsIG51bWVyaWMgdmFsdWVzIGFuZCBvdXRwdXQgYXMgdGhlIHRvdGFsIG51bWJlciBvZiBtaXNzaW5nIHZhbHVlcyBmb3IgZWFjaCBjb2x1bW4gdXNpbmcgYHN1bShpcy5uYSgpKWAuIAoKVGhlIGBzYXBwbHkoKWAgd2FzIHVzZWQgdG8gYXBwbHkgYHN1bShpcy5uYSgpKWAgaW4gbXVsdGlwbGUgY29sdW1ucyBmb3Igc2Nhbm5pbmcuCgpUaGVyZSBpcyBubyBOQSB2YWx1ZXMgZGV0ZWN0ZWQgaW4gdGhlIGRhdGFzZXQgYG5ld19wb3BgLiAKCmBgYHtyfQpzYXBwbHkobmV3X3BvcCwgZnVuY3Rpb24oeCkgc3VtKGlzLm5hKHgpKSkKYGBgCgojIyMgU2NhbiBmb3Igc3BlY2lhbCB2YWx1ZXMKClRoZSBgaXMuc3BlY2lhbGAgZnVuY3Rpb24gaXMgY3JlYXRlZCB0byBjaGVjayBmb3Igc3BlY2lhbCB2YWx1ZXMgdGhhdCBhcmUgZWl0aGVyIGluZmluaXRlIHZhbHVlcyBvciBOb3QgYSBOdW1iZXIgdmFsdWVzIChuYW4pIGluIHRoZSBkYXRhc2V0LgoKVGhlIHNwZWNpYWwgdmFsdWVzIHdlcmUgc2Nhbm5lZCBmb3IgYWxsIG51bWVyaWMgZGF0YSBpbiBgbmV3X3BvcGAgZGF0YXNldCBhbmQgdGhlIG91dHB1dCBhcyB0aGUgdG90YWwgbnVtYmVyIG9mIHNwZWNpYWwgdmFsdWVzIGZvciBlYWNoIGNvbHVtbnMgdXNpbmcgYHN1bShpcy5zcGVjaWFsKCkpYC4KClRoZSBgc2FwcGx5KClgIHdhcyBhbHNvIHVzZWQgdG8gYXBwbHkgYHN1bShpcy5zcGVjaWFsKCkpYCBpbiBtdWx0aXBsZSBjb2x1bW5zIGZvciBzY2FubmluZyBzcGVjaWFsIHZhbHVlcy4KClRoZXJlIGlzIG5vIHNwZWNpYWwgdmFsdWUgZGV0ZWN0ZWQgaW4gdGhlIGRhdGFzZXQuIAoKCmBgYHtyfQppcy5zcGVjaWFsIDwtIGZ1bmN0aW9uKHgpewppZiAoaXMubnVtZXJpYyh4KSkgKGlzLmluZmluaXRlKHgpIHwgaXMubmFuKHgpKQp9CmBgYAoKCmBgYHtyfQpzYXBwbHkobmV3X3BvcCwgZnVuY3Rpb24oeCkgc3VtKGlzLnNwZWNpYWwoeCkpKQpgYGAKCiMjIyBTY2FuIGZvciBvYnZpdm91cyBlcnJvcnMKClRoZSBkYXRhIGluY29uc2lzdGVuY2llcyB3ZXJlIGNoZWNrZWQgZm9yIHRoZSBkYXRhc2V0IGJ5IGdlbmVyYXRpbmcgYSBydWxlIGZvciBudW1lcmljIGRhdGEuIFRoZSBydWxlIGlzIG5vIG5lZ2F0aXZlIG51bWVyaWMgdmFsdWVzIGluIHRoZSB0b3RhbCBwb3B1bGF0aW9uIG9mIDIwMTggYW5kIDIwMTkuCgpUaGUgcnVsZSB3YXMgY3JlYXRlZCB1c2luZyBgZWRpdHNldCgpYCBhbmQgYXNzaWduZWQgaXQgaW50byBgcnVsZWAuCgpUaGUgcnVsZSB3YXMgdGhlbiBhcHBsaWVkIHRvIHRoZSBkYXRhc2V0IHVzaW5nIGB2aW9sYXRlZEVkaXRzKClgIHRvIG91dHB1dCBsb2dpY2FsIHZhbHVlcyB3aGVyZSBUUlVFIGlzIHdoZXJlIGluY29uc2lzdGVuY2llcyBhcmUgZXhpc3RlZC4KCiogVGhlIG91dHB1dCB0dXJuZWQgb3V0IHRvIGhhdmUgbm8gZGF0YSBpbmNvbnNpc3RlbmNpZXMgaW4gdGhlIGRhdGFzZXQuIApgYGB7cn0KcnVsZSA8LSBlZGl0c2V0KGMoIlRvdGFsXzIwMTggPiAwIiwgIlRvdGFsXzIwMTkgPiAwIikpCnJ1bGUKYGBgCmBgYHtyfQp2aW9sYXRlZEVkaXRzKHJ1bGUsIG5ld19wb3ApIApgYGAKCgojIwlTY2FuIElJCgojIyMgIFNjYW4gZm9yIG51bWJlciBhbmQgcHJvcG9ydGlvbnMgb2YgcmVzaWRlbnRzIGJ5IGdlbmRlciAKCmBCb3hwbG90YCB3YXMgdXNlZCB0byBzY2FuIG51bWVyaWMgdmFsdWVzIGZyb20gYEVzdGltYXRlZCByZXNpZGVudHNgIGFuZCBgUG9wdWxhdGlvbiByYXRpb2AgY29sdW1ucyBmb3IgYW55IHBvdGVudGlhbCBvdXRsaWVycyBpbiB0aGUgZGF0YXNldC4KClRoZXJlIHdlcmUgdHdvIG91dGxpZXJzIHJlY29yZGVkIGluIHRoZSBib3hwbG90IG9mIGBFc3RpbWF0ZWQgcmVzaWRlbnRzYCB3aGljaCByZXNwb25kZWQgZm9yIG1vcmUgdGhhbiAxNTAsMDAwIHJlc2lkZW50cyBhY3Jvc3MgTEdBcyBpbiBWaWN0b3JpYS4KClRoZSBvdXRsaWVycyB3ZXJlIHRoZW4gZGV0ZWN0ZWQgYnkgWi1zY29yZSBtZXRob2QgdXNpbmcgYHNjb3Jlcyh0eXBlID0gInoiKWAuCgpUaGUgc3VtbWFyeSBvZiB6IHNjb3JlcyBzaG93ZWQgdGhhdCB0aGUgbWluaW11bSB6LXNjb3JlIGlzIC0xLjA0MDggYW5kIHRoZSBtYXhpbXVtIGlzIDMuMzk1LgoKU2luY2UgdGhlIGFic29sdXRlIHZhbHVlcyBvZiB6IHNjb3JlIGdyZWF0ZXIgdGhhbiAzIGFyZSBjb25zaWRlcmVkIGFzIG91dGxpZXJzLCBgd2hpY2goYWJzKHouc2NvcmVzKT4zKWAgd2FzIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGxvY2F0aW9uIG9mIG91dGxpZXJzLgoKKiBUaGUgb2JzZXJ2YXRpb24gaW4gcm93IDE0IGFuZCA5NCB3ZXJlIGNvbnNpZGVyZWQgYXMgb3V0bGllcnMuCiogSXQgaGlnaGxpZ2h0ZWQgdGhhdCB0aGUgTEdBIG5hbWVkIENhc2V5IGluIFZpY3RvcmlhIGhhZCB0aGUgbW9zdCBvdXRzdGFuZGluZyBwb3B1bGF0aW9uIHdoaWNoIGlzIG1vcmUgMTUwLDAwMCByZXNpZGVudHMgYnkgZ2VuZGVyIGxpdmluZyBpbiB0aGUgYXJlYS4KKiBTaW5jZSB0aGlzIG91dHB1dCBtaWdodCBiZSBpbnRlcmVzdGluZyBmb3IgZnV0dXJlIHF1ZXN0aW9ucywgdGhlc2Ugb3V0bGllcnMgd291bGQgbm90IGJlIGVsaW1pbmF0ZWQuCiAgICAKYGBge3IsIGZpZy53aWR0aD0gN30KYm94cGxvdChuZXdfcG9wJGBFc3RpbWF0ZWQgcmVzaWRlbnRzYCwgbWFpbj0iTnVtYmVyIG9mIHJlc2lkZW50cyBpbiBWaWN0b3JpYSAoMjAxOCkiLCB5bGFiID0gIlJlc2lkZW50cyIpCmBgYAoKCmBgYHtyfQp6LnNjb3JlcyA8LSBuZXdfcG9wJGBFc3RpbWF0ZWQgcmVzaWRlbnRzYCAlPiUgIHNjb3Jlcyh0eXBlID0gInoiKQp6LnNjb3JlcyAlPiUgc3VtbWFyeSgpCmBgYAoKYGBge3J9CndoaWNoKGFicyh6LnNjb3JlcykgPjMgKQpuZXdfcG9wW2MoMTQsOTQpLCBdCmBgYAoKCmBgYHtyfQpsZW5ndGggKHdoaWNoKCBhYnMoei5zY29yZXMpID4zICkpCmBgYAoKClRoZXJlIHdlcmUgZm91ciBvdXRsaWVycyByZWNvcmRlZCBpbiB0aGUgYm94cGxvdCBvZiBgUG9wdWxhdGlvbiByYXRpb2Agd2hpY2ggd2FzIHJhbmdpbmcgZnJvbSBlaXRoZXIgbW9yZSB0aGFuIDUyJSBvciBsZXNzIHRoYW4gNDglIG9mIHJlc2lkZW50cyBsaXZpbmcgYWNyb3NzIExHQXMuIAoKVGhlIG91dGxpZXJzIHdlcmUgdGhlbiBkZXRlY3RlZCBieSBaLXNjb3JlIG1ldGhvZCB1c2luZyBgc2NvcmVzKHR5cGUgPSAieiIpYC4KClRoZSBzdW1tYXJ5IG9mIHogc2NvcmVzIHNob3dlZCB0aGF0IHRoZSBtaW5pbXVtIHotc2NvcmUyIGlzIC00LjYzMTUgYW5kIHRoZSBtYXhpbXVtIGlzIDQuNjM4MDYwLgoKU2luY2UgdGhlIGFic29sdXRlIHZhbHVlcyBvZiB6IHNjb3JlIGdyZWF0ZXIgdGhhbiAzIGFyZSBjb25zaWRlcmVkIGFzIG91dGxpZXJzLCBgd2hpY2goYWJzKHouc2NvcmVzKT4zKWAgd2FzIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGxvY2F0aW9uIG9mIG91dGxpZXJzLgoKKiBUaGUgb2JzZXJ2YXRpb24gaW4gcm93IDgwIGFuZCAxNjAgd2VyZSBjb25zaWRlcmVkIGFzIG91dGxpZXJzLgoqIEl0IGhpZ2hsaWdodGVkIHRoYXQgdGhlIExHQSBuYW1lZCBVbmljb3Jwb3JhdGVkIGluIFZpY3RvcmlhIHdoaWNoIGhhZCB0aGUgcHJvcG9ydGlvbnMgb2YgZmVtYWxlIHJlc2lkZW50cyBsb3dlciB0aGFuIDQ4JSBhbmQgdGhlIHByb3BvcnRpb25zIG9mIG1hbGUgcmVzaWRlbnRzIGhpZ2hlciB0aGFuIDUyJS4KKiBVbmljb3Jwb3RhdGVkIFZpYyBhcmUgYXJlYXMgd2l0aG91dCBsb2NhbCBnb3J2ZXJubWVudCAoVHJhdmVsIFZpY3RvcmlhKSBhdCAgaHR0cHM6Ly93d3cudHJhdmVsdmljdG9yaWEuY29tLmF1L3ZpY3RvcmlhL2xvY2FsZ292ZXJubWVudC8uCiogU2luY2UgdGhlc2Ugb3V0bGllcnMgYXJlIGFsc28gbWVhbmluZ2Z1bCwgdGhleSB3b3VsZCBhbHNvIG5vdCBiZSBlbGltaW5hdGVkIGZyb20gdGhlIGRhdGFzZXQuCgpgYGB7cn0KYm94cGxvdChuZXdfcG9wJGBQb3B1bGF0aW9uIHJhdGlvYCwgbWFpbj0iUHJvcG9ydGlvbnMgb2YgcmVzaWRlbnRzIGluIFZpY3RvcmlhICgyMDE4KSIsIHlsYWIgPSAicGVyY2VudGFnZSIpCmBgYAoKCmBgYHtyfQp6LnNjb3JlczIgPC0gbmV3X3BvcCRgUG9wdWxhdGlvbiByYXRpb2AgJT4lICBzY29yZXModHlwZSA9ICJ6IikKei5zY29yZXMyICU+JSBzdW1tYXJ5KCkKYGBgCgoKYGBge3J9CndoaWNoKGFicyh6LnNjb3JlczIpID4zKQpgYGAKYGBge3J9Cm5ld19wb3BbYyg4MCwxNjApLCBdCmBgYAoKIyMjIFNjYW4gZm9yIHRvdGFsIHBvcHVsYXRpb24gaW4gMjAxOCBhbmQgMjAxOQoKVGhlIHRvdGFsIHBvcHVsYXRpb24gaW4gMjAxOCBhbmQgMjAxOSBhY3Jvc3MgTEdBcyB3ZXJlIHN1YnNldHRlZCBmcm9tIHRoZSBkYXRhc2V0IGZvciBzY2FubmluZyBmb3IgbXVsdGl2YXJpYXRlIGRhdGEuIAoKVGhlIE1haGFsYW5vYmlzIGRpc3RhbmNlIHdhcyB1c2VkIHRvIGRldGVjdCBtdWx0aXZhcmlhdGUgb3V0bGllcnMgZm9yIHRoZSBzdWJzZXQgYHBvcF9zdWJgIGRhdGFzZXQgdXNpbmcgYG12bigpYC4KCkFjY29yZGluZyB0byBDaGktc3F1YXJlIFEtUSBwbG90LCB0aGVyZSBhcmUgNzIgb3V0bGllcnMgZGVjdGVjdGVkIGluIHRoZSBzdWJzZXQuIFRoZXNlIG91dGxpZXJzIHdvdWxkIHRoZW4gYmUgaGFuZGxlZCBieSB0cmFuc2Zvcm1pbmcgdmFsdWVzLgoKYGBge3J9CnBvcF9zdWIgPC0gbmV3X3BvcCAlPiUgc2VsZWN0KGBUb3RhbF8yMDE4YCwgYFRvdGFsXzIwMTlgKQpyZXN1bHRzIDwtIG12bihkYXRhID0gcG9wX3N1YiwgbXVsdGl2YXJpYXRlT3V0bGllck1ldGhvZCA9ICJxdWFuIiwgc2hvd091dGxpZXJzID0gVFJVRSkKYGBgCgpUaGUgbG9jYXRpb24gb2Ygb3V0bGllcnMgd2VyZSBzaG93biBiZWxvdzoKCmBgYHtyfQpyZXN1bHRzJG11bHRpdmFyaWF0ZU91dGxpZXJzCmBgYAoKCmBCb3hwbG90YCB3YXMgdXNlZCB0byBzY2FuIG51bWVyaWMgdmFsdWVzIGZvciBgR3Jvd3RoIHJhdGVgIGZvciBhbnkgcG90ZW50aWFsIG91dGxpZXJzIGluIHRoZSBkYXRhc2V0LgoKVGhlcmUgd2VyZSBmb3VyIG91dGxpZXJzIHJlY29yZGVkIGluIHRoZSBib3hwbG90IG9mIGBFc3RpbWF0ZWQgcmVzaWRlbnRzYCB3aGljaCBpbmRpY2F0ZWQgdGhlIGdyb3d0aCByYXRlIG9mIG1vcmUgdGhhbiA0LjAuCgpUaGUgb3V0bGllcnMgd2VyZSB0aGVuIGRldGVjdGVkIGJ5IFotc2NvcmUgbWV0aG9kIHVzaW5nIGBzY29yZXModHlwZSA9ICJ6IilgLgoKVGhlIHN1bW1hcnkgb2YgeiBzY29yZXMgc2hvd2VkIHRoYXQgdGhlIG1pbmltdW0gei1zY29yZSBpcyAtMS43OTQ1IGFuZCB0aGUgbWF4aW11bSBpcyAzLjEwMzEuCgpTaW5jZSB0aGUgYWJzb2x1dGUgdmFsdWVzIG9mIHogc2NvcmUgZ3JlYXRlciB0aGFuIDMgYXJlIGNvbnNpZGVyZWQgYXMgb3V0bGllcnMsIGB3aGljaChhYnMoei5zY29yZXMpPjMpYCB3YXMgdXNlZCB0byBpZGVudGlmeSB0aGUgbG9jYXRpb24gb2Ygb3V0bGllcnMuCgoqIFRoZSBvYnNlcnZhdGlvbiBpbiByb3cgNzYgYW5kIDE1NiB3ZXJlIGNvbnNpZGVyZWQgYXMgb3V0bGllcnMuCiogSXQgaGlnaGxpZ2h0ZWQgdGhhdCB0aGUgTEdBIG5hbWVkIFd5bmRoYW0gaW4gVmljdG9yaWEgaGFkIHRoZSBoaWdoZXN0IGdyb3d0aCByYXRlIG9mIHBvcHVsYXRpb24gZnJvbSAyMDE4IHRvIDIwMTkuCiogU2luY2UgdGhpcyBvdXRwdXQgY291bGQgYnJpbmcgaW50ZXJlc3Rpbmcgc3RvcnkgZm9yIGZ1dHVyZSBhbmFseXNpcywgdGhlc2Ugb3V0bGllcnMgd291bGQgbm90IGJlIGVsaW1pbmF0ZWQuCgpgYGB7cn0KYm94cGxvdChuZXdfcG9wJGBHcm93dGggcmF0ZWAsIG1haW4gPSAiR3Jvd3RoIHJhdGUgb2YgTEdBcyBpbiBWaWN0b3JpYSBiZXR3ZWVuIDIwMTggYW5kIDIwMTkiKQpgYGAKCmBgYHtyfQp6LnNjb3JlczMgPC0gbmV3X3BvcCRgR3Jvd3RoIHJhdGVgICU+JSAgc2NvcmVzKHR5cGUgPSAieiIpCnouc2NvcmVzMyAlPiUgc3VtbWFyeSgpCmBgYAoKYGBge3J9CndoaWNoKGFicyh6LnNjb3JlczMpID4zICkKbmV3X3BvcFtjKDc2LDE1NiksIF0KYGBgCgoKIyMJVHJhbnNmb3JtIAoKVGhlIGRhdGEgZGlzdHJpYnV0aW9uIHdhcyBjaGVja2VkIGZvciBib3RoIGBUb3RhbF8yMDE4YCBhbmQgYFRvdGFsXzIwMTlgIHVzaW5nIGBoaXN0KClgLgoKQm90aCBvZiB0aGUgZGlzdHJpYnV0aW9ucyBzaG93ZWQgaGlnaCByaWdodCBza2V3bmVzcyBpbiB0aGUgdmFyaWFibGVzLiBUaGVyZWZvcmUsICRsbiQgdHJhbnNmb3JtYXRpb24gd2FzIHRha2VuIGludG8gZGF0YSB0cmFuc2Zvcm1hdGlvbiB0byByZWR1Y2UgdGhlIHNrZXduZXNzIHVzaW5nIGBsb2coKWAuIAoKCmBgYHtyfQpoaXN0KG5ld19wb3AkVG90YWxfMjAxOCwgbWFpbiA9ICJUb3RhbCBwb3B1bGF0aW9uIGluIDIwMTgiKQpgYGAKCgpgYGB7cn0KaGlzdChuZXdfcG9wJFRvdGFsXzIwMTksIG1haW4gPSAiVG90YWwgcG9wdWxhdGlvbiBpbiAyMDE5IikKYGBgCgpUaGUgZGlzdHJpYnV0aW9uIGZvciBgVG90YWxfMjAxOGAgYW5kIGBUb3RhbF8yMDE5YCBhZnRlciAkbG4kIHRyYW5zZm9ybWF0aW9uOgoKKiBUaGUgZGlzdHJpYnV0aW9uIGZvciB0d28gdmFyaWFibGVzIHdlcmUgbW9yZSBzeW1tZXRyaWNhbCBhZnRlciBkYXRhIHRyYW5zZm9ybWF0aW9uLgoKYGBge3J9CmxvZ18yMDE4IDwtIGxvZyhuZXdfcG9wJFRvdGFsXzIwMTgpCmhpc3QobG9nXzIwMTgsIG1haW4gPSAiTG9nIHBvcHVsYXRpb24gaW4gMjAxOCIpCmBgYAoKYGBge3J9CmxvZ18yMDE5IDwtIGxvZyhuZXdfcG9wJFRvdGFsXzIwMTkpCmhpc3QobG9nXzIwMTksIG1haW4gPSAiTG9nIHBvcHVsYXRpb24gaW4gMjAxOSIpCmBgYAoKIyMgUmVmZXJlbmNlcwoKQXVzdHJhbGlhbiBCdXJlYXUgb2YgU3RhdGlzdGljcyAyMDE5LCAqUG9wdWxhdGlvbiBFc3RpbWF0ZXMgYnkgQWdlIGFuZCBTZXgsIExvY2FsIEdvdmVybm1lbnQgQXJlYXMgKEFTR1MgMjAxOCksIDIwMTgqLCAgQXVzdHJhbGlhJ3Mgc3RhdGlzdGljIGRhdGFzZXRzLCBkYXRhIGZpbGUsIEF1c3RyYWxpYW4gR292ZXJubWVudCwgQXVzdHJhbGlhbiBCdXJlYXUgb2YgU3RhdGlzdGljcywgTWVsYm91cm5lLCB2aWV3ZWQgMjAgTWF5IDIwMjAsIDxodHRwczovL3d3dy5hYnMuZ292LmF1L0FVU1NUQVRTL2Fic0AubnNmL0RldGFpbHNQYWdlLzMyMzUuMDIwMTg/T3BlbkRvY3VtZW50Pi4gCgpBdXN0cmFsaWFuIEJ1cmVhdSBvZiBTdGF0aXN0aWNzIDIwMTksICpQb3B1bGF0aW9uIEVzdGltYXRlcyBieSBMb2NhbCBHb3Zlcm5tZW50IEFyZWEsIDIwMTggdG8gMjAxOSAqLCAgQXVzdHJhbGlhJ3Mgc3RhdGlzdGljIGRhdGFzZXRzLCBkYXRhIGZpbGUsIEF1c3RyYWxpYW4gR292ZXJubWVudCwgQXVzdHJhbGlhbiBCdXJlYXUgb2YgU3RhdGlzdGljcywgTWVsYm91cm5lLCB2aWV3ZWQgMjAgTWF5IDIwMjAsIDxodHRwczovL3d3dy5hYnMuZ292LmF1L0FVU1NUQVRTL2Fic0AubnNmL0RldGFpbHNQYWdlLzMyMTguMDIwMTgtMTk/T3BlbkRvY3VtZW50JmZiY2xpZD1Jd0FSMjA1X0dfV3dxWEhaRHkwU0p4c1hmSlhfU2JTTk40b3dBb191WW5zUTFlY3FtaE1zdVRwYUo0eFZ3Pi4gCgpQYXJrZXIsIEIgMjAwMiwgKlBsYW5uaW5nIEFuYWx5c2lzOiBDYWxjdWxhdGluZyBHcm93dGggUmF0ZXMqLCBVbml2ZXJzaXR5IG9mIE9yZWdvbiwgdmlld2VkIDMwIE1heSAyMDIwLCA8aHR0cHM6Ly9wYWdlcy51b3JlZ29uLmVkdS9yZ3AvUFBQTTYxMy9jbGFzczhhLmh0bSM6fjp0ZXh0PVRoZSUyMGFubnVhbCUyMHBlcmNlbnRhZ2UlMjBncm93dGglMjByYXRlLE4lMkMlMjB0aGUlMjBudW1iZXIlMjBvZiUyMHllYXJzLiZ0ZXh0PUluJTIwMTk4MCUyQyUyMHRoZSUyMHBvcHVsYXRpb24lMjBpbiUyMExhbmUlMjBDb3VudHklMjB3YXMlMjAyNTAlMkMwMDA+LiAKClRyYXZlbCBWaWN0b3JpYSAyMDIwLCAqTG9jYWwgR292ZXJubWVudCBBcmVhcyosIFRyYXZlbCBWaWN0b3JpYSwgdmlld2VkIDMwIE1heSAyMDIwLCA8aHR0cHM6Ly93d3cudHJhdmVsdmljdG9yaWEuY29tLmF1L3ZpY3RvcmlhL2xvY2FsZ292ZXJubWVudC8+LiAKCjxicj4KPGJyPgo=