Corresponding datasets:
Dataset ‘Panicker_et_al_2019_surveyeffortdataset.csv’ contains the effort for all the surveys. Read into the program as ‘effdat’
Dataset ‘Panicker_et_al_2019_cetaceandataset.csv’ is the sightings dataset which include both on survey effort and opportunistic sightings. The sightings data set also include variables such as depth at boat location, slope, aspect and nearest distance to land. Depth was obtained from GeoMapApp (Ryan et al. 2009). Slope, aspect and nearest distance to land was calculated using ArcGIS. The file is read into the program as ‘cetenvdat’.
Dataset ‘Panicker_et_al_2019_beaufortdataset.csv’ is the dataset with corresponding beaufort states. This sheet has the distance covered in each beaufort state per season, per route, per day. Read into the program as ‘effbeaudist’
Names of subsets from data csv files within this notebook:
- ‘idcetenvdat’ is the subset for identified sightings including opportunistic sightings.
- ‘oncetenvdat’ is the subset for on survey effort sightings.
- ‘idcetenvdatstats’ is the subset for identified sightings with the exception of baleen whale and pygmy whale sightings as n=1. This file is used for all statistical analysis.
- ‘comidcetenvdatstats’ is the sightings data for identified sightings of three of the most commonly sighted species (spinnner, bottlenose and pilot).
- ‘routenames’ is a dataset created for a list of survey routes and corresponding route numbers.
Note: If subsets have inter or ne at the end, it corresponds to inter-monsoon or northeast monsoon seasons
R Setup
Working directory for R studio, Reading Data files and Data preparation
Run line by line to avoid masking
#knitr::opts_chunk$set(echo = FALSE)
rm(list = ls()) # clears workspace
# Working directory on your computer! CHANGE AS YOU NEED
# set the working directory to your home directory where data files are stored
setwd("/Volumes/GoogleDrive/My Drive/Laksh I project/design & data/Data Entry/Laksh R files/Panicker_2019_Cetaceans_Lakshadweep/")
# Required Packages and libraries
library(lubridate)
library(gdata)
library(plotrix)
library(psych)
library(devtools)
library(reshape2)
library(ggplot2)
# Reading in data files
effdat<-read.csv("Panicker_et_al_2019_surveyeffortdataset.csv", header = T, stringsAsFactors = F) # effort dataset
cetenvdat<-read.csv("Panicker_et_al_2019_cetaceandataset.csv", header = T, stringsAsFactors = F) # cetacean dataset
effbeaudist<-read.csv("Panicker_et_al_2019_beaufortdataset.csv", header = T, stringsAsFactors = F) # beaufort dataset
# Data preparation for analysis
# Creating a dataset of routenames and corresponding route numbers
routenames<-data.frame((c(1,2,3,4,5,6,7,8,9,10,11,12)),(c("AGT-AKC","KVT-AGT","BTR-AKC","KVT-AKC","CHT-AKC","KLT-AKC","KVT-AND","BTR-KVT","KLT-CHT","KVT-KLP","AMN-KDT","KVT-KLT")))
colnames(routenames) <- c("routeno", "route")
# Creating a subset for the identified species
idcetenvdat<-subset(cetenvdat, !cetenvdat$species == "blackfish" & !cetenvdat$species == "uniddolphin" & !cetenvdat$species == "unidcet" & !cetenvdat$species=="unidsmallwhale" & !cetenvdat$species == "unidwhale" & !cetenvdat$species == "unidsmalldolphin" )
# Creating a subset for on survey effort sightings
oncetenvdat<-subset(cetenvdat, !cetenvdat$eff == "off")
# Removing baleen and pgymykiller whale from identified species as sample size is 1 for these species (This step needed for stats analysis)
idcetenvdatstats<-drop.levels(subset(idcetenvdat,!idcetenvdat$species == "baleen" & !idcetenvdat$species == "pygmykiller"))
# Creating a subset for identified commonly sighted species (n>10 namely, spinner dolphin, bottlenose dolphin and pilot whale)
comidcetenvdatstats<-rbind(subset(idcetenvdat, idcetenvdat$species == "spinner"), subset(idcetenvdat, idcetenvdat$species == "bottlenose"), subset(idcetenvdat, idcetenvdat$species == "pilot"))
# Creating a subset for identified species in northeast monsoon season
idcetenvdatstatsne<-subset(idcetenvdatstats, idcetenvdatstats$seas == 'ne')
# Creating a subset for identified species in northeast monsoon season for commonly sighted species (n>10 namely, spinner dolphin, bottlenose dolphin and pilot whale)
comidcetenvdatstatsne<-subset(comidcetenvdatstats, comidcetenvdatstats$seas == 'ne')
# Creating a subset for identified species in inter monsoon season
idcetenvdatstatsinter<-subset(idcetenvdatstats, idcetenvdatstats$seas == 'inter')
# Creating a subset for identified species in inter monsoon season for commonly sighted species (n>10 namely, spinner dolphin, bottlenose dolphin and pilot whale)
comidcetenvdatstatsinter<-subset(comidcetenvdatstats, comidcetenvdatstats$seas == 'inter')
print ("SETUP DONE AND DATA READ INTO R")
[1] "SETUP DONE AND DATA READ INTO R"
Structure of data
Note: Column header details are given in ReadMe file.
Effort dataset (effdat)
# structure of effort
effdat$date<-as.Date(effdat$date, "%m/%d/%y") # setting data format
str(effdat)
'data.frame': 78 obs. of 13 variables:
$ date : Date, format: "2015-10-28" "2015-10-31" "2015-10-31" "2015-11-01" ...
$ seas : chr "ne" "ne" "ne" "ne" ...
$ HSV : chr "small" "large" "large" "small" ...
$ routeno : int 10 9 5 3 8 4 11 2 6 9 ...
$ route : chr "KVT KLP" "KLT CHT" "CHT AKC" "BTR AKC" ...
$ tripno : int 1 1 1 1 1 1 1 1 1 2 ...
$ dist : num 69.6 31.3 33.5 69.1 58.6 ...
$ hr.dec : num 2.83 1.25 1.03 2.28 2.08 1.92 0.37 1.88 1.15 1.08 ...
$ hrs : chr "2:50" "1:15" "1:02" "2:17" ...
$ starttimewbreaks: chr "8:35" "12:55" "14:43" "9:59" ...
$ endtimewbreaks : chr "12:01" "13:53" "15:45" "12:40" ...
$ sight : chr "Y" "Y" "Y" "Y" ...
$ no.sight : int 2 2 1 2 1 1 1 4 1 0 ...
Cetacean dataset (cetenvdat)
str(cetenvdat)
'data.frame': 139 obs. of 19 variables:
$ sno : int 32 33 76 77 91 92 93 94 95 102 ...
$ mon : int 11 11 12 12 3 3 3 3 3 3 ...
$ date : int 18 18 11 11 11 11 11 11 11 18 ...
$ year : int 2015 2015 2015 2015 2016 2016 2016 2016 2016 2016 ...
$ seas : chr "ne" "ne" "ne" "ne" ...
$ HSV : chr "large" "large" "large" "large" ...
$ eff : chr "on" "on" "on" "on" ...
$ routeno : int 1 1 1 1 1 1 1 1 1 1 ...
$ route : chr "AGT AKC" "AGT AKC" "AGT AKC" "AGT AKC" ...
$ time : chr "12:10" "12:20" "12:36" "12:36" ...
$ species : chr "spinner" "unidcet" "uniddolphin" "unidsmalldolphin" ...
$ class : chr "smalldolphin" "cetacean" "dolphin" "smalldolphin" ...
$ lat : num 11 11 11 11 10.9 ...
$ long : num 72.5 72.4 72.5 72.5 72.3 ...
$ grpsize : int 20 2 1 2 6 12 1 4 15 6 ...
$ depth : int -1604 -1525 -1140 -1140 -655 -198 -51 -948 -1561 -966 ...
$ neardistkm: num 19.13 13.62 14.26 14.26 2.93 ...
$ slope : num 3.08 6.07 14.41 14.41 17.24 ...
$ beaufort : int 4 4 3 3 1 1 1 1 1 3 ...
No. of sightings, survey effort and beaufort states
Refer to subheading of results section of manuscript
Survey effort
# Total hours spent on survey effort
toteffhours<-sum(effdat$hr.dec)
paste ("Total hours spent on survey effort =", toteffhours)
[1] "Total hours spent on survey effort = 128.75"
# Total distance covered during survey effort
toteffdist<-sum(effdat$dist)
paste("Total distance (km) covered during survey effort = ", toteffdist)
[1] "Total distance (km) covered during survey effort = 3880.33"
# Number of surveys hours each day
paste("Average number of hours on survey effort per day = ", round(mean(effdat$hr.dec),2), "+/-", round(std.error(effdat$hr.dec),1))
[1] "Average number of hours on survey effort per day = 1.65 +/- 0.1"
paste("Min hours on survey effort in a day = ", round(min(effdat$hr.dec),1))
[1] "Min hours on survey effort in a day = 0.2"
paste("Max hours on survey effort in a day = ", round(max(effdat$hr.dec),1))
[1] "Max hours on survey effort in a day = 3.2"
No. of sightings
# note: Off effort and opporunistic is the same!
# Total number of cetacean group sightings (including opportunistic sightings)
paste ("Total no of cetacean group sightings (on and off survey effort) =", nrow(cetenvdat))
[1] "Total no of cetacean group sightings (on and off survey effort) = 139"
# No: of cetacean group sightings (on survey effort)
paste ("No. of cetacean group sightings on survey effort =", length(which(cetenvdat == "on")))
[1] "No. of cetacean group sightings on survey effort = 78"
# No: of cetacean group sightings (off survey effort/opportunistic)
paste ("No. of cetacean group sightings off survey effort =", length(which(cetenvdat == "off")))
[1] "No. of cetacean group sightings off survey effort = 61"
# Total number of identified cetacean groups (on and off survey effort)
paste ("Total no of identified cetacean groups (on and off survey effort) =", nrow(idcetenvdat))
[1] "Total no of identified cetacean groups (on and off survey effort) = 74"
# Number of identified cetacean groups (on survey effort)
paste ("No. of identified cetacean groups on survey effort =", length(which(idcetenvdat == "on")))
[1] "No. of identified cetacean groups on survey effort = 31"
Beaufort states recorded during survey effort
Table of distance (km) for each beaufort state
beau.table<-tapply((effbeaudist$Distance),(effbeaudist$Beaufort),FUN=sum)
beau.table
0 1 2 3 4 5 6
17.00 775.48 1139.90 1206.70 603.42 115.57 34.80
Percentages of the distances with respect to the total distance traveled in a particular beaufort state (e.g. 80.63% distance traveled in 0-3 state, note that this includes not just 0 but 0-3, 15.5% in beaufort 4, 2.96% in beaufort 5 and 0.89% in beaufort 6)
beau.one.two.three.percent<-round(((beau.table[1]+beau.table[2]+beau.table[3]+beau.table[4])/sum(beau.table))*100,1)
beau.one.two.three.percent
0
80.6
beau.four.percent<-round(((beau.table[5])/sum(beau.table))*100,1)
beau.four.percent
4
15.5
beau.five.percent<-round(((beau.table[6])/sum(beau.table))*100,1)
beau.five.percent
5
3
beau.six.percent<-round(((beau.table[7])/sum(beau.table))*100,1)
beau.six.percent
6
0.9
rm(beau.table, beau.one.two.three.percent, beau.four.percent, beau.five.percent, beau.six.percent)
Encounter rates
Overall Encounter rate
totencratedist<-round (((nrow(oncetenvdat)/toteffdist)*100),2)
paste("Overall encounter rate (per 100km) of cetacean groups for the entire study area =", totencratedist)
[1] "Overall encounter rate (per 100km) of cetacean groups for the entire study area = 2.01"
Route-wise encounter rate (per 100 km)
step1<-aggregate(effdat$dist ~ effdat$routeno, FUN=sum) # extracting sum of distances for routes
step2<-aggregate(effdat$no.sight ~ effdat$routeno, FUN=sum) # extracting sum of sightings for routes
step3<-step2$`effdat$no.sight`/step1$`effdat$dist` # encrate/km for each route = sighting/distance for each route, step dataframes can be removed from workspace after running.
route_encrate<-round(step3*100,2) # enc rate/distance * 100 kms and rounded to two decimal points
rm(step1, step2, step3)
route_encrate <- data.frame(routenames,route_encrate)
route_encrate
Species list
Refer to the second subheading of the results section
Species list and most commonly sighted
Eight toothed whale and one baleen whale were encountered. Note: Balaenoptera sp identified till genus, Tursiops sp (includes aduncus and truncatus)
species<- c("Baleen whale", "Blackfish", "Bottlenose dolphin", "False killer whale", "Pilot whale", "Pygmy killer whale", "Risso's dolphin", "Spinner dolphin","Spotted dolphin", "Striped dolphin", "Unidentified cetacean", "Unidentified dolphin", "Unidentified small dolphin", "Unidentified small whale", "Unidentified whale")
freq<-table(cetenvdat$species)
freq<-as.vector(freq)
species_counts<-data.frame(species, freq)
species_counts
rm(freq)
Season-wise species lists
Baleen; Baleen whale; Balaenoptera sp, Bottlenose; Tursiops sp, False Killer whale; Pseudorca crassidens, pilot; Globicephala machrorhynchus, pygmykiller; Feresa attenuata, risso; Grampus griseus, spinner; * Stenella longirostris, spotted; Stenella attenuata, striped; Stenella coruleoalba*, unidcet; unidentified cetacean, uniddolphin; unidentified dolphin, unidsmalldolphin; unidentified small dolphin, unidsmallwhale; unidentified small whale, unidwhale; unidentified whale.
Species sighted during the northeast monsoon season
# No: of species in ne monsoon season
table(idcetenvdatstatsne$species)
bottlenose falsekiller pilot risso spinner spotted striped
11 3 10 5 8 1 4
Species sighted during the inter monsoon season
# No: of species in inter monsoon season
table(idcetenvdatstatsinter$species)
bottlenose falsekiller pilot risso spinner spotted striped
7 1 3 2 14 2 1
Group sizes (Table 1)
Average group size, standard errors and minimum and maximum group sizes for each species
meangrpsize<-round(tapply(cetenvdat$grpsize,cetenvdat$species, mean, na.rm = TRUE),2)
meangrpsize<-as.vector(meangrpsize)
SEgrpsize<-round(tapply(cetenvdat$grpsize,cetenvdat$species, std.error, na.rm = TRUE),2)
SEgrpsize<-as.vector(SEgrpsize)
SEgrpsize<-round(SEgrpsize,1)
mingrpsize<-tapply(cetenvdat$grpsize,cetenvdat$species, min, na.rm = TRUE)
mingrpsize<-as.vector(mingrpsize)
maxgrpsize<-tapply(cetenvdat$grpsize,cetenvdat$species, max, na.rm = TRUE)
maxgrpsize<-as.vector(maxgrpsize)
species_grpsize<-data.frame(species, meangrpsize, SEgrpsize, mingrpsize, maxgrpsize)
species_grpsize<-species_grpsize[1:10,]
species_grpsize
rm(meangrpsize, SEgrpsize, mingrpsize, maxgrpsize)
Seafloor depths at sighting locations(Table 1)
Average depth for cetacean sightings in the entire study area (in metres)
paste("Average depth =", round(mean(cetenvdat$depth),2), "+/-" ,round(std.error(cetenvdat$depth),2))
[1] "Average depth = -1179.1 +/- 57.34"
paste("Minimum depth =", round(min(cetenvdat$depth),2))
[1] "Minimum depth = -2259"
paste("Maximum depth =", round(max(cetenvdat$depth),2))
[1] "Maximum depth = -5"
Average depths, standard errors and minimum and maximum group sizes for each species
meandepth<-round(tapply(cetenvdat$depth,cetenvdat$species, mean, na.rm = TRUE),2)
meandepth<-as.vector(meandepth)
SEdepth<-round(tapply(cetenvdat$depth,cetenvdat$species, std.error, na.rm = TRUE),2)
SEdepth<-as.vector(SEdepth)
mindepth<-tapply(cetenvdat$depth,cetenvdat$species, min, na.rm = TRUE)
mindepth<-as.vector(mindepth)
maxdepth<-tapply(cetenvdat$depth,cetenvdat$species, max, na.rm = TRUE)
maxdepth<-as.vector(maxdepth)
species_depth<-data.frame(species, meandepth, SEdepth, mindepth, maxdepth)
species_depth<-species_depth[1:10,]
species_depth
rm(maxdepth, meandepth, mindepth, SEdepth)
Cetacean sightings across season (Figure 4)
Cetacean sightings in northeast monsoon and inter monsoon season (only on survey effort)
# on effort sightings
table(oncetenvdat$seas)
inter ne
27 51
Effort (in km) across season
# Distances (effort) in each season
test<-subset(effdat, effdat$seas == "ne")
test2<-subset(effdat, !effdat$seas == "ne")
paste("Dist (km) in north east monsoon = ", sum(test$dist), "and Dist (km) in inter monsoon = ", sum(test2$dist))
[1] "Dist (km) in north east monsoon = 1720.9 and Dist (km) in inter monsoon = 2159.43"
# Proprotion of effort in each season
paste("Proportion traveled in north east monsoon = ", round((sum(test$dist)/toteffdist)*100,2), "%", "and Proportion traveled in inter monsoon = ", round((sum(test2$dist)/toteffdist)*100,2), "%")
[1] "Proportion traveled in north east monsoon = 44.35 % and Proportion traveled in inter monsoon = 55.65 %"
rm(test2)
rm(test)
Error in names(frame)[names(frame) == "x"] <- name :
names() applied to a non-vector
Barplot of observed and expected cetacean sightings across season (on survey effort)
Expected ratio’s correspond to distance traveled in a season
par(mar = c(7,6,4,4)) # sets the outer margin, order = left,bottom,top,right
#par(oma=c(0,0,0,5.8))
obsexpseas<-as.matrix(data.frame(inter=c(27, 43.41), ne=c(51,34.59))) # creating a matrix with observed and expected cetacean sighting values for intermonsoon (27 & 43.41) and ne monsoon (51,34.59)
onseasbarplot<-barplot(obsexpseas, beside=TRUE,
width = 0.5,
xlab = "Season",
ylab="No: of cetacean sightings",
names.arg=c("Inter monsoon (n=27)","Northeast monsoon (n=51)"),
cex.lab = 0.9,
cex.axis = 1,
cex.names = 0.7,
col=c("grey80", "grey20"),
density = c(100,100),
ylim = c(0,80),
xlim=c(0.3,5))
legend("topleft", c("Cetacean sightings on survey", "Expected cetacean sighting based on effort"), fill = c("grey80", "grey20"), cex=0.7, bty='n')

Non parameteric statistical test - Chi-Square Goodness of Fit
Chi square goodness of fit test between observed and expected values. Expected values are calculated as effort (distance traveled in each season). The test is significant and the null hypothesis is rejected.
Null hypotheis: Sightings are equally distributed across the two seasons as per the distance traveled during survey effort.
Alternate Hypothesis: Sightings are differentially distributed across the two seasons as per the distance traveled during survey effort.
# chi square test for on effort sightings in each season - goodness of fit according to distance traveled
effdatne<-subset(effdat, effdat$seas == 'ne') # effort dataset for only ne monsoon
effdatinter<-subset(effdat, effdat$seas == 'inter') # effort dataset for only inter monsoon
toteffdistne<-sum(effdatne$dist) # total distance traveled for northeast monsoon
toteffdistinter<-sum(effdatinter$dist) # total distance traveled for inter monsoon
# table(oncetenvdat$seas) # sightings per season on effort
# chisquare goodness of fit test for no: of sightings in each season to expected number of sightings based on distance travelled.
table(oncetenvdat$seas)
inter ne
27 51
seasallchisq<-chisq.test( (table(oncetenvdat$seas)),
p=c((toteffdistinter/toteffdist),(toteffdistne/toteffdist)) )
seasallchisq
Chi-squared test for given probabilities
data: (table(oncetenvdat$seas))
X-squared = 13.984, df = 1, p-value = 0.0001844
paste('Expected value for inter monsoon period is', round(seasallchisq$expected[1],2))
[1] "Expected value for inter monsoon period is 43.41"
paste('Expected values for north east monsoon is', round(seasallchisq$expected[2],2))
[1] "Expected values for north east monsoon is 34.59"
# formula chi.sq.test ( no: of seas sightings 27 (inter), 51(ne), probability = 0.5565068 (inter), 0.4434932 (ne) )
Cetacean species across distance to nearest landmass
Boxplot of distance to nearest landmass for all species
Species codes; bal = Baleen whale, T = Bottlenose dolphin, PC = False killer whale, GM = Short finned pilot whale, FA = Pgymy killer whale, GG = Rissos dolphin, SL = Spinner dolphin, SA = Spotted dolphin, SC = Striped dolphin
par(mar = c(5,5,3,3)) # sets the outer margin, order = left,bottom,top,right
neardistboxplot<-boxplot(idcetenvdatstats$neardistkm~idcetenvdatstats$species, xlab = "Species (n)", ylab="Nearest distance (km)", main = "Nearest distance to land for each species", names=c("T (18)","PC(4)","GM(13)","GG(7)","SL(22)","SA(3)","SC(5)"), cex.lab = 1.2, cex.main = 1, col="mediumaquamarine")

# species codes; bal = Baleen whale, T = Bottlenose dolphin, PC = False killer whale, GM = Short finned pilot whale, FA = Pgymy killer whale, GG = Rissos dolphin, SL = Spinner dolphin, SA = Spotted dolphin, SC = Striped dolphin
Non parameteric statistical test - Kruskal-Wallis test
Null hypothesis: All species are uniformly distributed with respect to the nearest landmass on the ferry routes.
Alternate hypothesis: Species are differentially distributed with respect to the nearest landmass on the ferry routes.
Kruskal Wallis test was performed and test was significant. Therefore the Null hypothsis is rejected.
# for all sps (except baleen and pygmy)
kruskal.test(as.factor(idcetenvdatstats$neardistkm)~as.factor(idcetenvdatstats$species), data=idcetenvdatstats)
Kruskal-Wallis rank sum test
data: as.factor(idcetenvdatstats$neardistkm) by as.factor(idcetenvdatstats$species)
Kruskal-Wallis chi-squared = 16.962, df = 6, p-value = 0.009425
Medians for nearest and furthest species
paste ("Spinner dolphins median (in km) =", round(neardistboxplot$stats[3,5],2))
[1] "Spinner dolphins median (in km) = 1.82"
paste ("Spotted dolphins median (in km) =", round(neardistboxplot$stats[3,6],2))
[1] "Spotted dolphins median (in km) = 43.28"
paste ("Striped dolphins median (in km) =", round(neardistboxplot$stats[3,7],2))
[1] "Striped dolphins median (in km) = 24.72"
Cetacean species across seafloor slope gradient
Boxplot of slope distribution for all species
Species codes; bal = Baleen whale, T = Bottlenose dolphin, PC = False killer whale, GM = Short finned pilot whale, FA = Pgymy killer whale, GG = Rissos dolphin, SL = Spinner dolphin, SA = Spotted dolphin, SC = Striped dolphin
par(mar = c(5,5,3,3)) # sets the outer margin, order = left,bottom,top,right
slopeboxplot<-boxplot(idcetenvdatstats$slope~idcetenvdatstats$species, xlab = "Species (n)", ylab="Slope", main = "Slope distribution for each species", names=c("T (18)","PC(4)","GM(13)", "GG(7)","SL(22)","SA(3)","SC(5)"), cex.lab = 1.2, cex.main = 1, col="mediumaquamarine")

# species codes; bal = Baleen whale, T = Bottlenose dolphin, PC = False killer whale, GM = Short finned pilot whale, FA = Pgymy killer whale, GG = Rissos dolphin, SL = Spinner dolphin, SA = Spotted dolphin, SC = Striped dolphin
Non parameteric statistical test - Kruskal-Wallis test
Null hypothesis: All species are uniformly distributed across slope gradients along the ferry routes.
Alternate hypothesis: Species are differentially distributed across slope gradients along the ferry routes.
Kruskal Wallis test was performed and test was significant. Therefore the Null hypothsis is rejected.
# for common sps
kruskal.test(as.factor(idcetenvdatstats$slope)~as.factor(idcetenvdatstats$species), data=idcetenvdatstats)
Kruskal-Wallis rank sum test
data: as.factor(idcetenvdatstats$slope) by as.factor(idcetenvdatstats$species)
Kruskal-Wallis chi-squared = 15.542, df = 6, p-value = 0.01643
Medians for species in the flatest and steepest slopes
paste ("Spinner dolphins median steepest slope =", round(slopeboxplot$stats[3,5],2))
[1] "Spinner dolphins median steepest slope = 13.54"
paste ("Spotted dolphins median flat slope =", round(slopeboxplot$stats[3,6],2))
[1] "Spotted dolphins median flat slope = 1.51"
paste ("Striped dolphins median flat slope =", round(slopeboxplot$stats[3,7],2))
[1] "Striped dolphins median flat slope = 1.65"
Cetacean species across seafloor depth
Boxplot between cetacean species and seafloor depth
Species codes; bal = Baleen whale, T = Bottlenose dolphin, PC = False killer whale, GM = Short finned pilot whale, FA = Pgymy killer whale, GG = Rissos dolphin, SL = Spinner dolphin, SA = Spotted dolphin, SC = Striped dolphin
# All species and depth
par(mar = c(5,5,3,3)) # sets the outer margin, order = left,bottom,top,right
depthboxplot<-boxplot(idcetenvdatstats$depth~idcetenvdatstats$species, xlab = "Species (n)", ylab="Seafloor depth(m)", main = "Seafloor depth distribution for each species", names=c("T (18)","PC(4)","GM(13)","GG(7)","SL(22)","SA(3)","SC(5)"), cex.lab = 1.2, cex.main = 1, col="mediumaquamarine") # xlab = x label, ylab = y label, cex.lab = label font size, cex.main = title font size, main = title

# species codes; bal = Baleen whale, T = Bottlenose dolphin, PC = False killer whale, GM = Short finned pilot whale, FA = Pgymy killer whale, GG = Rissos dolphin, SL = Spinner dolphin, SA = Spotted dolphin, SC = Striped dolphin
Non parameteric statistical test species and depth - Kruskal-Wallis test
Null hypothesis: All species are uniformly distributed away across seafloor depths.
Alternate hypothesis: Species are differentially distributed across seafloor depths.
Kruskal Wallis test was performed and test was not significant. Therefore the Null hypothsis is not rejected.
# for all sps (except baleen and pygmy)
kruskal.test(as.factor(idcetenvdatstats$depth)~as.factor(idcetenvdatstats$species), data=idcetenvdatstats)
Kruskal-Wallis rank sum test
data: as.factor(idcetenvdatstats$depth) by as.factor(idcetenvdatstats$species)
Kruskal-Wallis chi-squared = 10.912, df = 6, p-value = 0.09114
LS0tCnRpdGxlOiAiQ2V0YWNlYW4gZGlzdHJpYnV0aW9uIGFuZCBkaXZlcnNpdHkgaW4gTGFrc2hhZHdlZXAgSXNsYW5kcywgSW5kaWEgdXNpbmcgYSBwbGF0Zm9ybSBvZiBvcHBvcnR1bml0eTogT2N0b2JlciAyMDE1IHRvIEFwcmlsIDIwMTYgLSBEYXRhIEFuYWx5c2lzIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMgQXV0aG9yIGluZm9ybWF0aW9uOgoKRGF0ZTogIjkvMjIvMjAxOSIKCkF1dGhvciAoYW5hbHlzaXMpOiBEaXZ5YSBQYW5pY2tlcgoKU3R1ZHk6IENldGFjZWFuIGRpc3RyaWJ1dGlvbiBhbmQgZGl2ZXJzaXR5IGluIExha3NoYWR3ZWVwIElzbGFuZHM6IE9jdG9iZXIgMjAxNSB0byBBcHJpbCAyMDE2CgpGdW5kaW5nOiBSdWZmb3JkIFNtYWxsIEdyYW50cyBmb3IgTmF0dXJlIENvbnNlcnZhdGlvbgoKSW5zdGl0dXRpb25zOiBVbml2ZXJzaXR5IG9mIFdhc2hpbmd0b24sIE5hdGlvbmFsIENlbnRyZSBmb3IgQmlvbG9naWNhbCBTY2llbmNlcywgQ2VudHJlIGZvciBXaWxkbGlmZSBTdHVkaWVzCgpFbWFpbCBmb3IgY29ycmVzcG9uZGVuY2U6IGRwYW5pY0B1dy5lZHUKCkNpdGF0aW9uOiBQYW5pY2tlciwgRC4sIFN1dGFyaWEsIEQuLCBLdW1hciwgQS4sIFN0YWZmb3JkLCBLLiAoMjAxOSkgJ0NldGFjZWFuIGRpc3RyaWJ1dGlvbiBhbmQgZGl2ZXJzaXR5IGluIExha3NoYWR3ZWVwIElzbGFuZHMsIEluZGlhIHVzaW5nIHBsYXRmb3JtcyBvZiBvcHBvcnR1bml0eTogT2N0IDIwMTUgdG8gQXByIDIwMTYnLiBSZXNlYXJjaFdvcmtzLiBVbml2ZXJzaXR5IG9mIFdhc2hpbmd0b24uCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyBDb3JyZXNwb25kaW5nIGRhdGFzZXRzOgoKRGF0YXNldCAqJ1Bhbmlja2VyX2V0X2FsXzIwMTlfc3VydmV5ZWZmb3J0ZGF0YXNldC5jc3YnKiBjb250YWlucyB0aGUgZWZmb3J0IGZvciBhbGwgdGhlIHN1cnZleXMuIFJlYWQgaW50byB0aGUgcHJvZ3JhbSBhcyAqJ2VmZmRhdCcqCgpEYXRhc2V0IConUGFuaWNrZXJfZXRfYWxfMjAxOV9jZXRhY2VhbmRhdGFzZXQuY3N2JyogaXMgdGhlIHNpZ2h0aW5ncyBkYXRhc2V0IHdoaWNoIGluY2x1ZGUgYm90aCBvbiBzdXJ2ZXkgZWZmb3J0IGFuZCBvcHBvcnR1bmlzdGljIHNpZ2h0aW5ncy4gVGhlIHNpZ2h0aW5ncyBkYXRhIHNldCBhbHNvIGluY2x1ZGUgdmFyaWFibGVzIHN1Y2ggYXMgZGVwdGggYXQgYm9hdCBsb2NhdGlvbiwgc2xvcGUsIGFzcGVjdCBhbmQgbmVhcmVzdCBkaXN0YW5jZSB0byBsYW5kLiBEZXB0aCB3YXMgb2J0YWluZWQgZnJvbSBHZW9NYXBBcHAgKFJ5YW4gZXQgYWwuIDIwMDkpLiBTbG9wZSwgYXNwZWN0IGFuZCBuZWFyZXN0IGRpc3RhbmNlIHRvIGxhbmQgd2FzIGNhbGN1bGF0ZWQgdXNpbmcgQXJjR0lTLiBUaGUgZmlsZSBpcyByZWFkIGludG8gdGhlIHByb2dyYW0gYXMgKidjZXRlbnZkYXQnKi4KCkRhdGFzZXQgKidQYW5pY2tlcl9ldF9hbF8yMDE5X2JlYXVmb3J0ZGF0YXNldC5jc3YnKiBpcyB0aGUgZGF0YXNldCB3aXRoIGNvcnJlc3BvbmRpbmcgYmVhdWZvcnQgc3RhdGVzLiBUaGlzIHNoZWV0IGhhcyB0aGUgZGlzdGFuY2UgY292ZXJlZCBpbiBlYWNoIGJlYXVmb3J0IHN0YXRlIHBlciBzZWFzb24sIHBlciByb3V0ZSwgcGVyIGRheS4gUmVhZCBpbnRvIHRoZSBwcm9ncmFtIGFzIConZWZmYmVhdWRpc3QnKgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMgTmFtZXMgb2Ygc3Vic2V0cyBmcm9tIGRhdGEgY3N2IGZpbGVzIHdpdGhpbiB0aGlzIG5vdGVib29rOgoKMS4gKidpZGNldGVudmRhdCcqIGlzIHRoZSBzdWJzZXQgZm9yIGlkZW50aWZpZWQgc2lnaHRpbmdzIGluY2x1ZGluZyBvcHBvcnR1bmlzdGljIHNpZ2h0aW5ncy4KMi4gKidvbmNldGVudmRhdCcqIGlzIHRoZSBzdWJzZXQgZm9yIG9uIHN1cnZleSBlZmZvcnQgc2lnaHRpbmdzLgozLiAqJ2lkY2V0ZW52ZGF0c3RhdHMnKiBpcyB0aGUgc3Vic2V0IGZvciBpZGVudGlmaWVkIHNpZ2h0aW5ncyB3aXRoIHRoZSBleGNlcHRpb24gb2YgYmFsZWVuIHdoYWxlIGFuZCBweWdteSB3aGFsZSBzaWdodGluZ3MgYXMgbj0xLiBUaGlzIGZpbGUgaXMgdXNlZCBmb3IgYWxsIHN0YXRpc3RpY2FsIGFuYWx5c2lzLiAKNC4gKidjb21pZGNldGVudmRhdHN0YXRzJyogaXMgdGhlIHNpZ2h0aW5ncyBkYXRhIGZvciBpZGVudGlmaWVkIHNpZ2h0aW5ncyBvZiB0aHJlZSBvZiB0aGUgbW9zdCBjb21tb25seSBzaWdodGVkIHNwZWNpZXMgKHNwaW5ubmVyLCBib3R0bGVub3NlIGFuZCBwaWxvdCkuIAo1LiAqJ3JvdXRlbmFtZXMnKiBpcyBhIGRhdGFzZXQgY3JlYXRlZCBmb3IgYSBsaXN0IG9mIHN1cnZleSByb3V0ZXMgYW5kIGNvcnJlc3BvbmRpbmcgcm91dGUgbnVtYmVycy4KCl8qKk5vdGUqKl86IElmIHN1YnNldHMgaGF2ZSBpbnRlciBvciBuZSBhdCB0aGUgZW5kLCBpdCBjb3JyZXNwb25kcyB0byBpbnRlci1tb25zb29uIG9yIG5vcnRoZWFzdCBtb25zb29uIHNlYXNvbnMKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMjIFIgU2V0dXAKIyMjIyMgV29ya2luZyBkaXJlY3RvcnkgZm9yIFIgc3R1ZGlvLCBSZWFkaW5nIERhdGEgZmlsZXMgYW5kIERhdGEgcHJlcGFyYXRpb24KUnVuIGxpbmUgYnkgbGluZSB0byBhdm9pZCBtYXNraW5nIApgYGB7ciBzZXR1cH0KI2tuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UpCnJtKGxpc3QgPSBscygpKSAjIGNsZWFycyB3b3Jrc3BhY2UKCiMgV29ya2luZyBkaXJlY3Rvcnkgb24geW91ciBjb21wdXRlciEgQ0hBTkdFIEFTIFlPVSBORUVECiMgc2V0IHRoZSB3b3JraW5nIGRpcmVjdG9yeSB0byB5b3VyIGhvbWUgZGlyZWN0b3J5IHdoZXJlIGRhdGEgZmlsZXMgYXJlIHN0b3JlZApzZXR3ZCgiL1ZvbHVtZXMvR29vZ2xlRHJpdmUvTXkgRHJpdmUvTGFrc2ggSSBwcm9qZWN0L2Rlc2lnbiAmIGRhdGEvRGF0YSBFbnRyeS9MYWtzaCBSIGZpbGVzL1Bhbmlja2VyXzIwMTlfQ2V0YWNlYW5zX0xha3NoYWR3ZWVwLyIpIAoKIyBSZXF1aXJlZCBQYWNrYWdlcyBhbmQgbGlicmFyaWVzCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGdkYXRhKQpsaWJyYXJ5KHBsb3RyaXgpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkoZGV2dG9vbHMpCmxpYnJhcnkocmVzaGFwZTIpCmxpYnJhcnkoZ2dwbG90MikKCiMgUmVhZGluZyBpbiBkYXRhIGZpbGVzCmVmZmRhdDwtcmVhZC5jc3YoIlBhbmlja2VyX2V0X2FsXzIwMTlfc3VydmV5ZWZmb3J0ZGF0YXNldC5jc3YiLCBoZWFkZXIgPSBULCBzdHJpbmdzQXNGYWN0b3JzID0gRikgIyBlZmZvcnQgZGF0YXNldApjZXRlbnZkYXQ8LXJlYWQuY3N2KCJQYW5pY2tlcl9ldF9hbF8yMDE5X2NldGFjZWFuZGF0YXNldC5jc3YiLCBoZWFkZXIgPSBULCBzdHJpbmdzQXNGYWN0b3JzID0gRikgIyBjZXRhY2VhbiBkYXRhc2V0CmVmZmJlYXVkaXN0PC1yZWFkLmNzdigiUGFuaWNrZXJfZXRfYWxfMjAxOV9iZWF1Zm9ydGRhdGFzZXQuY3N2IiwgaGVhZGVyID0gVCwgc3RyaW5nc0FzRmFjdG9ycyA9IEYpICMgYmVhdWZvcnQgZGF0YXNldAoKIyBEYXRhIHByZXBhcmF0aW9uIGZvciBhbmFseXNpcwoKIyBDcmVhdGluZyBhIGRhdGFzZXQgb2Ygcm91dGVuYW1lcyBhbmQgY29ycmVzcG9uZGluZyByb3V0ZSBudW1iZXJzCnJvdXRlbmFtZXM8LWRhdGEuZnJhbWUoKGMoMSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTIpKSwoYygiQUdULUFLQyIsIktWVC1BR1QiLCJCVFItQUtDIiwiS1ZULUFLQyIsIkNIVC1BS0MiLCJLTFQtQUtDIiwiS1ZULUFORCIsIkJUUi1LVlQiLCJLTFQtQ0hUIiwiS1ZULUtMUCIsIkFNTi1LRFQiLCJLVlQtS0xUIikpKQpjb2xuYW1lcyhyb3V0ZW5hbWVzKSA8LSBjKCJyb3V0ZW5vIiwgInJvdXRlIikKCiMgQ3JlYXRpbmcgYSBzdWJzZXQgZm9yIHRoZSBpZGVudGlmaWVkIHNwZWNpZXMKaWRjZXRlbnZkYXQ8LXN1YnNldChjZXRlbnZkYXQsICFjZXRlbnZkYXQkc3BlY2llcyA9PSAiYmxhY2tmaXNoIiAmICFjZXRlbnZkYXQkc3BlY2llcyA9PSAidW5pZGRvbHBoaW4iICYgIWNldGVudmRhdCRzcGVjaWVzID09ICJ1bmlkY2V0IiAmICFjZXRlbnZkYXQkc3BlY2llcz09InVuaWRzbWFsbHdoYWxlIiAmICFjZXRlbnZkYXQkc3BlY2llcyA9PSAidW5pZHdoYWxlIiAmICFjZXRlbnZkYXQkc3BlY2llcyA9PSAidW5pZHNtYWxsZG9scGhpbiIgKQoKIyBDcmVhdGluZyBhIHN1YnNldCBmb3Igb24gc3VydmV5IGVmZm9ydCBzaWdodGluZ3MKb25jZXRlbnZkYXQ8LXN1YnNldChjZXRlbnZkYXQsICFjZXRlbnZkYXQkZWZmID09ICJvZmYiKQoKIyBSZW1vdmluZyBiYWxlZW4gYW5kIHBneW15a2lsbGVyIHdoYWxlIGZyb20gaWRlbnRpZmllZCBzcGVjaWVzIGFzIHNhbXBsZSBzaXplIGlzIDEgZm9yIHRoZXNlIHNwZWNpZXMgKFRoaXMgc3RlcCBuZWVkZWQgZm9yIHN0YXRzIGFuYWx5c2lzKQppZGNldGVudmRhdHN0YXRzPC1kcm9wLmxldmVscyhzdWJzZXQoaWRjZXRlbnZkYXQsIWlkY2V0ZW52ZGF0JHNwZWNpZXMgPT0gImJhbGVlbiIgJiAhaWRjZXRlbnZkYXQkc3BlY2llcyA9PSAicHlnbXlraWxsZXIiKSkKCiMgQ3JlYXRpbmcgYSBzdWJzZXQgZm9yIGlkZW50aWZpZWQgY29tbW9ubHkgc2lnaHRlZCBzcGVjaWVzIChuPjEwIG5hbWVseSwgc3Bpbm5lciBkb2xwaGluLCBib3R0bGVub3NlIGRvbHBoaW4gYW5kIHBpbG90IHdoYWxlKQpjb21pZGNldGVudmRhdHN0YXRzPC1yYmluZChzdWJzZXQoaWRjZXRlbnZkYXQsIGlkY2V0ZW52ZGF0JHNwZWNpZXMgPT0gInNwaW5uZXIiKSwgc3Vic2V0KGlkY2V0ZW52ZGF0LCBpZGNldGVudmRhdCRzcGVjaWVzID09ICJib3R0bGVub3NlIiksIHN1YnNldChpZGNldGVudmRhdCwgaWRjZXRlbnZkYXQkc3BlY2llcyA9PSAicGlsb3QiKSkKCiMgQ3JlYXRpbmcgYSBzdWJzZXQgZm9yIGlkZW50aWZpZWQgc3BlY2llcyBpbiBub3J0aGVhc3QgbW9uc29vbiBzZWFzb24KaWRjZXRlbnZkYXRzdGF0c25lPC1zdWJzZXQoaWRjZXRlbnZkYXRzdGF0cywgaWRjZXRlbnZkYXRzdGF0cyRzZWFzID09ICduZScpCgojIENyZWF0aW5nIGEgc3Vic2V0IGZvciBpZGVudGlmaWVkIHNwZWNpZXMgaW4gbm9ydGhlYXN0IG1vbnNvb24gc2Vhc29uIGZvciBjb21tb25seSBzaWdodGVkIHNwZWNpZXMgKG4+MTAgbmFtZWx5LCBzcGlubmVyIGRvbHBoaW4sIGJvdHRsZW5vc2UgZG9scGhpbiBhbmQgcGlsb3Qgd2hhbGUpCmNvbWlkY2V0ZW52ZGF0c3RhdHNuZTwtc3Vic2V0KGNvbWlkY2V0ZW52ZGF0c3RhdHMsIGNvbWlkY2V0ZW52ZGF0c3RhdHMkc2VhcyA9PSAnbmUnKQoKIyBDcmVhdGluZyBhIHN1YnNldCBmb3IgaWRlbnRpZmllZCBzcGVjaWVzIGluIGludGVyIG1vbnNvb24gc2Vhc29uCmlkY2V0ZW52ZGF0c3RhdHNpbnRlcjwtc3Vic2V0KGlkY2V0ZW52ZGF0c3RhdHMsIGlkY2V0ZW52ZGF0c3RhdHMkc2VhcyA9PSAnaW50ZXInKQoKIyBDcmVhdGluZyBhIHN1YnNldCBmb3IgaWRlbnRpZmllZCBzcGVjaWVzIGluIGludGVyIG1vbnNvb24gc2Vhc29uIGZvciBjb21tb25seSBzaWdodGVkIHNwZWNpZXMgKG4+MTAgbmFtZWx5LCBzcGlubmVyIGRvbHBoaW4sIGJvdHRsZW5vc2UgZG9scGhpbiBhbmQgcGlsb3Qgd2hhbGUpCmNvbWlkY2V0ZW52ZGF0c3RhdHNpbnRlcjwtc3Vic2V0KGNvbWlkY2V0ZW52ZGF0c3RhdHMsIGNvbWlkY2V0ZW52ZGF0c3RhdHMkc2VhcyA9PSAnaW50ZXInKQoKcHJpbnQgKCJTRVRVUCBET05FIEFORCBEQVRBIFJFQUQgSU5UTyBSIikKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyBUYWJsZSBvZiBDb250ZW50cwoKW1N0cnVjdHVyZSBvZiBkYXRhXSAKCi0gKltFZmZvcnQgZGF0YXNldCAoZWZmZGF0KV0qCi0gKltDZXRhY2VhbiBkYXRhc2V0IChjZXRlbnZkYXQpXSoKCltOby4gb2Ygc2lnaHRpbmdzLCBzdXJ2ZXkgZWZmb3J0IGFuZCBiZWF1Zm9ydCBzdGF0ZXNdIAoKLSAqW1N1cnZleSBlZmZvcnRdKgotICpbTm8uIG9mIHNpZ2h0aW5nc10qCi0gKltCZWF1Zm9ydCBzdGF0ZXMgcmVjb3JkZWQgZHVyaW5nIHN1cnZleSBlZmZvcnRdKgoKW0VuY291bnRlciByYXRlc10gCgotICpbT3ZlcmFsbCBFbmNvdW50ZXIgcmF0ZV0qCi0gKltSb3V0ZS13aXNlIGVuY291bnRlciByYXRlIChwZXIgMTAwIGttKV0qCgpbU3BlY2llcyBsaXN0XSAKCi0gKltTcGVjaWVzIGxpc3QgYW5kIG1vc3QgY29tbW9ubHkgc2lnaHRlZF0qCi0gKltTZWFzb24td2lzZSBzcGVjaWVzIGxpc3RzXSoKCltHcm91cCBzaXplcyAoVGFibGUgMSldIAoKLSAqW0F2ZXJhZ2UgZ3JvdXAgc2l6ZSwgc3RhbmRhcmQgZXJyb3JzIGFuZCBtaW5pbXVtIGFuZCBtYXhpbXVtIGdyb3VwIHNpemVzIGZvciBlYWNoIHNwZWNpZXNdKgoKW1NlYWZsb29yIGRlcHRocyBhdCBzaWdodGluZyBsb2NhdGlvbnMoVGFibGUgMSldIAoKLSAqW0F2ZXJhZ2UgZGVwdGhzLCBzdGFuZGFyZCBlcnJvcnMgYW5kIG1pbmltdW0gYW5kIG1heGltdW0gZ3JvdXAgc2l6ZXMgZm9yIGVhY2ggc3BlY2llc10qCgpbQ2V0YWNlYW4gc2lnaHRpbmdzIGFjcm9zcyBzZWFzb24gKEZpZ3VyZSA0KV0KCi0gKltCYXJwbG90IG9mIG9ic2VydmVkIGFuZCBleHBlY3RlZCBjZXRhY2VhbiBzaWdodGluZ3MgYWNyb3NzIHNlYXNvbiAob24gc3VydmV5IGVmZm9ydCldKgotICpbTm9uIHBhcmFtZXRlcmljIHN0YXRpc3RpY2FsIHRlc3QgLSBDaGktU3F1YXJlIEdvb2RuZXNzIG9mIEZpdF0qCgpbQ2V0YWNlYW4gc3BlY2llcyBhY3Jvc3MgZGlzdGFuY2UgdG8gbmVhcmVzdCBsYW5kbWFzc10KCi0gKltCb3hwbG90IG9mIGRpc3RhbmNlIHRvIG5lYXJlc3QgbGFuZG1hc3MgZm9yIGFsbCBzcGVjaWVzXSoKLSAqW05vbiBwYXJhbWV0ZXJpYyBzdGF0aXN0aWNhbCB0ZXN0IC0gS3J1c2thbC1XYWxsaXMgdGVzdF0qCgpbQ2V0YWNlYW4gc3BlY2llcyBhY3Jvc3Mgc2VhZmxvb3Igc2xvcGUgZ3JhZGllbnRdIAoKLSAqW0JveHBsb3Qgb2Ygc2xvcGUgZGlzdHJpYnV0aW9uIGZvciBhbGwgc3BlY2llc10qCi0gKltOb24gcGFyYW1ldGVyaWMgc3RhdGlzdGljYWwgdGVzdCAtIEtydXNrYWwtV2FsbGlzIHRlc3RdKgoKW0NldGFjZWFuIHNwZWNpZXMgYWNyb3NzIHNlYWZsb29yIGRlcHRoXSAKCi0gKltCb3hwbG90IGJldHdlZW4gY2V0YWNlYW4gc3BlY2llcyBhbmQgc2VhZmxvb3IgZGVwdGhdKgotICpbTm9uIHBhcmFtZXRlcmljIHN0YXRpc3RpY2FsIHRlc3Qgc3BlY2llcyBhbmQgZGVwdGggLSBLcnVza2FsLVdhbGxpcyB0ZXN0XSoKCltQbG90IG9mIGNldGFjZWFuIHNwZWNpZXMgYWNyb3NzIG5lYXJlc3QgZGlzdGFuY2UgdG8gbGFuZCBhbmQgc2xvcGUgZ3JhZGllbnQgKEZpZ3VyZSA1KV0gCgo8YnI+CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIFN0cnVjdHVyZSBvZiBkYXRhCgpfKipOb3RlKipfOiBDb2x1bW4gaGVhZGVyIGRldGFpbHMgYXJlIGdpdmVuIGluIFJlYWRNZSBmaWxlLiAKCiMjIyMgRWZmb3J0IGRhdGFzZXQgKGVmZmRhdCkKYGBge3Igc3RydWN0dXJlIGVmZm9ydCBkYXRhc2V0fQojIHN0cnVjdHVyZSBvZiBlZmZvcnQKZWZmZGF0JGRhdGU8LWFzLkRhdGUoZWZmZGF0JGRhdGUsICIlbS8lZC8leSIpICMgc2V0dGluZyBkYXRhIGZvcm1hdApzdHIoZWZmZGF0KQpgYGAKCiMjIyMgQ2V0YWNlYW4gZGF0YXNldCAoY2V0ZW52ZGF0KQpgYGB7ciBzdHJ1Y3R1cmUgc2lnaHRpbmdzIGRhdGFzZXR9CnN0cihjZXRlbnZkYXQpCmBgYAoKPGJyPgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBOby4gb2Ygc2lnaHRpbmdzLCBzdXJ2ZXkgZWZmb3J0IGFuZCBiZWF1Zm9ydCBzdGF0ZXMKClJlZmVyIHRvIHN1YmhlYWRpbmcgb2YgcmVzdWx0cyBzZWN0aW9uIG9mIG1hbnVzY3JpcHQKCiMjIyMgU3VydmV5IGVmZm9ydApgYGB7ciBUb3RhbCBzdXJ2ZXkgZWZmb3J0IGRldGFpbHN9CiMgVG90YWwgaG91cnMgc3BlbnQgb24gc3VydmV5IGVmZm9ydAp0b3RlZmZob3Vyczwtc3VtKGVmZmRhdCRoci5kZWMpCnBhc3RlICgiVG90YWwgaG91cnMgc3BlbnQgb24gc3VydmV5IGVmZm9ydCA9IiwgdG90ZWZmaG91cnMpCgojIFRvdGFsIGRpc3RhbmNlIGNvdmVyZWQgZHVyaW5nIHN1cnZleSBlZmZvcnQKdG90ZWZmZGlzdDwtc3VtKGVmZmRhdCRkaXN0KQpwYXN0ZSgiVG90YWwgZGlzdGFuY2UgKGttKSBjb3ZlcmVkIGR1cmluZyBzdXJ2ZXkgZWZmb3J0ID0gIiwgdG90ZWZmZGlzdCkKCiMgTnVtYmVyIG9mIHN1cnZleXMgaG91cnMgZWFjaCBkYXkKcGFzdGUoIkF2ZXJhZ2UgbnVtYmVyIG9mIGhvdXJzIG9uIHN1cnZleSBlZmZvcnQgcGVyIGRheSA9ICIsIHJvdW5kKG1lYW4oZWZmZGF0JGhyLmRlYyksMiksICIrLy0iLCByb3VuZChzdGQuZXJyb3IoZWZmZGF0JGhyLmRlYyksMSkpCnBhc3RlKCJNaW4gaG91cnMgb24gc3VydmV5IGVmZm9ydCBpbiBhIGRheSA9ICIsIHJvdW5kKG1pbihlZmZkYXQkaHIuZGVjKSwxKSkKcGFzdGUoIk1heCBob3VycyBvbiBzdXJ2ZXkgZWZmb3J0IGluIGEgZGF5ID0gIiwgcm91bmQobWF4KGVmZmRhdCRoci5kZWMpLDEpKQpgYGAKCiMjIyMgTm8uIG9mIHNpZ2h0aW5ncwoKYGBge3IgTm8uIG9mIHNpZ2h0aW5nc30KIyBub3RlOiBPZmYgZWZmb3J0IGFuZCBvcHBvcnVuaXN0aWMgaXMgdGhlIHNhbWUhCiMgVG90YWwgbnVtYmVyIG9mIGNldGFjZWFuIGdyb3VwIHNpZ2h0aW5ncyAoaW5jbHVkaW5nIG9wcG9ydHVuaXN0aWMgc2lnaHRpbmdzKQpwYXN0ZSAoIlRvdGFsIG5vIG9mIGNldGFjZWFuIGdyb3VwIHNpZ2h0aW5ncyAob24gYW5kIG9mZiBzdXJ2ZXkgZWZmb3J0KSA9IiwgbnJvdyhjZXRlbnZkYXQpKQoKIyBObzogb2YgY2V0YWNlYW4gZ3JvdXAgc2lnaHRpbmdzIChvbiBzdXJ2ZXkgZWZmb3J0KQpwYXN0ZSAoIk5vLiBvZiBjZXRhY2VhbiBncm91cCBzaWdodGluZ3Mgb24gc3VydmV5IGVmZm9ydCA9IiwgbGVuZ3RoKHdoaWNoKGNldGVudmRhdCA9PSAib24iKSkpCgojIE5vOiBvZiBjZXRhY2VhbiBncm91cCBzaWdodGluZ3MgKG9mZiBzdXJ2ZXkgZWZmb3J0L29wcG9ydHVuaXN0aWMpCnBhc3RlICgiTm8uIG9mIGNldGFjZWFuIGdyb3VwIHNpZ2h0aW5ncyBvZmYgc3VydmV5IGVmZm9ydCA9IiwgbGVuZ3RoKHdoaWNoKGNldGVudmRhdCA9PSAib2ZmIikpKQoKIyBUb3RhbCBudW1iZXIgb2YgaWRlbnRpZmllZCBjZXRhY2VhbiBncm91cHMgKG9uIGFuZCBvZmYgc3VydmV5IGVmZm9ydCkKcGFzdGUgKCJUb3RhbCBubyBvZiBpZGVudGlmaWVkIGNldGFjZWFuIGdyb3VwcyAob24gYW5kIG9mZiBzdXJ2ZXkgZWZmb3J0KSA9IiwgbnJvdyhpZGNldGVudmRhdCkpCgojIE51bWJlciBvZiBpZGVudGlmaWVkIGNldGFjZWFuIGdyb3VwcyAob24gc3VydmV5IGVmZm9ydCkKcGFzdGUgKCJOby4gb2YgaWRlbnRpZmllZCBjZXRhY2VhbiBncm91cHMgb24gc3VydmV5IGVmZm9ydCA9IiwgbGVuZ3RoKHdoaWNoKGlkY2V0ZW52ZGF0ID09ICJvbiIpKSkKYGBgCgojIyMjIEJlYXVmb3J0IHN0YXRlcyByZWNvcmRlZCBkdXJpbmcgc3VydmV5IGVmZm9ydAoKVGFibGUgb2YgZGlzdGFuY2UgKGttKSBmb3IgZWFjaCBiZWF1Zm9ydCBzdGF0ZQpgYGB7ciBCZWF1Zm9ydCBpbiBLbX0KYmVhdS50YWJsZTwtdGFwcGx5KChlZmZiZWF1ZGlzdCREaXN0YW5jZSksKGVmZmJlYXVkaXN0JEJlYXVmb3J0KSxGVU49c3VtKQpiZWF1LnRhYmxlCmBgYAoKUGVyY2VudGFnZXMgb2YgdGhlIGRpc3RhbmNlcyB3aXRoIHJlc3BlY3QgdG8gdGhlIHRvdGFsIGRpc3RhbmNlIHRyYXZlbGVkIGluIGEgcGFydGljdWxhciBiZWF1Zm9ydCBzdGF0ZSAoZS5nLiA4MC42MyUgZGlzdGFuY2UgdHJhdmVsZWQgaW4gMC0zIHN0YXRlLCBub3RlIHRoYXQgdGhpcyBpbmNsdWRlcyBub3QganVzdCAwIGJ1dCAwLTMsIDE1LjUlIGluIGJlYXVmb3J0IDQsIDIuOTYlIGluIGJlYXVmb3J0IDUgYW5kIDAuODklIGluIGJlYXVmb3J0IDYpCmBgYHtyIEJlYXVmb3J0IFBlcmNlbnRhZ2VzfQpiZWF1Lm9uZS50d28udGhyZWUucGVyY2VudDwtcm91bmQoKChiZWF1LnRhYmxlWzFdK2JlYXUudGFibGVbMl0rYmVhdS50YWJsZVszXStiZWF1LnRhYmxlWzRdKS9zdW0oYmVhdS50YWJsZSkpKjEwMCwxKQpiZWF1Lm9uZS50d28udGhyZWUucGVyY2VudApiZWF1LmZvdXIucGVyY2VudDwtcm91bmQoKChiZWF1LnRhYmxlWzVdKS9zdW0oYmVhdS50YWJsZSkpKjEwMCwxKQpiZWF1LmZvdXIucGVyY2VudApiZWF1LmZpdmUucGVyY2VudDwtcm91bmQoKChiZWF1LnRhYmxlWzZdKS9zdW0oYmVhdS50YWJsZSkpKjEwMCwxKQpiZWF1LmZpdmUucGVyY2VudApiZWF1LnNpeC5wZXJjZW50PC1yb3VuZCgoKGJlYXUudGFibGVbN10pL3N1bShiZWF1LnRhYmxlKSkqMTAwLDEpCmJlYXUuc2l4LnBlcmNlbnQKcm0oYmVhdS50YWJsZSwgYmVhdS5vbmUudHdvLnRocmVlLnBlcmNlbnQsIGJlYXUuZm91ci5wZXJjZW50LCBiZWF1LmZpdmUucGVyY2VudCwgYmVhdS5zaXgucGVyY2VudCkKYGBgCgo8YnI+CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEVuY291bnRlciByYXRlcwoKIyMjIyMgT3ZlcmFsbCBFbmNvdW50ZXIgcmF0ZQpgYGB7ciBlbmMgcmF0ZS9kaXN0IHRvdH0KdG90ZW5jcmF0ZWRpc3Q8LXJvdW5kICgoKG5yb3cob25jZXRlbnZkYXQpL3RvdGVmZmRpc3QpKjEwMCksMikKcGFzdGUoIk92ZXJhbGwgZW5jb3VudGVyIHJhdGUgKHBlciAxMDBrbSkgb2YgY2V0YWNlYW4gZ3JvdXBzIGZvciB0aGUgZW50aXJlIHN0dWR5IGFyZWEgPSIsIHRvdGVuY3JhdGVkaXN0KQpgYGAKCiMjIyMjIFJvdXRlLXdpc2UgZW5jb3VudGVyIHJhdGUgKHBlciAxMDAga20pCgpgYGB7ciBlbmMgcmF0ZS8xMDBrbSByb3V0ZXN9CnN0ZXAxPC1hZ2dyZWdhdGUoZWZmZGF0JGRpc3QgfiBlZmZkYXQkcm91dGVubywgRlVOPXN1bSkgIyBleHRyYWN0aW5nIHN1bSBvZiBkaXN0YW5jZXMgZm9yIHJvdXRlcwpzdGVwMjwtYWdncmVnYXRlKGVmZmRhdCRuby5zaWdodCB+IGVmZmRhdCRyb3V0ZW5vLCBGVU49c3VtKSAjIGV4dHJhY3Rpbmcgc3VtIG9mIHNpZ2h0aW5ncyBmb3Igcm91dGVzCnN0ZXAzPC1zdGVwMiRgZWZmZGF0JG5vLnNpZ2h0YC9zdGVwMSRgZWZmZGF0JGRpc3RgICMgZW5jcmF0ZS9rbSBmb3IgZWFjaCByb3V0ZSA9IHNpZ2h0aW5nL2Rpc3RhbmNlIGZvciBlYWNoIHJvdXRlLCBzdGVwIGRhdGFmcmFtZXMgY2FuIGJlIHJlbW92ZWQgZnJvbSB3b3Jrc3BhY2UgYWZ0ZXIgcnVubmluZy4gCnJvdXRlX2VuY3JhdGU8LXJvdW5kKHN0ZXAzKjEwMCwyKSAjIGVuYyByYXRlL2Rpc3RhbmNlICogMTAwIGttcyBhbmQgcm91bmRlZCB0byB0d28gZGVjaW1hbCBwb2ludHMKcm0oc3RlcDEsIHN0ZXAyLCBzdGVwMykKcm91dGVfZW5jcmF0ZSA8LSBkYXRhLmZyYW1lKHJvdXRlbmFtZXMscm91dGVfZW5jcmF0ZSkKcm91dGVfZW5jcmF0ZSAKYGBgCgo8YnI+Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgU3BlY2llcyBsaXN0CgpSZWZlciB0byB0aGUgc2Vjb25kIHN1YmhlYWRpbmcgb2YgdGhlIHJlc3VsdHMgc2VjdGlvbgoKIyMjIyBTcGVjaWVzIGxpc3QgYW5kIG1vc3QgY29tbW9ubHkgc2lnaHRlZAoKRWlnaHQgdG9vdGhlZCB3aGFsZSBhbmQgb25lIGJhbGVlbiB3aGFsZSB3ZXJlIGVuY291bnRlcmVkLgoqTm90ZSo6ICpCYWxhZW5vcHRlcmEqIHNwIGlkZW50aWZpZWQgdGlsbCBnZW51cywgKlR1cnNpb3BzKiBzcCAoaW5jbHVkZXMgYWR1bmN1cyBhbmQgdHJ1bmNhdHVzKQpgYGB7ciBkaXZlcnNpdHl9CgpzcGVjaWVzPC0gYygiQmFsZWVuIHdoYWxlIiwgIkJsYWNrZmlzaCIsICJCb3R0bGVub3NlIGRvbHBoaW4iLCAiRmFsc2Uga2lsbGVyIHdoYWxlIiwgIlBpbG90IHdoYWxlIiwgIlB5Z215IGtpbGxlciB3aGFsZSIsICJSaXNzbydzIGRvbHBoaW4iLCAiU3Bpbm5lciBkb2xwaGluIiwiU3BvdHRlZCBkb2xwaGluIiwgIlN0cmlwZWQgZG9scGhpbiIsICJVbmlkZW50aWZpZWQgY2V0YWNlYW4iLCAiVW5pZGVudGlmaWVkIGRvbHBoaW4iLCAiVW5pZGVudGlmaWVkIHNtYWxsIGRvbHBoaW4iLCAiVW5pZGVudGlmaWVkIHNtYWxsIHdoYWxlIiwgIlVuaWRlbnRpZmllZCB3aGFsZSIpCgpmcmVxPC10YWJsZShjZXRlbnZkYXQkc3BlY2llcykKZnJlcTwtYXMudmVjdG9yKGZyZXEpCnNwZWNpZXNfY291bnRzPC1kYXRhLmZyYW1lKHNwZWNpZXMsIGZyZXEpCnNwZWNpZXNfY291bnRzCnJtKGZyZXEpCmBgYAoKIyMjIyBTZWFzb24td2lzZSBzcGVjaWVzIGxpc3RzCgpCYWxlZW47IEJhbGVlbiB3aGFsZTsgKkJhbGFlbm9wdGVyYSBzcCosIEJvdHRsZW5vc2U7ICpUdXJzaW9wcyBzcCosIEZhbHNlIEtpbGxlciB3aGFsZTsgKlBzZXVkb3JjYSBjcmFzc2lkZW5zKiwgcGlsb3Q7ICpHbG9iaWNlcGhhbGEgbWFjaHJvcmh5bmNodXMqLCBweWdteWtpbGxlcjsgKkZlcmVzYSBhdHRlbnVhdGEqLCByaXNzbzsgKkdyYW1wdXMgZ3Jpc2V1cyosIHNwaW5uZXI7ICogU3RlbmVsbGEgbG9uZ2lyb3N0cmlzKiwgc3BvdHRlZDsgKlN0ZW5lbGxhIGF0dGVudWF0YSosIHN0cmlwZWQ7ICpTdGVuZWxsYSBjb3J1bGVvYWxiYSosIHVuaWRjZXQ7IHVuaWRlbnRpZmllZCBjZXRhY2VhbiwgdW5pZGRvbHBoaW47IHVuaWRlbnRpZmllZCBkb2xwaGluLCB1bmlkc21hbGxkb2xwaGluOyB1bmlkZW50aWZpZWQgc21hbGwgZG9scGhpbiwgdW5pZHNtYWxsd2hhbGU7IHVuaWRlbnRpZmllZCBzbWFsbCB3aGFsZSwgdW5pZHdoYWxlOyB1bmlkZW50aWZpZWQgd2hhbGUuIAoKU3BlY2llcyBzaWdodGVkIGR1cmluZyB0aGUgbm9ydGhlYXN0IG1vbnNvb24gc2Vhc29uCmBgYHtyIHNwcyBkaXZlcnNpdHkgbmV9CiMgTm86IG9mIHNwZWNpZXMgaW4gbmUgbW9uc29vbiBzZWFzb24KdGFibGUoaWRjZXRlbnZkYXRzdGF0c25lJHNwZWNpZXMpCmBgYAoKU3BlY2llcyBzaWdodGVkIGR1cmluZyB0aGUgaW50ZXIgbW9uc29vbiBzZWFzb24KYGBge3Igc3BzIGRpdmVyc2l0eSBpbnRlcn0KIyBObzogb2Ygc3BlY2llcyBpbiBpbnRlciBtb25zb29uIHNlYXNvbgp0YWJsZShpZGNldGVudmRhdHN0YXRzaW50ZXIkc3BlY2llcykKYGBgCgo8YnI+CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIEdyb3VwIHNpemVzIChUYWJsZSAxKQoKIyMjIyBBdmVyYWdlIGdyb3VwIHNpemUsIHN0YW5kYXJkIGVycm9ycyBhbmQgbWluaW11bSBhbmQgbWF4aW11bSBncm91cCBzaXplcyBmb3IgZWFjaCBzcGVjaWVzCgpgYGB7ciBtZWFuIGdyb3VwIHNpemUgLSBzcGVjaWVzIHdpc2V9Cm1lYW5ncnBzaXplPC1yb3VuZCh0YXBwbHkoY2V0ZW52ZGF0JGdycHNpemUsY2V0ZW52ZGF0JHNwZWNpZXMsIG1lYW4sIG5hLnJtID0gVFJVRSksMikKbWVhbmdycHNpemU8LWFzLnZlY3RvcihtZWFuZ3Jwc2l6ZSkKU0VncnBzaXplPC1yb3VuZCh0YXBwbHkoY2V0ZW52ZGF0JGdycHNpemUsY2V0ZW52ZGF0JHNwZWNpZXMsIHN0ZC5lcnJvciwgbmEucm0gPSBUUlVFKSwyKQpTRWdycHNpemU8LWFzLnZlY3RvcihTRWdycHNpemUpClNFZ3Jwc2l6ZTwtcm91bmQoU0VncnBzaXplLDEpCm1pbmdycHNpemU8LXRhcHBseShjZXRlbnZkYXQkZ3Jwc2l6ZSxjZXRlbnZkYXQkc3BlY2llcywgbWluLCBuYS5ybSA9IFRSVUUpCm1pbmdycHNpemU8LWFzLnZlY3RvcihtaW5ncnBzaXplKQptYXhncnBzaXplPC10YXBwbHkoY2V0ZW52ZGF0JGdycHNpemUsY2V0ZW52ZGF0JHNwZWNpZXMsIG1heCwgbmEucm0gPSBUUlVFKQptYXhncnBzaXplPC1hcy52ZWN0b3IobWF4Z3Jwc2l6ZSkKc3BlY2llc19ncnBzaXplPC1kYXRhLmZyYW1lKHNwZWNpZXMsIG1lYW5ncnBzaXplLCBTRWdycHNpemUsIG1pbmdycHNpemUsIG1heGdycHNpemUpCnNwZWNpZXNfZ3Jwc2l6ZTwtc3BlY2llc19ncnBzaXplWzE6MTAsXQpzcGVjaWVzX2dycHNpemUKcm0obWVhbmdycHNpemUsIFNFZ3Jwc2l6ZSwgbWluZ3Jwc2l6ZSwgbWF4Z3Jwc2l6ZSkKYGBgCgoKPGJyPgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIFNlYWZsb29yIGRlcHRocyBhdCBzaWdodGluZyBsb2NhdGlvbnMoVGFibGUgMSkKCiMjIyMgQXZlcmFnZSBkZXB0aCBmb3IgY2V0YWNlYW4gc2lnaHRpbmdzIGluIHRoZSBlbnRpcmUgc3R1ZHkgYXJlYSAoaW4gbWV0cmVzKQoKYGBge3IgZGVwdGggdG90YWx9CnBhc3RlKCJBdmVyYWdlIGRlcHRoID0iLCByb3VuZChtZWFuKGNldGVudmRhdCRkZXB0aCksMiksICIrLy0iICxyb3VuZChzdGQuZXJyb3IoY2V0ZW52ZGF0JGRlcHRoKSwyKSkKcGFzdGUoIk1pbmltdW0gZGVwdGggPSIsIHJvdW5kKG1pbihjZXRlbnZkYXQkZGVwdGgpLDIpKQpwYXN0ZSgiTWF4aW11bSAgZGVwdGggPSIsIHJvdW5kKG1heChjZXRlbnZkYXQkZGVwdGgpLDIpKQpgYGAKCiMjIyMgQXZlcmFnZSBkZXB0aHMsIHN0YW5kYXJkIGVycm9ycyBhbmQgbWluaW11bSBhbmQgbWF4aW11bSBncm91cCBzaXplcyBmb3IgZWFjaCBzcGVjaWVzCmBgYHtyIGRlcHRoIHNwZWNpZXMgbWVhbn0KbWVhbmRlcHRoPC1yb3VuZCh0YXBwbHkoY2V0ZW52ZGF0JGRlcHRoLGNldGVudmRhdCRzcGVjaWVzLCBtZWFuLCBuYS5ybSA9IFRSVUUpLDIpCm1lYW5kZXB0aDwtYXMudmVjdG9yKG1lYW5kZXB0aCkKU0VkZXB0aDwtcm91bmQodGFwcGx5KGNldGVudmRhdCRkZXB0aCxjZXRlbnZkYXQkc3BlY2llcywgc3RkLmVycm9yLCBuYS5ybSA9IFRSVUUpLDIpClNFZGVwdGg8LWFzLnZlY3RvcihTRWRlcHRoKQptaW5kZXB0aDwtdGFwcGx5KGNldGVudmRhdCRkZXB0aCxjZXRlbnZkYXQkc3BlY2llcywgbWluLCBuYS5ybSA9IFRSVUUpCm1pbmRlcHRoPC1hcy52ZWN0b3IobWluZGVwdGgpCm1heGRlcHRoPC10YXBwbHkoY2V0ZW52ZGF0JGRlcHRoLGNldGVudmRhdCRzcGVjaWVzLCBtYXgsIG5hLnJtID0gVFJVRSkKbWF4ZGVwdGg8LWFzLnZlY3RvcihtYXhkZXB0aCkKc3BlY2llc19kZXB0aDwtZGF0YS5mcmFtZShzcGVjaWVzLCBtZWFuZGVwdGgsIFNFZGVwdGgsIG1pbmRlcHRoLCBtYXhkZXB0aCkKc3BlY2llc19kZXB0aDwtc3BlY2llc19kZXB0aFsxOjEwLF0Kc3BlY2llc19kZXB0aApybShtYXhkZXB0aCwgbWVhbmRlcHRoLCBtaW5kZXB0aCwgU0VkZXB0aCkKYGBgCgo8YnI+CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIENldGFjZWFuIHNpZ2h0aW5ncyBhY3Jvc3Mgc2Vhc29uIChGaWd1cmUgNCkKCkNldGFjZWFuIHNpZ2h0aW5ncyBpbiBub3J0aGVhc3QgbW9uc29vbiBhbmQgaW50ZXIgbW9uc29vbiBzZWFzb24gKG9ubHkgb24gc3VydmV5IGVmZm9ydCkKCmBgYHtyIHNlYXNvbiBhbGwgc2lnaHQgb24gZWZmb3J0fQojIG9uIGVmZm9ydCBzaWdodGluZ3MKdGFibGUob25jZXRlbnZkYXQkc2VhcykKYGBgCgpFZmZvcnQgKGluIGttKSBhY3Jvc3Mgc2Vhc29uCgpgYGB7ciBFZmZvcnQgYWNyb3NzIHNlYXNvbn0KCiMgRGlzdGFuY2VzIChlZmZvcnQpIGluIGVhY2ggc2Vhc29uCnRlc3Q8LXN1YnNldChlZmZkYXQsIGVmZmRhdCRzZWFzID09ICJuZSIpCnRlc3QyPC1zdWJzZXQoZWZmZGF0LCAhZWZmZGF0JHNlYXMgPT0gIm5lIikKcGFzdGUoIkRpc3QgKGttKSBpbiBub3J0aCBlYXN0IG1vbnNvb24gPSAiLCBzdW0odGVzdCRkaXN0KSwgImFuZCBEaXN0IChrbSkgaW4gaW50ZXIgbW9uc29vbiA9ICIsIHN1bSh0ZXN0MiRkaXN0KSkKCiMgUHJvcHJvdGlvbiBvZiBlZmZvcnQgaW4gZWFjaCBzZWFzb24KcGFzdGUoIlByb3BvcnRpb24gdHJhdmVsZWQgaW4gbm9ydGggZWFzdCBtb25zb29uID0gIiwgcm91bmQoKHN1bSh0ZXN0JGRpc3QpL3RvdGVmZmRpc3QpKjEwMCwyKSwgIiUiLCAiYW5kIFByb3BvcnRpb24gdHJhdmVsZWQgaW4gaW50ZXIgbW9uc29vbiA9ICIsIHJvdW5kKChzdW0odGVzdDIkZGlzdCkvdG90ZWZmZGlzdCkqMTAwLDIpLCAiJSIpCgpybSh0ZXN0MikKcm0odGVzdCkKYGBgCgoKIyMjIyMgQmFycGxvdCBvZiBvYnNlcnZlZCBhbmQgZXhwZWN0ZWQgY2V0YWNlYW4gc2lnaHRpbmdzIGFjcm9zcyBzZWFzb24gKG9uIHN1cnZleSBlZmZvcnQpCgpFeHBlY3RlZCByYXRpbydzIGNvcnJlc3BvbmQgdG8gZGlzdGFuY2UgdHJhdmVsZWQgaW4gYSBzZWFzb24KCmBgYHtyIHBsb3QgYWxsIHNpZ2h0IG9uIGVmZm9ydH0KcGFyKG1hciA9IGMoNyw2LDQsNCkpICMgc2V0cyB0aGUgb3V0ZXIgbWFyZ2luLCBvcmRlciA9IGxlZnQsYm90dG9tLHRvcCxyaWdodAojcGFyKG9tYT1jKDAsMCwwLDUuOCkpCm9ic2V4cHNlYXM8LWFzLm1hdHJpeChkYXRhLmZyYW1lKGludGVyPWMoMjcsIDQzLjQxKSwgbmU9Yyg1MSwzNC41OSkpKSAjIGNyZWF0aW5nIGEgbWF0cml4IHdpdGggb2JzZXJ2ZWQgYW5kIGV4cGVjdGVkIGNldGFjZWFuIHNpZ2h0aW5nIHZhbHVlcyBmb3IgaW50ZXJtb25zb29uICgyNyAmIDQzLjQxKSBhbmQgbmUgbW9uc29vbiAoNTEsMzQuNTkpCm9uc2Vhc2JhcnBsb3Q8LWJhcnBsb3Qob2JzZXhwc2VhcywgYmVzaWRlPVRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC41LCAKICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gIlNlYXNvbiIsIAogICAgICAgICAgICAgICAgICAgICAgIHlsYWI9Ik5vOiBvZiBjZXRhY2VhbiBzaWdodGluZ3MiLCAKICAgICAgICAgICAgICAgICAgICAgICBuYW1lcy5hcmc9YygiSW50ZXIgbW9uc29vbiAobj0yNykiLCJOb3J0aGVhc3QgbW9uc29vbiAobj01MSkiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgY2V4LmxhYiA9IDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgY2V4LmF4aXMgPSAxLCAKICAgICAgICAgICAgICAgICAgICAgICBjZXgubmFtZXMgPSAwLjcsIAogICAgICAgICAgICAgICAgICAgICAgIGNvbD1jKCJncmV5ODAiLCAiZ3JleTIwIiksIAogICAgICAgICAgICAgICAgICAgICAgIGRlbnNpdHkgPSBjKDEwMCwxMDApLCAKICAgICAgICAgICAgICAgICAgICAgICB5bGltID0gYygwLDgwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgeGxpbT1jKDAuMyw1KSkKbGVnZW5kKCJ0b3BsZWZ0IiwgIGMoIkNldGFjZWFuIHNpZ2h0aW5ncyBvbiBzdXJ2ZXkiLCAiRXhwZWN0ZWQgY2V0YWNlYW4gc2lnaHRpbmcgYmFzZWQgb24gZWZmb3J0IiksIGZpbGwgPSBjKCJncmV5ODAiLCAiZ3JleTIwIiksIGNleD0wLjcsIGJ0eT0nbicpCmBgYAoKIyMjIyMgTm9uIHBhcmFtZXRlcmljIHN0YXRpc3RpY2FsIHRlc3QgLSBDaGktU3F1YXJlIEdvb2RuZXNzIG9mIEZpdAoKQ2hpIHNxdWFyZSBnb29kbmVzcyBvZiBmaXQgdGVzdCBiZXR3ZWVuIG9ic2VydmVkIGFuZCBleHBlY3RlZCB2YWx1ZXMuIEV4cGVjdGVkIHZhbHVlcyBhcmUgY2FsY3VsYXRlZCBhcyBlZmZvcnQgKGRpc3RhbmNlIHRyYXZlbGVkIGluIGVhY2ggc2Vhc29uKS4gVGhlIHRlc3QgaXMgc2lnbmlmaWNhbnQgYW5kIHRoZSBudWxsIGh5cG90aGVzaXMgaXMgcmVqZWN0ZWQuIAoKTnVsbCBoeXBvdGhlaXM6IFNpZ2h0aW5ncyBhcmUgZXF1YWxseSBkaXN0cmlidXRlZCBhY3Jvc3MgdGhlIHR3byBzZWFzb25zIGFzIHBlciB0aGUgZGlzdGFuY2UgdHJhdmVsZWQgZHVyaW5nIHN1cnZleSBlZmZvcnQuCgpBbHRlcm5hdGUgSHlwb3RoZXNpczogU2lnaHRpbmdzIGFyZSBkaWZmZXJlbnRpYWxseSBkaXN0cmlidXRlZCBhY3Jvc3MgdGhlIHR3byBzZWFzb25zIGFzIHBlciB0aGUgZGlzdGFuY2UgdHJhdmVsZWQgZHVyaW5nIHN1cnZleSBlZmZvcnQuCgpgYGB7ciBjaGkgc3F1YXJlIGdvb2RuZXNzIG9uIGVmZm9ydCBhbGwgc2lnaHRpbmdzfQojIGNoaSBzcXVhcmUgdGVzdCBmb3Igb24gZWZmb3J0IHNpZ2h0aW5ncyBpbiBlYWNoIHNlYXNvbiAtIGdvb2RuZXNzIG9mIGZpdCBhY2NvcmRpbmcgdG8gZGlzdGFuY2UgdHJhdmVsZWQKZWZmZGF0bmU8LXN1YnNldChlZmZkYXQsIGVmZmRhdCRzZWFzID09ICduZScpICMgZWZmb3J0IGRhdGFzZXQgZm9yIG9ubHkgbmUgbW9uc29vbgplZmZkYXRpbnRlcjwtc3Vic2V0KGVmZmRhdCwgZWZmZGF0JHNlYXMgPT0gJ2ludGVyJykgIyBlZmZvcnQgZGF0YXNldCBmb3Igb25seSBpbnRlciBtb25zb29uCnRvdGVmZmRpc3RuZTwtc3VtKGVmZmRhdG5lJGRpc3QpICMgdG90YWwgZGlzdGFuY2UgdHJhdmVsZWQgZm9yIG5vcnRoZWFzdCBtb25zb29uCnRvdGVmZmRpc3RpbnRlcjwtc3VtKGVmZmRhdGludGVyJGRpc3QpICMgdG90YWwgZGlzdGFuY2UgdHJhdmVsZWQgZm9yIGludGVyIG1vbnNvb24KIyB0YWJsZShvbmNldGVudmRhdCRzZWFzKSAjIHNpZ2h0aW5ncyBwZXIgc2Vhc29uIG9uIGVmZm9ydAojIGNoaXNxdWFyZSBnb29kbmVzcyBvZiBmaXQgdGVzdCBmb3Igbm86IG9mIHNpZ2h0aW5ncyBpbiBlYWNoIHNlYXNvbiB0byBleHBlY3RlZCBudW1iZXIgb2Ygc2lnaHRpbmdzIGJhc2VkIG9uIGRpc3RhbmNlIHRyYXZlbGxlZC4KdGFibGUob25jZXRlbnZkYXQkc2VhcykKc2Vhc2FsbGNoaXNxPC1jaGlzcS50ZXN0KCAodGFibGUob25jZXRlbnZkYXQkc2VhcykpLAogICAgICAgICAgICAgcD1jKCh0b3RlZmZkaXN0aW50ZXIvdG90ZWZmZGlzdCksKHRvdGVmZmRpc3RuZS90b3RlZmZkaXN0KSkgKSAKc2Vhc2FsbGNoaXNxCnBhc3RlKCdFeHBlY3RlZCB2YWx1ZSBmb3IgaW50ZXIgbW9uc29vbiBwZXJpb2QgaXMnLCByb3VuZChzZWFzYWxsY2hpc3EkZXhwZWN0ZWRbMV0sMikpCnBhc3RlKCdFeHBlY3RlZCB2YWx1ZXMgZm9yIG5vcnRoIGVhc3QgbW9uc29vbiBpcycsIHJvdW5kKHNlYXNhbGxjaGlzcSRleHBlY3RlZFsyXSwyKSkKIyBmb3JtdWxhIGNoaS5zcS50ZXN0ICggbm86IG9mIHNlYXMgc2lnaHRpbmdzIDI3IChpbnRlciksIDUxKG5lKSwgcHJvYmFiaWxpdHkgPSAwLjU1NjUwNjggKGludGVyKSwgMC40NDM0OTMyIChuZSkgKQoKYGBgCgo8YnI+CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIENldGFjZWFuIHNwZWNpZXMgYWNyb3NzIGRpc3RhbmNlIHRvIG5lYXJlc3QgbGFuZG1hc3MKCiMjIyMjIEJveHBsb3Qgb2YgZGlzdGFuY2UgdG8gbmVhcmVzdCBsYW5kbWFzcyBmb3IgYWxsIHNwZWNpZXMKClNwZWNpZXMgY29kZXM7IGJhbCA9IEJhbGVlbiB3aGFsZSwgVCA9IEJvdHRsZW5vc2UgZG9scGhpbiwgUEMgPSBGYWxzZSBraWxsZXIgd2hhbGUsIEdNID0gU2hvcnQgZmlubmVkIHBpbG90IHdoYWxlLCBGQSA9IFBneW15IGtpbGxlciB3aGFsZSwgR0cgPSBSaXNzb3MgZG9scGhpbiwgU0wgPSBTcGlubmVyIGRvbHBoaW4sIFNBID0gU3BvdHRlZCBkb2xwaGluLCBTQyA9IFN0cmlwZWQgZG9scGhpbgpgYGB7ciBuZWFyZXN0IGRpc3RhbmNlfQpwYXIobWFyID0gYyg1LDUsMywzKSkgIyBzZXRzIHRoZSBvdXRlciBtYXJnaW4sIG9yZGVyID0gbGVmdCxib3R0b20sdG9wLHJpZ2h0Cm5lYXJkaXN0Ym94cGxvdDwtYm94cGxvdChpZGNldGVudmRhdHN0YXRzJG5lYXJkaXN0a21+aWRjZXRlbnZkYXRzdGF0cyRzcGVjaWVzLCB4bGFiID0gIlNwZWNpZXMgKG4pIiwgeWxhYj0iTmVhcmVzdCBkaXN0YW5jZSAoa20pIiwgbWFpbiA9ICJOZWFyZXN0IGRpc3RhbmNlIHRvIGxhbmQgZm9yIGVhY2ggc3BlY2llcyIsIG5hbWVzPWMoIlQgKDE4KSIsIlBDKDQpIiwiR00oMTMpIiwiR0coNykiLCJTTCgyMikiLCJTQSgzKSIsIlNDKDUpIiksIGNleC5sYWIgPSAxLjIsIGNleC5tYWluID0gMSwgY29sPSJtZWRpdW1hcXVhbWFyaW5lIikKIyBzcGVjaWVzIGNvZGVzOyBiYWwgPSBCYWxlZW4gd2hhbGUsIFQgPSBCb3R0bGVub3NlIGRvbHBoaW4sIFBDID0gRmFsc2Uga2lsbGVyIHdoYWxlLCBHTSA9IFNob3J0IGZpbm5lZCBwaWxvdCB3aGFsZSwgRkEgPSBQZ3lteSBraWxsZXIgd2hhbGUsIEdHID0gUmlzc29zIGRvbHBoaW4sIFNMID0gU3Bpbm5lciBkb2xwaGluLCBTQSA9IFNwb3R0ZWQgZG9scGhpbiwgU0MgPSBTdHJpcGVkIGRvbHBoaW4KYGBgCgojIyMjIyBOb24gcGFyYW1ldGVyaWMgc3RhdGlzdGljYWwgdGVzdCAtIEtydXNrYWwtV2FsbGlzIHRlc3QKCk51bGwgaHlwb3RoZXNpczogQWxsIHNwZWNpZXMgYXJlIHVuaWZvcm1seSBkaXN0cmlidXRlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIG5lYXJlc3QgbGFuZG1hc3Mgb24gdGhlIGZlcnJ5IHJvdXRlcy4KCkFsdGVybmF0ZSBoeXBvdGhlc2lzOiBTcGVjaWVzIGFyZSBkaWZmZXJlbnRpYWxseSBkaXN0cmlidXRlZCB3aXRoIHJlc3BlY3QgdG8gdGhlIG5lYXJlc3QgbGFuZG1hc3Mgb24gdGhlIGZlcnJ5IHJvdXRlcy4gCgpLcnVza2FsIFdhbGxpcyB0ZXN0IHdhcyBwZXJmb3JtZWQgYW5kIHRlc3Qgd2FzIHNpZ25pZmljYW50LiBUaGVyZWZvcmUgdGhlIE51bGwgaHlwb3Roc2lzIGlzIHJlamVjdGVkLgoKYGBge3Igbm9uIHBhcmEgbmVhcmRpc3QgYWxsIHNwc30KCiMgZm9yIGFsbCBzcHMgKGV4Y2VwdCBiYWxlZW4gYW5kIHB5Z215KQprcnVza2FsLnRlc3QoYXMuZmFjdG9yKGlkY2V0ZW52ZGF0c3RhdHMkbmVhcmRpc3RrbSl+YXMuZmFjdG9yKGlkY2V0ZW52ZGF0c3RhdHMkc3BlY2llcyksIGRhdGE9aWRjZXRlbnZkYXRzdGF0cykKYGBgCgoKTWVkaWFucyBmb3IgbmVhcmVzdCBhbmQgZnVydGhlc3Qgc3BlY2llcwoKYGBge3IgTWVkaWFucyBmb3IgbmVhcmVzdCBhbmQgZnVydGhlc3Qgc3BlY2llc30KcGFzdGUgKCJTcGlubmVyIGRvbHBoaW5zIG1lZGlhbiAoaW4ga20pID0iLCByb3VuZChuZWFyZGlzdGJveHBsb3Qkc3RhdHNbMyw1XSwyKSkKcGFzdGUgKCJTcG90dGVkIGRvbHBoaW5zIG1lZGlhbiAoaW4ga20pID0iLCByb3VuZChuZWFyZGlzdGJveHBsb3Qkc3RhdHNbMyw2XSwyKSkKcGFzdGUgKCJTdHJpcGVkIGRvbHBoaW5zIG1lZGlhbiAoaW4ga20pID0iLCByb3VuZChuZWFyZGlzdGJveHBsb3Qkc3RhdHNbMyw3XSwyKSkKYGBgCgo8YnI+Ci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgQ2V0YWNlYW4gc3BlY2llcyBhY3Jvc3Mgc2VhZmxvb3Igc2xvcGUgZ3JhZGllbnQKCiMjIyMjIEJveHBsb3Qgb2Ygc2xvcGUgZGlzdHJpYnV0aW9uIGZvciBhbGwgc3BlY2llcwoKU3BlY2llcyBjb2RlczsgYmFsID0gQmFsZWVuIHdoYWxlLCBUID0gQm90dGxlbm9zZSBkb2xwaGluLCBQQyA9IEZhbHNlIGtpbGxlciB3aGFsZSwgR00gPSBTaG9ydCBmaW5uZWQgcGlsb3Qgd2hhbGUsIEZBID0gUGd5bXkga2lsbGVyIHdoYWxlLCBHRyA9IFJpc3NvcyBkb2xwaGluLCBTTCA9IFNwaW5uZXIgZG9scGhpbiwgU0EgPSBTcG90dGVkIGRvbHBoaW4sIFNDID0gU3RyaXBlZCBkb2xwaGluCgpgYGB7ciBzbG9wZSBwbG90IGFsbCBzcGVjaWVzfQpwYXIobWFyID0gYyg1LDUsMywzKSkgIyBzZXRzIHRoZSBvdXRlciBtYXJnaW4sIG9yZGVyID0gbGVmdCxib3R0b20sdG9wLHJpZ2h0CnNsb3BlYm94cGxvdDwtYm94cGxvdChpZGNldGVudmRhdHN0YXRzJHNsb3BlfmlkY2V0ZW52ZGF0c3RhdHMkc3BlY2llcywgeGxhYiA9ICJTcGVjaWVzIChuKSIsIHlsYWI9IlNsb3BlIiwgbWFpbiA9ICJTbG9wZSBkaXN0cmlidXRpb24gZm9yIGVhY2ggc3BlY2llcyIsIG5hbWVzPWMoIlQgKDE4KSIsIlBDKDQpIiwiR00oMTMpIiwgIkdHKDcpIiwiU0woMjIpIiwiU0EoMykiLCJTQyg1KSIpLCBjZXgubGFiID0gMS4yLCBjZXgubWFpbiA9IDEsIGNvbD0ibWVkaXVtYXF1YW1hcmluZSIpCiMgc3BlY2llcyBjb2RlczsgYmFsID0gQmFsZWVuIHdoYWxlLCBUID0gQm90dGxlbm9zZSBkb2xwaGluLCBQQyA9IEZhbHNlIGtpbGxlciB3aGFsZSwgR00gPSBTaG9ydCBmaW5uZWQgcGlsb3Qgd2hhbGUsIEZBID0gUGd5bXkga2lsbGVyIHdoYWxlLCBHRyA9IFJpc3NvcyBkb2xwaGluLCBTTCA9IFNwaW5uZXIgZG9scGhpbiwgU0EgPSBTcG90dGVkIGRvbHBoaW4sIFNDID0gU3RyaXBlZCBkb2xwaGluCmBgYAoKIyMjIyMgTm9uIHBhcmFtZXRlcmljIHN0YXRpc3RpY2FsIHRlc3QgLSBLcnVza2FsLVdhbGxpcyB0ZXN0CgpOdWxsIGh5cG90aGVzaXM6IEFsbCBzcGVjaWVzIGFyZSB1bmlmb3JtbHkgZGlzdHJpYnV0ZWQgYWNyb3NzIHNsb3BlIGdyYWRpZW50cyBhbG9uZyB0aGUgZmVycnkgcm91dGVzLgoKQWx0ZXJuYXRlIGh5cG90aGVzaXM6IFNwZWNpZXMgYXJlIGRpZmZlcmVudGlhbGx5IGRpc3RyaWJ1dGVkIGFjcm9zcyBzbG9wZSBncmFkaWVudHMgYWxvbmcgdGhlIGZlcnJ5IHJvdXRlcy4gCgpLcnVza2FsIFdhbGxpcyB0ZXN0IHdhcyBwZXJmb3JtZWQgYW5kIHRlc3Qgd2FzIHNpZ25pZmljYW50LiBUaGVyZWZvcmUgdGhlIE51bGwgaHlwb3Roc2lzIGlzIHJlamVjdGVkLgoKYGBge3Igbm9uIHBhcmEgc2xvcGUgYWxsIHNwZWNpZXN9CiMgZm9yIGNvbW1vbiBzcHMKa3J1c2thbC50ZXN0KGFzLmZhY3RvcihpZGNldGVudmRhdHN0YXRzJHNsb3BlKX5hcy5mYWN0b3IoaWRjZXRlbnZkYXRzdGF0cyRzcGVjaWVzKSwgZGF0YT1pZGNldGVudmRhdHN0YXRzKQoKYGBgCgpNZWRpYW5zIGZvciBzcGVjaWVzIGluIHRoZSBmbGF0ZXN0IGFuZCBzdGVlcGVzdCBzbG9wZXMKCmBgYHtyIE1lZGlhbnMgZm9yIGZsYXQgYW5kIHN0ZWVwIHNsb3BlIHNwZWNpZXN9CnBhc3RlICgiU3Bpbm5lciBkb2xwaGlucyBtZWRpYW4gc3RlZXBlc3Qgc2xvcGUgPSIsIHJvdW5kKHNsb3BlYm94cGxvdCRzdGF0c1szLDVdLDIpKQpwYXN0ZSAoIlNwb3R0ZWQgZG9scGhpbnMgbWVkaWFuIGZsYXQgc2xvcGUgPSIsIHJvdW5kKHNsb3BlYm94cGxvdCRzdGF0c1szLDZdLDIpKQpwYXN0ZSAoIlN0cmlwZWQgZG9scGhpbnMgbWVkaWFuIGZsYXQgc2xvcGUgPSIsIHJvdW5kKHNsb3BlYm94cGxvdCRzdGF0c1szLDddLDIpKQpgYGAKCjxicj4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBDZXRhY2VhbiBzcGVjaWVzIGFjcm9zcyBzZWFmbG9vciBkZXB0aAoKIyMjIyMgQm94cGxvdCBiZXR3ZWVuIGNldGFjZWFuIHNwZWNpZXMgYW5kIHNlYWZsb29yIGRlcHRoIAoKU3BlY2llcyBjb2RlczsgYmFsID0gQmFsZWVuIHdoYWxlLCBUID0gQm90dGxlbm9zZSBkb2xwaGluLCBQQyA9IEZhbHNlIGtpbGxlciB3aGFsZSwgR00gPSBTaG9ydCBmaW5uZWQgcGlsb3Qgd2hhbGUsIEZBID0gUGd5bXkga2lsbGVyIHdoYWxlLCBHRyA9IFJpc3NvcyBkb2xwaGluLCBTTCA9IFNwaW5uZXIgZG9scGhpbiwgU0EgPSBTcG90dGVkIGRvbHBoaW4sIFNDID0gU3RyaXBlZCBkb2xwaGluCgpgYGB7ciBkZXB0aCBwbG90IGFsbCBzcGVjaWVzfQoKIyBBbGwgc3BlY2llcyBhbmQgZGVwdGgKcGFyKG1hciA9IGMoNSw1LDMsMykpICMgc2V0cyB0aGUgb3V0ZXIgbWFyZ2luLCBvcmRlciA9IGxlZnQsYm90dG9tLHRvcCxyaWdodApkZXB0aGJveHBsb3Q8LWJveHBsb3QoaWRjZXRlbnZkYXRzdGF0cyRkZXB0aH5pZGNldGVudmRhdHN0YXRzJHNwZWNpZXMsIHhsYWIgPSAiU3BlY2llcyAobikiLCB5bGFiPSJTZWFmbG9vciBkZXB0aChtKSIsIG1haW4gPSAiU2VhZmxvb3IgZGVwdGggZGlzdHJpYnV0aW9uIGZvciBlYWNoIHNwZWNpZXMiLCBuYW1lcz1jKCJUICgxOCkiLCJQQyg0KSIsIkdNKDEzKSIsIkdHKDcpIiwiU0woMjIpIiwiU0EoMykiLCJTQyg1KSIpLCBjZXgubGFiID0gMS4yLCBjZXgubWFpbiA9IDEsIGNvbD0ibWVkaXVtYXF1YW1hcmluZSIpICMgeGxhYiA9IHggbGFiZWwsIHlsYWIgPSB5IGxhYmVsLCBjZXgubGFiID0gbGFiZWwgZm9udCBzaXplLCBjZXgubWFpbiA9IHRpdGxlIGZvbnQgc2l6ZSwgbWFpbiA9IHRpdGxlCiMgc3BlY2llcyBjb2RlczsgYmFsID0gQmFsZWVuIHdoYWxlLCBUID0gQm90dGxlbm9zZSBkb2xwaGluLCBQQyA9IEZhbHNlIGtpbGxlciB3aGFsZSwgR00gPSBTaG9ydCBmaW5uZWQgcGlsb3Qgd2hhbGUsIEZBID0gUGd5bXkga2lsbGVyIHdoYWxlLCBHRyA9IFJpc3NvcyBkb2xwaGluLCBTTCA9IFNwaW5uZXIgZG9scGhpbiwgU0EgPSBTcG90dGVkIGRvbHBoaW4sIFNDID0gU3RyaXBlZCBkb2xwaGluCmBgYAoKIyMjIyMgTm9uIHBhcmFtZXRlcmljIHN0YXRpc3RpY2FsIHRlc3Qgc3BlY2llcyBhbmQgZGVwdGggLSBLcnVza2FsLVdhbGxpcyB0ZXN0CgpOdWxsIGh5cG90aGVzaXM6IEFsbCBzcGVjaWVzIGFyZSB1bmlmb3JtbHkgZGlzdHJpYnV0ZWQgYXdheSBhY3Jvc3Mgc2VhZmxvb3IgZGVwdGhzLgoKQWx0ZXJuYXRlIGh5cG90aGVzaXM6IFNwZWNpZXMgYXJlIGRpZmZlcmVudGlhbGx5IGRpc3RyaWJ1dGVkIGFjcm9zcyBzZWFmbG9vciBkZXB0aHMuIAoKS3J1c2thbCBXYWxsaXMgdGVzdCB3YXMgcGVyZm9ybWVkIGFuZCB0ZXN0IHdhcyBub3Qgc2lnbmlmaWNhbnQuIFRoZXJlZm9yZSB0aGUgTnVsbCBoeXBvdGhzaXMgaXMgbm90IHJlamVjdGVkLgoKYGBge3IgZGVwdGggbm9uIHBhcmEgYWxsIHNwZWNpZXN9CgojIGZvciBhbGwgc3BzIChleGNlcHQgYmFsZWVuIGFuZCBweWdteSkKa3J1c2thbC50ZXN0KGFzLmZhY3RvcihpZGNldGVudmRhdHN0YXRzJGRlcHRoKX5hcy5mYWN0b3IoaWRjZXRlbnZkYXRzdGF0cyRzcGVjaWVzKSwgZGF0YT1pZGNldGVudmRhdHN0YXRzKQpgYGAKCjxicj4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBQbG90IG9mIGNldGFjZWFuIHNwZWNpZXMgYWNyb3NzIG5lYXJlc3QgZGlzdGFuY2UgdG8gbGFuZCBhbmQgc2xvcGUgZ3JhZGllbnQgKEZpZ3VyZSA1KQoKYGBge3IgU2xvcGUgYW5kIG5lYXJlc3QgZGlzdGFuY2UgdG8gbGFuZCBhY3Jvc3Mgc3BlY2llc30KIyMjIFBsb3R0aW5nIHNpZ25pZmljYW50IHJlc3VsdHMgdG9nZXRoZXIgCiMjIyMjIFNsb3BlIGFuZCBuZWFyZXN0IGRpc3RhbmNlIHRvIGxhbmQgYWNyb3NzIHNwZWNpZXMKCiMgY29sbGFwc2UgdGhlIGRhdGEgZnJhbWUKeDwtbWVsdChkYXRhID0gaWRjZXRlbnZkYXRzdGF0cywgaWQudmFycyA9ICJzcGVjaWVzIiwgbWVhc3VyZS52YXJzID0gYygic2xvcGUiLCAibmVhcmRpc3RrbSIpKQpyZXF1aXJlKGdncGxvdDIpCnNsb3BlZGlzdHBsb3Q8LWdncGxvdChkYXRhID0geCwgYWVzKHg9c3BlY2llcywgeT12YWx1ZSkpICsgCiAgIyBzcGVjaWZ5IGJveHBsb3QgYW5kIHZhcmlhYmxlIHRvIGJlIGZpbGxlZCBpbiB0aGlzIGNhc2UgJ3Nsb3BlJyAmICduZWFyZGlzdCcKICBnZW9tX2JveHBsb3QoYWVzKGZpbGw9dmFyaWFibGUpKSArCiAgIyBuYW1lIHggYW5kIHkgYXhpcwogIHhsYWIoIlNwZWNpZXMgKG4pIikgKyB5bGFiKCJTbG9wZSAocGVyY2VudCkiKSArCiAgIyBhZGQgYSBzZWNvbmQgeSBheGlzIG9uIHRoZSByaWdodCBhbmQgc3BlY2lmeSB2YWx1ZXMgdy5yLnQgdG8geCBheGlzICgqMXgpCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofi4qMSwgbmFtZSA9ICJEaXN0YW5jZSB0byBuZWFyZXN0IGxhbmQgKGttKSIpKSArCiAgCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9OTApKSArCiAgCiAgdGhlbWUocGxvdC5tYXJnaW49dW5pdChjKDEsMC44LDAuNSwwLjUpLCJjbSIpKSArCiAgCiAgIyBjaGFuZ2UgdGhlIGxlZ2VuZCBsYWJlbHMKICBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9IiIsIGxhYmVscz1jKCJTbG9wZSIsICJEaXN0YW5jZSB0byBuZWFyZXN0IGxhbmQiKSkgKwogICMgY2hhbmdlIHRoZSBsZWdlbmQgcG9zaXRpb24gKDAsMCkgPSBib3R0b20gbGVmdCAmICgxLDEpID0gdG9wIHJpZ2h0CiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYygwLjE2LCAwLjkpKSArCiAgIyBzaXplIG9mIGxlZ2VuZCB0ZXh0CiAgdGhlbWUobGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9cmVsKDAuNSkpKSArCiAgIyByZW1vdmUgdGhlIGxlZ2VuZCBiYWNrZ3JvdW5kCiAgdGhlbWUobGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCkpICsKICAjIGFkZGluZyBzYW1wbGUgc2l6ZXMgdG8gdGhlIHBsb3QKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJib3R0bGVub3NlIiA9ICJib3R0bGVub3NlIGRvbHBoaW4gKDE4KSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmFsc2VraWxsZXIiID0gImZhbHNlIGtpbGxlciB3aGFsZSg0KSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwaWxvdCIgPSAicGlsb3Qgd2hhbGUoMTMpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyaXNzbyIgPSAiUmlzc28ncyBkb2xwaGluICg3KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3Bpbm5lciIgPSJzcGlubmVyIGRvbHBoaW4oMjIpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzcG90dGVkIiA9InNwb3R0ZWQgZG9scGhpbigzKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3RyaXBlZCIgPSAic3RyaXBlZCBkb2xwaGluKDUpIikpIAojc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sc2hhcGU9MSxjb2w9J3JlZCcsZ2VvbT0ncG9pbnQnKQoKc2xvcGVkaXN0cGxvdApybSh4KQoKCmBgYAoKCjxicj4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMgUm91dGUgSW5mb3JtYXRpb24KYGBge3IgUm91dGUgaW5mb3JtYXRpb259CnN0ZXAxPC10YWJsZShlZmZkYXQkcm91dGUpICMgTm8uIG9mIHRpbWVzIGEgcm91dGUgd2FzIHRyYXZlcnNlZApzdGVwMTwtc3RlcDFbYygxLDgsMyw5LDUsNiwxMCw0LDcsMTEsMiwxMildICMgcmVvcmRlciB0byBtYXRjaCBjb3JyZXNwb25kaW5nIGNvbHVtbnMgaW4gcm91dGVfZW5jcmF0ZSBkYXRhZnJhbWUKc3RlcDE8LWFzLnZlY3RvcihzdGVwMSkgIyBtYWtpbmcgaW50byBhIHZlY3RvcgpzdGVwMjwtYWdncmVnYXRlKGVmZmRhdCRkaXN0IH4gZWZmZGF0JHJvdXRlbm8sIEZVTj1zdW0pICMgZXh0cmFjdGluZyBzdW0gb2YgZGlzdGFuY2VzIGZvciByb3V0ZXMKc3RlcDM8LWFnZ3JlZ2F0ZShlZmZkYXQkbm8uc2lnaHQgfiBlZmZkYXQkcm91dGVubywgRlVOPXN1bSkgIyBleHRyYWN0aW5nIHN1bSBvZiBzaWdodGluZ3MgZm9yIHJvdXRlcwpyb3V0ZV9pbmZvPC1kYXRhLmZyYW1lKHJvdXRlX2VuY3JhdGUsIHN0ZXAxLCBzdGVwMiwgc3RlcDMpICMgTWFraW5nIGEgZGF0YSBmcmFtZSB3aXRoIHJvdXRlIG5vLCByb3V0ZSBuYW1lLCBubzogb2YgdGltZXMgYSByb3V0ZSB3YXMgdHJhbnZlcnNlZCwgcm91dGUgZGlzdGFuY2UsIHJvdXRlIHNpZ2h0aW5ncyBhbmQgcm91dGUgZW5jIHJhdGUKcm91dGVfaW5mbzwtcm91dGVfaW5mb1tjKDEsMiw0LDYsOCwzKV0gIyByZW9yZGVyCmNvbG5hbWVzKHJvdXRlX2luZm8pPC1jKCJSb3V0ZSBOby4iLCAiUm91dGUgbmFtZSIsICJOby4gb2YgdGltZXMiLCAiRGlzdGFuY2UgKGttKSIsICJOby4gb2Ygc2lnaHRpbmdzIiwgIkVuY291bnRlciByYXRlIikKcm91dGVfaW5mbwpybShzdGVwMSwgc3RlcDIsIHN0ZXAzKQojd3JpdGUuY3N2KHJvdXRlX2luZm8sIGZpbGUgPSAiL1ZvbHVtZXMvR29vZ2xlRHJpdmUvTXkgRHJpdmUvTGFrc2ggSSBwcm9qZWN0L2Rlc2lnbiAmIGRhdGEvRGF0YSBFbnRyeS9MYWtzaCBSIGZpbGVzL1Bhbmlja2VyXzIwMTlfTERfYW5hbHlzaXNfbWFudXNjcmlwdF9saW5rL1NpZ2h0aW5ncyBhbmQgZWZmb3J0IGZvciBlYWNoIHJvdXRlLmNzdiIpCmBgYAoKPGJyPgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyBUSEUgRU5ECgoKCgoKCgo=