Introduction
Status and development of European ground squirrel populations in
agricultural land of southern Moravia
In Hrusovany and Pavlovice, there are patches that have been divided
into habitat categories, such as orchards and vineyards, and categories
of vegetation management, such as mowed or ploughed. The density of
ground squirrel burrow openings is also recorded for each patch.
Library
# install.packages("pacman")
# writeLines(pacman::p_lib(), "~/Desktop/list_of_R_packages.csv") # to quickly back up packages
# remotes::install_github("ThinkR-open/remedy")
# install.packages("remotes")
# remotes::install_github("statnmap/cartomisc")
pacman::p_load(rio, tidyverse,janitor, data.table, here, stringr, stats, gridExtra, vtable, tableone, skimr,
ggstats,
ggstatsplot,
ggdist,
gghalves,
plyr,
Hmisc,
RColorBrewer,
reshape2,
dplyr,
cli,
introdataviz,
kableExtra
) # just add needed packages to this line and Pacman will install and load them.
# devtools::install_github("psyteachr/introdataviz")
Data
hru <- import( here::here("data","hrusovany_densities.csv")) %>%
janitor::clean_names()%>%
mutate_if(is.character, str_to_title) %>%
mutate(habitat = ifelse(habitat == "Backyard", "Garden", habitat)) %>%
mutate(habitat = ifelse(habitat == "Tree Avenue", "Tree Alley", habitat)) %>%
mutate(habitat = ifelse(habitat == "Mowed Lawn", "Short-cut Lawn", habitat)) %>%
dplyr::mutate(habitat = if_else(habitat == "Vineyards", "Vineyard", habitat)) %>%
dplyr::mutate(district ="Hrušovany") %>%
mutate_if(is.character, as.factor)
summary(hru)
## district id habitat management
## Hrušovany:171 Min. : 3.0 Orchard :58 Fallow : 4
## 1st Qu.: 53.5 Vineyard :49 Mowed :65
## Median :102.0 Crop Field :20 No Management :30
## Mean :101.8 Garden :13 Ploughed :69
## 3rd Qu.:144.5 Steppe Grassland:10 Ploughed/Mowed: 3
## Max. :219.0 Shrubland : 9
## (Other) :12
## size_ha bo density
## Min. :0.01464 Min. : 0.000 Min. : 0.00
## 1st Qu.:0.06965 1st Qu.: 0.000 1st Qu.: 0.00
## Median :0.13528 Median : 0.000 Median : 0.00
## Mean :0.20014 Mean : 4.228 Mean : 21.35
## 3rd Qu.:0.21022 3rd Qu.: 3.000 3rd Qu.: 27.45
## Max. :1.66754 Max. :192.000 Max. :378.10
##
vp <- import( here::here("data","vp_densities.csv"))%>%
janitor::clean_names() %>%
dplyr::mutate(district = "Pavlovice", .before= "id")%>%
mutate_if(is.character, str_to_title) %>%
mutate(habitat = ifelse(habitat == "Backyard", "Garden", habitat)) %>%
mutate(habitat = ifelse(habitat == "Tree Avenue", "Tree Alley", habitat)) %>%
mutate(habitat = ifelse(habitat == "Mowed Lawn", "Short-cut Lawn", habitat)) %>%
dplyr::mutate(habitat = if_else(habitat == "Vineyards", "Vineyard", habitat)) %>%
mutate_if(is.character, as.factor)
summary(vp)
## district id habitat management
## Pavlovice:840 Min. : 1.0 Vineyard :286 Fallow : 27
## 1st Qu.:228.8 Orchard :213 Grazed : 4
## Median :458.5 Crop Field :102 Mowed :344
## Mean :461.9 Garden : 68 No Management :123
## 3rd Qu.:688.2 Short-cut Lawn: 63 Ploughed :307
## Max. :940.0 Shrubland : 54 Ploughed/Mowed: 35
## (Other) : 54
## size_ha bo density
## Min. : 0.0174 Min. : 0.0000 Min. : 0.000
## 1st Qu.: 0.1105 1st Qu.: 0.0000 1st Qu.: 0.000
## Median : 0.2215 Median : 0.0000 Median : 0.000
## Mean : 0.5068 Mean : 0.5667 Mean : 1.368
## 3rd Qu.: 0.4696 3rd Qu.: 0.0000 3rd Qu.: 0.000
## Max. :25.4100 Max. :30.0000 Max. :77.700
##
colonies <- rbind(hru, vp) %>%
dplyr::mutate(district = as.factor(district))
summary(colonies)
## district id habitat management
## Hrušovany:171 Min. : 1.0 Vineyard :335 Fallow : 31
## Pavlovice:840 1st Qu.:142.0 Orchard :271 Mowed :409
## Median :366.0 Crop Field :122 No Management :153
## Mean :401.0 Garden : 81 Ploughed :376
## 3rd Qu.:645.5 Short-cut Lawn: 71 Ploughed/Mowed: 38
## Max. :940.0 Shrubland : 63 Grazed : 4
## (Other) : 68
## size_ha bo density
## Min. : 0.01464 Min. : 0.000 Min. : 0.000
## 1st Qu.: 0.10368 1st Qu.: 0.000 1st Qu.: 0.000
## Median : 0.19892 Median : 0.000 Median : 0.000
## Mean : 0.45492 Mean : 1.186 Mean : 4.748
## 3rd Qu.: 0.41384 3rd Qu.: 0.000 3rd Qu.: 0.000
## Max. :25.41000 Max. :192.000 Max. :378.100
##
# Presence only
hru_presence <- hru %>%
dplyr::filter(bo>0)
vp_presence <- vp %>%
dplyr::filter(bo>0)
colonies_pres <- colonies %>%
dplyr::filter(bo>0)
plot_hru <- import(here::here("data","plot_size_hru.csv")) %>%
clean_names() %>%
dplyr::mutate(district = "Hrusovany", .before= "id")
plot_pa <- import(here::here("data","plot_size_pa.csv")) %>%
clean_names() %>%
dplyr::mutate(district = "Pavlovice", .before= "id")
plot_data <- rbind(plot_hru, plot_pa) %>%
dplyr::mutate(district = as.factor(district))
Explore data
Size of agricultural plots
# Create violin plot for Hrusovany
ggplot(plot_hru, aes(x=1, y=size_ha)) +
geom_violin() +
geom_text(aes(label = paste("mean = ",round(mean(size_ha), 3),", n = ",length(size_ha))),
y=0.05, nudge_y= 0.05, size=3) +
ggtitle("Hrusovany")+
theme_classic()

# Create violin plot for Pavlovice
ggplot(plot_pa, aes(x=1, y=size_ha)) +
geom_violin() +
geom_text(aes(label = paste("mean = ",round(mean(size_ha), 3),", n = ",length(size_ha))),
y= -0.5, nudge_y= 0.05, size=3) +
ggtitle("Pavlovice") +
theme_classic()

ggbetweenstats(plot_data, district, size_ha)

Density
table1 <- colonies %>%
dplyr::group_by(district) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district
|
District
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Hrušovany
|
21.351462
|
0
|
0
|
378.1
|
46.744447
|
171
|
|
Pavlovice
|
1.367738
|
0
|
0
|
77.7
|
6.045053
|
840
|
table1 <- colonies %>%
dplyr::group_by(district, habitat) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and habitat") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and habitat
|
District
|
Habitat
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Hrušovany
|
Crop Field
|
18.2500000
|
1.95
|
0
|
164.9
|
38.146966
|
20
|
|
Hrušovany
|
Garden
|
26.9615385
|
0.00
|
0
|
267.4
|
72.966277
|
13
|
|
Hrušovany
|
Orchard
|
26.4672414
|
10.40
|
0
|
378.1
|
54.191206
|
58
|
|
Hrušovany
|
Short-cut Lawn
|
18.6375000
|
8.95
|
0
|
63.5
|
23.653628
|
8
|
|
Hrušovany
|
Shrubland
|
3.3888889
|
0.00
|
0
|
22.2
|
7.569420
|
9
|
|
Hrušovany
|
Steppe Grassland
|
11.2400000
|
0.00
|
0
|
56.2
|
23.696001
|
10
|
|
Hrušovany
|
Tall Lawn
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
3
|
|
Hrušovany
|
Tree Stands
|
0.0000000
|
0.00
|
0
|
0.0
|
NA
|
1
|
|
Hrušovany
|
Vineyard
|
22.6224490
|
4.90
|
0
|
261.9
|
44.509583
|
49
|
|
Pavlovice
|
Crop Field
|
1.5803922
|
0.00
|
0
|
47.1
|
6.713722
|
102
|
|
Pavlovice
|
Garden
|
0.4323529
|
0.00
|
0
|
12.8
|
2.079139
|
68
|
|
Pavlovice
|
Orchard
|
1.6206573
|
0.00
|
0
|
39.5
|
5.238513
|
213
|
|
Pavlovice
|
Short-cut Lawn
|
3.0111111
|
0.00
|
0
|
77.7
|
13.019726
|
63
|
|
Pavlovice
|
Shrubland
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
54
|
|
Pavlovice
|
Steppe Grassland
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
15
|
|
Pavlovice
|
Tall Lawn
|
1.9555556
|
0.00
|
0
|
19.9
|
5.047565
|
18
|
|
Pavlovice
|
Tree Stands
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
7
|
|
Pavlovice
|
Vineyard
|
1.3377622
|
0.00
|
0
|
51.3
|
5.501825
|
286
|
|
Pavlovice
|
Pasture
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
3
|
|
Pavlovice
|
Ruderal
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
3
|
|
Pavlovice
|
Tree Alley
|
0.7000000
|
0.00
|
0
|
4.6
|
1.614222
|
8
|
table1 <- colonies %>%
dplyr::group_by(district, management) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and management type") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and management type
|
District
|
Management
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Hrušovany
|
Fallow
|
48.9000000
|
15.35
|
0
|
164.9
|
77.738064
|
4
|
|
Hrušovany
|
Mowed
|
17.1800000
|
4.10
|
0
|
117.1
|
24.739185
|
65
|
|
Hrušovany
|
No Management
|
6.0533333
|
0.00
|
0
|
56.2
|
15.476093
|
30
|
|
Hrušovany
|
Ploughed
|
30.8840580
|
7.10
|
0
|
378.1
|
65.208567
|
69
|
|
Hrušovany
|
Ploughed/Mowed
|
8.7333333
|
10.30
|
0
|
15.9
|
8.064945
|
3
|
|
Pavlovice
|
Fallow
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
27
|
|
Pavlovice
|
Mowed
|
1.5680233
|
0.00
|
0
|
77.7
|
6.712902
|
344
|
|
Pavlovice
|
No Management
|
0.3365854
|
0.00
|
0
|
19.9
|
2.039418
|
123
|
|
Pavlovice
|
Ploughed
|
1.7785016
|
0.00
|
0
|
51.3
|
6.841090
|
307
|
|
Pavlovice
|
Ploughed/Mowed
|
0.6314286
|
0.00
|
0
|
7.2
|
1.722988
|
35
|
|
Pavlovice
|
Grazed
|
0.0000000
|
0.00
|
0
|
0.0
|
0.000000
|
4
|
# Habitat and management
table1 <- colonies %>%
dplyr::group_by(habitat, management) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per habitat and management type") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per habitat and management type
|
Habitat
|
Management
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Crop Field
|
Fallow
|
6.309677
|
0
|
0
|
164.9
|
29.698646
|
31
|
|
Crop Field
|
Ploughed
|
3.632967
|
0
|
0
|
56.7
|
10.657080
|
91
|
|
Garden
|
Ploughed
|
4.748750
|
0
|
0
|
267.4
|
30.155135
|
80
|
|
Garden
|
Ploughed/Mowed
|
0.000000
|
0
|
0
|
0.0
|
NA
|
1
|
|
Orchard
|
Mowed
|
5.385714
|
0
|
0
|
117.1
|
15.181616
|
182
|
|
Orchard
|
No Management
|
1.666667
|
0
|
0
|
33.8
|
6.900452
|
24
|
|
Orchard
|
Ploughed
|
13.652381
|
0
|
0
|
378.1
|
49.918918
|
63
|
|
Orchard
|
Ploughed/Mowed
|
0.000000
|
0
|
0
|
0.0
|
0.000000
|
2
|
|
Short-cut Lawn
|
Mowed
|
4.771831
|
0
|
0
|
77.7
|
15.193816
|
71
|
|
Shrubland
|
No Management
|
0.484127
|
0
|
0
|
22.2
|
2.970185
|
63
|
|
Steppe Grassland
|
Mowed
|
0.000000
|
0
|
0
|
0.0
|
NA
|
1
|
|
Steppe Grassland
|
No Management
|
4.886957
|
0
|
0
|
56.2
|
16.191448
|
23
|
|
Steppe Grassland
|
Grazed
|
0.000000
|
0
|
0
|
0.0
|
NA
|
1
|
|
Tall Lawn
|
No Management
|
1.676190
|
0
|
0
|
19.9
|
4.706156
|
21
|
|
Tree Stands
|
Mowed
|
0.000000
|
0
|
0
|
0.0
|
0.000000
|
3
|
|
Tree Stands
|
No Management
|
0.000000
|
0
|
0
|
0.0
|
0.000000
|
5
|
|
Vineyard
|
Mowed
|
2.302083
|
0
|
0
|
56.0
|
7.976894
|
144
|
|
Vineyard
|
No Management
|
0.350000
|
0
|
0
|
4.9
|
1.309580
|
14
|
|
Vineyard
|
Ploughed
|
7.791549
|
0
|
0
|
261.9
|
27.972632
|
142
|
|
Vineyard
|
Ploughed/Mowed
|
1.380000
|
0
|
0
|
15.9
|
3.460432
|
35
|
|
Pasture
|
Grazed
|
0.000000
|
0
|
0
|
0.0
|
0.000000
|
3
|
|
Ruderal
|
No Management
|
0.000000
|
0
|
0
|
0.0
|
0.000000
|
3
|
|
Tree Alley
|
Mowed
|
0.700000
|
0
|
0
|
4.6
|
1.614222
|
8
|
Presence only
table1 <- colonies_pres %>%
dplyr::group_by(district) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district - Presence only
|
District
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Hrušovany
|
42.95412
|
27.5
|
0.6
|
378.1
|
59.01815
|
85
|
|
Pavlovice
|
10.54037
|
6.0
|
0.2
|
77.7
|
13.64933
|
109
|
table1 <- colonies_pres %>%
dplyr::group_by(district, habitat) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and habitat - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and habitat - Presence only
|
District
|
Habitat
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Hrušovany
|
Crop Field
|
33.181818
|
19.30
|
0.6
|
164.9
|
47.115302
|
11
|
|
Hrušovany
|
Garden
|
58.416667
|
18.60
|
7.0
|
267.4
|
102.824033
|
6
|
|
Hrušovany
|
Orchard
|
46.518182
|
33.80
|
4.1
|
378.1
|
65.338290
|
33
|
|
Hrušovany
|
Short-cut Lawn
|
37.275000
|
33.85
|
17.9
|
63.5
|
19.473122
|
4
|
|
Hrušovany
|
Shrubland
|
15.250000
|
15.25
|
8.3
|
22.2
|
9.828784
|
2
|
|
Hrušovany
|
Steppe Grassland
|
56.200000
|
56.20
|
56.2
|
56.2
|
0.000000
|
2
|
|
Hrušovany
|
Vineyard
|
41.055556
|
23.60
|
2.1
|
261.9
|
53.586683
|
27
|
|
Pavlovice
|
Crop Field
|
16.120000
|
11.75
|
1.0
|
47.1
|
15.665589
|
10
|
|
Pavlovice
|
Garden
|
9.800000
|
8.90
|
7.7
|
12.8
|
2.666458
|
3
|
|
Pavlovice
|
Orchard
|
9.862857
|
6.80
|
0.4
|
39.5
|
9.350215
|
35
|
|
Pavlovice
|
Short-cut Lawn
|
31.616667
|
14.15
|
6.8
|
77.7
|
31.885258
|
6
|
|
Pavlovice
|
Tall Lawn
|
8.800000
|
7.10
|
1.1
|
19.9
|
8.004166
|
4
|
|
Pavlovice
|
Vineyard
|
7.808163
|
3.20
|
0.2
|
51.3
|
11.320517
|
49
|
|
Pavlovice
|
Tree Alley
|
2.800000
|
2.80
|
1.0
|
4.6
|
2.545584
|
2
|
table1 <- colonies_pres %>%
dplyr::group_by(district, management) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and management type - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and management type - Presence only
|
District
|
Management
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Hrušovany
|
Fallow
|
65.200000
|
19.30
|
11.4
|
164.9
|
86.433038
|
3
|
|
Hrušovany
|
Mowed
|
32.844118
|
29.60
|
2.1
|
117.1
|
25.630015
|
34
|
|
Hrušovany
|
No Management
|
30.266667
|
28.00
|
4.9
|
56.2
|
22.577127
|
6
|
|
Hrušovany
|
Ploughed
|
53.275000
|
27.60
|
0.6
|
378.1
|
78.680072
|
40
|
|
Hrušovany
|
Ploughed/Mowed
|
13.100000
|
13.10
|
10.3
|
15.9
|
3.959798
|
2
|
|
Pavlovice
|
Mowed
|
10.177359
|
5.60
|
0.2
|
77.7
|
14.420040
|
53
|
|
Pavlovice
|
No Management
|
6.900000
|
4.55
|
1.1
|
19.9
|
6.865858
|
6
|
|
Pavlovice
|
Ploughed
|
13.317073
|
8.20
|
0.9
|
51.3
|
14.160595
|
41
|
|
Pavlovice
|
Ploughed/Mowed
|
2.455556
|
0.80
|
0.2
|
7.2
|
2.752776
|
9
|
# Habitat and management
table1 <- colonies_pres %>%
dplyr::group_by(habitat, management) %>%
dplyr::summarize(mean_density = mean(density),
median_density = median(density),
min_density = min(density),
max_density = max(density),
sd_density = sd(density),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per habitat and management type - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per habitat and management type - Presence only
|
Habitat
|
Management
|
Mean Density
|
Median Density
|
Min Density
|
Max Density
|
Sd Density
|
N
|
|
Crop Field
|
Fallow
|
65.200000
|
19.30
|
11.4
|
164.9
|
86.433038
|
3
|
|
Crop Field
|
Ploughed
|
18.366667
|
11.75
|
0.6
|
56.7
|
17.741013
|
18
|
|
Garden
|
Ploughed
|
42.211111
|
12.80
|
7.0
|
267.4
|
84.856709
|
9
|
|
Orchard
|
Mowed
|
20.855319
|
12.00
|
0.4
|
117.1
|
24.026180
|
47
|
|
Orchard
|
No Management
|
13.333333
|
3.40
|
2.8
|
33.8
|
17.727192
|
3
|
|
Orchard
|
Ploughed
|
47.783333
|
21.15
|
2.6
|
378.1
|
85.797870
|
18
|
|
Short-cut Lawn
|
Mowed
|
33.880000
|
23.50
|
6.8
|
77.7
|
26.452885
|
10
|
|
Shrubland
|
No Management
|
15.250000
|
15.25
|
8.3
|
22.2
|
9.828784
|
2
|
|
Steppe Grassland
|
No Management
|
56.200000
|
56.20
|
56.2
|
56.2
|
0.000000
|
2
|
|
Tall Lawn
|
No Management
|
8.800000
|
7.10
|
1.1
|
19.9
|
8.004166
|
4
|
|
Vineyard
|
Mowed
|
11.839286
|
6.30
|
0.2
|
56.0
|
14.829434
|
28
|
|
Vineyard
|
No Management
|
4.900000
|
4.90
|
4.9
|
4.9
|
NA
|
1
|
|
Vineyard
|
Ploughed
|
30.733333
|
12.30
|
0.9
|
261.9
|
49.264656
|
36
|
|
Vineyard
|
Ploughed/Mowed
|
4.390909
|
2.50
|
0.2
|
15.9
|
5.115751
|
11
|
|
Tree Alley
|
Mowed
|
2.800000
|
2.80
|
1.0
|
4.6
|
2.545584
|
2
|
Size of plots
table1 <- colonies %>%
dplyr::group_by(district) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district
|
District
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Hrušovany
|
0.2001361
|
0.1352804
|
0.0146362
|
1.667536
|
0.2262519
|
171
|
|
Pavlovice
|
0.5067885
|
0.2214649
|
0.0174018
|
25.410000
|
1.2011445
|
840
|
table1 <- colonies %>%
dplyr::group_by(district, habitat) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and habitat") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and habitat
|
District
|
Habitat
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Hrušovany
|
Crop Field
|
0.3966076
|
0.2568766
|
0.0303225
|
1.6675363
|
0.4236616
|
20
|
|
Hrušovany
|
Garden
|
0.1342761
|
0.0935023
|
0.0246976
|
0.5349839
|
0.1392483
|
13
|
|
Hrušovany
|
Orchard
|
0.1918580
|
0.1430234
|
0.0196987
|
0.9856231
|
0.1809191
|
58
|
|
Hrušovany
|
Short-cut Lawn
|
0.1435141
|
0.1334912
|
0.0202375
|
0.3857541
|
0.1141826
|
8
|
|
Hrušovany
|
Shrubland
|
0.1517028
|
0.1209329
|
0.0361502
|
0.5738480
|
0.1640914
|
9
|
|
Hrušovany
|
Steppe Grassland
|
0.1150404
|
0.1429195
|
0.0477385
|
0.1487839
|
0.0425300
|
10
|
|
Hrušovany
|
Tall Lawn
|
0.1154959
|
0.0935520
|
0.0551552
|
0.1977806
|
0.0738014
|
3
|
|
Hrušovany
|
Tree Stands
|
0.0206813
|
0.0206813
|
0.0206813
|
0.0206813
|
NA
|
1
|
|
Hrušovany
|
Vineyard
|
0.1915666
|
0.1309018
|
0.0146362
|
1.0428849
|
0.1963686
|
49
|
|
Pavlovice
|
Crop Field
|
0.5412581
|
0.1865635
|
0.0197371
|
11.3900000
|
1.2850366
|
102
|
|
Pavlovice
|
Garden
|
0.1482291
|
0.0903777
|
0.0174018
|
1.3176442
|
0.1926856
|
68
|
|
Pavlovice
|
Orchard
|
0.3539295
|
0.1951953
|
0.0289295
|
3.9477607
|
0.4824126
|
213
|
|
Pavlovice
|
Short-cut Lawn
|
0.2185341
|
0.1497017
|
0.0353690
|
1.3425311
|
0.2214651
|
63
|
|
Pavlovice
|
Shrubland
|
0.6007065
|
0.2386269
|
0.0196223
|
4.5183010
|
0.8993255
|
54
|
|
Pavlovice
|
Steppe Grassland
|
0.7657877
|
0.3211392
|
0.0441818
|
4.2158971
|
1.0531802
|
15
|
|
Pavlovice
|
Tall Lawn
|
0.2794462
|
0.1555036
|
0.0536121
|
1.3159649
|
0.3380599
|
18
|
|
Pavlovice
|
Tree Stands
|
0.4762270
|
0.2923001
|
0.1131347
|
1.1440361
|
0.4469978
|
7
|
|
Pavlovice
|
Vineyard
|
0.7396431
|
0.3251528
|
0.0277983
|
25.4100000
|
1.7639577
|
286
|
|
Pavlovice
|
Pasture
|
0.7046851
|
0.3873776
|
0.3479647
|
1.3787130
|
0.5840579
|
3
|
|
Pavlovice
|
Ruderal
|
0.1945866
|
0.1747893
|
0.1040609
|
0.3049097
|
0.1018774
|
3
|
|
Pavlovice
|
Tree Alley
|
0.5919291
|
0.3618700
|
0.1540836
|
1.9100263
|
0.5753529
|
8
|
table1 <- colonies %>%
dplyr::group_by(district, management) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and management type") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and management type
|
District
|
Management
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Hrušovany
|
Fallow
|
0.1012883
|
0.0838573
|
0.0303225
|
0.2071161
|
0.0749903
|
4
|
|
Hrušovany
|
Mowed
|
0.1837003
|
0.1417454
|
0.0196987
|
0.9856231
|
0.1705828
|
65
|
|
Hrušovany
|
No Management
|
0.1547822
|
0.1391000
|
0.0206813
|
0.5738480
|
0.1292096
|
30
|
|
Hrušovany
|
Ploughed
|
0.2354955
|
0.1351917
|
0.0146362
|
1.6675363
|
0.2951959
|
69
|
|
Hrušovany
|
Ploughed/Mowed
|
0.3283180
|
0.3770540
|
0.0247399
|
0.5831603
|
0.2823822
|
3
|
|
Pavlovice
|
Fallow
|
0.2059319
|
0.1197429
|
0.0244871
|
1.5442739
|
0.2902970
|
27
|
|
Pavlovice
|
Mowed
|
0.5168195
|
0.2264078
|
0.0289295
|
25.4100000
|
1.5139634
|
344
|
|
Pavlovice
|
No Management
|
0.4819026
|
0.2313789
|
0.0196223
|
4.5183010
|
0.6720863
|
123
|
|
Pavlovice
|
Ploughed
|
0.4106173
|
0.1832134
|
0.0174018
|
11.3900000
|
0.8485079
|
307
|
|
Pavlovice
|
Ploughed/Mowed
|
1.4483644
|
0.7468093
|
0.0852919
|
7.4042496
|
1.6776319
|
35
|
|
Pavlovice
|
Grazed
|
1.5824881
|
0.8830453
|
0.3479647
|
4.2158971
|
1.8192219
|
4
|
# Habitat and management
table1 <- colonies %>%
dplyr::group_by(habitat, management) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per habitat and management type") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per habitat and management type
|
Habitat
|
Management
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Crop Field
|
Fallow
|
0.1924295
|
0.1040679
|
0.0244871
|
1.5442739
|
0.2736239
|
31
|
|
Crop Field
|
Ploughed
|
0.6282985
|
0.2479741
|
0.0197371
|
11.3900000
|
1.3495035
|
91
|
|
Garden
|
Ploughed
|
0.1475053
|
0.0931697
|
0.0174018
|
1.3176442
|
0.1851267
|
80
|
|
Garden
|
Ploughed/Mowed
|
0.0247399
|
0.0247399
|
0.0247399
|
0.0247399
|
NA
|
1
|
|
Orchard
|
Mowed
|
0.3499308
|
0.1760018
|
0.0196987
|
3.9477607
|
0.5006071
|
182
|
|
Orchard
|
No Management
|
0.4442826
|
0.3518460
|
0.0906520
|
2.0177169
|
0.4076211
|
24
|
|
Orchard
|
Ploughed
|
0.1879936
|
0.1234033
|
0.0281398
|
0.7861068
|
0.1568365
|
63
|
|
Orchard
|
Ploughed/Mowed
|
0.1604780
|
0.1604780
|
0.0852919
|
0.2356642
|
0.1063293
|
2
|
|
Short-cut Lawn
|
Mowed
|
0.2100811
|
0.1440802
|
0.0202375
|
1.3425311
|
0.2128754
|
71
|
|
Shrubland
|
No Management
|
0.5365631
|
0.2000103
|
0.0196223
|
4.5183010
|
0.8484931
|
63
|
|
Steppe Grassland
|
Mowed
|
0.2159259
|
0.2159259
|
0.2159259
|
0.2159259
|
NA
|
1
|
|
Steppe Grassland
|
No Management
|
0.3567564
|
0.1487839
|
0.0441818
|
1.5364734
|
0.4115373
|
23
|
|
Steppe Grassland
|
Grazed
|
4.2158971
|
4.2158971
|
4.2158971
|
4.2158971
|
NA
|
1
|
|
Tall Lawn
|
No Management
|
0.2560248
|
0.1534268
|
0.0536121
|
1.3159649
|
0.3180290
|
21
|
|
Tree Stands
|
Mowed
|
0.1895977
|
0.1633583
|
0.1131347
|
0.2923001
|
0.0924199
|
3
|
|
Tree Stands
|
No Management
|
0.5570954
|
0.3723737
|
0.0206813
|
1.1440361
|
0.5268096
|
5
|
|
Vineyard
|
Mowed
|
0.7333548
|
0.2944272
|
0.0359544
|
25.4100000
|
2.2523277
|
144
|
|
Vineyard
|
No Management
|
0.1785764
|
0.1375409
|
0.0309899
|
0.4949014
|
0.1376545
|
14
|
|
Vineyard
|
Ploughed
|
0.4330249
|
0.2448186
|
0.0146362
|
4.5212598
|
0.5783951
|
142
|
|
Vineyard
|
Ploughed/Mowed
|
1.4666289
|
0.7468093
|
0.1811133
|
7.4042496
|
1.6649259
|
35
|
|
Pasture
|
Grazed
|
0.7046851
|
0.3873776
|
0.3479647
|
1.3787130
|
0.5840579
|
3
|
|
Ruderal
|
No Management
|
0.1945866
|
0.1747893
|
0.1040609
|
0.3049097
|
0.1018774
|
3
|
|
Tree Alley
|
Mowed
|
0.5919291
|
0.3618700
|
0.1540836
|
1.9100263
|
0.5753529
|
8
|
Presence only
table1 <- colonies_pres %>%
dplyr::group_by(district) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district - Presence only
|
District
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Hrušovany
|
0.2303903
|
0.1430515
|
0.0146362
|
1.667536
|
0.2709657
|
85
|
|
Pavlovice
|
1.1054466
|
0.4560539
|
0.0424719
|
25.410000
|
2.6039602
|
109
|
table1 <- colonies_pres %>%
dplyr::group_by(district, habitat) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and habitat - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and habitat - Presence only
|
District
|
Habitat
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Hrušovany
|
Crop Field
|
0.4052782
|
0.2071161
|
0.0303225
|
1.6675363
|
0.5214459
|
11
|
|
Hrušovany
|
Garden
|
0.2127082
|
0.1416330
|
0.0881456
|
0.5349839
|
0.1718984
|
6
|
|
Hrušovany
|
Orchard
|
0.2069387
|
0.1431608
|
0.0205713
|
0.9856231
|
0.2067632
|
33
|
|
Hrušovany
|
Short-cut Lawn
|
0.1182010
|
0.1055692
|
0.0558886
|
0.2057768
|
0.0694956
|
4
|
|
Hrušovany
|
Shrubland
|
0.1281067
|
0.1281067
|
0.1209329
|
0.1352804
|
0.0101452
|
2
|
|
Hrušovany
|
Steppe Grassland
|
0.0889138
|
0.0889138
|
0.0889138
|
0.0889138
|
0.0000000
|
2
|
|
Hrušovany
|
Vineyard
|
0.2264090
|
0.1496861
|
0.0146362
|
1.0428849
|
0.2361435
|
27
|
|
Pavlovice
|
Crop Field
|
0.3851903
|
0.2303097
|
0.0424719
|
1.0139817
|
0.3360204
|
10
|
|
Pavlovice
|
Garden
|
0.1069472
|
0.1120245
|
0.0783104
|
0.1305068
|
0.0264660
|
3
|
|
Pavlovice
|
Orchard
|
0.7705831
|
0.4560539
|
0.0475209
|
3.9477607
|
0.8521115
|
35
|
|
Pavlovice
|
Short-cut Lawn
|
0.2814993
|
0.1946690
|
0.0985939
|
0.7891762
|
0.2591121
|
6
|
|
Pavlovice
|
Tall Lawn
|
0.3283990
|
0.1463513
|
0.1002790
|
0.9206143
|
0.3961123
|
4
|
|
Pavlovice
|
Vineyard
|
1.7187884
|
0.7487816
|
0.0906884
|
25.4100000
|
3.7286426
|
49
|
|
Pavlovice
|
Tree Alley
|
1.0636540
|
1.0636540
|
0.2172817
|
1.9100263
|
1.1969512
|
2
|
table1 <- colonies_pres %>%
dplyr::group_by(district, management) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per district and management type - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per district and management type - Presence only
|
District
|
Management
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Hrušovany
|
Fallow
|
0.1083297
|
0.0875504
|
0.0303225
|
0.2071161
|
0.0902099
|
3
|
|
Hrušovany
|
Mowed
|
0.2101207
|
0.1604011
|
0.0205713
|
0.9856231
|
0.1994039
|
34
|
|
Hrušovany
|
No Management
|
0.1652889
|
0.1281067
|
0.0889138
|
0.3547129
|
0.1018198
|
6
|
|
Hrušovany
|
Ploughed
|
0.2540533
|
0.1377032
|
0.0146362
|
1.6675363
|
0.3409933
|
40
|
|
Hrušovany
|
Ploughed/Mowed
|
0.4801071
|
0.4801071
|
0.3770540
|
0.5831603
|
0.1457391
|
2
|
|
Pavlovice
|
Mowed
|
1.4487969
|
0.6213596
|
0.0636014
|
25.4100000
|
3.5779642
|
53
|
|
Pavlovice
|
No Management
|
0.3281995
|
0.2357093
|
0.1002790
|
0.9206143
|
0.3074804
|
6
|
|
Pavlovice
|
Ploughed
|
0.5404016
|
0.3692687
|
0.0424719
|
3.3848277
|
0.6055274
|
41
|
|
Pavlovice
|
Ploughed/Mowed
|
2.1757540
|
1.4495717
|
0.3736405
|
5.3673770
|
1.5082394
|
9
|
# Habitat and management
table1 <- colonies_pres %>%
dplyr::group_by(habitat, management) %>%
dplyr::summarize(mean_area = mean(size_ha),
median_area = median(size_ha),
min_area = min(size_ha),
max_area = max(size_ha),
sd_area = sd(size_ha),
n = n())
# Modify the column names to capitalize the first letter and remove hyphens
colnames(table1) <- str_to_title(gsub("_", " ", colnames(table1)))
kable(table1, caption = "Summary statistics per habitat and management type - Presence only") %>%
kableExtra::kable_styling(font_size = 10,
latex_options = "striped")
Summary statistics per habitat and management type - Presence only
|
Habitat
|
Management
|
Mean Area
|
Median Area
|
Min Area
|
Max Area
|
Sd Area
|
N
|
|
Crop Field
|
Fallow
|
0.1083297
|
0.0875504
|
0.0303225
|
0.2071161
|
0.0902099
|
3
|
|
Crop Field
|
Ploughed
|
0.4436097
|
0.2568766
|
0.0424719
|
1.6675363
|
0.4493147
|
18
|
|
Garden
|
Ploughed
|
0.1774546
|
0.1305068
|
0.0783104
|
0.5349839
|
0.1464228
|
9
|
|
Orchard
|
Mowed
|
0.6134802
|
0.2481750
|
0.0205713
|
3.9477607
|
0.7926764
|
47
|
|
Orchard
|
No Management
|
0.3367714
|
0.3547129
|
0.2961331
|
0.3594682
|
0.0352740
|
3
|
|
Orchard
|
Ploughed
|
0.2197501
|
0.1654932
|
0.0400045
|
0.5676248
|
0.1621767
|
18
|
|
Short-cut Lawn
|
Mowed
|
0.2161800
|
0.1532783
|
0.0558886
|
0.7891762
|
0.2145236
|
10
|
|
Shrubland
|
No Management
|
0.1281067
|
0.1281067
|
0.1209329
|
0.1352804
|
0.0101452
|
2
|
|
Steppe Grassland
|
No Management
|
0.0889138
|
0.0889138
|
0.0889138
|
0.0889138
|
0.0000000
|
2
|
|
Tall Lawn
|
No Management
|
0.3283990
|
0.1463513
|
0.1002790
|
0.9206143
|
0.3961123
|
4
|
|
Vineyard
|
Mowed
|
1.8145594
|
0.4412720
|
0.1293170
|
25.4100000
|
4.8549069
|
28
|
|
Vineyard
|
No Management
|
0.2029797
|
0.2029797
|
0.2029797
|
0.2029797
|
NA
|
1
|
|
Vineyard
|
Ploughed
|
0.5216953
|
0.2856495
|
0.0146362
|
3.3848277
|
0.6592842
|
36
|
|
Vineyard
|
Ploughed/Mowed
|
1.8674546
|
1.3805248
|
0.3736405
|
5.3673770
|
1.5140816
|
11
|
|
Tree Alley
|
Mowed
|
1.0636540
|
1.0636540
|
0.2172817
|
1.9100263
|
1.1969512
|
2
|
Boxplots
Habitat type
I would remove the means from the plots and leave the stats for Table
1 (perhaps Table 1 a, b)
# Compute the number of observations for each habitat type
n <- colonies %>%
group_by(habitat, district) %>%
dplyr::summarise(n = n())
# Find the maximum density value for each district
max_density <- colonies %>% group_by(district) %>% dplyr::summarise(max_density = max(density))
# Join the n and max_density data frames
n <- left_join(n, max_density, by = c("district" = "district"))
ggplot(colonies, aes(x=habitat, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by habitat type")+
facet_grid(. ~ district, scales = "free_x")+
geom_text(data=n, aes(x=habitat, y=max_density-5, label=paste("n =", n)), vjust=-1.1, size=3.5, position=position_dodge(0.4))+
coord_flip()+
theme(legend.position = "none")

Same scale example (I prefer the version with different scales)
# Compute the number of observations for each habitat type
n <- colonies %>%
group_by(habitat, district) %>%
dplyr::summarise(n = n())
# Find the maximum density value for each district
max_density <- colonies %>% group_by(district) %>% dplyr::summarise(max_density = max(density))
# Join the n and max_density data frames
n <- left_join(n, max_density, by = c("district" = "district"))
ggplot(colonies, aes(x=habitat, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by habitat type")+
facet_grid(. ~ district)+
geom_text(data=n, aes(x=habitat, y=max_density-5, label=paste("n =", n)), vjust=-1.1, size=3.5, position=position_dodge(0.4))+
coord_flip()+
theme(legend.position = "none")

Management
# Compute the number of observations for each habitat type
n <- colonies %>%
group_by(management, district) %>%
dplyr::summarise(n = n())
# Find the maximum density value for each district
max_density <- colonies %>% group_by(district) %>% dplyr::summarise(max_density = max(density))
# Join the n and max_density data frames
n <- left_join(n, max_density, by = c("district" = "district"))
ggplot(colonies, aes(x=management, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by management type")+
facet_grid(. ~ district, scales = "free_x")+
geom_text(data=n, aes(x=management, y=max_density-10, label=paste("n =", n)), vjust=-1.1, size=3.5, position=position_dodge(0.4))+
coord_flip()+
theme(legend.position = "none")

ggplot(hru, aes(x=habitat, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by Habitat in Hrusovany")+
coord_flip()

ggplot(vp, aes(x=habitat, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by Habitat in Velke Pavlovice")+
coord_flip()

ggplot(hru, aes(x=management, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by management type in Hrusovany")+
coord_flip()

ggplot(vp, aes(x=management, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by management type in Velke Pavlovice")+
coord_flip()

Presence only
For BOs > 0 only. It can be misleading. Needs to be clearly
stated.
ggplot(colonies_pres, aes(x=habitat, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by Habitat - Presence only")+
facet_grid(. ~ district, scales = "free_x")+
coord_flip()

ggplot(colonies_pres, aes(x=management, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by Management - Presence only")+
facet_grid(. ~ district, scales = "free_x")+
coord_flip()

Both with n
Habitat
# Load the dplyr package
# Compute the number of observations for each habitat and management type
nc_habitat <- colonies_pres %>%
group_by(habitat, district) %>%
dplyr::summarise(n = n())
# Find the maximum density value for each district
max_density <- colonies_pres %>% group_by(district) %>% dplyr::summarise(max_density = max(density))
# Join the n and max_density data frames
nc_habitat <- left_join(nc_habitat, max_density, by = c("district" = "district"))
# Generate the plot
p <- ggplot(colonies_pres, aes(x=habitat, y=density)) +
geom_boxplot() +
geom_text(data=nc_habitat, aes(x=habitat, y=max_density-5, label=paste("n =", n)), vjust=-1.1, size=3.5, position=position_dodge(0.4)) + # add n to the facets
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by habitat type - Presence only")+
facet_grid(. ~ district, scales = "free_x")+
coord_flip()+
theme(legend.position = "none")
# Show the plot
p

Same scale example (I still prefer the version with different
scales)
# Compute the number of observations for each habitat and management type
nc_habitat <- colonies_pres %>%
group_by(habitat, district) %>%
dplyr::summarise(n = n())
# Find the maximum density value for each district
max_density <- colonies_pres %>% group_by(district) %>% dplyr::summarise(max_density = max(density))
# Join the n and max_density data frames
nc_habitat <- left_join(nc_habitat, max_density, by = c("district" = "district"))
# Generate the plot
p <- ggplot(colonies_pres, aes(x=habitat, y=density)) +
geom_boxplot() +
geom_text(data=nc_habitat, aes(x=habitat, y=max_density-5, label=paste("n =", n)), vjust=-1.1, size=3.5, position=position_dodge(0.4)) + # add n to the facets
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by habitat type - Presence only")+
facet_grid(. ~ district)+
coord_flip()+
theme(legend.position = "none")
# Show the plot
p

Management
# Compute the number of observations for each management and district type
nc_management <- colonies_pres %>%
group_by(management, district) %>%
dplyr::summarise(n = n())
# Find the maximum density value for each district
max_density <- colonies_pres %>% group_by(district) %>% dplyr::summarise(max_density = max(density))
# Join the n and max_density data frames
nc_management <- left_join(nc_management, max_density, by = c("district" = "district"))
# Generate the plot
p <- ggplot(colonies_pres, aes(x=management, y=density)) +
geom_boxplot() +
geom_text(data=nc_management, aes(x=management, y=max_density-5, label=paste("n =", n)), vjust=-1.1, size=3.5, position=position_dodge(0.4)) + # add n to the facets
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by management type - Presence only")+
facet_grid(. ~ district, scales = "free_x")+
coord_flip()+
theme(legend.position = "none")
# Show the plot
p

ggplot(hru_presence, aes(x=habitat, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by Habitat in Hrusovany - Presence only")+
coord_flip()

ggplot(vp_presence, aes(x=habitat, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by Habitat in Velke Pavlovice - Presence only")+
coord_flip()

ggplot(hru_presence, aes(x=management, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by management type in Hrusovany - Presence only")+
coord_flip()

ggplot(vp_presence, aes(x=management, y=density)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by management type in Velke Pavlovice - Presence only")+
coord_flip()

Example color plot
Not so sure about the mean, with so many outliers. I’d leave just the
n. The boxplot gives already the median. Color is also optional.
Once you all decide the details, I’ll change it for all the
plots.
# Create a color palette for the management types
palette <- c("#0072B2", "#D55E00", "#CC79A7", "#F0E442")
names(palette) <- c("Ploughed", "Ploughed/Mowed", "Mowed", "No Management")
# Compute the number of observations for each management type
n <- vp_presence %>%
group_by(management) %>%
dplyr::summarise(n = n())
# Modify the plot code to include the color aesthetic and appropriate labels
ggplot(vp_presence, aes(x=management, y=density, fill=management)) +
geom_boxplot() +
xlab("") + ylab("Density (burrow openings/ha)") +
ggtitle("Density of burrow openings by Management Type in Velke Pavlovice - Presence Only") +
scale_fill_manual(values=palette) +
coord_flip()+
geom_text(data=n, aes(x=management, y=70, label=paste("n =", n)), vjust=-1, size=3.5, position=position_dodge(0.4))+
labs(fill = "Management")+
theme(legend.position = "none")

Anovas
And tukey post-hoc tests to identify which specific levels of the
variables are significantly different from one another.
# Perform a two-way ANOVA to test the effect of management and habitat on density
aov_results <- aov(density ~ management + habitat + district, data=colonies)
summary(aov_results)
## Df Sum Sq Mean Sq F value Pr(>F)
## management 5 4596 919 2.315 0.0419 *
## habitat 11 5224 475 1.196 0.2851
## district 1 54646 54646 137.590 <2e-16 ***
## Residuals 993 394388 397
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Perform post-hoc tests to identify significant differences between levels
tukey_results <- TukeyHSD(aov_results)
tukey_results
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = density ~ management + habitat + district, data = colonies)
##
## $management
## diff lwr upr p adj
## Mowed-Fallow -2.2605332 -12.8609007 8.339834 0.9904100
## No Management-Fallow -4.8521611 -16.0599369 6.355615 0.8190226
## Ploughed-Fallow 0.8100034 -9.8230874 11.443094 0.9999334
## Ploughed/Mowed-Fallow -5.0386248 -18.8103703 8.733121 0.9026602
## Grazed-Fallow -6.3096774 -36.5412171 23.921862 0.9913146
## No Management-Mowed -2.5916279 -7.9842238 2.800968 0.7437580
## Ploughed-Mowed 3.0705366 -0.9949856 7.136059 0.2593859
## Ploughed/Mowed-Mowed -2.7780916 -12.4283157 6.872132 0.9635060
## Grazed-Mowed -4.0491443 -32.6395595 24.541271 0.9986120
## Ploughed-No Management 5.6621645 0.2055247 11.118804 0.0367406
## Ploughed/Mowed-No Management -0.1864637 -10.5002056 10.127278 0.9999999
## Grazed-No Management -1.4575163 -30.2786595 27.363627 0.9999913
## Ploughed/Mowed-Ploughed -5.8486282 -15.5347860 3.837530 0.5160721
## Grazed-Ploughed -7.1196809 -35.7222449 21.482883 0.9806772
## Grazed-Ploughed/Mowed -1.2710526 -31.1826729 28.640568 0.9999963
##
## $habitat
## diff lwr upr p adj
## Garden-Crop Field 0.2433934 -9.113690 9.600477 1.0000000
## Orchard-Crop Field 5.0261823 -2.091632 12.143996 0.4677268
## Short-cut Lawn-Crop Field 3.3234323 -6.421627 13.068491 0.9939269
## Shrubland-Crop Field 1.6273562 -8.501271 11.755983 0.9999958
## Steppe Grassland-Crop Field 5.5938647 -8.738692 19.926421 0.9816639
## Tall Lawn-Crop Field 2.8194197 -12.604451 18.243290 0.9999842
## Tree Stands-Crop Field 0.1713687 -23.655210 23.997947 1.0000000
## Vineyard-Crop Field 2.0996604 -4.803861 9.003182 0.9977735
## Pasture-Crop Field 2.6007456 -35.552315 40.753806 1.0000000
## Ruderal-Crop Field 1.1432292 -37.009831 39.296290 1.0000000
## Tree Alley-Crop Field -0.7483987 -24.574977 23.078180 1.0000000
## Orchard-Garden 4.7827888 -3.484424 13.050001 0.7622488
## Short-cut Lawn-Garden 3.0800388 -7.533618 13.693695 0.9985461
## Shrubland-Garden 1.3839628 -9.582924 12.350850 0.9999997
## Steppe Grassland-Garden 5.3504713 -9.586252 20.287195 0.9908221
## Tall Lawn-Garden 2.5760262 -13.410822 18.562874 0.9999957
## Tree Stands-Garden -0.0720247 -24.266846 24.122796 1.0000000
## Vineyard-Garden 1.8562670 -6.227181 9.939715 0.9998432
## Pasture-Garden 2.3573521 -36.026753 40.741457 1.0000000
## Ruderal-Garden 0.8998358 -37.484270 39.283941 1.0000000
## Tree Alley-Garden -0.9917921 -25.186613 23.203029 1.0000000
## Short-cut Lawn-Orchard -1.7027500 -10.406655 7.001155 0.9999684
## Shrubland-Orchard -3.3988261 -12.530139 5.732487 0.9874332
## Steppe Grassland-Orchard 0.5676825 -13.078341 14.213706 1.0000000
## Tall Lawn-Orchard -2.2067626 -16.994851 12.581326 0.9999981
## Tree Stands-Orchard -4.8548135 -28.274840 18.565213 0.9999433
## Vineyard-Orchard -2.9265219 -8.260413 2.407370 0.8194464
## Pasture-Orchard -2.4254367 -40.325935 35.475062 1.0000000
## Ruderal-Orchard -3.8829531 -41.783452 34.017546 1.0000000
## Tree Alley-Orchard -5.7745810 -29.194607 17.645445 0.9996865
## Shrubland-Short-cut Lawn -1.6960761 -12.995801 9.603649 0.9999979
## Steppe Grassland-Short-cut Lawn 2.2704325 -12.912349 17.453214 0.9999980
## Tall Lawn-Short-cut Lawn -0.5040126 -16.720994 15.712968 1.0000000
## Tree Stands-Short-cut Lawn -3.1520635 -27.499559 21.195432 0.9999996
## Vineyard-Short-cut Lawn -1.2237719 -9.753327 7.305783 0.9999987
## Pasture-Short-cut Lawn -0.7226867 -39.203210 37.757837 1.0000000
## Ruderal-Short-cut Lawn -2.1802031 -40.660727 36.300321 1.0000000
## Tree Alley-Short-cut Lawn -4.0718310 -28.419326 20.275665 0.9999937
## Steppe Grassland-Shrubland 3.9665086 -11.465270 19.398287 0.9995329
## Tall Lawn-Shrubland 1.1920635 -15.258267 17.642394 1.0000000
## Tree Stands-Shrubland -1.4559875 -25.959527 23.047552 1.0000000
## Vineyard-Shrubland 0.4723042 -8.492974 9.437582 1.0000000
## Pasture-Shrubland 0.9733894 -37.606056 39.552835 1.0000000
## Ruderal-Shrubland -0.4841270 -39.063573 38.095319 1.0000000
## Tree Alley-Shrubland -2.3757549 -26.879294 22.127785 1.0000000
## Tall Lawn-Steppe Grassland -2.7744451 -22.099208 16.550318 0.9999987
## Tree Stands-Steppe Grassland -5.4224960 -31.941480 21.096488 0.9999505
## Vineyard-Steppe Grassland -3.4942043 -17.029687 10.041279 0.9995132
## Pasture-Steppe Grassland -2.9931192 -42.883052 36.896813 1.0000000
## Ruderal-Steppe Grassland -4.4506355 -44.340568 35.439297 0.9999999
## Tree Alley-Steppe Grassland -6.3422635 -32.861248 20.176721 0.9997667
## Tree Stands-Tall Lawn -2.6480509 -29.772397 24.476295 1.0000000
## Vineyard-Tall Lawn -0.7197593 -15.405906 13.966387 1.0000000
## Pasture-Tall Lawn -0.2186741 -40.513591 40.076243 1.0000000
## Ruderal-Tall Lawn -1.6761905 -41.971107 38.618726 1.0000000
## Tree Alley-Tall Lawn -3.5678184 -30.692164 23.556528 0.9999995
## Vineyard-Tree Stands 1.9282917 -21.427499 25.284083 1.0000000
## Pasture-Tree Stands 2.4293768 -41.768931 46.627684 1.0000000
## Ruderal-Tree Stands 0.9718605 -43.226447 45.170168 1.0000000
## Tree Alley-Tree Stands -0.9197674 -33.562381 31.722846 1.0000000
## Pasture-Vineyard 0.5010851 -37.359754 38.361924 1.0000000
## Ruderal-Vineyard -0.9564312 -38.817270 36.904408 1.0000000
## Tree Alley-Vineyard -2.8480591 -26.203850 20.507732 0.9999998
## Ruderal-Pasture -1.4575163 -54.762681 51.847648 1.0000000
## Tree Alley-Pasture -3.3491443 -47.547452 40.849163 1.0000000
## Tree Alley-Ruderal -1.8916279 -46.089935 42.306679 1.0000000
##
## $district
## diff lwr upr p adj
## Pavlovice-Hrušovany -19.37638 -22.65736 -16.09541 0
Presence only
And tukey post-hoc tests to identify which specific levels of the
variables are significantly different from one another.
# Perform a two-way ANOVA to test the effect of management and habitat on density
aov_results <- aov(density ~ management + habitat + district, data=colonies_pres)
summary(aov_results)
## Df Sum Sq Mean Sq F value Pr(>F)
## management 4 18345 4586 2.817 0.0267 *
## habitat 8 16107 2013 1.237 0.2801
## district 1 35371 35371 21.725 6.11e-06 ***
## Residuals 180 293059 1628
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Perform post-hoc tests to identify significant differences between levels
tukey_results <- TukeyHSD(aov_results)
tukey_results
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = density ~ management + habitat + district, data = colonies_pres)
##
## $management
## diff lwr upr p adj
## Mowed-Fallow -46.1643678 -111.456790 19.128055 0.2958522
## No Management-Fallow -46.6166667 -118.388850 25.155517 0.3827034
## Ploughed-Fallow -32.1506173 -97.523598 33.222363 0.6570096
## Ploughed/Mowed-Fallow -60.8090909 -133.230810 11.612628 0.1452719
## No Management-Mowed -0.4522989 -34.691934 33.787336 0.9999996
## Ploughed-Mowed 14.0137505 -3.154035 31.181536 0.1665963
## Ploughed/Mowed-Mowed -14.6447231 -50.225780 20.936334 0.7882062
## Ploughed-No Management 14.4660494 -19.926956 48.859054 0.7745745
## Ploughed/Mowed-No Management -14.1924242 -60.605327 32.220479 0.9168932
## Ploughed/Mowed-Ploughed -28.6584736 -64.387143 7.070196 0.1805889
##
## $habitat
## diff lwr upr p adj
## Garden-Crop Field 21.7469136 -28.72984 72.22366 0.9135625
## Orchard-Crop Field 17.5114558 -14.11806 49.14097 0.7219771
## Short-cut Lawn-Crop Field 27.4295530 -21.24846 76.10757 0.7022079
## Shrubland-Crop Field 9.2518519 -84.50455 103.00825 0.9999974
## Steppe Grassland-Crop Field 50.2018519 -43.55455 143.95825 0.7571806
## Tall Lawn-Crop Field 2.8018519 -66.31628 71.91999 1.0000000
## Vineyard-Crop Field 8.6567798 -22.57747 39.89103 0.9942130
## Tree Alley-Crop Field -3.6504470 -97.40685 90.10595 1.0000000
## Orchard-Garden -4.2354578 -49.17528 40.70436 0.9999982
## Short-cut Lawn-Garden 5.6826394 -52.52999 63.89527 0.9999976
## Shrubland-Garden -12.4950617 -111.53760 86.54747 0.9999825
## Steppe Grassland-Garden 28.4549383 -70.58760 127.49747 0.9926258
## Tall Lawn-Garden -18.9450617 -95.07966 57.18954 0.9972494
## Vineyard-Garden -13.0901338 -57.75264 31.57237 0.9915753
## Tree Alley-Garden -25.3973606 -124.43990 73.64517 0.9966074
## Short-cut Lawn-Orchard 9.9180973 -32.99151 52.82770 0.9983680
## Shrubland-Orchard -8.2596039 -99.15486 82.63565 0.9999987
## Steppe Grassland-Orchard 32.6903961 -58.20486 123.58565 0.9690365
## Tall Lawn-Orchard -14.7096039 -79.89397 50.47476 0.9986255
## Vineyard-Orchard -8.8546760 -30.00328 12.29393 0.9258570
## Tree Alley-Orchard -21.1619027 -112.05716 69.73335 0.9982816
## Shrubland-Short-cut Lawn -18.1777011 -116.31572 79.96032 0.9996759
## Steppe Grassland-Short-cut Lawn 22.7722989 -75.36572 120.91032 0.9983219
## Tall Lawn-Short-cut Lawn -24.6277011 -99.58185 50.32645 0.9822999
## Vineyard-Short-cut Lawn -18.7727732 -61.39185 23.84631 0.9029041
## Tree Alley-Short-cut Lawn -31.0800000 -129.21802 67.05802 0.9860084
## Steppe Grassland-Shrubland 40.9500000 -85.74564 167.64564 0.9840556
## Tall Lawn-Shrubland -6.4500000 -116.17164 103.27164 1.0000000
## Vineyard-Shrubland -0.5950721 -91.35354 90.16340 1.0000000
## Tree Alley-Shrubland -12.9022989 -139.59794 113.79334 0.9999967
## Tall Lawn-Steppe Grassland -47.4000000 -157.12164 62.32164 0.9123100
## Vineyard-Steppe Grassland -41.5450721 -132.30354 49.21340 0.8818319
## Tree Alley-Steppe Grassland -53.8522989 -180.54794 72.84334 0.9195673
## Vineyard-Tall Lawn 5.8549279 -59.13856 70.84842 0.9999987
## Tree Alley-Tall Lawn -6.4522989 -116.17394 103.26934 1.0000000
## Tree Alley-Vineyard -12.3072268 -103.06570 78.45124 0.9999695
##
## $district
## diff lwr upr p adj
## Pavlovice-Hrušovany -25.65017 -37.17136 -14.12898 1.9e-05
LS0tDQphdXRob3I6ICJGZXJuYW5kbyBNYXRlb3MtR29uesOhbGV6Ig0KZGF0ZTogTGFzdCB1cGRhdGUgImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogbm8NCiAgICAgIHNtb290aF9zY3JvbGw6IG5vDQogIG1kX2RvY3VtZW50Og0KICAgIHZhcmlhbnQ6IG1hcmtkb3duX2dpdGh1Yg0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCnRpdGxlOiAiVEFDUiAzIg0KDQoNCiMgdGl0bGU6ICJEZW5tYXJrIC0gQ09WSUQiDQojIGF1dGhvcjogIkZlcm5hbmRvIE1hdGVvcy1Hb256w6FsZXoiDQojIGRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCINCiMgb3V0cHV0Og0KIyAgIHdvcmRfZG9jdW1lbnQ6DQojICAgICB0b2M6IG5vDQojICAgICBmaWdfY2FwdGlvbjogdHJ1ZQ0KIyAgICAgcmVmZXJlbmNlX2RvY3g6IHN0eWxld29yZC5kb2N4DQojIA0KIyAgIA0KDQprbml0OiAoZnVuY3Rpb24oaW5wdXRGaWxlLCBlbmNvZGluZykgew0KICBybWFya2Rvd246OnJlbmRlcihpbnB1dEZpbGUsIGVuY29kaW5nID0gZW5jb2RpbmcsIG91dHB1dF9kaXIgPSAib3V0cHV0IikgfSkNCiAgDQoNCi0tLQ0KIyBJbnRyb2R1Y3Rpb24NCg0KU3RhdHVzIGFuZCBkZXZlbG9wbWVudCBvZiBFdXJvcGVhbiBncm91bmQgc3F1aXJyZWwgcG9wdWxhdGlvbnMgaW4gYWdyaWN1bHR1cmFsIGxhbmQgb2Ygc291dGhlcm4gTW9yYXZpYQ0KDQpJbiBIcnVzb3ZhbnkgYW5kIFBhdmxvdmljZSwgdGhlcmUgYXJlIHBhdGNoZXMgdGhhdCBoYXZlIGJlZW4gZGl2aWRlZCBpbnRvIGhhYml0YXQgY2F0ZWdvcmllcywgc3VjaCBhcyBvcmNoYXJkcyBhbmQgdmluZXlhcmRzLCBhbmQgY2F0ZWdvcmllcyBvZiB2ZWdldGF0aW9uIG1hbmFnZW1lbnQsIHN1Y2ggYXMgbW93ZWQgb3IgcGxvdWdoZWQuIFRoZSBkZW5zaXR5IG9mIGdyb3VuZCBzcXVpcnJlbCBidXJyb3cgb3BlbmluZ3MgaXMgYWxzbyByZWNvcmRlZCBmb3IgZWFjaCBwYXRjaC4NCg0KDQoNCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBlY2hvPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5wYXRoPSdvdXRwdXQvZmlncy8nLGZpZy53aWR0aCA9IDgsDQogZmlnLmhlaWdodCA9IDQsICAgICAgICAgICAgICBlY2hvPVRSVUUsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPSBGQUxTRSkNCg0KDQpvcHRpb25zKGFsbG93X2h0bWxfaW5fYWxsX291dHB1dHM9VFJVRSkNCmBgYA0KDQojIExpYnJhcnkNCg0KYGBge3IgbGlicmFyeX0NCiMgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCiMgd3JpdGVMaW5lcyhwYWNtYW46OnBfbGliKCksICJ+L0Rlc2t0b3AvbGlzdF9vZl9SX3BhY2thZ2VzLmNzdiIpICMgdG8gcXVpY2tseSBiYWNrIHVwIHBhY2thZ2VzDQojIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJUaGlua1Itb3Blbi9yZW1lZHkiKQ0KDQojIGluc3RhbGwucGFja2FnZXMoInJlbW90ZXMiKQ0KIyByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigic3RhdG5tYXAvY2FydG9taXNjIikNCg0KDQpwYWNtYW46OnBfbG9hZChyaW8sIHRpZHl2ZXJzZSxqYW5pdG9yLCBkYXRhLnRhYmxlLCBoZXJlLCBzdHJpbmdyLCBzdGF0cywgZ3JpZEV4dHJhLCB2dGFibGUsIHRhYmxlb25lLCBza2ltciwNCiAgICAgICAgICAgICAgIGdnc3RhdHMsDQogICAgICAgICAgICAgICBnZ3N0YXRzcGxvdCwNCiAgICAgICAgICAgICAgIGdnZGlzdCwNCiAgICAgICAgICAgICAgIGdnaGFsdmVzLA0KICAgICAgICAgICAgICAgcGx5ciwNCiAgICAgICAgICAgICAgIEhtaXNjLA0KICAgICAgICAgICAgICAgUkNvbG9yQnJld2VyLA0KICAgICAgICAgICAgICAgcmVzaGFwZTIsDQogICAgICAgICAgICAgICBkcGx5ciwNCiAgICAgICAgICAgICAgIGNsaSwNCiAgICAgICAgICAgICAgIGludHJvZGF0YXZpeiwNCiAgICAgICAgICAgICAgIGthYmxlRXh0cmEgDQoNCiAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgDQogICAgICAgICANCikgIyBqdXN0IGFkZCBuZWVkZWQgcGFja2FnZXMgdG8gdGhpcyBsaW5lIGFuZCBQYWNtYW4gd2lsbCBpbnN0YWxsIGFuZCBsb2FkIHRoZW0uDQoNCiMgZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJwc3l0ZWFjaHIvaW50cm9kYXRhdml6IikNCg0KDQpgYGANCg0KIyBEYXRhDQoNCg0KYGBge3IgbG9hZGF0YX0NCg0KDQpocnUgPC0gaW1wb3J0KCBoZXJlOjpoZXJlKCJkYXRhIiwiaHJ1c292YW55X2RlbnNpdGllcy5jc3YiKSkgJT4lIA0KICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpJT4lIA0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCBzdHJfdG9fdGl0bGUpICU+JSANCiAgbXV0YXRlKGhhYml0YXQgPSBpZmVsc2UoaGFiaXRhdCA9PSAiQmFja3lhcmQiLCAiR2FyZGVuIiwgaGFiaXRhdCkpICU+JSANCiAgbXV0YXRlKGhhYml0YXQgPSBpZmVsc2UoaGFiaXRhdCA9PSAiVHJlZSBBdmVudWUiLCAiVHJlZSBBbGxleSIsIGhhYml0YXQpKSAlPiUgDQogIG11dGF0ZShoYWJpdGF0ID0gaWZlbHNlKGhhYml0YXQgPT0gIk1vd2VkIExhd24iLCAiU2hvcnQtY3V0IExhd24iLCBoYWJpdGF0KSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGhhYml0YXQgPSAgaWZfZWxzZShoYWJpdGF0ID09ICJWaW5leWFyZHMiLCAiVmluZXlhcmQiLCBoYWJpdGF0KSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGRpc3RyaWN0ID0iSHJ1xaFvdmFueSIpICU+JSANCiAgbXV0YXRlX2lmKGlzLmNoYXJhY3RlciwgYXMuZmFjdG9yKQ0KICANCg0KICBzdW1tYXJ5KGhydSkNCg0KICB2cCA8LSBpbXBvcnQoIGhlcmU6OmhlcmUoImRhdGEiLCJ2cF9kZW5zaXRpZXMuY3N2IikpJT4lIA0KICAgIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIA0KICAgIGRwbHlyOjptdXRhdGUoZGlzdHJpY3QgPSAiUGF2bG92aWNlIiwgLmJlZm9yZT0gImlkIiklPiUgDQogICAgbXV0YXRlX2lmKGlzLmNoYXJhY3Rlciwgc3RyX3RvX3RpdGxlKSAlPiUgDQogICAgbXV0YXRlKGhhYml0YXQgPSBpZmVsc2UoaGFiaXRhdCA9PSAiQmFja3lhcmQiLCAiR2FyZGVuIiwgaGFiaXRhdCkpICU+JSANCiAgICBtdXRhdGUoaGFiaXRhdCA9IGlmZWxzZShoYWJpdGF0ID09ICJUcmVlIEF2ZW51ZSIsICJUcmVlIEFsbGV5IiwgaGFiaXRhdCkpICU+JSANCiAgICBtdXRhdGUoaGFiaXRhdCA9IGlmZWxzZShoYWJpdGF0ID09ICJNb3dlZCBMYXduIiwgIlNob3J0LWN1dCBMYXduIiwgaGFiaXRhdCkpICU+JSANCiAgICBkcGx5cjo6bXV0YXRlKGhhYml0YXQgPSAgaWZfZWxzZShoYWJpdGF0ID09ICJWaW5leWFyZHMiLCAiVmluZXlhcmQiLCBoYWJpdGF0KSkgJT4lIA0KICAgIG11dGF0ZV9pZihpcy5jaGFyYWN0ZXIsIGFzLmZhY3RvcikNCg0KIHN1bW1hcnkodnApDQogDQogY29sb25pZXMgPC0gIHJiaW5kKGhydSwgdnApICU+JSANCiAgIGRwbHlyOjptdXRhdGUoZGlzdHJpY3QgPSBhcy5mYWN0b3IoZGlzdHJpY3QpKQ0KIA0KIHN1bW1hcnkoY29sb25pZXMpDQogDQogIyBQcmVzZW5jZSBvbmx5DQogDQogaHJ1X3ByZXNlbmNlIDwtIGhydSAlPiUgDQogICBkcGx5cjo6ZmlsdGVyKGJvPjApDQogDQogdnBfcHJlc2VuY2UgPC0gdnAgJT4lIA0KICAgICAgZHBseXI6OmZpbHRlcihibz4wKQ0KIA0KIGNvbG9uaWVzX3ByZXMgPC0gY29sb25pZXMgJT4lIA0KICAgZHBseXI6OmZpbHRlcihibz4wKQ0KIA0KIA0KIHBsb3RfaHJ1IDwtIGltcG9ydChoZXJlOjpoZXJlKCJkYXRhIiwicGxvdF9zaXplX2hydS5jc3YiKSkgJT4lIA0KICAgY2xlYW5fbmFtZXMoKSAlPiUgDQogICBkcGx5cjo6bXV0YXRlKGRpc3RyaWN0ID0gIkhydXNvdmFueSIsIC5iZWZvcmU9ICJpZCIpDQogDQogDQogcGxvdF9wYSA8LSBpbXBvcnQoaGVyZTo6aGVyZSgiZGF0YSIsInBsb3Rfc2l6ZV9wYS5jc3YiKSkgJT4lIA0KICAgY2xlYW5fbmFtZXMoKSAlPiUgDQogICBkcGx5cjo6bXV0YXRlKGRpc3RyaWN0ID0gIlBhdmxvdmljZSIsIC5iZWZvcmU9ICJpZCIpDQogDQogIHBsb3RfZGF0YSA8LSAgcmJpbmQocGxvdF9ocnUsIHBsb3RfcGEpICU+JSANCiAgIGRwbHlyOjptdXRhdGUoZGlzdHJpY3QgPSBhcy5mYWN0b3IoZGlzdHJpY3QpKQ0KIA0KIA0KICAgDQpgYGANCg0KIyBFeHBsb3JlIGRhdGENCg0KIyMgU2l6ZSBvZiBhZ3JpY3VsdHVyYWwgcGxvdHMNCg0KYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NH0NCg0KIyBDcmVhdGUgdmlvbGluIHBsb3QgZm9yIEhydXNvdmFueQ0KZ2dwbG90KHBsb3RfaHJ1LCBhZXMoeD0xLCB5PXNpemVfaGEpKSArIA0KICBnZW9tX3Zpb2xpbigpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlKCJtZWFuID0gIixyb3VuZChtZWFuKHNpemVfaGEpLCAzKSwiLCBuID0gIixsZW5ndGgoc2l6ZV9oYSkpKSwNCiAgICAgICAgICAgIHk9MC4wNSwgbnVkZ2VfeT0gMC4wNSwgc2l6ZT0zKSArDQogIGdndGl0bGUoIkhydXNvdmFueSIpKw0KICB0aGVtZV9jbGFzc2ljKCkNCg0KDQoNCiMgQ3JlYXRlIHZpb2xpbiBwbG90IGZvciBQYXZsb3ZpY2UNCg0KDQpnZ3Bsb3QocGxvdF9wYSwgYWVzKHg9MSwgeT1zaXplX2hhKSkgKyANCiAgZ2VvbV92aW9saW4oKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZSgibWVhbiA9ICIscm91bmQobWVhbihzaXplX2hhKSwgMyksIiwgbiA9ICIsbGVuZ3RoKHNpemVfaGEpKSksDQogICAgICAgICAgICB5PSAtMC41LCBudWRnZV95PSAwLjA1LCBzaXplPTMpICsNCiAgZ2d0aXRsZSgiUGF2bG92aWNlIikgKw0KICB0aGVtZV9jbGFzc2ljKCkNCg0KDQpnZ2JldHdlZW5zdGF0cyhwbG90X2RhdGEsIGRpc3RyaWN0LCBzaXplX2hhKQ0KDQoNCmBgYA0KDQoNCg0KDQojIyBEZW5zaXR5DQpgYGB7cn0NCg0KDQp0YWJsZTEgPC0gY29sb25pZXMgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoZGlzdHJpY3QpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZShtZWFuX2RlbnNpdHkgPSBtZWFuKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWVkaWFuX2RlbnNpdHkgPSBtZWRpYW4oZGVuc2l0eSksDQogICAgICAgICAgICBtaW5fZGVuc2l0eSA9IG1pbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1heF9kZW5zaXR5ID0gbWF4KGRlbnNpdHkpLA0KICAgICAgICAgICAgICBzZF9kZW5zaXR5ID0gc2QoZGVuc2l0eSksDQogICAgICAgICAgICBuID0gbigpKQ0KDQojIE1vZGlmeSB0aGUgY29sdW1uIG5hbWVzIHRvIGNhcGl0YWxpemUgdGhlIGZpcnN0IGxldHRlciBhbmQgcmVtb3ZlIGh5cGhlbnMNCmNvbG5hbWVzKHRhYmxlMSkgPC0gc3RyX3RvX3RpdGxlKGdzdWIoIl8iLCAiICIsIGNvbG5hbWVzKHRhYmxlMSkpKQ0KICANCg0Ka2FibGUodGFibGUxLCBjYXB0aW9uID0gIlN1bW1hcnkgc3RhdGlzdGljcyBwZXIgZGlzdHJpY3QiKSAlPiUgDQogICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZvbnRfc2l6ZSA9IDEwLA0KICAgICAgICAgICAgICAgIGxhdGV4X29wdGlvbnMgPSAic3RyaXBlZCIpDQoNCg0KdGFibGUxIDwtIGNvbG9uaWVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0LCBoYWJpdGF0KSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpemUobWVhbl9kZW5zaXR5ID0gbWVhbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1lZGlhbl9kZW5zaXR5ID0gbWVkaWFuKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWluX2RlbnNpdHkgPSBtaW4oZGVuc2l0eSksDQogICAgICAgICAgICBtYXhfZGVuc2l0eSA9IG1heChkZW5zaXR5KSwNCiAgICAgICAgICAgICAgICAgc2RfZGVuc2l0eSA9IHNkKGRlbnNpdHkpLA0KICAgICAgICAgICAgbiA9IG4oKSkNCg0KIyBNb2RpZnkgdGhlIGNvbHVtbiBuYW1lcyB0byBjYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgYW5kIHJlbW92ZSBoeXBoZW5zDQpjb2xuYW1lcyh0YWJsZTEpIDwtIHN0cl90b190aXRsZShnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZTEpKSkNCg0Ka2FibGUodGFibGUxLCBjYXB0aW9uID0gIlN1bW1hcnkgc3RhdGlzdGljcyBwZXIgZGlzdHJpY3QgYW5kIGhhYml0YXQiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZm9udF9zaXplID0gMTAsDQogICAgICAgICAgICAgICAgbGF0ZXhfb3B0aW9ucyA9ICJzdHJpcGVkIikNCg0KDQoNCg0KdGFibGUxIDwtIGNvbG9uaWVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0LCBtYW5hZ2VtZW50KSAlPiUgDQogICAgZHBseXI6OnN1bW1hcml6ZShtZWFuX2RlbnNpdHkgPSBtZWFuKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWVkaWFuX2RlbnNpdHkgPSBtZWRpYW4oZGVuc2l0eSksDQogICAgICAgICAgICBtaW5fZGVuc2l0eSA9IG1pbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1heF9kZW5zaXR5ID0gbWF4KGRlbnNpdHkpLA0KICAgICAgICAgICAgICAgIHNkX2RlbnNpdHkgPSBzZChkZW5zaXR5KSwNCiAgICAgICAgICAgIG4gPSBuKCkpDQoNCiMgTW9kaWZ5IHRoZSBjb2x1bW4gbmFtZXMgdG8gY2FwaXRhbGl6ZSB0aGUgZmlyc3QgbGV0dGVyIGFuZCByZW1vdmUgaHlwaGVucw0KY29sbmFtZXModGFibGUxKSA8LSBzdHJfdG9fdGl0bGUoZ3N1YigiXyIsICIgIiwgY29sbmFtZXModGFibGUxKSkpDQoNCmthYmxlKHRhYmxlMSwgY2FwdGlvbiA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgcGVyIGRpc3RyaWN0IGFuZCBtYW5hZ2VtZW50IHR5cGUiKSAlPiUgDQogICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZvbnRfc2l6ZSA9IDEwLA0KICAgICAgICAgICAgICAgIGxhdGV4X29wdGlvbnMgPSAic3RyaXBlZCIpDQoNCg0KIyBIYWJpdGF0IGFuZCBtYW5hZ2VtZW50DQp0YWJsZTEgPC0gY29sb25pZXMgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoaGFiaXRhdCwgbWFuYWdlbWVudCkgJT4lIA0KICAgIGRwbHlyOjpzdW1tYXJpemUobWVhbl9kZW5zaXR5ID0gbWVhbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1lZGlhbl9kZW5zaXR5ID0gbWVkaWFuKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWluX2RlbnNpdHkgPSBtaW4oZGVuc2l0eSksDQogICAgICAgICAgICBtYXhfZGVuc2l0eSA9IG1heChkZW5zaXR5KSwNCiAgICAgICAgICAgICAgc2RfZGVuc2l0eSA9IHNkKGRlbnNpdHkpLA0KICAgICAgICAgICAgbiA9IG4oKSkNCg0KIyBNb2RpZnkgdGhlIGNvbHVtbiBuYW1lcyB0byBjYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgYW5kIHJlbW92ZSBoeXBoZW5zDQpjb2xuYW1lcyh0YWJsZTEpIDwtIHN0cl90b190aXRsZShnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZTEpKSkNCg0Ka2FibGUodGFibGUxLCBjYXB0aW9uID0gIlN1bW1hcnkgc3RhdGlzdGljcyBwZXIgaGFiaXRhdCBhbmQgbWFuYWdlbWVudCB0eXBlIikgJT4lIA0KICAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMCwNCiAgICAgICAgICAgICAgICBsYXRleF9vcHRpb25zID0gInN0cmlwZWQiKQ0KDQoNCmBgYA0KDQoNCiMjIyBQcmVzZW5jZSBvbmx5DQoNCmBgYHtyfQ0KDQp0YWJsZTEgPC0gY29sb25pZXNfcHJlcyAlPiUgDQogIGRwbHlyOjpncm91cF9ieShkaXN0cmljdCkgJT4lIA0KICAgIGRwbHlyOjpzdW1tYXJpemUobWVhbl9kZW5zaXR5ID0gbWVhbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1lZGlhbl9kZW5zaXR5ID0gbWVkaWFuKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWluX2RlbnNpdHkgPSBtaW4oZGVuc2l0eSksDQogICAgICAgICAgICBtYXhfZGVuc2l0eSA9IG1heChkZW5zaXR5KSwNCiAgICAgICAgICAgICAgICBzZF9kZW5zaXR5ID0gc2QoZGVuc2l0eSksDQogICAgICAgICAgICBuID0gbigpKQ0KDQojIE1vZGlmeSB0aGUgY29sdW1uIG5hbWVzIHRvIGNhcGl0YWxpemUgdGhlIGZpcnN0IGxldHRlciBhbmQgcmVtb3ZlIGh5cGhlbnMNCmNvbG5hbWVzKHRhYmxlMSkgPC0gc3RyX3RvX3RpdGxlKGdzdWIoIl8iLCAiICIsIGNvbG5hbWVzKHRhYmxlMSkpKQ0KICANCg0Ka2FibGUodGFibGUxLCBjYXB0aW9uID0gIlN1bW1hcnkgc3RhdGlzdGljcyBwZXIgZGlzdHJpY3QgLSBQcmVzZW5jZSBvbmx5IikgJT4lIA0KICAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMCwNCiAgICAgICAgICAgICAgICBsYXRleF9vcHRpb25zID0gInN0cmlwZWQiKQ0KDQoNCnRhYmxlMSA8LSBjb2xvbmllc19wcmVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0LCBoYWJpdGF0KSAlPiUgDQogICAgZHBseXI6OnN1bW1hcml6ZShtZWFuX2RlbnNpdHkgPSBtZWFuKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWVkaWFuX2RlbnNpdHkgPSBtZWRpYW4oZGVuc2l0eSksDQogICAgICAgICAgICBtaW5fZGVuc2l0eSA9IG1pbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1heF9kZW5zaXR5ID0gbWF4KGRlbnNpdHkpLA0KICAgICAgICAgICAgICAgICBzZF9kZW5zaXR5ID0gc2QoZGVuc2l0eSksDQogICAgICAgICAgICBuID0gbigpKQ0KDQojIE1vZGlmeSB0aGUgY29sdW1uIG5hbWVzIHRvIGNhcGl0YWxpemUgdGhlIGZpcnN0IGxldHRlciBhbmQgcmVtb3ZlIGh5cGhlbnMNCmNvbG5hbWVzKHRhYmxlMSkgPC0gc3RyX3RvX3RpdGxlKGdzdWIoIl8iLCAiICIsIGNvbG5hbWVzKHRhYmxlMSkpKQ0KDQprYWJsZSh0YWJsZTEsIGNhcHRpb24gPSAiU3VtbWFyeSBzdGF0aXN0aWNzIHBlciBkaXN0cmljdCBhbmQgaGFiaXRhdCAtIFByZXNlbmNlIG9ubHkiKSAlPiUgDQogICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZvbnRfc2l6ZSA9IDEwLA0KICAgICAgICAgICAgICAgIGxhdGV4X29wdGlvbnMgPSAic3RyaXBlZCIpDQoNCg0KDQoNCnRhYmxlMSA8LSBjb2xvbmllc19wcmVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0LCBtYW5hZ2VtZW50KSAlPiUgDQogICAgZHBseXI6OnN1bW1hcml6ZShtZWFuX2RlbnNpdHkgPSBtZWFuKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWVkaWFuX2RlbnNpdHkgPSBtZWRpYW4oZGVuc2l0eSksDQogICAgICAgICAgICBtaW5fZGVuc2l0eSA9IG1pbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1heF9kZW5zaXR5ID0gbWF4KGRlbnNpdHkpLA0KICAgICAgICAgICAgICAgICBzZF9kZW5zaXR5ID0gc2QoZGVuc2l0eSksDQogICAgICAgICAgICBuID0gbigpKQ0KDQojIE1vZGlmeSB0aGUgY29sdW1uIG5hbWVzIHRvIGNhcGl0YWxpemUgdGhlIGZpcnN0IGxldHRlciBhbmQgcmVtb3ZlIGh5cGhlbnMNCmNvbG5hbWVzKHRhYmxlMSkgPC0gc3RyX3RvX3RpdGxlKGdzdWIoIl8iLCAiICIsIGNvbG5hbWVzKHRhYmxlMSkpKQ0KDQprYWJsZSh0YWJsZTEsIGNhcHRpb24gPSAiU3VtbWFyeSBzdGF0aXN0aWNzIHBlciBkaXN0cmljdCBhbmQgbWFuYWdlbWVudCB0eXBlIC0gUHJlc2VuY2Ugb25seSIpICU+JSANCiAgIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZm9udF9zaXplID0gMTAsDQogICAgICAgICAgICAgICAgbGF0ZXhfb3B0aW9ucyA9ICJzdHJpcGVkIikNCg0KDQojIEhhYml0YXQgYW5kIG1hbmFnZW1lbnQNCnRhYmxlMSA8LSBjb2xvbmllc19wcmVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGhhYml0YXQsIG1hbmFnZW1lbnQpICU+JSANCiAgICBkcGx5cjo6c3VtbWFyaXplKG1lYW5fZGVuc2l0eSA9IG1lYW4oZGVuc2l0eSksDQogICAgICAgICAgICBtZWRpYW5fZGVuc2l0eSA9IG1lZGlhbihkZW5zaXR5KSwNCiAgICAgICAgICAgIG1pbl9kZW5zaXR5ID0gbWluKGRlbnNpdHkpLA0KICAgICAgICAgICAgbWF4X2RlbnNpdHkgPSBtYXgoZGVuc2l0eSksDQogICAgICAgICAgICAgICAgIHNkX2RlbnNpdHkgPSBzZChkZW5zaXR5KSwNCiAgICAgICAgICAgIG4gPSBuKCkpDQoNCiMgTW9kaWZ5IHRoZSBjb2x1bW4gbmFtZXMgdG8gY2FwaXRhbGl6ZSB0aGUgZmlyc3QgbGV0dGVyIGFuZCByZW1vdmUgaHlwaGVucw0KY29sbmFtZXModGFibGUxKSA8LSBzdHJfdG9fdGl0bGUoZ3N1YigiXyIsICIgIiwgY29sbmFtZXModGFibGUxKSkpDQoNCmthYmxlKHRhYmxlMSwgY2FwdGlvbiA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgcGVyIGhhYml0YXQgYW5kIG1hbmFnZW1lbnQgdHlwZSAtIFByZXNlbmNlIG9ubHkiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZm9udF9zaXplID0gMTAsDQogICAgICAgICAgICAgICAgbGF0ZXhfb3B0aW9ucyA9ICJzdHJpcGVkIikNCg0KYGBgDQoNCiMjIFNpemUgb2YgcGxvdHMNCg0KYGBge3J9DQoNCg0KdGFibGUxIDwtIGNvbG9uaWVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0KSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpemUobWVhbl9hcmVhID0gbWVhbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1lZGlhbl9hcmVhID0gbWVkaWFuKHNpemVfaGEpLA0KICAgICAgICAgICAgbWluX2FyZWEgPSBtaW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtYXhfYXJlYSA9IG1heChzaXplX2hhKSwNCiAgICAgICAgICAgICAgc2RfYXJlYSA9IHNkKHNpemVfaGEpLA0KICAgICAgICAgICAgbiA9IG4oKSkNCg0KIyBNb2RpZnkgdGhlIGNvbHVtbiBuYW1lcyB0byBjYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgYW5kIHJlbW92ZSBoeXBoZW5zDQpjb2xuYW1lcyh0YWJsZTEpIDwtIHN0cl90b190aXRsZShnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZTEpKSkNCiAgDQoNCmthYmxlKHRhYmxlMSwgY2FwdGlvbiA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgcGVyIGRpc3RyaWN0IikgJT4lIA0KICAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMCwNCiAgICAgICAgICAgICAgICBsYXRleF9vcHRpb25zID0gInN0cmlwZWQiKQ0KDQoNCnRhYmxlMSA8LSBjb2xvbmllcyAlPiUgDQogIGRwbHlyOjpncm91cF9ieShkaXN0cmljdCwgaGFiaXRhdCkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXplKG1lYW5fYXJlYSA9IG1lYW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtZWRpYW5fYXJlYSA9IG1lZGlhbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1pbl9hcmVhID0gbWluKHNpemVfaGEpLA0KICAgICAgICAgICAgbWF4X2FyZWEgPSBtYXgoc2l6ZV9oYSksDQogICAgICAgICAgICAgIHNkX2FyZWEgPSBzZChzaXplX2hhKSwNCiAgICAgICAgICAgIG4gPSBuKCkpDQoNCiMgTW9kaWZ5IHRoZSBjb2x1bW4gbmFtZXMgdG8gY2FwaXRhbGl6ZSB0aGUgZmlyc3QgbGV0dGVyIGFuZCByZW1vdmUgaHlwaGVucw0KY29sbmFtZXModGFibGUxKSA8LSBzdHJfdG9fdGl0bGUoZ3N1YigiXyIsICIgIiwgY29sbmFtZXModGFibGUxKSkpDQoNCmthYmxlKHRhYmxlMSwgY2FwdGlvbiA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgcGVyIGRpc3RyaWN0IGFuZCBoYWJpdGF0IikgJT4lIA0KICAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMCwNCiAgICAgICAgICAgICAgICBsYXRleF9vcHRpb25zID0gInN0cmlwZWQiKQ0KDQoNCg0KDQp0YWJsZTEgPC0gY29sb25pZXMgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoZGlzdHJpY3QsIG1hbmFnZW1lbnQpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZShtZWFuX2FyZWEgPSBtZWFuKHNpemVfaGEpLA0KICAgICAgICAgICAgbWVkaWFuX2FyZWEgPSBtZWRpYW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtaW5fYXJlYSA9IG1pbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1heF9hcmVhID0gbWF4KHNpemVfaGEpLA0KICAgICAgICAgICAgICBzZF9hcmVhID0gc2Qoc2l6ZV9oYSksDQogICAgICAgICAgICBuID0gbigpKQ0KDQojIE1vZGlmeSB0aGUgY29sdW1uIG5hbWVzIHRvIGNhcGl0YWxpemUgdGhlIGZpcnN0IGxldHRlciBhbmQgcmVtb3ZlIGh5cGhlbnMNCmNvbG5hbWVzKHRhYmxlMSkgPC0gc3RyX3RvX3RpdGxlKGdzdWIoIl8iLCAiICIsIGNvbG5hbWVzKHRhYmxlMSkpKQ0KDQprYWJsZSh0YWJsZTEsIGNhcHRpb24gPSAiU3VtbWFyeSBzdGF0aXN0aWNzIHBlciBkaXN0cmljdCBhbmQgbWFuYWdlbWVudCB0eXBlIikgJT4lIA0KIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZm9udF9zaXplID0gMTAsDQogICAgICAgICAgICAgICAgbGF0ZXhfb3B0aW9ucyA9ICJzdHJpcGVkIikNCg0KDQojIEhhYml0YXQgYW5kIG1hbmFnZW1lbnQNCnRhYmxlMSA8LSBjb2xvbmllcyAlPiUgDQogIGRwbHlyOjpncm91cF9ieShoYWJpdGF0LCBtYW5hZ2VtZW50KSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpemUobWVhbl9hcmVhID0gbWVhbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1lZGlhbl9hcmVhID0gbWVkaWFuKHNpemVfaGEpLA0KICAgICAgICAgICAgbWluX2FyZWEgPSBtaW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtYXhfYXJlYSA9IG1heChzaXplX2hhKSwNCiAgICAgICAgICAgICAgc2RfYXJlYSA9IHNkKHNpemVfaGEpLA0KICAgICAgICAgICAgbiA9IG4oKSkNCg0KIyBNb2RpZnkgdGhlIGNvbHVtbiBuYW1lcyB0byBjYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgYW5kIHJlbW92ZSBoeXBoZW5zDQpjb2xuYW1lcyh0YWJsZTEpIDwtIHN0cl90b190aXRsZShnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZTEpKSkNCg0Ka2FibGUodGFibGUxLCBjYXB0aW9uID0gIlN1bW1hcnkgc3RhdGlzdGljcyBwZXIgaGFiaXRhdCBhbmQgbWFuYWdlbWVudCB0eXBlIikgJT4lIA0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZvbnRfc2l6ZSA9IDEwLA0KICAgICAgICAgICAgICAgIGxhdGV4X29wdGlvbnMgPSAic3RyaXBlZCIpDQoNCg0KYGBgDQoNCg0KIyMjIFByZXNlbmNlIG9ubHkNCg0KYGBge3J9DQoNCnRhYmxlMSA8LSBjb2xvbmllc19wcmVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0KSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpemUobWVhbl9hcmVhID0gbWVhbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1lZGlhbl9hcmVhID0gbWVkaWFuKHNpemVfaGEpLA0KICAgICAgICAgICAgbWluX2FyZWEgPSBtaW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtYXhfYXJlYSA9IG1heChzaXplX2hhKSwNCiAgICAgICAgICAgICAgc2RfYXJlYSA9IHNkKHNpemVfaGEpLA0KICAgICAgICAgICAgbiA9IG4oKSkNCg0KIyBNb2RpZnkgdGhlIGNvbHVtbiBuYW1lcyB0byBjYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgYW5kIHJlbW92ZSBoeXBoZW5zDQpjb2xuYW1lcyh0YWJsZTEpIDwtIHN0cl90b190aXRsZShnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZTEpKSkNCiAgDQoNCmthYmxlKHRhYmxlMSwgY2FwdGlvbiA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgcGVyIGRpc3RyaWN0IC0gUHJlc2VuY2Ugb25seSIpICU+JSANCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMCwNCiAgICAgICAgICAgICAgICBsYXRleF9vcHRpb25zID0gInN0cmlwZWQiKQ0KDQoNCnRhYmxlMSA8LSBjb2xvbmllc19wcmVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0LCBoYWJpdGF0KSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpemUobWVhbl9hcmVhID0gbWVhbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1lZGlhbl9hcmVhID0gbWVkaWFuKHNpemVfaGEpLA0KICAgICAgICAgICAgbWluX2FyZWEgPSBtaW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtYXhfYXJlYSA9IG1heChzaXplX2hhKSwNCiAgICAgICAgICAgICAgc2RfYXJlYSA9IHNkKHNpemVfaGEpLA0KICAgICAgICAgICAgbiA9IG4oKSkNCg0KIyBNb2RpZnkgdGhlIGNvbHVtbiBuYW1lcyB0byBjYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgYW5kIHJlbW92ZSBoeXBoZW5zDQpjb2xuYW1lcyh0YWJsZTEpIDwtIHN0cl90b190aXRsZShnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZTEpKSkNCg0Ka2FibGUodGFibGUxLCBjYXB0aW9uID0gIlN1bW1hcnkgc3RhdGlzdGljcyBwZXIgZGlzdHJpY3QgYW5kIGhhYml0YXQgLSBQcmVzZW5jZSBvbmx5IikgJT4lIA0KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGZvbnRfc2l6ZSA9IDEwLA0KICAgICAgICAgICAgICAgIGxhdGV4X29wdGlvbnMgPSAic3RyaXBlZCIpDQoNCg0KDQoNCnRhYmxlMSA8LSBjb2xvbmllc19wcmVzICU+JSANCiAgZHBseXI6Omdyb3VwX2J5KGRpc3RyaWN0LCBtYW5hZ2VtZW50KSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpemUobWVhbl9hcmVhID0gbWVhbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1lZGlhbl9hcmVhID0gbWVkaWFuKHNpemVfaGEpLA0KICAgICAgICAgICAgbWluX2FyZWEgPSBtaW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtYXhfYXJlYSA9IG1heChzaXplX2hhKSwNCiAgICAgICAgICAgICAgc2RfYXJlYSA9IHNkKHNpemVfaGEpLA0KICAgICAgICAgICAgbiA9IG4oKSkNCg0KIyBNb2RpZnkgdGhlIGNvbHVtbiBuYW1lcyB0byBjYXBpdGFsaXplIHRoZSBmaXJzdCBsZXR0ZXIgYW5kIHJlbW92ZSBoeXBoZW5zDQpjb2xuYW1lcyh0YWJsZTEpIDwtIHN0cl90b190aXRsZShnc3ViKCJfIiwgIiAiLCBjb2xuYW1lcyh0YWJsZTEpKSkNCg0Ka2FibGUodGFibGUxLCBjYXB0aW9uID0gIlN1bW1hcnkgc3RhdGlzdGljcyBwZXIgZGlzdHJpY3QgYW5kIG1hbmFnZW1lbnQgdHlwZSAtIFByZXNlbmNlIG9ubHkiKSAlPiUgDQoga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmb250X3NpemUgPSAxMCwNCiAgICAgICAgICAgICAgICBsYXRleF9vcHRpb25zID0gInN0cmlwZWQiKQ0KDQoNCiMgSGFiaXRhdCBhbmQgbWFuYWdlbWVudA0KdGFibGUxIDwtIGNvbG9uaWVzX3ByZXMgJT4lIA0KICBkcGx5cjo6Z3JvdXBfYnkoaGFiaXRhdCwgbWFuYWdlbWVudCkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXplKG1lYW5fYXJlYSA9IG1lYW4oc2l6ZV9oYSksDQogICAgICAgICAgICBtZWRpYW5fYXJlYSA9IG1lZGlhbihzaXplX2hhKSwNCiAgICAgICAgICAgIG1pbl9hcmVhID0gbWluKHNpemVfaGEpLA0KICAgICAgICAgICAgbWF4X2FyZWEgPSBtYXgoc2l6ZV9oYSksDQogICAgICAgICAgICAgIHNkX2FyZWEgPSBzZChzaXplX2hhKSwNCiAgICAgICAgICAgIG4gPSBuKCkpDQoNCiMgTW9kaWZ5IHRoZSBjb2x1bW4gbmFtZXMgdG8gY2FwaXRhbGl6ZSB0aGUgZmlyc3QgbGV0dGVyIGFuZCByZW1vdmUgaHlwaGVucw0KY29sbmFtZXModGFibGUxKSA8LSBzdHJfdG9fdGl0bGUoZ3N1YigiXyIsICIgIiwgY29sbmFtZXModGFibGUxKSkpDQoNCmthYmxlKHRhYmxlMSwgY2FwdGlvbiA9ICJTdW1tYXJ5IHN0YXRpc3RpY3MgcGVyIGhhYml0YXQgYW5kIG1hbmFnZW1lbnQgdHlwZSAtIFByZXNlbmNlIG9ubHkiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoZm9udF9zaXplID0gMTAsDQogICAgICAgICAgICAgICAgbGF0ZXhfb3B0aW9ucyA9ICJzdHJpcGVkIikNCg0KYGBgDQoNCiMgQm94cGxvdHMNCg0KIyMgSGFiaXRhdCB0eXBlDQoNCkkgd291bGQgcmVtb3ZlIHRoZSBtZWFucyBmcm9tIHRoZSBwbG90cyBhbmQgbGVhdmUgdGhlIHN0YXRzIGZvciBUYWJsZSAxIChwZXJoYXBzIFRhYmxlIDEgYSwgYikNCg0KYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9DQojIENvbXB1dGUgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgZm9yIGVhY2ggaGFiaXRhdCB0eXBlDQpuIDwtIGNvbG9uaWVzICU+JSANCiAgZ3JvdXBfYnkoaGFiaXRhdCwgZGlzdHJpY3QpICU+JSANCiAgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKQ0KDQojIEZpbmQgdGhlIG1heGltdW0gZGVuc2l0eSB2YWx1ZSBmb3IgZWFjaCBkaXN0cmljdA0KbWF4X2RlbnNpdHkgPC0gY29sb25pZXMgJT4lIGdyb3VwX2J5KGRpc3RyaWN0KSAlPiUgZHBseXI6OnN1bW1hcmlzZShtYXhfZGVuc2l0eSA9IG1heChkZW5zaXR5KSkNCg0KIyBKb2luIHRoZSBuIGFuZCBtYXhfZGVuc2l0eSBkYXRhIGZyYW1lcw0KbiA8LSBsZWZ0X2pvaW4obiwgbWF4X2RlbnNpdHksIGJ5ID0gYygiZGlzdHJpY3QiID0gImRpc3RyaWN0IikpDQoNCmdncGxvdChjb2xvbmllcywgYWVzKHg9aGFiaXRhdCwgeT1kZW5zaXR5KSkgKyANCiAgZ2VvbV9ib3hwbG90KCkgKw0KICB4bGFiKCIiKSArIHlsYWIoIkRlbnNpdHkgKGJ1cnJvdyBvcGVuaW5ncy9oYSkiKSArDQogIGdndGl0bGUoIkRlbnNpdHkgb2YgYnVycm93IG9wZW5pbmdzIGJ5IGhhYml0YXQgdHlwZSIpKw0KICBmYWNldF9ncmlkKC4gfiBkaXN0cmljdCwgc2NhbGVzID0gImZyZWVfeCIpKw0KICBnZW9tX3RleHQoZGF0YT1uLCBhZXMoeD1oYWJpdGF0LCB5PW1heF9kZW5zaXR5LTUsIGxhYmVsPXBhc3RlKCJuID0iLCBuKSksIHZqdXN0PS0xLjEsIHNpemU9My41LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgwLjQpKSsNCiAgY29vcmRfZmxpcCgpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQoNCg0KYGBgDQoNCg0KIyMjIFNhbWUgc2NhbGUgZXhhbXBsZSAoSSBwcmVmZXIgdGhlIHZlcnNpb24gd2l0aCBkaWZmZXJlbnQgc2NhbGVzKQ0KDQpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0NCiMgQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBmb3IgZWFjaCBoYWJpdGF0IHR5cGUNCm4gPC0gY29sb25pZXMgJT4lIA0KICBncm91cF9ieShoYWJpdGF0LCBkaXN0cmljdCkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXNlKG4gPSBuKCkpDQoNCiMgRmluZCB0aGUgbWF4aW11bSBkZW5zaXR5IHZhbHVlIGZvciBlYWNoIGRpc3RyaWN0DQptYXhfZGVuc2l0eSA8LSBjb2xvbmllcyAlPiUgZ3JvdXBfYnkoZGlzdHJpY3QpICU+JSBkcGx5cjo6c3VtbWFyaXNlKG1heF9kZW5zaXR5ID0gbWF4KGRlbnNpdHkpKQ0KDQojIEpvaW4gdGhlIG4gYW5kIG1heF9kZW5zaXR5IGRhdGEgZnJhbWVzDQpuIDwtIGxlZnRfam9pbihuLCBtYXhfZGVuc2l0eSwgYnkgPSBjKCJkaXN0cmljdCIgPSAiZGlzdHJpY3QiKSkNCg0KZ2dwbG90KGNvbG9uaWVzLCBhZXMoeD1oYWJpdGF0LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgaGFiaXRhdCB0eXBlIikrDQogIGZhY2V0X2dyaWQoLiB+IGRpc3RyaWN0KSsNCiAgZ2VvbV90ZXh0KGRhdGE9biwgYWVzKHg9aGFiaXRhdCwgeT1tYXhfZGVuc2l0eS01LCBsYWJlbD1wYXN0ZSgibiA9IiwgbikpLCB2anVzdD0tMS4xLCBzaXplPTMuNSwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoMC40KSkrDQogIGNvb3JkX2ZsaXAoKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KYGBgDQoNCg0KIyMgTWFuYWdlbWVudA0KDQpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0NCiMgQ29tcHV0ZSB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBmb3IgZWFjaCBoYWJpdGF0IHR5cGUNCm4gPC0gY29sb25pZXMgJT4lIA0KICBncm91cF9ieShtYW5hZ2VtZW50LCBkaXN0cmljdCkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXNlKG4gPSBuKCkpDQoNCiMgRmluZCB0aGUgbWF4aW11bSBkZW5zaXR5IHZhbHVlIGZvciBlYWNoIGRpc3RyaWN0DQptYXhfZGVuc2l0eSA8LSBjb2xvbmllcyAlPiUgZ3JvdXBfYnkoZGlzdHJpY3QpICU+JSBkcGx5cjo6c3VtbWFyaXNlKG1heF9kZW5zaXR5ID0gbWF4KGRlbnNpdHkpKQ0KDQojIEpvaW4gdGhlIG4gYW5kIG1heF9kZW5zaXR5IGRhdGEgZnJhbWVzDQpuIDwtIGxlZnRfam9pbihuLCBtYXhfZGVuc2l0eSwgYnkgPSBjKCJkaXN0cmljdCIgPSAiZGlzdHJpY3QiKSkNCg0KZ2dwbG90KGNvbG9uaWVzLCBhZXMoeD1tYW5hZ2VtZW50LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgbWFuYWdlbWVudCB0eXBlIikrDQogIGZhY2V0X2dyaWQoLiB+IGRpc3RyaWN0LCBzY2FsZXMgPSAiZnJlZV94IikrDQogIGdlb21fdGV4dChkYXRhPW4sIGFlcyh4PW1hbmFnZW1lbnQsIHk9bWF4X2RlbnNpdHktMTAsIGxhYmVsPXBhc3RlKCJuID0iLCBuKSksIHZqdXN0PS0xLjEsIHNpemU9My41LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgwLjQpKSsNCiAgY29vcmRfZmxpcCgpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGANCg0KDQoNCg0KYGBge3J9DQoNCg0KDQpnZ3Bsb3QoaHJ1LCBhZXMoeD1oYWJpdGF0LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgSGFiaXRhdCBpbiBIcnVzb3ZhbnkiKSsNCiAgY29vcmRfZmxpcCgpDQoNCmdncGxvdCh2cCwgYWVzKHg9aGFiaXRhdCwgeT1kZW5zaXR5KSkgKyANCiAgZ2VvbV9ib3hwbG90KCkgKw0KICB4bGFiKCIiKSArIHlsYWIoIkRlbnNpdHkgKGJ1cnJvdyBvcGVuaW5ncy9oYSkiKSArDQogIGdndGl0bGUoIkRlbnNpdHkgb2YgYnVycm93IG9wZW5pbmdzIGJ5IEhhYml0YXQgaW4gVmVsa2UgUGF2bG92aWNlIikrDQogIGNvb3JkX2ZsaXAoKQ0KDQpnZ3Bsb3QoaHJ1LCBhZXMoeD1tYW5hZ2VtZW50LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgbWFuYWdlbWVudCB0eXBlIGluIEhydXNvdmFueSIpKw0KICBjb29yZF9mbGlwKCkNCg0KZ2dwbG90KHZwLCBhZXMoeD1tYW5hZ2VtZW50LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgbWFuYWdlbWVudCB0eXBlIGluIFZlbGtlIFBhdmxvdmljZSIpKw0KICBjb29yZF9mbGlwKCkNCg0KYGBgDQoNCiMgUHJlc2VuY2Ugb25seQ0KDQpGb3IgQk9zID4gMCBvbmx5LiBJdCBjYW4gYmUgbWlzbGVhZGluZy4gTmVlZHMgdG8gYmUgY2xlYXJseSBzdGF0ZWQuDQoNCmBgYHtyfQ0KZ2dwbG90KGNvbG9uaWVzX3ByZXMsIGFlcyh4PWhhYml0YXQsIHk9ZGVuc2l0eSkpICsgDQogIGdlb21fYm94cGxvdCgpICsNCiAgeGxhYigiIikgKyB5bGFiKCJEZW5zaXR5IChidXJyb3cgb3BlbmluZ3MvaGEpIikgKw0KICBnZ3RpdGxlKCJEZW5zaXR5IG9mIGJ1cnJvdyBvcGVuaW5ncyBieSBIYWJpdGF0IC0gUHJlc2VuY2Ugb25seSIpKw0KICBmYWNldF9ncmlkKC4gfiBkaXN0cmljdCwgc2NhbGVzID0gImZyZWVfeCIpKw0KICBjb29yZF9mbGlwKCkNCg0KDQpnZ3Bsb3QoY29sb25pZXNfcHJlcywgYWVzKHg9bWFuYWdlbWVudCwgeT1kZW5zaXR5KSkgKyANCiAgZ2VvbV9ib3hwbG90KCkgKw0KICB4bGFiKCIiKSArIHlsYWIoIkRlbnNpdHkgKGJ1cnJvdyBvcGVuaW5ncy9oYSkiKSArDQogIGdndGl0bGUoIkRlbnNpdHkgb2YgYnVycm93IG9wZW5pbmdzIGJ5IE1hbmFnZW1lbnQgLSBQcmVzZW5jZSBvbmx5IikrDQogICAgZmFjZXRfZ3JpZCguIH4gZGlzdHJpY3QsIHNjYWxlcyA9ICJmcmVlX3giKSsNCiAgY29vcmRfZmxpcCgpDQoNCmBgYA0KDQoNCiMjIEJvdGggd2l0aCBuDQoNCiMjIyBIYWJpdGF0DQpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0NCg0KIyBMb2FkIHRoZSBkcGx5ciBwYWNrYWdlDQoNCg0KIyBDb21wdXRlIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIGZvciBlYWNoIGhhYml0YXQgYW5kIG1hbmFnZW1lbnQgdHlwZQ0KbmNfaGFiaXRhdCA8LSBjb2xvbmllc19wcmVzICU+JSANCiAgZ3JvdXBfYnkoaGFiaXRhdCwgZGlzdHJpY3QpICU+JSANCiAgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKQ0KDQojIEZpbmQgdGhlIG1heGltdW0gZGVuc2l0eSB2YWx1ZSBmb3IgZWFjaCBkaXN0cmljdA0KbWF4X2RlbnNpdHkgPC0gY29sb25pZXNfcHJlcyAlPiUgZ3JvdXBfYnkoZGlzdHJpY3QpICU+JSBkcGx5cjo6c3VtbWFyaXNlKG1heF9kZW5zaXR5ID0gbWF4KGRlbnNpdHkpKQ0KDQojIEpvaW4gdGhlIG4gYW5kIG1heF9kZW5zaXR5IGRhdGEgZnJhbWVzDQpuY19oYWJpdGF0IDwtIGxlZnRfam9pbihuY19oYWJpdGF0LCBtYXhfZGVuc2l0eSwgYnkgPSBjKCJkaXN0cmljdCIgPSAiZGlzdHJpY3QiKSkNCg0KIyBHZW5lcmF0ZSB0aGUgcGxvdA0KcCA8LSBnZ3Bsb3QoY29sb25pZXNfcHJlcywgYWVzKHg9aGFiaXRhdCwgeT1kZW5zaXR5KSkgKyANCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBnZW9tX3RleHQoZGF0YT1uY19oYWJpdGF0LCBhZXMoeD1oYWJpdGF0LCB5PW1heF9kZW5zaXR5LTUsIGxhYmVsPXBhc3RlKCJuID0iLCBuKSksIHZqdXN0PS0xLjEsIHNpemU9My41LCBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgwLjQpKSArICAjIGFkZCBuIHRvIHRoZSBmYWNldHMNCiAgeGxhYigiIikgKyB5bGFiKCJEZW5zaXR5IChidXJyb3cgb3BlbmluZ3MvaGEpIikgKw0KICBnZ3RpdGxlKCJEZW5zaXR5IG9mIGJ1cnJvdyBvcGVuaW5ncyBieSBoYWJpdGF0IHR5cGUgLSBQcmVzZW5jZSBvbmx5IikrDQogIGZhY2V0X2dyaWQoLiB+IGRpc3RyaWN0LCBzY2FsZXMgPSAiZnJlZV94IikrDQogIGNvb3JkX2ZsaXAoKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KDQojIFNob3cgdGhlIHBsb3QNCnANCg0KDQoNCmBgYA0KDQoNCiMjIyBTYW1lIHNjYWxlIGV4YW1wbGUgKEkgc3RpbGwgcHJlZmVyIHRoZSB2ZXJzaW9uIHdpdGggZGlmZmVyZW50IHNjYWxlcykNCg0KYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9DQojIENvbXB1dGUgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgZm9yIGVhY2ggaGFiaXRhdCBhbmQgbWFuYWdlbWVudCB0eXBlDQpuY19oYWJpdGF0IDwtIGNvbG9uaWVzX3ByZXMgJT4lIA0KICBncm91cF9ieShoYWJpdGF0LCBkaXN0cmljdCkgJT4lIA0KICBkcGx5cjo6c3VtbWFyaXNlKG4gPSBuKCkpDQoNCiMgRmluZCB0aGUgbWF4aW11bSBkZW5zaXR5IHZhbHVlIGZvciBlYWNoIGRpc3RyaWN0DQptYXhfZGVuc2l0eSA8LSBjb2xvbmllc19wcmVzICU+JSBncm91cF9ieShkaXN0cmljdCkgJT4lIGRwbHlyOjpzdW1tYXJpc2UobWF4X2RlbnNpdHkgPSBtYXgoZGVuc2l0eSkpDQoNCiMgSm9pbiB0aGUgbiBhbmQgbWF4X2RlbnNpdHkgZGF0YSBmcmFtZXMNCm5jX2hhYml0YXQgPC0gbGVmdF9qb2luKG5jX2hhYml0YXQsIG1heF9kZW5zaXR5LCBieSA9IGMoImRpc3RyaWN0IiA9ICJkaXN0cmljdCIpKQ0KDQojIEdlbmVyYXRlIHRoZSBwbG90DQpwIDwtIGdncGxvdChjb2xvbmllc19wcmVzLCBhZXMoeD1oYWJpdGF0LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIGdlb21fdGV4dChkYXRhPW5jX2hhYml0YXQsIGFlcyh4PWhhYml0YXQsIHk9bWF4X2RlbnNpdHktNSwgbGFiZWw9cGFzdGUoIm4gPSIsIG4pKSwgdmp1c3Q9LTEuMSwgc2l6ZT0zLjUsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuNCkpICsgICMgYWRkIG4gdG8gdGhlIGZhY2V0cw0KICB4bGFiKCIiKSArIHlsYWIoIkRlbnNpdHkgKGJ1cnJvdyBvcGVuaW5ncy9oYSkiKSArDQogIGdndGl0bGUoIkRlbnNpdHkgb2YgYnVycm93IG9wZW5pbmdzIGJ5IGhhYml0YXQgdHlwZSAtIFByZXNlbmNlIG9ubHkiKSsNCiAgZmFjZXRfZ3JpZCguIH4gZGlzdHJpY3QpKw0KICBjb29yZF9mbGlwKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KIyBTaG93IHRoZSBwbG90DQpwDQoNCmBgYA0KDQoNCg0KDQojIyMgTWFuYWdlbWVudA0KDQpgYGB7ciBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0NCg0KIyBDb21wdXRlIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIGZvciBlYWNoIG1hbmFnZW1lbnQgYW5kIGRpc3RyaWN0IHR5cGUNCm5jX21hbmFnZW1lbnQgPC0gY29sb25pZXNfcHJlcyAlPiUgDQogIGdyb3VwX2J5KG1hbmFnZW1lbnQsIGRpc3RyaWN0KSAlPiUgDQogIGRwbHlyOjpzdW1tYXJpc2UobiA9IG4oKSkNCg0KIyBGaW5kIHRoZSBtYXhpbXVtIGRlbnNpdHkgdmFsdWUgZm9yIGVhY2ggZGlzdHJpY3QNCm1heF9kZW5zaXR5IDwtIGNvbG9uaWVzX3ByZXMgJT4lIGdyb3VwX2J5KGRpc3RyaWN0KSAlPiUgZHBseXI6OnN1bW1hcmlzZShtYXhfZGVuc2l0eSA9IG1heChkZW5zaXR5KSkNCg0KIyBKb2luIHRoZSBuIGFuZCBtYXhfZGVuc2l0eSBkYXRhIGZyYW1lcw0KbmNfbWFuYWdlbWVudCA8LSBsZWZ0X2pvaW4obmNfbWFuYWdlbWVudCwgbWF4X2RlbnNpdHksIGJ5ID0gYygiZGlzdHJpY3QiID0gImRpc3RyaWN0IikpDQoNCiMgR2VuZXJhdGUgdGhlIHBsb3QNCnAgPC0gZ2dwbG90KGNvbG9uaWVzX3ByZXMsIGFlcyh4PW1hbmFnZW1lbnQsIHk9ZGVuc2l0eSkpICsgDQogIGdlb21fYm94cGxvdCgpICsNCiAgZ2VvbV90ZXh0KGRhdGE9bmNfbWFuYWdlbWVudCwgYWVzKHg9bWFuYWdlbWVudCwgeT1tYXhfZGVuc2l0eS01LCBsYWJlbD1wYXN0ZSgibiA9IiwgbikpLCB2anVzdD0tMS4xLCBzaXplPTMuNSwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoMC40KSkgKyAgIyBhZGQgbiB0byB0aGUgZmFjZXRzDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgbWFuYWdlbWVudCB0eXBlIC0gUHJlc2VuY2Ugb25seSIpKw0KICBmYWNldF9ncmlkKC4gfiBkaXN0cmljdCwgc2NhbGVzID0gImZyZWVfeCIpKw0KICBjb29yZF9mbGlwKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KIyBTaG93IHRoZSBwbG90DQpwDQoNCmBgYA0KDQoNCmBgYHtyfQ0KDQpnZ3Bsb3QoaHJ1X3ByZXNlbmNlLCBhZXMoeD1oYWJpdGF0LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgSGFiaXRhdCBpbiBIcnVzb3ZhbnkgLSBQcmVzZW5jZSBvbmx5IikrDQogIGNvb3JkX2ZsaXAoKQ0KDQpnZ3Bsb3QodnBfcHJlc2VuY2UsIGFlcyh4PWhhYml0YXQsIHk9ZGVuc2l0eSkpICsgDQogIGdlb21fYm94cGxvdCgpICsNCiAgeGxhYigiIikgKyB5bGFiKCJEZW5zaXR5IChidXJyb3cgb3BlbmluZ3MvaGEpIikgKw0KICBnZ3RpdGxlKCJEZW5zaXR5IG9mIGJ1cnJvdyBvcGVuaW5ncyBieSBIYWJpdGF0IGluIFZlbGtlIFBhdmxvdmljZSAtIFByZXNlbmNlIG9ubHkiKSsNCiAgY29vcmRfZmxpcCgpDQoNCmdncGxvdChocnVfcHJlc2VuY2UsIGFlcyh4PW1hbmFnZW1lbnQsIHk9ZGVuc2l0eSkpICsgDQogIGdlb21fYm94cGxvdCgpICsNCiAgeGxhYigiIikgKyB5bGFiKCJEZW5zaXR5IChidXJyb3cgb3BlbmluZ3MvaGEpIikgKw0KICBnZ3RpdGxlKCJEZW5zaXR5IG9mIGJ1cnJvdyBvcGVuaW5ncyBieSBtYW5hZ2VtZW50IHR5cGUgaW4gSHJ1c292YW55IC0gUHJlc2VuY2Ugb25seSIpKw0KICBjb29yZF9mbGlwKCkNCg0KZ2dwbG90KHZwX3ByZXNlbmNlLCBhZXMoeD1tYW5hZ2VtZW50LCB5PWRlbnNpdHkpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgbWFuYWdlbWVudCB0eXBlIGluIFZlbGtlIFBhdmxvdmljZSAtIFByZXNlbmNlIG9ubHkiKSsNCiAgY29vcmRfZmxpcCgpDQoNCg0KDQoNCg0KYGBgDQoNCg0KIyBFeGFtcGxlIGNvbG9yIHBsb3QNCg0KTm90IHNvIHN1cmUgYWJvdXQgdGhlIG1lYW4sIHdpdGggc28gbWFueSBvdXRsaWVycy4gSSdkIGxlYXZlIGp1c3QgdGhlIG4uIFRoZSBib3hwbG90IGdpdmVzIGFscmVhZHkgdGhlIG1lZGlhbi4NCkNvbG9yIGlzIGFsc28gb3B0aW9uYWwuIA0KDQpPbmNlIHlvdSBhbGwgZGVjaWRlIHRoZSBkZXRhaWxzLCBJJ2xsIGNoYW5nZSBpdCBmb3IgYWxsIHRoZSBwbG90cy4NCg0KYGBge3J9DQoNCiMgQ3JlYXRlIGEgY29sb3IgcGFsZXR0ZSBmb3IgdGhlIG1hbmFnZW1lbnQgdHlwZXMNCnBhbGV0dGUgPC0gYygiIzAwNzJCMiIsICIjRDU1RTAwIiwgIiNDQzc5QTciLCAiI0YwRTQ0MiIpDQpuYW1lcyhwYWxldHRlKSA8LSBjKCJQbG91Z2hlZCIsICJQbG91Z2hlZC9Nb3dlZCIsICJNb3dlZCIsICJObyBNYW5hZ2VtZW50IikNCg0KIyBDb21wdXRlIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIGZvciBlYWNoIG1hbmFnZW1lbnQgdHlwZQ0KbiA8LSB2cF9wcmVzZW5jZSAlPiUgDQogIGdyb3VwX2J5KG1hbmFnZW1lbnQpICU+JSANCiAgZHBseXI6OnN1bW1hcmlzZShuID0gbigpKQ0KDQoNCiMgTW9kaWZ5IHRoZSBwbG90IGNvZGUgdG8gaW5jbHVkZSB0aGUgY29sb3IgYWVzdGhldGljIGFuZCBhcHByb3ByaWF0ZSBsYWJlbHMNCmdncGxvdCh2cF9wcmVzZW5jZSwgYWVzKHg9bWFuYWdlbWVudCwgeT1kZW5zaXR5LCBmaWxsPW1hbmFnZW1lbnQpKSArIA0KICBnZW9tX2JveHBsb3QoKSArDQogIHhsYWIoIiIpICsgeWxhYigiRGVuc2l0eSAoYnVycm93IG9wZW5pbmdzL2hhKSIpICsNCiAgZ2d0aXRsZSgiRGVuc2l0eSBvZiBidXJyb3cgb3BlbmluZ3MgYnkgTWFuYWdlbWVudCBUeXBlIGluIFZlbGtlIFBhdmxvdmljZSAtIFByZXNlbmNlIE9ubHkiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1wYWxldHRlKSArDQogIGNvb3JkX2ZsaXAoKSsNCiAgICBnZW9tX3RleHQoZGF0YT1uLCBhZXMoeD1tYW5hZ2VtZW50LCB5PTcwLCBsYWJlbD1wYXN0ZSgibiA9IiwgbikpLCB2anVzdD0tMSwgc2l6ZT0zLjUsIHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKDAuNCkpKw0KICAgbGFicyhmaWxsID0gIk1hbmFnZW1lbnQiKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQ0KICANCg0KYGBgDQoNCg0KDQoNCg0KDQojIEFub3Zhcw0KDQpBbmQgdHVrZXkgcG9zdC1ob2MgdGVzdHMgdG8gaWRlbnRpZnkgd2hpY2ggc3BlY2lmaWMgbGV2ZWxzIG9mIHRoZSB2YXJpYWJsZXMgYXJlIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IGZyb20gb25lIGFub3RoZXIuDQoNCmBgYHtyfQ0KDQoNCg0KIyBQZXJmb3JtIGEgdHdvLXdheSBBTk9WQSB0byB0ZXN0IHRoZSBlZmZlY3Qgb2YgbWFuYWdlbWVudCBhbmQgaGFiaXRhdCBvbiBkZW5zaXR5DQphb3ZfcmVzdWx0cyA8LSBhb3YoZGVuc2l0eSB+IG1hbmFnZW1lbnQgKyBoYWJpdGF0ICsgZGlzdHJpY3QsIGRhdGE9Y29sb25pZXMpDQoNCnN1bW1hcnkoYW92X3Jlc3VsdHMpDQoNCiMgUGVyZm9ybSBwb3N0LWhvYyB0ZXN0cyB0byBpZGVudGlmeSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBiZXR3ZWVuIGxldmVscw0KdHVrZXlfcmVzdWx0cyA8LSBUdWtleUhTRChhb3ZfcmVzdWx0cykNCg0KdHVrZXlfcmVzdWx0cw0KYGBgDQoNCiMjIFByZXNlbmNlIG9ubHkNCg0KQW5kIHR1a2V5IHBvc3QtaG9jIHRlc3RzIHRvIGlkZW50aWZ5IHdoaWNoIHNwZWNpZmljIGxldmVscyBvZiB0aGUgdmFyaWFibGVzIGFyZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBmcm9tIG9uZSBhbm90aGVyLg0KDQpgYGB7cn0NCg0KDQoNCiMgUGVyZm9ybSBhIHR3by13YXkgQU5PVkEgdG8gdGVzdCB0aGUgZWZmZWN0IG9mIG1hbmFnZW1lbnQgYW5kIGhhYml0YXQgb24gZGVuc2l0eQ0KYW92X3Jlc3VsdHMgPC0gYW92KGRlbnNpdHkgfiBtYW5hZ2VtZW50ICsgaGFiaXRhdCArIGRpc3RyaWN0LCBkYXRhPWNvbG9uaWVzX3ByZXMpDQoNCnN1bW1hcnkoYW92X3Jlc3VsdHMpDQoNCiMgUGVyZm9ybSBwb3N0LWhvYyB0ZXN0cyB0byBpZGVudGlmeSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBiZXR3ZWVuIGxldmVscw0KdHVrZXlfcmVzdWx0cyA8LSBUdWtleUhTRChhb3ZfcmVzdWx0cykNCg0KdHVrZXlfcmVzdWx0cw0KYGBgDQo=