Introduction

Preliminary visual exploration of data. > Click code to see how it was done

The data comes from samples collected as spraints: Each of them was analysed under the microscope, bones and scales identified whenever possible. Fish bones were measured and gave us the size group of the individual.

The aim of the study is to show the variability of the otter diet, both in terms of size and biodiversity.

The studied locations are:

  • Bílina river (Upper and Lower)
  • Chomutvka river (Upper and Lower)
  • Přísečnice (A water reservoir for human consumption)
  • Lake Milada (A recently recovered mining area)

We would expect to find differences in predation between lakes and rivers, between upper and lower courses of the rivers, and also between the two lakes, as Milada was much more recently formed than Přísečnice.

Predation should reflect the size distribution and availability of each species, so we should be able to see differences in the size distribution between stocked fish (Salmonids) and wild fish, such as Gobio sp.

Libraries

Data tyding

Raw data

Original data in wide format: One column for each observation of species and each size category

# Data----

path <- here::here("data", "krusnehory.xlsx")

raw <- path %>%
  excel_sheets() %>%
  set_names() %>%
  map_df(read_excel, #join all sheets by row
         path = path,
         .id = "location") %>% #create new column with the name of the sheets
  clean_names()                #probably many errors, so better clean

head(raw)
## # A tibble: 6 x 213
##   location stretch month season abramis alburnoides_bip~ alburnus_alburn~
##   <chr>    <chr>   <chr> <chr>    <dbl>            <dbl>            <dbl>
## 1 Bílina   dolní   April spring       0                0                0
## 2 Bílina   dolní   Augu~ summer       0                0                0
## 3 Bílina   dolní   Febr~ winter       1                4                4
## 4 Bílina   dolní   Janu~ winter       1                0                0
## 5 Bílina   dolní   July  summer       0                0                0
## 6 Bílina   dolní   March spring       0                0                0
## # ... with 206 more variables: anguilla_anguilla <dbl>,
## #   barbatula_barbatula <dbl>, barbus_barbus <dbl>, blicca_bjoerkna <dbl>,
## #   carassius <dbl>, cottus <dbl>, ctenopharyngodon <dbl>, cyprinidae <dbl>,
## #   cyprinus_carpio <dbl>, esox_lucius <dbl>, gobio <dbl>,
## #   gasterosseus_aculeatus <dbl>, gymnocephalus <dbl>,
## #   chondrostoma_nasus <dbl>, ictalurus_nebulosus <dbl>, ic_neb_5_10_cm <dbl>,
## #   ic_neb_10_15_cm <dbl>, lepomis_gibbosus <dbl>, leucaspius_delineatus <dbl>,
## #   leuciscus_cephalus <dbl>, leuciscus_leuciscus <dbl>, lota_lota <dbl>,
## #   misgurnus_fosilis <dbl>, neogobius_melanostomus <dbl>,
## #   oncorhynchus_mykkiss <dbl>, perca_fluviatilis <dbl>,
## #   phoxinus_phoxinus <dbl>, pseudorasbora_parva <dbl>, rhodeus_sericeus <dbl>,
## #   rutilus_rutilus <dbl>, salmonids <dbl>, salmo_trutta_fario <dbl>,
## #   scardinius_erythrophtalmus <dbl>, silurus_glanis <dbl>, tinca_tinca <dbl>,
## #   astacus <dbl>, molusca <dbl>, coleoptera <dbl>, odonata_larvae <dbl>,
## #   insecta <dbl>, anura <dbl>, aves <dbl>, mammalia <dbl>, caudata <dbl>,
## #   serpentes <dbl>, al_bi_5_10_cm <dbl>, al_bi_10_15_cm <dbl>,
## #   al_al_0_5_cm <dbl>, al_al_5_10_cm <dbl>, al_al_10_15_cm <dbl>,
## #   ba_ba_5_10_cm <dbl>, ba_ba_10_15_cm <dbl>, ba_ba_15_20_cm <dbl>,
## #   br_br_5_10_cm <dbl>, br_br_10_15_cm <dbl>, br_br_15_20_cm <dbl>,
## #   br_br_20_25_cm <dbl>, br_br_25_30_cm <dbl>, br_br_30_35_cm <dbl>,
## #   br_br_35_40_cm <dbl>, br_br_40_45_cm <dbl>, ca_5_10_cm <dbl>,
## #   ca_10_15_cm <dbl>, ca_15_20_cm <dbl>, ca_20_25_cm <dbl>, ca_25_30_cm <dbl>,
## #   ca_30_35_cm <dbl>, ca_35_40_cm <dbl>, cg_5_10_cm <dbl>, cg_10_15_cm <dbl>,
## #   cy_0_5_cm <dbl>, cy_5_10_cm <dbl>, cy_10_15_cm <dbl>, cy_15_20_cm <dbl>,
## #   cy_20_25_cm <dbl>, cy_25_30_cm <dbl>, cy_30_35_cm <dbl>, cy_35_40_cm <dbl>,
## #   cy_40_45_cm <dbl>, el_0_5_cm <dbl>, el_5_10_cm <dbl>, el_10_15_cm <dbl>,
## #   el_15_20_cm <dbl>, el_20_25_cm <dbl>, el_25_30_cm <dbl>, el_30_35_cm <dbl>,
## #   el_35_40_cm <dbl>, gg_0_5_cm <dbl>, gg_5_10_cm <dbl>, gg_10_15_cm <dbl>,
## #   gg_15_20_cm <dbl>, gy_5_10_cm <dbl>, gy_10_15_cm <dbl>,
## #   ch_na_5_10_cm <dbl>, ch_na_10_15_cm <dbl>, ch_na_15_20_cm <dbl>,
## #   ch_na_20_25_cm <dbl>, ch_na_25_30_cm <dbl>, ch_na_30_35_cm <dbl>,
## #   le_del_0_5_cm <dbl>, ...

Long format

Before the analysis we need to:

  • Pivot the data into long format (One row per observation).
  • Create new variables for “species” and “size”.
  • Fix typos and other small errors.
# What a mess. Let's try to tidy it. 
# 
# 1) separate all those columns with sizes from the species. 
# 2) pivot sizes into a single column
# 3) filter by initials, add a species column for the fish with size, one by one. FUck.

tidy_size <- raw %>%
  dplyr::select(location, stretch, month, season, contains("_cm")) %>%
  pivot_longer(
    cols = contains("cm"),
    names_to = "size",
    values_to = "number",
    values_drop_na = TRUE
  ) %>%                                #join later with new species column below
  
  # levels(as.factor(tidy_size$size)) # how many different sizes? jooooder
  
  
  # Better redo the following code nightmare with case_when()!!
  
  dplyr::mutate(species = ifelse(
    grepl("al_bi_", size),
    "Alburnoides bipunctatus",
    ifelse(
      grepl("al_al_", size),
      "Alburnus alburnus",
      ifelse(
        grepl("st_tr_", size),            #looks like a typing error
        "Salmo trutta m. fario",
        ifelse(
          grepl("ab_br_", size),
          "Abramis sp.",
          ifelse(
            grepl("ba_ba_", size),
            "Barbatula barbatula",
            ifelse(
              grepl("br_br_", size),
              "Barbus barbus",
              ifelse(
                grepl("ca_", size),
                "Carassius sp.",
                ifelse(
                  grepl("cg_", size),
                  "Ctenopharyngodon idella",
                  ifelse(
                    grepl("cy_", size),
                    "Cyprinus carpio",
                    ifelse(
                      grepl("ct_id_", size),
                      "Ctenopharyngodon idella",
                      ifelse(
                        grepl("ga_ac", size),
                        "Gasterosteus aculeatus",
                        ifelse(
                          grepl("ch_na_", size),
                          "Chondrostoma nasus",
                          ifelse(
                            grepl("el_", size),
                            "Esox lucius",
                            ifelse(
                              grepl("gg_", size),
                              "Gobio a Romanogobio sp.",
                              ifelse(
                                grepl("gy_", size),
                                "Gymnocephalus cernua",
                                ifelse(
                                  grepl("ic_neb_", size),
                                  "Ictalurus nebulosus",
                                  ifelse(
                                    grepl("le_ce_", size),
                                    "Squalius cephalus",
                                    ifelse(
                                      grepl("le_del_", size),
                                      "Leucaspius delineatus",
                                      ifelse(
                                        grepl("le_gi_", size),
                                        "Lepomis gibbosus",
                                        ifelse(
                                          grepl("le_le_", size),
                                          "Leuciscus leuciscus",
                                          ifelse(
                                            grepl("lo_lo_", size),
                                            "Lota lota",
                                            ifelse(
                                              grepl("mi_fo_", size),
                                              "Misgurnus fosilis",
                                              ifelse(
                                                grepl("neog_mel_", size),
                                                "Neogobius melanostomus",
                                                ifelse(
                                                  grepl("on_myk_", size),
                                                  "Oncorhynchus mykiss",
                                                  ifelse(
                                                    grepl("pf_", size),
                                                    "Perca fluviatilis",
                                                    ifelse(
                                                      grepl("ph_ph_", size),
                                                      "Phoxinus phoxinus",
                                                      ifelse(
                                                        grepl("pp_", size),
                                                        "Pseudorasbora parva",
                                                        ifelse(
                                                          grepl("rs_", size),
                                                          "Rhodeus sericeus",
                                                          ifelse(
                                                            grepl("rr_", size),
                                                            "Rutilus rutilus",
                                                            ifelse(
                                                              grepl("sa_", size),
                                                              "Salmonids",
                                                              ifelse(
                                                                grepl("se_", size),
                                                                "Scardinius erythrophtalmus",
                                                                ifelse(
                                                                  grepl("si_gl_", size),
                                                                  "Silurus glanis",
                                                                  ifelse(
                                                                    grepl("sl_tr_", size),
                                                                    "Salmo trutta m. fario",
                                                                    ifelse(
                                                                      grepl("st_luc_", size),
                                                                      "Stizostedion lucioperca",
                                                                      ifelse(grepl("tt_", size), "Tinca tinca", "error") #adding option for error in case I missed a name
                                                                    )
                                                                  )
                                                                )
                                                              )
                                                            )
                                                          )
                                                        )
                                                      )
                                                    )
                                                  )
                                                )
                                              )
                                            )
                                          )
                                        )
                                      )
                                    )
                                  )
                                )
                              )
                            )
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  ))

head(tidy_size)
## # A tibble: 6 x 7
##   location stretch month season size            number species                
##   <chr>    <chr>   <chr> <chr>  <chr>            <dbl> <chr>                  
## 1 Bílina   dolní   April spring ic_neb_5_10_cm       0 Ictalurus nebulosus    
## 2 Bílina   dolní   April spring ic_neb_10_15_cm      0 Ictalurus nebulosus    
## 3 Bílina   dolní   April spring al_bi_5_10_cm        0 Alburnoides bipunctatus
## 4 Bílina   dolní   April spring al_bi_10_15_cm       0 Alburnoides bipunctatus
## 5 Bílina   dolní   April spring al_al_0_5_cm         0 Alburnus alburnus      
## 6 Bílina   dolní   April spring al_al_5_10_cm        0 Alburnus alburnus
########################## PREVIOUS ATTEMPTS, DON'T RUN ######################


#   pivot_longer(
#     cols = Abramis:"Stizostedion lucioperca",
#     names_to = "species",
#     values_to = "numberPrey",
#     values_drop_na = TRUE
#   ) 
#   
# 
# 
#   
#   pivot_longer(
#     cols = contains("cm"),
#     names_to = "size",
#     values_to = "number",
#     values_drop_na = TRUE
#   ) %>%                      # nooooooooo! hay que hacerlo manual, cada size with its species
#   dplyr::filter(number > 0) %>%
#   dplyr::mutate(size = str_remove_all(size, "[*a-zA-Z]")) %>% #fuck regular expressions
#   dplyr::mutate (size = glue("{size}cm")) %>%  #had to install dev version of dplyr
#   dplyr::mutate(size = str_trim(size)) %>% #remove extra space
#   dplyr::mutate(size = fct_relevel(size, "5-10 cm", after = 1)) %>%
#   uncount(number) %>% # to get individual observations!!
#   pivot_longer(
#     cols = Abramis:"Stizostedion lucioperca",
#     names_to = "species",
#     values_to = "numberPrey",
#     values_drop_na = TRUE
#   ) 
# 
# glimpse(tidy)
# str(tidy)
# 
# colourCount = length(unique(tidy$size))
# getPalette = colorRampPalette(brewer.pal(9, "OrRd")[2:9])

The data is now in long format (Just need to “uncount” the “number” column in the next step). Now we need to:

  • Add the rest of the species without size measurements

  • To do that, we need to select them from raw and pivot them to get the number too.

  • Bind row to tidy_size

  • Clean the size variable

  • Rejoice

New variable size and renaming and reordering factor levels

# OK, kousek po kousku. Now we have to:
# 
# 4) add the rest of the species without size measurements
#    4.1)  To do that, we need to select them from raw and pivot them to get the number too.
#    
# 5) bind row to tidy_size
# 6) clean the size variable
# 7) Rejoice


extra_sp <- raw %>% 
  dplyr::select(location, stretch, month, season, anguilla_anguilla, cyprinidae, astacus:serpentes) %>%
  pivot_longer(
    cols = c("anguilla_anguilla", "cyprinidae", astacus:serpentes),
    names_to = "species",
    values_to = "number",
    values_drop_na = TRUE
  )

tidy_db <- bind_rows(tidy_size, extra_sp) %>% 
  dplyr::filter(number > 0) %>%
  dplyr::mutate(size = str_remove_all(size, "[*a-zA-Z_]")) %>%  
  dplyr::mutate(size = dplyr::recode(size, 
                                     "05" = "0-5 cm",
                                     "510" = "5-10 cm",
                                     "1015" = "10-15 cm",
                                     "1520" = "15-20 cm",
                                     "2025" = "20-25 cm",
                                     "2530" = "25-30 cm",
                                     "3035" = "30-35 cm",
                                     "35-40" = "35-40 cm",
                                     "4045" = "40-45 cm"
  )) %>% 
  dplyr::mutate(size = fct_relevel(size, "5-10 cm", after = 1)) %>%
  uncount(number) %>%                 # to get individual observations!!
  dplyr::mutate(species = str_to_sentence(species)) %>% 
  dplyr::mutate(species = dplyr::recode(species, 
                                        "Astacus" = "Astacoidea",
                                        "Anguilla_anguilla" = "Anguilla anguilla",
                                        "Salmo trutta m. fario" = "Salmonids",
                                        "Oncorhynchus mykiss" = "Salmonids",
                                        "Cyprinidae" = "Unidentified Cyprinidae",
                                        "Alburnoides bipunctatus" = "Alburnus alburnus",
                                        "Gobio a romanogobio sp." = "Gobio a Romanogobio sp."
  )) %>% # Trouts pooled into salmonids, Alburnoides into alburnus
  dplyr::mutate(stretch = dplyr::recode(stretch, 
                                        "dolní" = "Lower",
                                        "horní" = "Upper")) %>%
  dplyr::mutate(species = as.factor(species)) %>% 
  dplyr::mutate(stretch = as.factor(stretch)) %>% 
  dplyr::mutate(species = fct_relevel(species, "Aves", after = Inf)) %>% 
  dplyr::mutate(species = fct_relevel(species, "Insecta", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Mammalia", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Anura", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Serpentes", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Astacoidea", after = Inf)) %>%
  dplyr::mutate(season = dplyr::recode(season, 
                                       "winter" = "Winter",
                                       "spring" = "Spring",
                                       "summer" = "Summer",
                                       "autumn" = "Autumn")) %>% 
  dplyr::mutate(season = as.factor(season)) %>% 
  dplyr::mutate(season = fct_relevel(season, "Spring", "Summer", "Autumn", "Winter" )) %>% 
  dplyr::mutate(location = as.factor(location)) %>% 
  # Divide streams into Upper and lower and removing variable stretch
  dplyr::mutate(location = case_when(location == "Bílina" & stretch == "Upper" ~ "Horní Bílina",
          location == "Bílina" & stretch == "Lower" ~ "Dolní Bílina", 
          location == "Chomutovka" & stretch == "Lower" ~ "Dolní Chomutovka",
          location == "Chomutovka" & stretch == "Upper" ~ "Horní Chomutovka",
          location == "Prisecnice" ~ "Přísečnice",
          TRUE ~ "jezero Milada")) %>% 
  dplyr::mutate(location = as.factor(location)) %>% 
  dplyr::select(-stretch)
  


summary(tidy_db)
##              location      month              season          size    
##  Dolní Bílina    :522   Length:1725        Spring:420   5-10 cm :693  
##  Dolní Chomutovka:149   Class :character   Summer:399   10-15 cm:405  
##  Horní Bílina    :129   Mode  :character   Autumn:555   15-20 cm: 75  
##  Horní Chomutovka:173                      Winter:351   20-25 cm: 34  
##  jezero Milada   :386                                   25-30 cm: 12  
##  Přísečnice      :366                                   (Other) : 10  
##                                                         NA's    :496  
##                     species   
##  Salmonids              :310  
##  Gobio a Romanogobio sp.:255  
##  Perca fluviatilis      :220  
##  Anura                  :219  
##  Astacoidea             :154  
##  Unidentified Cyprinidae: 87  
##  (Other)                :480
head(tidy_db)
## # A tibble: 6 x 5
##   location     month season size     species                
##   <fct>        <chr> <fct>  <fct>    <fct>                  
## 1 Dolní Bílina April Spring 10-15 cm Cyprinus carpio        
## 2 Dolní Bílina April Spring 0-5 cm   Gobio a Romanogobio sp.
## 3 Dolní Bílina April Spring 0-5 cm   Gobio a Romanogobio sp.
## 4 Dolní Bílina April Spring 5-10 cm  Gobio a Romanogobio sp.
## 5 Dolní Bílina April Spring 5-10 cm  Gobio a Romanogobio sp.
## 6 Dolní Bílina April Spring 5-10 cm  Gobio a Romanogobio sp.
write.csv2(tidy_db,"dataShiny/tidy_db", row.names = FALSE)

Fish lumped in one category

lumped_fish <- tidy_db %>% 
  dplyr::mutate(species = case_when(
    species == "Aves" ~ "Aves",
    species == "Insecta" ~ 'Insecta',
    species == "Mammalia" ~ 'Mammalia',
    species == "Anura" ~ 'Anura',
    species == "Serpentes" ~ 'Serpentes',
    species == "Astacoidea" ~ 'Astacoidea',
    
    TRUE ~ 'Fish' ))


head(lumped_fish)
## # A tibble: 6 x 5
##   location     month season size     species
##   <fct>        <chr> <fct>  <fct>    <chr>  
## 1 Dolní Bílina April Spring 10-15 cm Fish   
## 2 Dolní Bílina April Spring 0-5 cm   Fish   
## 3 Dolní Bílina April Spring 0-5 cm   Fish   
## 4 Dolní Bílina April Spring 5-10 cm  Fish   
## 5 Dolní Bílina April Spring 5-10 cm  Fish   
## 6 Dolní Bílina April Spring 5-10 cm  Fish
write.csv2(lumped_fish,"dataShiny/lumped_fish", row.names = FALSE)

Diet: What do otters eat, in which proportion of species?

The category “Salmonids” includes Salmo trutta m.fario, Oncorhynchus mykiss and unidentified salmonids.

Identified prey

Number of individual prey found in spraints in each location

total_prey <- tidy_db %>% 
  dplyr::select(location, species) %>%
  dplyr::count(species, location) %>% 
  pivot_wider(names_from = location, values_from = n ) %>% 
  replace(is.na(.), 0)

kable(total_prey, align = "lccrr") %>% 
  kableExtra::kable_styling()
species Dolní Bílina Dolní Chomutovka Horní Chomutovka Horní Bílina jezero Milada Přísečnice
Abramis sp. 3 0 0 0 0 0
Alburnus alburnus 8 0 0 0 0 0
Anguilla anguilla 3 0 0 0 0 0
Barbatula barbatula 2 18 1 0 0 0
Barbus barbus 5 0 0 0 0 0
Carassius sp. 24 5 1 6 0 0
Ctenopharyngodon idella 0 1 3 0 1 0
Cyprinus carpio 59 5 2 0 2 0
Esox lucius 0 1 0 0 0 0
Gobio a Romanogobio sp. 200 21 1 0 1 32
Gymnocephalus cernua 2 0 0 0 21 0
Ictalurus nebulosus 1 0 0 0 0 0
Lepomis gibbosus 5 0 0 0 8 0
Lota lota 0 0 0 0 0 1
Perca fluviatilis 5 9 1 1 200 4
Phoxinus phoxinus 0 0 0 0 0 9
Pseudorasbora parva 31 13 0 0 0 0
Rutilus rutilus 26 3 2 1 2 5
Salmonids 1 7 119 57 5 121
Scardinius erythrophtalmus 4 1 0 1 32 0
Silurus glanis 4 1 0 0 2 2
Squalius cephalus 32 28 0 0 1 2
Tinca tinca 11 1 0 0 45 0
Unidentified Cyprinidae 39 14 4 4 22 4
Aves 7 2 0 0 5 0
Insecta 1 0 0 1 5 2
Mammalia 0 3 0 0 0 1
Anura 45 14 38 39 13 70
Serpentes 3 2 0 0 1 0
Astacoidea 1 0 1 19 20 113

Diet is very varied

Custom palette

#Create custom palette
# 
seed <- c("#ff0000", "#00ff00", "#0000ff")

species_v <- levels(tidy_db$species)

species_vector<- c(species_v, "Other")

# names(palette1) = species_vector

species_colors = setNames(object = createPalette(31, seed, prefix="mine"), nm = species_vector)

swatch(species_colors)

#print(species_colors)
tidy_db %>% 
  mutate(species = fct_reorder(species, desc(species))) %>%
  ggplot(aes(x = location, fill=species)) + 
  scale_fill_manual(values= species_colors) +
  #facet_grid(. ~ season)+
  geom_bar()+
  theme_bw() +
  scale_y_continuous("Samples collected") +
  scale_x_discrete("") +
  labs(fill = "Species") +
  #theme(axis.text.x = element_text(angle = 90)) +
  coord_flip() +
  labs(title = "Krusne Hory") +
  #scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) + 
  theme(axis.title.x = element_text(size = 15)) + 
  theme(axis.title.y = element_text(size = 15)) + 
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

Most Common Prey by season

(Lumping 5% less common)

tidy_db %>% 
  # group by location before lumping so that 0.05 applies to each separately
  dplyr::group_by(location) %>% 
  mutate(species = fct_lump_prop(species,0.05)) %>% 
  ungroup() %>% 
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Astacoidea", "Anura", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%   
  dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) + 
  scale_fill_manual(values= species_colors) +
  facet_wrap(. ~ season)+
  geom_bar()+
  theme_bw() +
  scale_y_continuous("Identified prey") +
  scale_x_discrete("") +
  labs(fill = "Species") +
  #theme(axis.text.x = element_text(angle = 90)) +
  coord_flip() +
  labs(title = "Krusne Hory: Most common prey by season") +
  # scale_fill_brewer(palette = "Paired") +
  # scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) + 
  theme(axis.title.x = element_text(size = 15)) + 
  theme(axis.title.y = element_text(size = 15)) + 
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

All together as proportion

# tidy_db %>% 
#   # group by stretch and location before lumping so that 0.05 applies to each stretch separatedly
#   # dplyr::group_by(stretch,location) %>% 
#   # mutate(species = fct_lump_prop(species,0.05)) %>% 
#   # ungroup() %>% 
#   # mutate(species = fct_reorder(species, desc(species))) %>%
#   # dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
#   ggplot(aes(x = location, fill=species)) +
#   facet_grid(. ~ season)+
#   scale_fill_discrete(drop=FALSE) +
#   scale_y_continuous("Proportion of species") +
#   scale_x_discrete("") +
#   geom_bar(position = "fill") +
#   labs(fill = "Species proportion") +
#   # theme(axis.text.x = element_text(angle = 90)) +
#   coord_flip() +
#   labs(title = "Krusne Hory")  

Most common prey: All together as proportion (lumping 5% less common)

tidy_db %>% 
  # group by stretch and location before lumping so that 0.05 applies to each stretch separatedly
  dplyr::group_by(location) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ungroup() %>%
 mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Astacoidea", "Anura", after = Inf)) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
 dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) +
  scale_fill_manual(values= species_colors) +
  #facet_grid(. ~ season)+
  scale_y_continuous("Proportion of species", labels = scales::percent) +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species proportion") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Krusne Hory: Most common prey, year round") + 
  coord_flip()+
  guides(fill = guide_legend(reverse = TRUE))

All fish lumped together, as proportion

lumped_fish %>%
  mutate(species = fct_relevel(species,"Fish")) %>%
  dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) +
  #facet_grid(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion of species", labels = scales::percent) +
    scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species proportion") +
  scale_fill_brewer(palette = "Paired") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Krusne Hory") +
  coord_flip() +
  guides(fill = guide_legend(reverse = TRUE))

All fish lumped together, as proportion, by season

lumped_fish %>%
  mutate(species = fct_relevel(species,"Fish")) %>%
  dplyr::mutate(location = fct_relevel(location, "jezero Milada", after = 0)) %>%
  ggplot(aes(x = location, fill=species)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion of species", labels = scales::percent) +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species proportion") +
  scale_fill_brewer(palette = "Paired") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Krusne Hory") +
  coord_flip()+
  guides(fill = guide_legend(reverse = TRUE))

Each location separately

Horní Bílina

Percentage of each prey in the diet

(Data not lumped)

hBilina <- tidy_db %>%
  filter(location == "Horní Bílina")



# hBilina %>%
#   #mutate(species = fct_lump_prop(species,0.05)) %>% 
#   mutate(species = fct_reorder(species, desc(species))) %>%
#   dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
#   ggplot(aes(x =location , fill = species)) +
#   scale_fill_discrete(drop = TRUE) +
#   scale_y_continuous("") +
#   scale_x_discrete("") +
#   geom_bar(position = "fill") +
#   labs(fill = "Species") +
#   #theme(axis.text.x = element_text(angle = 90)) +
#   labs(title = "Diet: Species proportion in Upper and Lower Bílina") +
#   coord_flip() +
#   theme(axis.text.x = element_text(size = 10)) +
#   theme(axis.title.x = element_text(size = 15)) +
#   theme(axis.title.y = element_text(size = 15)) +
#   theme(plot.title = element_text(size = 15))

hBilina %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Horní Bílina: Percentage of each prey group") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Diet by season

I would say it’s only relevant to compare Spring, Summer and Autumn, because there are just 5 observations in Winter.

Total proportions

hBilina %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  mutate(species = fct_reorder(species, desc(species))) %>%
 # dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  ggplot(aes(x = season , fill = species)) +
  scale_fill_discrete(drop = TRUE) +
  scale_y_continuous("Species proportion") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Bílina: Diet by Season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

No winter

hBilina %>%
  dplyr::filter(season != "Winter") %>% 
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  mutate(species = fct_reorder(species, desc(species))) %>%
 # dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  ggplot(aes(x = season , fill = species)) +
  scale_fill_discrete(drop = TRUE) +
  scale_y_continuous("Species proportion") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Bílina: Diet by Season (no winter)") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

By season, with percentages

Plot with free scales

hBilina %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) +
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1) +
  labs(y = "", x ="") +
  facet_wrap(~ season,scales = "free") +
  coord_flip() +
  labs(title = "Horní Bílina: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Plot with fixed scales

hBilina %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) +
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  +  
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.1, hjust = 0, size =2.8) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Horní Bílina: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Dolní Bílina

Percentage of each prey in the diet

dBilina <- tidy_db %>%
  filter(location == "Dolní Bílina")

dBilina %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  +
  
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1, size =3) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Dolni Bílina: Percentage of each prey group") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

dBilina %>%
  mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE) +

  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1, size = 3) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Dolni Bílina: Percentage of each prey group (0.05 lumped)") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Diet by season

dfSummary(dBilina)
## Data Frame Summary  
## dBilina  
## Dimensions: 522 x 5  
## Duplicates: 380  
## 
## -----------------------------------------------------------------------------------------------------------------------
## No   Variable      Stats / Values                  Freqs (% of Valid)   Graph                     Valid      Missing   
## ---- ------------- ------------------------------- -------------------- ------------------------- ---------- ----------
## 1    location      1. Doln<ed> B<ed>lina           522 (100.0%)         IIIIIIIIIIIIIIIIIIII      522        0         
##      [factor]      2. Doln<ed> Chomutovka            0 (  0.0%)                                   (100%)     (0%)      
##                    3. Horn<ed> B<ed>lina             0 (  0.0%)                                                        
##                    4. Horn<ed> Chomutovka            0 (  0.0%)                                                        
##                    5. jezero Milada                  0 (  0.0%)                                                        
##                    6. P<f8><ed>se<e8>nice            0 (  0.0%)                                                        
## 
## 2    month         1. April                         58 (11.1%)          II                        522        0         
##      [character]   2. August                       102 (19.5%)          III                       (100%)     (0%)      
##                    3. February                     104 (19.9%)          III                                            
##                    4. January                       58 (11.1%)          II                                             
##                    5. July                          34 ( 6.5%)          I                                              
##                    6. March                         30 ( 5.8%)          I                                              
##                    7. November                     104 (19.9%)          III                                            
##                    8. September                     32 ( 6.1%)          I                                              
## 
## 3    season        1. Spring                        88 (16.9%)          III                       522        0         
##      [factor]      2. Summer                       136 (26.1%)          IIIII                     (100%)     (0%)      
##                    3. Autumn                       136 (26.1%)          IIIII                                          
##                    4. Winter                       162 (31.0%)          IIIIII                                         
## 
## 4    size          1. 0-5 cm                         3 ( 0.7%)                                    423        99        
##      [factor]      2. 5-10 cm                      192 (45.4%)          IIIIIIIII                 (81.03%)   (18.97%)  
##                    3. 10-15 cm                     182 (43.0%)          IIIIIIII                                       
##                    4. 15-20 cm                      23 ( 5.4%)          I                                              
##                    5. 20-25 cm                      16 ( 3.8%)                                                         
##                    6. 25-30 cm                       5 ( 1.2%)                                                         
##                    7. 30-35 cm                       0 ( 0.0%)                                                         
##                    8. 40-45 cm                       2 ( 0.5%)                                                         
## 
## 5    species       1. Abramis sp.                    3 ( 0.6%)                                    522        0         
##      [factor]      2. Alburnus alburnus              8 ( 1.5%)                                    (100%)     (0%)      
##                    3. Anguilla anguilla              3 ( 0.6%)                                                         
##                    4. Barbatula barbatula            2 ( 0.4%)                                                         
##                    5. Barbus barbus                  5 ( 1.0%)                                                         
##                    6. Carassius sp.                 24 ( 4.6%)                                                         
##                    7. Ctenopharyngodon idella        0 ( 0.0%)                                                         
##                    8. Cyprinus carpio               59 (11.3%)          II                                             
##                    9. Esox lucius                    0 ( 0.0%)                                                         
##                    10. Gobio a Romanogobio sp.     200 (38.3%)          IIIIIII                                        
##                    [ 20 others ]                   218 (41.8%)          IIIIIIII                                       
## -----------------------------------------------------------------------------------------------------------------------

Fixed scales

dBilina %>%
  mutate(species = fct_lump_prop(species,0.05)) %>% 
 # dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Doln Bílina: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Přísečnice

Water reservoir for human consumption.

Percentage of each prey in the diet

pris <- tidy_db %>%
  filter(location == "Přísečnice")


pris %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1, size=3) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Přísečnice: Percentage of each prey group") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

pris %>%
  mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
 ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1, size = 3) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Přísečnice: Percentage of each prey group (0.05 lumped)") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

# 

Diet by season

Probably wise not to plot winter. Spring/summer vs Autumn also quite unbalanced.

dfSummary(pris)
## Data Frame Summary  
## pris  
## Dimensions: 366 x 5  
## Duplicates: 301  
## 
## --------------------------------------------------------------------------------------------------------------------
## No   Variable      Stats / Values                  Freqs (% of Valid)   Graph                  Valid      Missing   
## ---- ------------- ------------------------------- -------------------- ---------------------- ---------- ----------
## 1    location      1. Doln<ed> B<ed>lina             0 (  0.0%)                                366        0         
##      [factor]      2. Doln<ed> Chomutovka            0 (  0.0%)                                (100%)     (0%)      
##                    3. Horn<ed> B<ed>lina             0 (  0.0%)                                                     
##                    4. Horn<ed> Chomutovka            0 (  0.0%)                                                     
##                    5. jezero Milada                  0 (  0.0%)                                                     
##                    6. P<f8><ed>se<e8>nice          366 (100.0%)         IIIIIIIIIIIIIIIIIIII                        
## 
## 2    month         1. April                         43 (11.8%)          II                     366        0         
##      [character]   2. August                        20 ( 5.5%)          I                      (100%)     (0%)      
##                    3. February                      28 ( 7.6%)          I                                           
##                    4. January                       12 ( 3.3%)                                                      
##                    5. July                          41 (11.2%)          II                                          
##                    6. March                         31 ( 8.5%)          I                                           
##                    7. November                     127 (34.7%)          IIIIII                                      
##                    8. September                     64 (17.5%)          III                                         
## 
## 3    season        1. Spring                        74 (20.2%)          IIII                   366        0         
##      [factor]      2. Summer                        61 (16.7%)          III                    (100%)     (0%)      
##                    3. Autumn                       191 (52.2%)          IIIIIIIIII                                  
##                    4. Winter                        40 (10.9%)          II                                          
## 
## 4    size          1. 0-5 cm                         1 ( 0.6%)                                 176        190       
##      [factor]      2. 5-10 cm                      116 (65.9%)          IIIIIIIIIIIII          (48.09%)   (51.91%)  
##                    3. 10-15 cm                      41 (23.3%)          IIII                                        
##                    4. 15-20 cm                      10 ( 5.7%)          I                                           
##                    5. 20-25 cm                       3 ( 1.7%)                                                      
##                    6. 25-30 cm                       4 ( 2.3%)                                                      
##                    7. 30-35 cm                       1 ( 0.6%)                                                      
##                    8. 40-45 cm                       0 ( 0.0%)                                                      
## 
## 5    species       1. Abramis sp.                    0 ( 0.0%)                                 366        0         
##      [factor]      2. Alburnus alburnus              0 ( 0.0%)                                 (100%)     (0%)      
##                    3. Anguilla anguilla              0 ( 0.0%)                                                      
##                    4. Barbatula barbatula            0 ( 0.0%)                                                      
##                    5. Barbus barbus                  0 ( 0.0%)                                                      
##                    6. Carassius sp.                  0 ( 0.0%)                                                      
##                    7. Ctenopharyngodon idella        0 ( 0.0%)                                                      
##                    8. Cyprinus carpio                0 ( 0.0%)                                                      
##                    9. Esox lucius                    0 ( 0.0%)                                                      
##                    10. Gobio a Romanogobio sp.      32 ( 8.7%)          I                                           
##                    [ 20 others ]                   334 (91.3%)          IIIIIIIIIIIIIIIIII                          
## --------------------------------------------------------------------------------------------------------------------

Fixed scales

pris %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
 ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 1L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Přísečnice: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

pris %>%
  mutate(species = fct_lump_prop(species,0.05)) %>% 
  dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  +  
  geom_text(aes( label = scales::percent(..prop..,accuracy = 1L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Přísečnice: Otter diet by season (0.05 lumped)") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Jezero Milada

Percentage of each prey in the diet

jez <- tidy_db %>%
  filter(location == "jezero Milada")

jez %>%
  mutate(species = fct_infreq(species)) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  +  
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.2, hjust = -0.1, size= 3) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Jezero Milada: Percentage of each prey in the diet") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 2L))

jez %>%
  mutate(species = fct_infreq(species)) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  +  
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1, size= 3) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Jezero Milada: Percentage of each prey in the diet") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 2L))

Diet by season

Perhaps we can plot winter.

dfSummary(jez)
## Data Frame Summary  
## jez  
## Dimensions: 386 x 5  
## Duplicates: 308  
## 
## --------------------------------------------------------------------------------------------------------------------
## No   Variable      Stats / Values                  Freqs (% of Valid)   Graph                    Valid     Missing  
## ---- ------------- ------------------------------- -------------------- ------------------------ --------- ---------
## 1    location      1. Doln<ed> B<ed>lina             0 (  0.0%)                                  386       0        
##      [factor]      2. Doln<ed> Chomutovka            0 (  0.0%)                                  (100%)    (0%)     
##                    3. Horn<ed> B<ed>lina             0 (  0.0%)                                                     
##                    4. Horn<ed> Chomutovka            0 (  0.0%)                                                     
##                    5. jezero Milada                386 (100.0%)         IIIIIIIIIIIIIIIIIIII                        
##                    6. P<f8><ed>se<e8>nice            0 (  0.0%)                                                     
## 
## 2    month         1. April                         30 ( 7.8%)          I                        386       0        
##      [character]   2. August                       125 (32.4%)          IIIIII                   (100%)    (0%)     
##                    3. February                      58 (15.0%)          III                                         
##                    4. July                          13 ( 3.4%)                                                      
##                    5. March                         50 (13.0%)          II                                          
##                    6. September                    110 (28.5%)          IIIII                                       
## 
## 3    season        1. Spring                        80 (20.7%)          IIII                     386       0        
##      [factor]      2. Summer                       138 (35.8%)          IIIIIII                  (100%)    (0%)     
##                    3. Autumn                       110 (28.5%)          IIIII                                       
##                    4. Winter                        58 (15.0%)          III                                         
## 
## 4    size          1. 0-5 cm                         2 ( 0.6%)                                   320       66       
##      [factor]      2. 5-10 cm                      223 (69.7%)          IIIIIIIIIIIII            (82.9%)   (17.1%)  
##                    3. 10-15 cm                      76 (23.8%)          IIII                                        
##                    4. 15-20 cm                      13 ( 4.1%)                                                      
##                    5. 20-25 cm                       3 ( 0.9%)                                                      
##                    6. 25-30 cm                       2 ( 0.6%)                                                      
##                    7. 30-35 cm                       1 ( 0.3%)                                                      
##                    8. 40-45 cm                       0 ( 0.0%)                                                      
## 
## 5    species       1. Abramis sp.                    0 ( 0.0%)                                   386       0        
##      [factor]      2. Alburnus alburnus              0 ( 0.0%)                                   (100%)    (0%)     
##                    3. Anguilla anguilla              0 ( 0.0%)                                                      
##                    4. Barbatula barbatula            0 ( 0.0%)                                                      
##                    5. Barbus barbus                  0 ( 0.0%)                                                      
##                    6. Carassius sp.                  0 ( 0.0%)                                                      
##                    7. Ctenopharyngodon idella        1 ( 0.3%)                                                      
##                    8. Cyprinus carpio                2 ( 0.5%)                                                      
##                    9. Esox lucius                    0 ( 0.0%)                                                      
##                    10. Gobio a Romanogobio sp.       1 ( 0.3%)                                                      
##                    [ 20 others ]                   382 (99.0%)          IIIIIIIIIIIIIIIIIII                         
## --------------------------------------------------------------------------------------------------------------------

Total proportions

jez %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = season , fill = species)) +
  #facet_grid(. ~ season)+
  scale_fill_discrete(drop = TRUE) +
  scale_y_continuous("Species proportion") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species") +
  #theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Jezero Milada: Diet by Season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

Fixed scales

jez %>%
  mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Jezero Milada: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Dolní Chomutovka

Percentage of each prey in the diet

dCho <- tidy_db %>%
  filter(location == "Dolní Chomutovka")

dCho %>%
  mutate(species = fct_infreq(species)) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Dolní Chomutovka: Percentage of each prey in the diet") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

dCho %>%
  mutate(species = fct_infreq(species)) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Dolní Chomutovka: Percentage of each prey in the diet") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Diet by season

dfSummary(dCho)
## Data Frame Summary  
## dCho  
## Dimensions: 149 x 5  
## Duplicates: 80  
## 
## -----------------------------------------------------------------------------------------------------------------------
## No   Variable      Stats / Values                  Freqs (% of Valid)   Graph                     Valid      Missing   
## ---- ------------- ------------------------------- -------------------- ------------------------- ---------- ----------
## 1    location      1. Doln<ed> B<ed>lina             0 (  0.0%)                                   149        0         
##      [factor]      2. Doln<ed> Chomutovka          149 (100.0%)         IIIIIIIIIIIIIIIIIIII      (100%)     (0%)      
##                    3. Horn<ed> B<ed>lina             0 (  0.0%)                                                        
##                    4. Horn<ed> Chomutovka            0 (  0.0%)                                                        
##                    5. jezero Milada                  0 (  0.0%)                                                        
##                    6. P<f8><ed>se<e8>nice            0 (  0.0%)                                                        
## 
## 2    month         1. April                         8 ( 5.4%)           I                         149        0         
##      [character]   2. August                       18 (12.1%)           II                        (100%)     (0%)      
##                    3. February                     17 (11.4%)           II                                             
##                    4. January                      19 (12.8%)           II                                             
##                    5. July                         16 (10.7%)           II                                             
##                    6. March                        39 (26.2%)           IIIII                                          
##                    7. November                     16 (10.7%)           II                                             
##                    8. September                    16 (10.7%)           II                                             
## 
## 3    season        1. Spring                       47 (31.5%)           IIIIII                    149        0         
##      [factor]      2. Summer                       34 (22.8%)           IIII                      (100%)     (0%)      
##                    3. Autumn                       32 (21.5%)           IIII                                           
##                    4. Winter                       36 (24.2%)           IIII                                           
## 
## 4    size          1. 0-5 cm                        0 ( 0.0%)                                     114        35        
##      [factor]      2. 5-10 cm                      64 (56.1%)           IIIIIIIIIII               (76.51%)   (23.49%)  
##                    3. 10-15 cm                     43 (37.7%)           IIIIIII                                        
##                    4. 15-20 cm                      2 ( 1.8%)                                                          
##                    5. 20-25 cm                      4 ( 3.5%)                                                          
##                    6. 25-30 cm                      1 ( 0.9%)                                                          
##                    7. 30-35 cm                      0 ( 0.0%)                                                          
##                    8. 40-45 cm                      0 ( 0.0%)                                                          
## 
## 5    species       1. Abramis sp.                   0 ( 0.0%)                                     149        0         
##      [factor]      2. Alburnus alburnus             0 ( 0.0%)                                     (100%)     (0%)      
##                    3. Anguilla anguilla             0 ( 0.0%)                                                          
##                    4. Barbatula barbatula          18 (12.1%)           II                                             
##                    5. Barbus barbus                 0 ( 0.0%)                                                          
##                    6. Carassius sp.                 5 ( 3.4%)                                                          
##                    7. Ctenopharyngodon idella       1 ( 0.7%)                                                          
##                    8. Cyprinus carpio               5 ( 3.4%)                                                          
##                    9. Esox lucius                   1 ( 0.7%)                                                          
##                    10. Gobio a Romanogobio sp.     21 (14.1%)           II                                             
##                    [ 20 others ]                   98 (65.8%)           IIIIIIIIIIIII                                  
## -----------------------------------------------------------------------------------------------------------------------

Total proportions

dCho %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = season , fill = species)) +
  #facet_grid(. ~ season)+
  scale_fill_discrete(drop = TRUE) +
  scale_y_continuous("Species proportion") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species") +
  #theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Dolní Chomutovka: Diet by Season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

Plot with fixed scales, not lumped

dCho %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  #dplyr::filter(season != "Winter") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  +  
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1,size=3) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Dolní Chomutovka: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Horní Chomutovka

Percentage of each prey in the diet

hCho <- tidy_db %>%
  filter(location == "Horní Chomutovka")

hCho %>%
  mutate(species = fct_infreq(species)) %>%
 # mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = 0, hjust = -0.1, size=3) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Horní Chomutovka: Percentage of each prey in the diet") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Lumped

hCho %>%
  mutate(species = fct_infreq(species)) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0.5, hjust = -0.1) +
  labs(y = "", x ="") +
  coord_flip() +
  labs(title = "Horní Chomutovka: Percentage of each prey in the diet") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

Diet by season

We shouldn’t have summer into account. Autumn is also in the limit.

dfSummary(hCho)
## Data Frame Summary  
## hCho  
## Dimensions: 173 x 5  
## Duplicates: 131  
## 
## -----------------------------------------------------------------------------------------------------------------------
## No   Variable      Stats / Values                  Freqs (% of Valid)   Graph                     Valid      Missing   
## ---- ------------- ------------------------------- -------------------- ------------------------- ---------- ----------
## 1    location      1. Doln<ed> B<ed>lina             0 (  0.0%)                                   173        0         
##      [factor]      2. Doln<ed> Chomutovka            0 (  0.0%)                                   (100%)     (0%)      
##                    3. Horn<ed> B<ed>lina             0 (  0.0%)                                                        
##                    4. Horn<ed> Chomutovka          173 (100.0%)         IIIIIIIIIIIIIIIIIIII                           
##                    5. jezero Milada                  0 (  0.0%)                                                        
##                    6. P<f8><ed>se<e8>nice            0 (  0.0%)                                                        
## 
## 2    month         1. April                        63 (36.4%)           IIIIIII                   173        0         
##      [character]   2. August                        4 ( 2.3%)                                     (100%)     (0%)      
##                    3. February                     22 (12.7%)           II                                             
##                    4. January                      28 (16.2%)           III                                            
##                    5. July                          5 ( 2.9%)                                                          
##                    6. March                        22 (12.7%)           II                                             
##                    7. November                     14 ( 8.1%)           I                                              
##                    8. September                    15 ( 8.7%)           I                                              
## 
## 3    season        1. Spring                       85 (49.1%)           IIIIIIIII                 173        0         
##      [factor]      2. Summer                        9 ( 5.2%)           I                         (100%)     (0%)      
##                    3. Autumn                       29 (16.8%)           III                                            
##                    4. Winter                       50 (28.9%)           IIIII                                          
## 
## 4    size          1. 0-5 cm                        0 ( 0.0%)                                     130        43        
##      [factor]      2. 5-10 cm                      69 (53.1%)           IIIIIIIIII                (75.14%)   (24.86%)  
##                    3. 10-15 cm                     37 (28.5%)           IIIII                                          
##                    4. 15-20 cm                     16 (12.3%)           II                                             
##                    5. 20-25 cm                      8 ( 6.2%)           I                                              
##                    6. 25-30 cm                      0 ( 0.0%)                                                          
##                    7. 30-35 cm                      0 ( 0.0%)                                                          
##                    8. 40-45 cm                      0 ( 0.0%)                                                          
## 
## 5    species       1. Abramis sp.                    0 ( 0.0%)                                    173        0         
##      [factor]      2. Alburnus alburnus              0 ( 0.0%)                                    (100%)     (0%)      
##                    3. Anguilla anguilla              0 ( 0.0%)                                                         
##                    4. Barbatula barbatula            1 ( 0.6%)                                                         
##                    5. Barbus barbus                  0 ( 0.0%)                                                         
##                    6. Carassius sp.                  1 ( 0.6%)                                                         
##                    7. Ctenopharyngodon idella        3 ( 1.7%)                                                         
##                    8. Cyprinus carpio                2 ( 1.2%)                                                         
##                    9. Esox lucius                    0 ( 0.0%)                                                         
##                    10. Gobio a Romanogobio sp.       1 ( 0.6%)                                                         
##                    [ 20 others ]                   165 (95.4%)          IIIIIIIIIIIIIIIIIII                            
## -----------------------------------------------------------------------------------------------------------------------

Total proportions

hCho %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::filter(season != "Summer") %>% 
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = season , fill = species)) +
  #facet_grid(. ~ season)+
  scale_fill_discrete(drop = TRUE) +
  scale_y_continuous("Species proportion") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Species") +
  #theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Chomutovka: Diet by Season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))+
  guides(fill = guide_legend(reverse = TRUE))

Plot with fixed scales, not lumped

hCho %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>% 
  dplyr::filter(season != "Summer") %>% 
  #dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>% 
  mutate(species = fct_infreq(species)) %>%
  ggplot( aes(x= species, group = location), show.legend = FALSE) + 
  
  geom_bar(aes(y = ..prop.., fill = factor(..x..)), stat="count", show.legend = FALSE)  + 
  geom_text(aes( label = scales::percent(..prop..,accuracy = 2L),
                 y= ..prop.. ), stat= "count", vjust = -0, hjust = 0) +
  labs(y = "", x ="") +
  facet_wrap(~ season) +
  coord_flip() +
  labs(title = "Horní Chomutovka: Otter diet by season") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1L))

SIZE

Diet by location and size

Plot all together just to see if the data looks right.

tidy_db %>%
  drop_na(size) %>% 
  # group by stretch and location before lumping so that 0.05 applies to each stretch separatedly
  # dplyr::group_by(stretch,location) %>%
  # mutate(species = fct_lump_prop(species,0.05)) %>%
  # ungroup() %>%
  # mutate(species = fct_reorder(species, desc(species))) %>%
  # dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill=size)) +
  facet_grid(. ~ location)+
  geom_bar(na.rm = TRUE)+
  theme_bw() +
  scale_y_continuous("Samples collected") +
  scale_x_discrete("") +
  labs(fill = "Size Group") +
  #theme(axis.text.x = element_text(angle = 90)) +
  coord_flip() +
  labs(title = "Krusne Hory") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

lumped_fish %>%
  drop_na(size) %>% 
  dplyr::filter(species == "Fish") %>%
 ggplot(aes(x = location, fill = size)) +
  #facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("") +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
 # coord_flip() +
  labs(title = "Krusne Hory: Size distribution") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=TRUE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))
## List of 2
##  $ axis.title.y:List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : num 15
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  $ plot.title  :List of 11
##   ..$ family       : NULL
##   ..$ face         : NULL
##   ..$ colour       : NULL
##   ..$ size         : num 15
##   ..$ hjust        : NULL
##   ..$ vjust        : NULL
##   ..$ angle        : NULL
##   ..$ lineheight   : NULL
##   ..$ margin       : NULL
##   ..$ debug        : NULL
##   ..$ inherit.blank: logi FALSE
##   ..- attr(*, "class")= chr [1:2] "element_text" "element"
##  - attr(*, "class")= chr [1:2] "theme" "gg"
##  - attr(*, "complete")= logi FALSE
##  - attr(*, "validate")= logi TRUE

All together as proportion

Just the fish with size measurements, pooling 5% less common

tidy_db %>%
  drop_na(size) %>%
  # group by stretch and location before lumping so that 0.05 applies to each stretch separatedly
  dplyr::group_by(location) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ungroup() %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill=size)) +
  facet_grid(. ~ location)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Krusne Hory") +
  coord_flip()

 # guides(fill = guide_legend(reverse = TRUE))

Horní Bilina

Lumped data.

hBilina %>%
  drop_na(size) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill = size)) +
  scale_fill_discrete(drop = FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Bílina") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Not lumped

hBilina %>%
  drop_na(size) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill = size)) +
  scale_fill_discrete(drop = FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Bílina") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

By season

hBilina %>%
  drop_na(size) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill = size)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop = TRUE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Bílina, diet by season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Dolní Bílina

Lumped data.

dBilina %>%
  drop_na(size) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill = size)) +
  scale_fill_discrete(drop = FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Dolní Bílina") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Not lumped

dBilina %>%
  drop_na(size) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill = size)) +
  scale_fill_discrete(drop = FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Dolní Bílina") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

By season

dBilina %>%
  drop_na(size) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill = size)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop = TRUE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Dolní Bílina, diet by season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Přísečnice

Not Lumped

pris %>%
  drop_na(size) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = species, fill=size)) +
  #facet_grid(. ~ location)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Přísečnice") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Lumped

pris %>%
  drop_na(size) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = species, fill=size)) +
  #facet_grid(. ~ location)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Přísečnice") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

pris %>%
  drop_na(size) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = species, fill=size)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Přísečnice, diet by season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Jezero Milada

Mining recovered area

Not lumped

jez <- tidy_db %>%
  filter(location == "jezero Milada")

jez %>%
  drop_na(size) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = species, fill=size)) +
  #facet_grid(. ~ location)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "jezero Milada") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Lumped

jez %>%
  drop_na(size) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = species, fill=size)) +
  #facet_grid(. ~ location)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "jezero Milada") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

jez %>%
  drop_na(size) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  mutate(species = fct_lump_prop(species,0.05)) %>%
  ggplot(aes(x = species, fill=size)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Jezero Milada, diet by season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Horní Chomutovka

Not lumped

hCho %>%
  drop_na(size) %>%
  
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill=size)) +
 # facet_grid(. ~ stretch)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Chomutovka") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

hCho %>%
  drop_na(size) %>%
   dplyr::filter(season != "Summer") %>% 
#  mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill=size)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Horní Chomutovka, diet by season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Dolní Chomutovka

Not lumped

dCho %>%
  drop_na(size) %>%
  #mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill=size)) +
 # facet_grid(. ~ stretch)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Dolní Chomutovka") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

dCho %>%
  drop_na(size) %>%
#   dplyr::filter(season != "Summer") %>% 
#  mutate(species = fct_lump_prop(species,0.05)) %>%
  mutate(species = fct_reorder(species, desc(species))) %>%
  dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
  ggplot(aes(x = species, fill=size)) +
  facet_wrap(. ~ season)+
  scale_fill_discrete(drop=FALSE) +
  scale_y_continuous("Proportion size") +
  scale_x_discrete("") +
  geom_bar(position = "fill") +
  labs(fill = "Size Group (cm)") +
  # theme(axis.text.x = element_text(angle = 90)) +
  labs(title = "Dolní Chomutovka, diet by season") +
  coord_flip() +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

How do upper and lower courses of the streams compare ?

Differences in species

#filter upper

# upper <- tidy_db %>%
#   dplyr::filter(stretch == "Upper")
#
#
# upper %>%
#   dplyr::group_by(location) %>%
#   mutate(species = fct_lump_prop(species,0.05)) %>%
#   ungroup() %>%
#   mutate(species = fct_reorder(species, desc(species))) %>%
#   dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
#   ggplot(aes(x =location , fill = species)) +
#   #facet_grid(. ~ season)+
#   scale_fill_discrete(drop = TRUE) +
#   scale_y_continuous("") +
#   scale_x_discrete("") +
#   geom_bar(position = "fill") +
#   labs(fill = "Species") +
#   # theme(axis.text.x = element_text(angle = 90)) +
#   labs(title = "Diet: Species proportion in upper courses of the streams") +
#   #coord_flip() +
#   theme(axis.text.x = element_text(size = 10)) +
#   theme(axis.title.x = element_text(size = 15)) +
#   theme(axis.title.y = element_text(size = 15)) +
#   theme(plot.title = element_text(size = 15))
#
# #filter lower
#
# lower <- tidy_db %>%
#   dplyr::filter(stretch == "Lower")
#
#
# lower %>%
#   dplyr::group_by(location) %>%
#   mutate(species = fct_lump_prop(species,0.05)) %>%
#   ungroup() %>%
#   mutate(species = fct_reorder(species, desc(species))) %>%
#   dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
#   ggplot(aes(x =location , fill = species)) +
#   #facet_grid(. ~ season)+
#   scale_fill_discrete(drop = TRUE) +
#   scale_y_continuous("") +
#   scale_x_discrete("") +
#   geom_bar(position = "fill") +
#   labs(fill = "Species") +
#   # theme(axis.text.x = element_text(angle = 90)) +
#   labs(title = "Diet: Species proportion in lower courses of the streams") +
#   #coord_flip() +
#   theme(axis.text.x = element_text(size = 10)) +
#   theme(axis.title.x = element_text(size = 15)) +
#   theme(axis.title.y = element_text(size = 15)) +
#   theme(plot.title = element_text(size = 15))
#
#

Differences in size

# #filter upper
#
# upper <- tidy_db %>%
#   dplyr::filter(stretch == "Upper")
#
#
# upper %>%
#   drop_na(size) %>%
#   dplyr::group_by(location) %>%
#   mutate(species = fct_lump_prop(species,0.05)) %>%
#   ungroup() %>%
#   mutate(species = fct_reorder(species, desc(species))) %>%
#   dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
#   ggplot(aes(x =species , fill = size)) +
#   facet_grid(. ~ location)+
#   scale_fill_discrete(drop = TRUE) +
#   scale_y_continuous("") +
#   scale_x_discrete("") +
#   geom_bar(position = "fill") +
#   labs(fill = "Size") +
#   # theme(axis.text.x = element_text(angle = 90)) +
#   labs(title = "Diet: Size proportion in upper courses of the streams") +
#   coord_flip() +
#   theme(axis.text.x = element_text(size = 10)) +
#   theme(axis.title.x = element_text(size = 15)) +
#   theme(axis.title.y = element_text(size = 15)) +
#   theme(plot.title = element_text(size = 15))
#
# #filter lower
#
# lower <- tidy_db %>%
#   drop_na(size) %>%
#   dplyr::filter(stretch == "Lower")
#
#
# lower %>%
#   dplyr::group_by(location) %>%
#   mutate(species = fct_lump_prop(species,0.05)) %>%
#   ungroup() %>%
#   mutate(species = fct_reorder(species, desc(species))) %>%
#   dplyr::mutate(species = fct_relevel(species, "Other", after = Inf)) %>%
#   ggplot(aes(x =species , fill = size)) +
#   facet_grid(. ~ location)+
#   scale_fill_discrete(drop = TRUE) +
#   scale_y_continuous("") +
#   scale_x_discrete("") +
#   geom_bar(position = "fill") +
#   labs(fill = "Size") +
#   # theme(axis.text.x = element_text(angle = 90)) +
#   labs(title = "Diet: Size proportion in lower courses of the streams") +
#   coord_flip() +
#   theme(axis.text.x = element_text(size = 10)) +
#   theme(axis.title.x = element_text(size = 15)) +
#   theme(axis.title.y = element_text(size = 15)) +
#   theme(plot.title = element_text(size = 15))

Just salmonid size

tidy_db %>%
 dplyr::filter(species == "Salmonids") %>%
  ggplot(aes(x = species, fill = size)) +
  facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete(labels=NULL) +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
 # coord_flip() +
  labs(title = "Krusne Hory: Size distribution of salmonids") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

Comparing size distribution for natural sp vs stocked sp

salmo_vs_gobio <- c("Salmonids", "Gobio a Romanogobio sp.")
salmo_vs_tinca <- c("Salmonids", "Tinca tinca")
salmo_vs_perca <- c("Salmonids", "Perca fluviatilis")
salmo_vs_leuciscus <- c("Salmonids", "Leuciscus cephalus")
salmo_vs_rutilus <- c("Salmonids", "Rutilus rutilus")

tidy_db %>%
 dplyr::filter(species %in% salmo_vs_gobio) %>%
  ggplot(aes(x = species, fill = size)) +
  facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("") +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
 # coord_flip() +
  labs(title = "Krusne Hory: Size distribution of salmonids and Gobio sp") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

tidy_db %>%
 dplyr::filter(species %in% salmo_vs_tinca) %>%
  ggplot(aes(x = species, fill = size)) +
  facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("") +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
 # coord_flip() +
  labs(title = "Krusne Hory: Size distribution of salmonids and Tinca tinca") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

tidy_db %>%
 dplyr::filter(species %in% salmo_vs_perca) %>%
  ggplot(aes(x = species, fill = size)) +
  facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("") +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
  coord_flip() +
  labs(title = "Krusne Hory: Size distribution of salmonids and Perca fluviatilis") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

tidy_db %>%
 dplyr::filter(species %in% salmo_vs_leuciscus) %>%
  ggplot(aes(x = species, fill = size)) +
  facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("") +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
  coord_flip() +
  labs(title = "Krusne Hory: Size distribution of salmonids and Leuciscus cephalus") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

tidy_db %>%
 dplyr::filter(species %in% salmo_vs_rutilus) %>%
  ggplot(aes(x = species, fill = size)) +
  facet_grid(. ~ location)+
  geom_bar( position = "dodge")+
  scale_y_continuous("") +
  scale_x_discrete("") +
  labs(fill = "Size") +
  #theme(axis.text.x = element_text(angle = 90)) +
 # coord_flip() +
  labs(title = "Krusne Hory: Size distribution of salmonids and Rutilus rutilus") +
  scale_fill_brewer(palette = "Paired") +
  scale_fill_discrete(drop=FALSE) +
  theme(axis.text.x = element_text(size = 10)) +
  theme(axis.title.x = element_text(size = 15)) +
  theme(axis.title.y = element_text(size = 15)) +
  theme(plot.title = element_text(size = 15))

LS0tDQphdXRob3I6ICJGZXJuYW5kbyBNYXRlb3MtR29uesOhbGV6Ig0KZGF0ZTogTGFzdCB1cGRhdGUgImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogbm8NCiAgICAgIHNtb290aF9zY3JvbGw6IG5vDQogIG1kX2RvY3VtZW50Og0KICAgIHZhcmlhbnQ6IG1hcmtkb3duX2dpdGh1Yg0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCnRpdGxlOiAiT3R0ZXIgRGlldDogS3J1xaFuw6kgaG9yeSBBdXR1bW4gMjAxOSINCg0KDQojIHRpdGxlOiAiT3R0ZXIgRGlldDogS3J1xaFuw6kgaG9yeSBBdXR1bW4gMjAxOSINCiMgYXV0aG9yOiAiRmVybmFuZG8gTWF0ZW9zLUdvbnrDoWxleiINCiMgZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0KIyBvdXRwdXQ6DQojICAgd29yZF9kb2N1bWVudDoNCiMgICAgIHRvYzogbm8NCiMgICAgIGZpZ19jYXB0aW9uOiB0cnVlDQojICAgICByZWZlcmVuY2VfZG9jeDogc3R5bGV3b3JkLmRvY3gNCiMgDQojICAgDQoNCmtuaXQ6IChmdW5jdGlvbihpbnB1dEZpbGUsIGVuY29kaW5nKSB7DQogIHJtYXJrZG93bjo6cmVuZGVyKGlucHV0RmlsZSwgZW5jb2RpbmcgPSBlbmNvZGluZywgb3V0cHV0X2RpciA9ICJSZXN1bHRzIikgfSkNCi0tLQ0KIyBJbnRyb2R1Y3Rpb24NCg0KUHJlbGltaW5hcnkgdmlzdWFsIGV4cGxvcmF0aW9uIG9mIGRhdGEuID4gQ2xpY2sgY29kZSB0byBzZWUgaG93IGl0IHdhcyBkb25lIA0KDQpUaGUgZGF0YSBjb21lcyBmcm9tIHNhbXBsZXMgY29sbGVjdGVkIGFzIHNwcmFpbnRzOiBFYWNoIG9mIHRoZW0gd2FzIGFuYWx5c2VkIHVuZGVyIHRoZSBtaWNyb3Njb3BlLCBib25lcyBhbmQgc2NhbGVzIGlkZW50aWZpZWQgd2hlbmV2ZXIgcG9zc2libGUuIEZpc2ggYm9uZXMgd2VyZSBtZWFzdXJlZCBhbmQgZ2F2ZSB1cyB0aGUgc2l6ZSBncm91cCBvZiB0aGUgaW5kaXZpZHVhbC4gIA0KDQpUaGUgYWltIG9mIHRoZSBzdHVkeSBpcyB0byBzaG93IHRoZSB2YXJpYWJpbGl0eSBvZiB0aGUgb3R0ZXIgZGlldCwgYm90aCBpbiB0ZXJtcyBvZiBzaXplIGFuZCBiaW9kaXZlcnNpdHkuICANCg0KVGhlIHN0dWRpZWQgbG9jYXRpb25zIGFyZTogIA0KDQoqIELDrWxpbmEgcml2ZXIgKFVwcGVyIGFuZCBMb3dlcikNCiogQ2hvbXV0dmthIHJpdmVyIChVcHBlciBhbmQgTG93ZXIpDQoqIFDFmcOtc2XEjW5pY2UgKEEgd2F0ZXIgcmVzZXJ2b2lyIGZvciBodW1hbiBjb25zdW1wdGlvbikNCiogTGFrZSBNaWxhZGEgKEEgcmVjZW50bHkgcmVjb3ZlcmVkIG1pbmluZyBhcmVhKSAgDQoNCldlIHdvdWxkIGV4cGVjdCB0byBmaW5kIGRpZmZlcmVuY2VzIGluIHByZWRhdGlvbiBiZXR3ZWVuIGxha2VzIGFuZCByaXZlcnMsIGJldHdlZW4gdXBwZXIgYW5kIGxvd2VyIGNvdXJzZXMgb2YgdGhlIHJpdmVycywgYW5kIGFsc28gYmV0d2VlbiB0aGUgdHdvIGxha2VzLCBhcyBNaWxhZGEgd2FzIG11Y2ggbW9yZSByZWNlbnRseSBmb3JtZWQgdGhhbiBQxZnDrXNlxI1uaWNlLiAgDQoNClByZWRhdGlvbiBzaG91bGQgcmVmbGVjdCB0aGUgc2l6ZSBkaXN0cmlidXRpb24gYW5kIGF2YWlsYWJpbGl0eSBvZiBlYWNoIHNwZWNpZXMsIHNvIHdlIHNob3VsZCBiZSBhYmxlIHRvIHNlZSBkaWZmZXJlbmNlcyBpbiB0aGUgc2l6ZSBkaXN0cmlidXRpb24gYmV0d2VlbiBzdG9ja2VkIGZpc2ggKFNhbG1vbmlkcykgYW5kIHdpbGQgZmlzaCwgc3VjaCBhcyBHb2JpbyBzcC4gIA0KDQoNCg0KDQoNCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBlY2hvPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aD02LCBmaWcuYXNwID0gMC42MTgsIGZpZy5wYXRoPSdGaWdzLycsDQogICAgICAgICAgICAgICAgICAgICAgZWNobz1UUlVFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFKQ0KDQpvcHRpb25zKGFsbG93X2h0bWxfaW5fYWxsX291dHB1dHM9VFJVRSkNCmBgYA0KDQoNCiMgTGlicmFyaWVzDQoNCmBgYHtyIGxpYnJhcmllcywgaW5jbHVkZT1GQUxTRX0NCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImdhZGVuYnVpZS9yZWdleHBsYWluIikNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInRpZHl2ZXJzZS9kcGx5ciIpDQojbGlicmFyeShkZXZ0b29scykNCiNpbnN0YWxsX2dpdGh1YigiaG9sdHp5L2VwdVJhdGUiKQ0KI2xpYnJhcnkoZXB1UmF0ZSkNCiNpbnN0YWxsIHRoZSBwYWNrYWdlcyBpZiBuZWNlc3NhcnkNCmlmKCFyZXF1aXJlKCJmcyIpKSBpbnN0YWxsLnBhY2thZ2VzKCJmcyIpDQppZighcmVxdWlyZSgicmVhZHhsIikpIGluc3RhbGwucGFja2FnZXMoInJlYWR4bCIpDQojcmVtb3Rlczo6aW5zdGFsbF9naXRodWIoImphbnV6L3JtZHJpdmUiKQ0KI2xpYnJhcnkocmVnZXhwbGFpbikNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInRpZHl2ZXJzZS9nb29nbGVkcml2ZSIpDQpsaWJyYXJ5KHJtZHJpdmUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoYnJvb20pDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkocnN0YXRpeCkNCmxpYnJhcnkoZ2dtb3NhaWMpDQpsaWJyYXJ5KCJvZmZpY2VyIikNCmxpYnJhcnkoInJ2ZyIpDQpsaWJyYXJ5KGFyc2VuYWwpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkoZ3JpZEV4dHJhKSANCmxpYnJhcnkoZ2dwdWJyKQ0KbGlicmFyeShmb3JtYXR0YWJsZSkNCmxpYnJhcnkoaW5mZXIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShncmlkKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2x1ZSkNCmxpYnJhcnkoZnMpDQpsaWJyYXJ5KGdvb2dsZWRyaXZlKQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpsaWJyYXJ5KHBhbHMpDQpsaWJyYXJ5KHN1bW1hcnl0b29scykNCmxpYnJhcnkoZ3JEZXZpY2VzKQ0KbGlicmFyeShQb2x5Y2hyb21lKQ0KDQojZWRpdCB0aGUgUiBwcm9maWxlIHNvIGl0IGxpa2VzIEN6ZWNoDQoNCiMgdXNldGhpczo6ZWRpdF9yX3Byb2ZpbGUoJ3Byb2plY3QnKQ0KIyANCiMgY29kZSB0byBlZGl0IHRoZSBycHJvZmlsZQ0KIyBpZiAoLlBsYXRmb3JtJE9TLnR5cGUgPT0gJ3dpbmRvd3MnKSB7DQojICAgU3lzLnNldGxvY2FsZShjYXRlZ29yeSA9ICdMQ19BTEwnLCdFbmdsaXNoX1VuaXRlZCBTdGF0ZXMuMTI1MCcpDQojIH0gZWxzZSB7DQojICAgU3lzLnNldGxvY2FsZShjYXRlZ29yeSA9ICdMQ19BTEwnLCdlbl9VUy5VVEYtOCcpDQojIH0NCg0KYGBgDQoNCg0KIyBEYXRhIHR5ZGluZw0KDQojIyBSYXcgZGF0YQ0KDQpPcmlnaW5hbCBkYXRhIGluICoqd2lkZSBmb3JtYXQqKjogDQpPbmUgY29sdW1uIGZvciBlYWNoIG9ic2VydmF0aW9uIG9mIHNwZWNpZXMgYW5kIGVhY2ggc2l6ZSBjYXRlZ29yeSANCg0KYGBge3IgcmF3ZGF0YX0NCiMgRGF0YS0tLS0NCg0KcGF0aCA8LSBoZXJlOjpoZXJlKCJkYXRhIiwgImtydXNuZWhvcnkueGxzeCIpDQoNCnJhdyA8LSBwYXRoICU+JQ0KICBleGNlbF9zaGVldHMoKSAlPiUNCiAgc2V0X25hbWVzKCkgJT4lDQogIG1hcF9kZihyZWFkX2V4Y2VsLCAjam9pbiBhbGwgc2hlZXRzIGJ5IHJvdw0KICAgICAgICAgcGF0aCA9IHBhdGgsDQogICAgICAgICAuaWQgPSAibG9jYXRpb24iKSAlPiUgI2NyZWF0ZSBuZXcgY29sdW1uIHdpdGggdGhlIG5hbWUgb2YgdGhlIHNoZWV0cw0KICBjbGVhbl9uYW1lcygpICAgICAgICAgICAgICAgICNwcm9iYWJseSBtYW55IGVycm9ycywgc28gYmV0dGVyIGNsZWFuDQoNCmhlYWQocmF3KQ0KYGBgDQoNCg0KDQojIyBMb25nIGZvcm1hdA0KDQpCZWZvcmUgdGhlIGFuYWx5c2lzIHdlIG5lZWQgdG86DQoNCi0gUGl2b3QgdGhlIGRhdGEgaW50byAqKmxvbmcgZm9ybWF0KiogKE9uZSByb3cgcGVyIG9ic2VydmF0aW9uKS4NCi0gQ3JlYXRlIG5ldyB2YXJpYWJsZXMgZm9yICJzcGVjaWVzIiBhbmQgInNpemUiLg0KLSBGaXggdHlwb3MgYW5kIG90aGVyIHNtYWxsIGVycm9ycy4NCg0KDQoNCmBgYHtyIHRpZHlpbmcsIGVjaG89VFJVRX0NCg0KIyBXaGF0IGEgbWVzcy4gTGV0J3MgdHJ5IHRvIHRpZHkgaXQuIA0KIyANCiMgMSkgc2VwYXJhdGUgYWxsIHRob3NlIGNvbHVtbnMgd2l0aCBzaXplcyBmcm9tIHRoZSBzcGVjaWVzLiANCiMgMikgcGl2b3Qgc2l6ZXMgaW50byBhIHNpbmdsZSBjb2x1bW4NCiMgMykgZmlsdGVyIGJ5IGluaXRpYWxzLCBhZGQgYSBzcGVjaWVzIGNvbHVtbiBmb3IgdGhlIGZpc2ggd2l0aCBzaXplLCBvbmUgYnkgb25lLiBGVWNrLg0KDQp0aWR5X3NpemUgPC0gcmF3ICU+JQ0KICBkcGx5cjo6c2VsZWN0KGxvY2F0aW9uLCBzdHJldGNoLCBtb250aCwgc2Vhc29uLCBjb250YWlucygiX2NtIikpICU+JQ0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IGNvbnRhaW5zKCJjbSIpLA0KICAgIG5hbWVzX3RvID0gInNpemUiLA0KICAgIHZhbHVlc190byA9ICJudW1iZXIiLA0KICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KICApICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2pvaW4gbGF0ZXIgd2l0aCBuZXcgc3BlY2llcyBjb2x1bW4gYmVsb3cNCiAgDQogICMgbGV2ZWxzKGFzLmZhY3Rvcih0aWR5X3NpemUkc2l6ZSkpICMgaG93IG1hbnkgZGlmZmVyZW50IHNpemVzPyBqb29vb2Rlcg0KICANCiAgDQogICMgQmV0dGVyIHJlZG8gdGhlIGZvbGxvd2luZyBjb2RlIG5pZ2h0bWFyZSB3aXRoIGNhc2Vfd2hlbigpISENCiAgDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGlmZWxzZSgNCiAgICBncmVwbCgiYWxfYmlfIiwgc2l6ZSksDQogICAgIkFsYnVybm9pZGVzIGJpcHVuY3RhdHVzIiwNCiAgICBpZmVsc2UoDQogICAgICBncmVwbCgiYWxfYWxfIiwgc2l6ZSksDQogICAgICAiQWxidXJudXMgYWxidXJudXMiLA0KICAgICAgaWZlbHNlKA0KICAgICAgICBncmVwbCgic3RfdHJfIiwgc2l6ZSksICAgICAgICAgICAgI2xvb2tzIGxpa2UgYSB0eXBpbmcgZXJyb3INCiAgICAgICAgIlNhbG1vIHRydXR0YSBtLiBmYXJpbyIsDQogICAgICAgIGlmZWxzZSgNCiAgICAgICAgICBncmVwbCgiYWJfYnJfIiwgc2l6ZSksDQogICAgICAgICAgIkFicmFtaXMgc3AuIiwNCiAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICBncmVwbCgiYmFfYmFfIiwgc2l6ZSksDQogICAgICAgICAgICAiQmFyYmF0dWxhIGJhcmJhdHVsYSIsDQogICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgIGdyZXBsKCJicl9icl8iLCBzaXplKSwNCiAgICAgICAgICAgICAgIkJhcmJ1cyBiYXJidXMiLA0KICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgZ3JlcGwoImNhXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICJDYXJhc3NpdXMgc3AuIiwNCiAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICBncmVwbCgiY2dfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAiQ3Rlbm9waGFyeW5nb2RvbiBpZGVsbGEiLA0KICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICBncmVwbCgiY3lfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICJDeXByaW51cyBjYXJwaW8iLA0KICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoImN0X2lkXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICJDdGVub3BoYXJ5bmdvZG9uIGlkZWxsYSIsDQogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoImdhX2FjIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAiR2FzdGVyb3N0ZXVzIGFjdWxlYXR1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJjaF9uYV8iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIkNob25kcm9zdG9tYSBuYXN1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiZWxfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVzb3ggbHVjaXVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiZ2dfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR29iaW8gYSBSb21hbm9nb2JpbyBzcC4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiZ3lfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJHeW1ub2NlcGhhbHVzIGNlcm51YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiaWNfbmViXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJY3RhbHVydXMgbmVidWxvc3VzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgibGVfY2VfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3F1YWxpdXMgY2VwaGFsdXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgibGVfZGVsXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGV1Y2FzcGl1cyBkZWxpbmVhdHVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJsZV9naV8iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGVwb21pcyBnaWJib3N1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoImxlX2xlXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxldWNpc2N1cyBsZXVjaXNjdXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgibG9fbG9fIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMb3RhIGxvdGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIm1pX2ZvXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNaXNndXJudXMgZm9zaWxpcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIm5lb2dfbWVsXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5lb2dvYml1cyBtZWxhbm9zdG9tdXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgib25fbXlrXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT25jb3JoeW5jaHVzIG15a2lzcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgicGZfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBlcmNhIGZsdXZpYXRpbGlzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgicGhfcGhfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGhveGludXMgcGhveGludXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgicHBfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQc2V1ZG9yYXNib3JhIHBhcnZhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJyc18iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmhvZGV1cyBzZXJpY2V1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoInJyXyIsIHNpemUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJ1dGlsdXMgcnV0aWx1cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCJzYV8iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNhbG1vbmlkcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgic2VfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjYXJkaW5pdXMgZXJ5dGhyb3BodGFsbXVzIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgic2lfZ2xfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2lsdXJ1cyBnbGFuaXMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgic2xfdHJfIiwgc2l6ZSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTYWxtbyB0cnV0dGEgbS4gZmFyaW8iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoInN0X2x1Y18iLCBzaXplKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3Rpem9zdGVkaW9uIGx1Y2lvcGVyY2EiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShncmVwbCgidHRfIiwgc2l6ZSksICJUaW5jYSB0aW5jYSIsICJlcnJvciIpICNhZGRpbmcgb3B0aW9uIGZvciBlcnJvciBpbiBjYXNlIEkgbWlzc2VkIGEgbmFtZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICApDQogICAgICAgICAgICApDQogICAgICAgICAgKQ0KICAgICAgICApDQogICAgICApDQogICAgKQ0KICApKQ0KDQpoZWFkKHRpZHlfc2l6ZSkNCg0KDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFBSRVZJT1VTIEFUVEVNUFRTLCBET04nVCBSVU4gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQoNCiMgICBwaXZvdF9sb25nZXIoDQojICAgICBjb2xzID0gQWJyYW1pczoiU3Rpem9zdGVkaW9uIGx1Y2lvcGVyY2EiLA0KIyAgICAgbmFtZXNfdG8gPSAic3BlY2llcyIsDQojICAgICB2YWx1ZXNfdG8gPSAibnVtYmVyUHJleSIsDQojICAgICB2YWx1ZXNfZHJvcF9uYSA9IFRSVUUNCiMgICApIA0KIyAgIA0KIyANCiMgDQojICAgDQojICAgcGl2b3RfbG9uZ2VyKA0KIyAgICAgY29scyA9IGNvbnRhaW5zKCJjbSIpLA0KIyAgICAgbmFtZXNfdG8gPSAic2l6ZSIsDQojICAgICB2YWx1ZXNfdG8gPSAibnVtYmVyIiwNCiMgICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KIyAgICkgJT4lICAgICAgICAgICAgICAgICAgICAgICMgbm9vb29vb29vbyEgaGF5IHF1ZSBoYWNlcmxvIG1hbnVhbCwgY2FkYSBzaXplIHdpdGggaXRzIHNwZWNpZXMNCiMgICBkcGx5cjo6ZmlsdGVyKG51bWJlciA+IDApICU+JQ0KIyAgIGRwbHlyOjptdXRhdGUoc2l6ZSA9IHN0cl9yZW1vdmVfYWxsKHNpemUsICJbKmEtekEtWl0iKSkgJT4lICNmdWNrIHJlZ3VsYXIgZXhwcmVzc2lvbnMNCiMgICBkcGx5cjo6bXV0YXRlIChzaXplID0gZ2x1ZSgie3NpemV9Y20iKSkgJT4lICAjaGFkIHRvIGluc3RhbGwgZGV2IHZlcnNpb24gb2YgZHBseXINCiMgICBkcGx5cjo6bXV0YXRlKHNpemUgPSBzdHJfdHJpbShzaXplKSkgJT4lICNyZW1vdmUgZXh0cmEgc3BhY2UNCiMgICBkcGx5cjo6bXV0YXRlKHNpemUgPSBmY3RfcmVsZXZlbChzaXplLCAiNS0xMCBjbSIsIGFmdGVyID0gMSkpICU+JQ0KIyAgIHVuY291bnQobnVtYmVyKSAlPiUgIyB0byBnZXQgaW5kaXZpZHVhbCBvYnNlcnZhdGlvbnMhIQ0KIyAgIHBpdm90X2xvbmdlcigNCiMgICAgIGNvbHMgPSBBYnJhbWlzOiJTdGl6b3N0ZWRpb24gbHVjaW9wZXJjYSIsDQojICAgICBuYW1lc190byA9ICJzcGVjaWVzIiwNCiMgICAgIHZhbHVlc190byA9ICJudW1iZXJQcmV5IiwNCiMgICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KIyAgICkgDQojIA0KIyBnbGltcHNlKHRpZHkpDQojIHN0cih0aWR5KQ0KIyANCiMgY29sb3VyQ291bnQgPSBsZW5ndGgodW5pcXVlKHRpZHkkc2l6ZSkpDQojIGdldFBhbGV0dGUgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoOSwgIk9yUmQiKVsyOjldKQ0KDQoNCmBgYA0KDQpUaGUgZGF0YSBpcyBub3cgaW4gKipsb25nIGZvcm1hdCoqIChKdXN0IG5lZWQgdG8gInVuY291bnQiIHRoZSAibnVtYmVyIiBjb2x1bW4gaW4gdGhlIG5leHQgc3RlcCkuDQpOb3cgd2UgbmVlZCB0bzoNCg0KLSBBZGQgdGhlIHJlc3Qgb2YgdGhlIHNwZWNpZXMgd2l0aG91dCBzaXplIG1lYXN1cmVtZW50cw0KLSBUbyBkbyB0aGF0LCB3ZSBuZWVkIHRvIHNlbGVjdCB0aGVtIGZyb20gcmF3IGFuZCBwaXZvdCB0aGVtIHRvIGdldCB0aGUgbnVtYmVyIHRvby4NCg0KLSBCaW5kIHJvdyB0byB0aWR5X3NpemUNCi0gQ2xlYW4gdGhlIHNpemUgdmFyaWFibGUNCi0gUmVqb2ljZQ0KDQojIyBOZXcgdmFyaWFibGUgc2l6ZSBhbmQgcmVuYW1pbmcgYW5kIHJlb3JkZXJpbmcgZmFjdG9yIGxldmVscw0KDQoNCmBgYHtyIG1lcmdlX3NwZWNpZXMsIGVjaG89VFJVRX0NCg0KIyBPSywga291c2VrIHBvIGtvdXNrdS4gTm93IHdlIGhhdmUgdG86DQojIA0KIyA0KSBhZGQgdGhlIHJlc3Qgb2YgdGhlIHNwZWNpZXMgd2l0aG91dCBzaXplIG1lYXN1cmVtZW50cw0KIyAgICA0LjEpICBUbyBkbyB0aGF0LCB3ZSBuZWVkIHRvIHNlbGVjdCB0aGVtIGZyb20gcmF3IGFuZCBwaXZvdCB0aGVtIHRvIGdldCB0aGUgbnVtYmVyIHRvby4NCiMgICAgDQojIDUpIGJpbmQgcm93IHRvIHRpZHlfc2l6ZQ0KIyA2KSBjbGVhbiB0aGUgc2l6ZSB2YXJpYWJsZQ0KIyA3KSBSZWpvaWNlDQoNCg0KZXh0cmFfc3AgPC0gcmF3ICU+JSANCiAgZHBseXI6OnNlbGVjdChsb2NhdGlvbiwgc3RyZXRjaCwgbW9udGgsIHNlYXNvbiwgYW5ndWlsbGFfYW5ndWlsbGEsIGN5cHJpbmlkYWUsIGFzdGFjdXM6c2VycGVudGVzKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKA0KICAgIGNvbHMgPSBjKCJhbmd1aWxsYV9hbmd1aWxsYSIsICJjeXByaW5pZGFlIiwgYXN0YWN1czpzZXJwZW50ZXMpLA0KICAgIG5hbWVzX3RvID0gInNwZWNpZXMiLA0KICAgIHZhbHVlc190byA9ICJudW1iZXIiLA0KICAgIHZhbHVlc19kcm9wX25hID0gVFJVRQ0KICApDQoNCnRpZHlfZGIgPC0gYmluZF9yb3dzKHRpZHlfc2l6ZSwgZXh0cmFfc3ApICU+JSANCiAgZHBseXI6OmZpbHRlcihudW1iZXIgPiAwKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzaXplID0gc3RyX3JlbW92ZV9hbGwoc2l6ZSwgIlsqYS16QS1aX10iKSkgJT4lICANCiAgZHBseXI6Om11dGF0ZShzaXplID0gZHBseXI6OnJlY29kZShzaXplLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMDUiID0gIjAtNSBjbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjUxMCIgPSAiNS0xMCBjbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwMTUiID0gIjEwLTE1IGNtIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUyMCIgPSAiMTUtMjAgY20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMDI1IiA9ICIyMC0yNSBjbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjI1MzAiID0gIjI1LTMwIGNtIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMzAzNSIgPSAiMzAtMzUgY20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIzNS00MCIgPSAiMzUtNDAgY20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI0MDQ1IiA9ICI0MC00NSBjbSINCiAgKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNpemUgPSBmY3RfcmVsZXZlbChzaXplLCAiNS0xMCBjbSIsIGFmdGVyID0gMSkpICU+JQ0KICB1bmNvdW50KG51bWJlcikgJT4lICAgICAgICAgICAgICAgICAjIHRvIGdldCBpbmRpdmlkdWFsIG9ic2VydmF0aW9ucyEhDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IHN0cl90b19zZW50ZW5jZShzcGVjaWVzKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBkcGx5cjo6cmVjb2RlKHNwZWNpZXMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBc3RhY3VzIiA9ICJBc3RhY29pZGVhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQW5ndWlsbGFfYW5ndWlsbGEiID0gIkFuZ3VpbGxhIGFuZ3VpbGxhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2FsbW8gdHJ1dHRhIG0uIGZhcmlvIiA9ICJTYWxtb25pZHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPbmNvcmh5bmNodXMgbXlraXNzIiA9ICJTYWxtb25pZHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDeXByaW5pZGFlIiA9ICJVbmlkZW50aWZpZWQgQ3lwcmluaWRhZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsYnVybm9pZGVzIGJpcHVuY3RhdHVzIiA9ICJBbGJ1cm51cyBhbGJ1cm51cyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdvYmlvIGEgcm9tYW5vZ29iaW8gc3AuIiA9ICJHb2JpbyBhIFJvbWFub2dvYmlvIHNwLiINCiAgKSkgJT4lICMgVHJvdXRzIHBvb2xlZCBpbnRvIHNhbG1vbmlkcywgQWxidXJub2lkZXMgaW50byBhbGJ1cm51cw0KICBkcGx5cjo6bXV0YXRlKHN0cmV0Y2ggPSBkcGx5cjo6cmVjb2RlKHN0cmV0Y2gsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkb2xuw60iID0gIkxvd2VyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaG9ybsOtIiA9ICJVcHBlciIpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gYXMuZmFjdG9yKHNwZWNpZXMpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoc3RyZXRjaCA9IGFzLmZhY3RvcihzdHJldGNoKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiQXZlcyIsIGFmdGVyID0gSW5mKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiSW5zZWN0YSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJNYW1tYWxpYSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJBbnVyYSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJTZXJwZW50ZXMiLCBhZnRlciA9IEluZikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiQXN0YWNvaWRlYSIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc2Vhc29uID0gZHBseXI6OnJlY29kZShzZWFzb24sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpbnRlciIgPSAiV2ludGVyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzcHJpbmciID0gIlNwcmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3VtbWVyIiA9ICJTdW1tZXIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImF1dHVtbiIgPSAiQXV0dW1uIikpICU+JSANCiAgZHBseXI6Om11dGF0ZShzZWFzb24gPSBhcy5mYWN0b3Ioc2Vhc29uKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKHNlYXNvbiA9IGZjdF9yZWxldmVsKHNlYXNvbiwgIlNwcmluZyIsICJTdW1tZXIiLCAiQXV0dW1uIiwgIldpbnRlciIgKSkgJT4lIA0KICBkcGx5cjo6bXV0YXRlKGxvY2F0aW9uID0gYXMuZmFjdG9yKGxvY2F0aW9uKSkgJT4lIA0KICAjIERpdmlkZSBzdHJlYW1zIGludG8gVXBwZXIgYW5kIGxvd2VyIGFuZCByZW1vdmluZyB2YXJpYWJsZSBzdHJldGNoDQogIGRwbHlyOjptdXRhdGUobG9jYXRpb24gPSBjYXNlX3doZW4obG9jYXRpb24gPT0gIkLDrWxpbmEiICYgc3RyZXRjaCA9PSAiVXBwZXIiIH4gIkhvcm7DrSBCw61saW5hIiwNCiAgICAgICAgICBsb2NhdGlvbiA9PSAiQsOtbGluYSIgJiBzdHJldGNoID09ICJMb3dlciIgfiAiRG9sbsOtIELDrWxpbmEiLCANCiAgICAgICAgICBsb2NhdGlvbiA9PSAiQ2hvbXV0b3ZrYSIgJiBzdHJldGNoID09ICJMb3dlciIgfiAiRG9sbsOtIENob211dG92a2EiLA0KICAgICAgICAgIGxvY2F0aW9uID09ICJDaG9tdXRvdmthIiAmIHN0cmV0Y2ggPT0gIlVwcGVyIiB+ICJIb3Juw60gQ2hvbXV0b3ZrYSIsDQogICAgICAgICAgbG9jYXRpb24gPT0gIlByaXNlY25pY2UiIH4gIlDFmcOtc2XEjW5pY2UiLA0KICAgICAgICAgIFRSVUUgfiAiamV6ZXJvIE1pbGFkYSIpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUobG9jYXRpb24gPSBhcy5mYWN0b3IobG9jYXRpb24pKSAlPiUgDQogIGRwbHlyOjpzZWxlY3QoLXN0cmV0Y2gpDQogIA0KDQoNCnN1bW1hcnkodGlkeV9kYikNCg0KaGVhZCh0aWR5X2RiKQ0KDQp3cml0ZS5jc3YyKHRpZHlfZGIsImRhdGFTaGlueS90aWR5X2RiIiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCmBgYA0KDQoNCiMjIEZpc2ggbHVtcGVkIGluIG9uZSBjYXRlZ29yeQ0KDQpgYGB7ciBmaXNoLWx1bXBlZH0NCg0KbHVtcGVkX2Zpc2ggPC0gdGlkeV9kYiAlPiUgDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGNhc2Vfd2hlbigNCiAgICBzcGVjaWVzID09ICJBdmVzIiB+ICJBdmVzIiwNCiAgICBzcGVjaWVzID09ICJJbnNlY3RhIiB+ICdJbnNlY3RhJywNCiAgICBzcGVjaWVzID09ICJNYW1tYWxpYSIgfiAnTWFtbWFsaWEnLA0KICAgIHNwZWNpZXMgPT0gIkFudXJhIiB+ICdBbnVyYScsDQogICAgc3BlY2llcyA9PSAiU2VycGVudGVzIiB+ICdTZXJwZW50ZXMnLA0KICAgIHNwZWNpZXMgPT0gIkFzdGFjb2lkZWEiIH4gJ0FzdGFjb2lkZWEnLA0KICAgIA0KICAgIFRSVUUgfiAnRmlzaCcgKSkNCg0KDQpoZWFkKGx1bXBlZF9maXNoKQ0KDQp3cml0ZS5jc3YyKGx1bXBlZF9maXNoLCJkYXRhU2hpbnkvbHVtcGVkX2Zpc2giLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KDQpgYGANCg0KIyBEaWV0OiBXaGF0IGRvIG90dGVycyBlYXQsIGluIHdoaWNoIHByb3BvcnRpb24gb2Ygc3BlY2llcz8NCg0KVGhlIGNhdGVnb3J5ICJTYWxtb25pZHMiIGluY2x1ZGVzIFNhbG1vIHRydXR0YSBtLmZhcmlvLCBPbmNvcmh5bmNodXMgbXlraXNzIGFuZCB1bmlkZW50aWZpZWQgc2FsbW9uaWRzLg0KDQojIyBJZGVudGlmaWVkIHByZXkNCg0KTnVtYmVyIG9mIGluZGl2aWR1YWwgcHJleSBmb3VuZCBpbiBzcHJhaW50cyBpbiBlYWNoIGxvY2F0aW9uDQoNCmBgYHtyIG51bWJlci10YWJsZX0NCg0KdG90YWxfcHJleSA8LSB0aWR5X2RiICU+JSANCiAgZHBseXI6OnNlbGVjdChsb2NhdGlvbiwgc3BlY2llcykgJT4lDQogIGRwbHlyOjpjb3VudChzcGVjaWVzLCBsb2NhdGlvbikgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gbG9jYXRpb24sIHZhbHVlc19mcm9tID0gbiApICU+JSANCiAgcmVwbGFjZShpcy5uYSguKSwgMCkNCg0Ka2FibGUodG90YWxfcHJleSwgYWxpZ24gPSAibGNjcnIiKSAlPiUgDQogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoKQ0KDQpgYGANCg0KIyMgRGlldCBpcyB2ZXJ5IHZhcmllZA0KDQojIyMgQ3VzdG9tIHBhbGV0dGUNCg0KYGBge3IgY3VzdG9tX3BhbGV0dGV9DQoNCiNDcmVhdGUgY3VzdG9tIHBhbGV0dGUNCiMgDQpzZWVkIDwtIGMoIiNmZjAwMDAiLCAiIzAwZmYwMCIsICIjMDAwMGZmIikNCg0Kc3BlY2llc192IDwtIGxldmVscyh0aWR5X2RiJHNwZWNpZXMpDQoNCnNwZWNpZXNfdmVjdG9yPC0gYyhzcGVjaWVzX3YsICJPdGhlciIpDQoNCiMgbmFtZXMocGFsZXR0ZTEpID0gc3BlY2llc192ZWN0b3INCg0Kc3BlY2llc19jb2xvcnMgPSBzZXROYW1lcyhvYmplY3QgPSBjcmVhdGVQYWxldHRlKDMxLCBzZWVkLCBwcmVmaXg9Im1pbmUiKSwgbm0gPSBzcGVjaWVzX3ZlY3RvcikNCg0Kc3dhdGNoKHNwZWNpZXNfY29sb3JzKQ0KI3ByaW50KHNwZWNpZXNfY29sb3JzKQ0KYGBgDQoNCg0KDQpgYGB7ciBudW1iZXJfYnlfc3BlY2llcywgZmlnLndpZHRoPTEwfQ0KDQp0aWR5X2RiICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvY2F0aW9uLCBmaWxsPXNwZWNpZXMpKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9IHNwZWNpZXNfY29sb3JzKSArDQogICNmYWNldF9ncmlkKC4gfiBzZWFzb24pKw0KICBnZW9tX2JhcigpKw0KICB0aGVtZV9idygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJTYW1wbGVzIGNvbGxlY3RlZCIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU3BlY2llcyIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnkiKSArDQogICNzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKyANCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsgDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArIA0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpDQoNCg0KDQpgYGANCg0KIyMgTW9zdCBDb21tb24gUHJleSBieSBzZWFzb24NCg0KKEx1bXBpbmcgNSUgbGVzcyBjb21tb24pDQoNCmBgYHtyIG51bWJlci1ieS1zcC1sZXNzLWNhdGVnb3JpZXMsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEzfQ0KDQoNCg0KdGlkeV9kYiAlPiUgDQogICMgZ3JvdXAgYnkgbG9jYXRpb24gYmVmb3JlIGx1bXBpbmcgc28gdGhhdCAwLjA1IGFwcGxpZXMgdG8gZWFjaCBzZXBhcmF0ZWx5DQogIGRwbHlyOjpncm91cF9ieShsb2NhdGlvbikgJT4lIA0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIkFzdGFjb2lkZWEiLCAiQW51cmEiLCBhZnRlciA9IEluZikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSAgIA0KICBkcGx5cjo6bXV0YXRlKGxvY2F0aW9uID0gZmN0X3JlbGV2ZWwobG9jYXRpb24sICJqZXplcm8gTWlsYWRhIiwgYWZ0ZXIgPSAwKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvY2F0aW9uLCBmaWxsPXNwZWNpZXMpKSArIA0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9IHNwZWNpZXNfY29sb3JzKSArDQogIGZhY2V0X3dyYXAoLiB+IHNlYXNvbikrDQogIGdlb21fYmFyKCkrDQogIHRoZW1lX2J3KCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIklkZW50aWZpZWQgcHJleSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU3BlY2llcyIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnk6IE1vc3QgY29tbW9uIHByZXkgYnkgc2Vhc29uIikgKw0KICAjIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKw0KICAjIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArIA0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKyANCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsgDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkrDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkNCg0KDQoNCmBgYA0KDQoNCg0KDQoNCg0KDQojIyBBbGwgdG9nZXRoZXIgYXMgcHJvcG9ydGlvbiANCg0KYGBge3IgcHJvcHNwLCBlY2hvPVRSVUV9DQoNCiMgdGlkeV9kYiAlPiUgDQojICAgIyBncm91cCBieSBzdHJldGNoIGFuZCBsb2NhdGlvbiBiZWZvcmUgbHVtcGluZyBzbyB0aGF0IDAuMDUgYXBwbGllcyB0byBlYWNoIHN0cmV0Y2ggc2VwYXJhdGVkbHkNCiMgICAjIGRwbHlyOjpncm91cF9ieShzdHJldGNoLGxvY2F0aW9uKSAlPiUgDQojICAgIyBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KIyAgICMgdW5ncm91cCgpICU+JSANCiMgICAjIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KIyAgICMgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQojICAgZ2dwbG90KGFlcyh4ID0gbG9jYXRpb24sIGZpbGw9c3BlY2llcykpICsNCiMgICBmYWNldF9ncmlkKC4gfiBzZWFzb24pKw0KIyAgIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KIyAgIHNjYWxlX3lfY29udGludW91cygiUHJvcG9ydGlvbiBvZiBzcGVjaWVzIikgKw0KIyAgIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiMgICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KIyAgIGxhYnMoZmlsbCA9ICJTcGVjaWVzIHByb3BvcnRpb24iKSArDQojICAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KIyAgIGNvb3JkX2ZsaXAoKSArDQojICAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeSIpICANCg0KDQoNCg0KYGBgDQoNCiMjIE1vc3QgY29tbW9uIHByZXk6IEFsbCB0b2dldGhlciBhcyBwcm9wb3J0aW9uIChsdW1waW5nIDUlIGxlc3MgY29tbW9uKQ0KDQpgYGB7ciBwcm9wc3AtbW9zdC1jb21tb24sIGVjaG89VFJVRSwgZmlnLndpZHRoPTEwfQ0KDQoNCnRpZHlfZGIgJT4lIA0KICAjIGdyb3VwIGJ5IHN0cmV0Y2ggYW5kIGxvY2F0aW9uIGJlZm9yZSBsdW1waW5nIHNvIHRoYXQgMC4wNSBhcHBsaWVzIHRvIGVhY2ggc3RyZXRjaCBzZXBhcmF0ZWRseQ0KICBkcGx5cjo6Z3JvdXBfYnkobG9jYXRpb24pICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIkFzdGFjb2lkZWEiLCAiQW51cmEiLCBhZnRlciA9IEluZikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JQ0KIGRwbHlyOjptdXRhdGUobG9jYXRpb24gPSBmY3RfcmVsZXZlbChsb2NhdGlvbiwgImplemVybyBNaWxhZGEiLCBhZnRlciA9IDApKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbG9jYXRpb24sIGZpbGw9c3BlY2llcykpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPSBzcGVjaWVzX2NvbG9ycykgKw0KICAjZmFjZXRfZ3JpZCguIH4gc2Vhc29uKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIG9mIHNwZWNpZXMiLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU3BlY2llcyBwcm9wb3J0aW9uIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnk6IE1vc3QgY29tbW9uIHByZXksIHllYXIgcm91bmQiKSArIA0KICBjb29yZF9mbGlwKCkrDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkNCg0KDQoNCg0KYGBgDQoNCg0KDQoNCg0KIyMgQWxsIGZpc2ggbHVtcGVkIHRvZ2V0aGVyLCBhcyBwcm9wb3J0aW9uIA0KDQoNCmBgYHtyIHByb3BzcGZpc2gsIGVjaG89VFJVRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTB9DQoNCg0KDQpsdW1wZWRfZmlzaCAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCJGaXNoIikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGxvY2F0aW9uID0gZmN0X3JlbGV2ZWwobG9jYXRpb24sICJqZXplcm8gTWlsYWRhIiwgYWZ0ZXIgPSAwKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGxvY2F0aW9uLCBmaWxsPXNwZWNpZXMpKSArDQogICNmYWNldF9ncmlkKC4gfiBzZWFzb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIG9mIHNwZWNpZXMiLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTcGVjaWVzIHByb3BvcnRpb24iKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnkiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkNCg0KDQoNCg0KYGBgDQoNCiMjIEFsbCBmaXNoIGx1bXBlZCB0b2dldGhlciwgYXMgcHJvcG9ydGlvbiwgYnkgc2Vhc29uIA0KDQoNCmBgYHtyIHByb3BzcGZpc2gtc2Vhc29uLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEwfQ0KDQoNCg0KbHVtcGVkX2Zpc2ggJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywiRmlzaCIpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShsb2NhdGlvbiA9IGZjdF9yZWxldmVsKGxvY2F0aW9uLCAiamV6ZXJvIE1pbGFkYSIsIGFmdGVyID0gMCkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBsb2NhdGlvbiwgZmlsbD1zcGVjaWVzKSkgKw0KICBmYWNldF93cmFwKC4gfiBzZWFzb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIG9mIHNwZWNpZXMiLCBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU3BlY2llcyBwcm9wb3J0aW9uIikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIktydXNuZSBIb3J5IikgKw0KICBjb29yZF9mbGlwKCkrDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkNCg0KDQoNCg0KYGBgDQoNCg0KIyMgRWFjaCBsb2NhdGlvbiBzZXBhcmF0ZWx5IA0KDQoNCiMgSG9ybsOtIELDrWxpbmEgDQoNCiMjIFBlcmNlbnRhZ2Ugb2YgZWFjaCBwcmV5IGluIHRoZSBkaWV0DQoNCihEYXRhIG5vdCBsdW1wZWQpDQoNCmBgYHtyIGhCaWxpbmFzcCwgZWNobz1UUlVFLCBmaWcud2lkdGg9MTB9DQoNCmhCaWxpbmEgPC0gdGlkeV9kYiAlPiUNCiAgZmlsdGVyKGxvY2F0aW9uID09ICJIb3Juw60gQsOtbGluYSIpDQoNCg0KDQojIGhCaWxpbmEgJT4lDQojICAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQojICAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQojICAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQojICAgZ2dwbG90KGFlcyh4ID1sb2NhdGlvbiAsIGZpbGwgPSBzcGVjaWVzKSkgKw0KIyAgIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcCA9IFRSVUUpICsNCiMgICBzY2FsZV95X2NvbnRpbnVvdXMoIiIpICsNCiMgICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQojICAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiMgICBsYWJzKGZpbGwgPSAiU3BlY2llcyIpICsNCiMgICAjdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiMgICBsYWJzKHRpdGxlID0gIkRpZXQ6IFNwZWNpZXMgcHJvcG9ydGlvbiBpbiBVcHBlciBhbmQgTG93ZXIgQsOtbGluYSIpICsNCiMgICBjb29yZF9mbGlwKCkgKw0KIyAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiMgICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KIyAgIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQojICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQpoQmlsaW5hICU+JQ0KICAjbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JSANCiAgI2RwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lIA0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9pbmZyZXEoc3BlY2llcykpICU+JQ0KICBnZ3Bsb3QoIGFlcyh4PSBzcGVjaWVzLCBncm91cCA9IGxvY2F0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdD0iY291bnQiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyANCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoLi5wcm9wLi4sYWNjdXJhY3kgPSAyTCksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gLTAuNSwgaGp1c3QgPSAtMC4xKSArDQogIGxhYnMoeSA9ICIiLCB4ID0iIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIkhvcm7DrSBCw61saW5hOiBQZXJjZW50YWdlIG9mIGVhY2ggcHJleSBncm91cCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpDQoNCmBgYA0KDQoNCg0KIyMgRGlldCBieSBzZWFzb24NCg0KSSB3b3VsZCBzYXkgaXQncyBvbmx5IHJlbGV2YW50IHRvIGNvbXBhcmUgU3ByaW5nLCBTdW1tZXIgYW5kIEF1dHVtbiwgYmVjYXVzZSB0aGVyZSBhcmUganVzdCA1IG9ic2VydmF0aW9ucyBpbiBXaW50ZXIuDQoNCiMjIyBUb3RhbCBwcm9wb3J0aW9ucw0KDQpgYGB7ciBoQmlsaW5hU2Vhc29uV2ludGVyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9IDR9DQpoQmlsaW5hICU+JQ0KICAjbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIyBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uICwgZmlsbCA9IHNwZWNpZXMpKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcCA9IFRSVUUpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJTcGVjaWVzIHByb3BvcnRpb24iKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNwZWNpZXMiKSArDQogICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJIb3Juw60gQsOtbGluYTogRGlldCBieSBTZWFzb24iKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQ0KDQpgYGANCg0KDQojIyMgTm8gd2ludGVyDQoNCmBgYHtyIGhCaWxpbmFTZWFzb24sIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0gNH0NCg0KaEJpbGluYSAlPiUNCiAgZHBseXI6OmZpbHRlcihzZWFzb24gIT0gIldpbnRlciIpICU+JSANCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICMgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHNlYXNvbiAsIGZpbGwgPSBzcGVjaWVzKSkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3AgPSBUUlVFKSArDQogIHNjYWxlX3lfY29udGludW91cygiU3BlY2llcyBwcm9wb3J0aW9uIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTcGVjaWVzIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiSG9ybsOtIELDrWxpbmE6IERpZXQgYnkgU2Vhc29uIChubyB3aW50ZXIpIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkrDQogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkNCg0KYGBgDQpgYGB7cn0NCg0KYGBgDQoNCiMjIyBCeSBzZWFzb24sIHdpdGggcGVyY2VudGFnZXMNCg0KIyMjIyBQbG90IHdpdGggZnJlZSBzY2FsZXMNCg0KYGBge3IgaEJpbGluYVNlYXNvblBlcmNlbnRhZ2VzLCBmaWcud2lkdGg9IDEyLCBmaWcuaGVpZ2h0PTR9DQoNCmhCaWxpbmEgJT4lDQogICNtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiV2ludGVyIikgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdD0iY291bnQiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyANCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoLi5wcm9wLi4sYWNjdXJhY3kgPSAyTCksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gLTAuNSwgaGp1c3QgPSAtMC4xKSArDQogIGxhYnMoeSA9ICIiLCB4ID0iIikgKw0KICBmYWNldF93cmFwKH4gc2Vhc29uLHNjYWxlcyA9ICJmcmVlIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIkhvcm7DrSBCw61saW5hOiBPdHRlciBkaWV0IGJ5IHNlYXNvbiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpDQpgYGANCg0KIyMjIyBQbG90IHdpdGggZml4ZWQgc2NhbGVzDQoNCg0KYGBge3Igc2Vhc29uRml4c2NhbGVzLCBmaWcud2lkdGg9MTMsIGZpZy5oZWlnaHQ9NH0NCg0KaEJpbGluYSAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uICE9ICJXaW50ZXIiKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArICANCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoLi5wcm9wLi4sYWNjdXJhY3kgPSAyTCksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gLTAuMSwgaGp1c3QgPSAwLCBzaXplID0yLjgpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGZhY2V0X3dyYXAofiBzZWFzb24pICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJIb3Juw60gQsOtbGluYTogT3R0ZXIgZGlldCBieSBzZWFzb24iKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KDQoNCg0KYGBgDQoNCg0KIyBEb2xuw60gQsOtbGluYSANCg0KIyMgUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQNCg0KDQpgYGB7ciBkQmlsaW5hc3AsIGZpZy5oZWlnaHQ9IDEwLCBmaWcud2lkdGg9OH0NCmRCaWxpbmEgPC0gdGlkeV9kYiAlPiUNCiAgZmlsdGVyKGxvY2F0aW9uID09ICJEb2xuw60gQsOtbGluYSIpDQoNCmRCaWxpbmEgJT4lDQogICNtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsNCiAgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjUsIGhqdXN0ID0gLTAuMSwgc2l6ZSA9MykgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJEb2xuaSBCw61saW5hOiBQZXJjZW50YWdlIG9mIGVhY2ggcHJleSBncm91cCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpDQpgYGANCg0KYGBge3IgZEJpbGluYVByZXlMdW1wZWR9DQoNCmRCaWxpbmEgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdD0iY291bnQiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQoNCiAgZ2VvbV90ZXh0KGFlcyggbGFiZWwgPSBzY2FsZXM6OnBlcmNlbnQoLi5wcm9wLi4sYWNjdXJhY3kgPSAyTCksDQogICAgICAgICAgICAgICAgIHk9IC4ucHJvcC4uICksIHN0YXQ9ICJjb3VudCIsIHZqdXN0ID0gLTAuNSwgaGp1c3QgPSAtMC4xLCBzaXplID0gMykgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJEb2xuaSBCw61saW5hOiBQZXJjZW50YWdlIG9mIGVhY2ggcHJleSBncm91cCAoMC4wNSBsdW1wZWQpIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkNCg0KDQpgYGANCg0KDQoNCiMjIERpZXQgYnkgc2Vhc29uDQoNCmBgYHtyIGRCaWxpbmFTdHJ9DQoNCmRmU3VtbWFyeShkQmlsaW5hKQ0KDQpgYGANCg0KDQojIyMgRml4ZWQgc2NhbGVzDQoNCmBgYHtyIGRCaWxpbmFzcDIsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMn0NCg0KZEJpbGluYSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JSANCiAjIGRwbHlyOjpmaWx0ZXIoc2Vhc29uICE9ICJXaW50ZXIiKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjUsIGhqdXN0ID0gLTAuMSkgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgZmFjZXRfd3JhcCh+IHNlYXNvbikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIkRvbG4gQsOtbGluYTogT3R0ZXIgZGlldCBieSBzZWFzb24iKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KDQoNCg0KYGBgDQoNCg0KDQoNCiMgUMWZw61zZcSNbmljZSANCg0KV2F0ZXIgcmVzZXJ2b2lyIGZvciBodW1hbiBjb25zdW1wdGlvbi4NCg0KIyMgUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQNCg0KYGBge3IgcHJpc3NwLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTEwfQ0KDQpwcmlzIDwtIHRpZHlfZGIgJT4lDQogIGZpbHRlcihsb2NhdGlvbiA9PSAiUMWZw61zZcSNbmljZSIpDQoNCg0KcHJpcyAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjUsIGhqdXN0ID0gLTAuMSwgc2l6ZT0zKSArDQogIGxhYnMoeSA9ICIiLCB4ID0iIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIlDFmcOtc2XEjW5pY2U6IFBlcmNlbnRhZ2Ugb2YgZWFjaCBwcmV5IGdyb3VwIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkNCmBgYA0KDQpgYGB7ciBwcmlzbHVtcGVkLCBmaWcuaGVpZ2h0PTYsZmlnLndpZHRoPTEyfQ0KDQpwcmlzICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjUsIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDMpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiUMWZw61zZcSNbmljZTogUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgZ3JvdXAgKDAuMDUgbHVtcGVkKSIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpDQoNCiMgDQoNCmBgYA0KDQojIyBEaWV0IGJ5IHNlYXNvbg0KDQpQcm9iYWJseSB3aXNlIG5vdCB0byBwbG90IHdpbnRlci4gU3ByaW5nL3N1bW1lciB2cyBBdXR1bW4gYWxzbyBxdWl0ZSB1bmJhbGFuY2VkLg0KDQpgYGB7ciBwcmlzU3RyfQ0KDQpkZlN1bW1hcnkocHJpcykNCg0KYGBgDQoNCg0KIyMjIEZpeGVkIHNjYWxlcw0KDQpgYGB7ciBwcmlzRGlldDIsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD02fQ0KDQpwcmlzICU+JQ0KICAjbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JSANCiAgZHBseXI6OmZpbHRlcihzZWFzb24gIT0gIldpbnRlciIpICU+JSANCiAgI2RwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lIA0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9pbmZyZXEoc3BlY2llcykpICU+JQ0KIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLixhY2N1cmFjeSA9IDFMKSwNCiAgICAgICAgICAgICAgICAgeT0gLi5wcm9wLi4gKSwgc3RhdD0gImNvdW50Iiwgdmp1c3QgPSAwLCBoanVzdCA9IC0wLjEpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGZhY2V0X3dyYXAofiBzZWFzb24pICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJQxZnDrXNlxI1uaWNlOiBPdHRlciBkaWV0IGJ5IHNlYXNvbiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpDQpgYGANCg0KYGBge3IgbHVtcGVkcHJpcywgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTB9DQpwcmlzICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiV2ludGVyIikgJT4lIA0KICAjZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUgDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQpnZ3Bsb3QoIGFlcyh4PSBzcGVjaWVzLCBncm91cCA9IGxvY2F0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdD0iY291bnQiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyAgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMUwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IDAsIGhqdXN0ID0gLTAuMSkgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgZmFjZXRfd3JhcCh+IHNlYXNvbikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIlDFmcOtc2XEjW5pY2U6IE90dGVyIGRpZXQgYnkgc2Vhc29uICgwLjA1IGx1bXBlZCkiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KDQpgYGANCg0KDQoNCiMgSmV6ZXJvIE1pbGFkYSANCg0KIyMgUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQNCg0KYGBge3IgamV6c3AsIGVjaG89VFJVRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTB9DQpqZXogPC0gdGlkeV9kYiAlPiUNCiAgZmlsdGVyKGxvY2F0aW9uID09ICJqZXplcm8gTWlsYWRhIikNCg0KamV6ICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9pbmZyZXEoc3BlY2llcykpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQpnZ3Bsb3QoIGFlcyh4PSBzcGVjaWVzLCBncm91cCA9IGxvY2F0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdD0iY291bnQiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyAgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjIsIGhqdXN0ID0gLTAuMSwgc2l6ZT0gMykgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJKZXplcm8gTWlsYWRhOiBQZXJjZW50YWdlIG9mIGVhY2ggcHJleSBpbiB0aGUgZGlldCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAyTCkpDQpgYGANCg0KYGBge3IgamV6bm90bHVtcGVkLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0NCg0KamV6ICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9pbmZyZXEoc3BlY2llcykpICU+JQ0KICAjbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLixhY2N1cmFjeSA9IDJMKSwNCiAgICAgICAgICAgICAgICAgeT0gLi5wcm9wLi4gKSwgc3RhdD0gImNvdW50Iiwgdmp1c3QgPSAwLCBoanVzdCA9IC0wLjEsIHNpemU9IDMpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiSmV6ZXJvIE1pbGFkYTogUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMkwpKQ0KYGBgDQoNCiMjIERpZXQgYnkgc2Vhc29uDQoNClBlcmhhcHMgd2UgY2FuIHBsb3Qgd2ludGVyLg0KDQpgYGB7ciBqZXpTdHJ9DQoNCmRmU3VtbWFyeShqZXopDQoNCmBgYA0KDQojIyBUb3RhbCBwcm9wb3J0aW9ucw0KDQpgYGB7ciBqZXpzcFNlYXNvbiwgZWNobz1UUlVFfQ0KDQpqZXogJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNlYXNvbiAsIGZpbGwgPSBzcGVjaWVzKSkgKw0KICAjZmFjZXRfZ3JpZCguIH4gc2Vhc29uKSsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wID0gVFJVRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlNwZWNpZXMgcHJvcG9ydGlvbiIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU3BlY2llcyIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiSmV6ZXJvIE1pbGFkYTogRGlldCBieSBTZWFzb24iKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQ0KDQpgYGANCg0KIyMjIEZpeGVkIHNjYWxlcw0KDQpgYGB7ciBqZXpTZWFzb25GaXhlZCwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTB9DQoNCmpleiAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JSANCiAgI2RwbHlyOjpmaWx0ZXIoc2Vhc29uICE9ICJXaW50ZXIiKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjUsIGhqdXN0ID0gLTAuMSkgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgZmFjZXRfd3JhcCh+IHNlYXNvbikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIkplemVybyBNaWxhZGE6IE90dGVyIGRpZXQgYnkgc2Vhc29uIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkNCg0KYGBgDQoNCg0KDQojIERvbG7DrSBDaG9tdXRvdmthDQoNCiMjIFBlcmNlbnRhZ2Ugb2YgZWFjaCBwcmV5IGluIHRoZSBkaWV0DQoNCmBgYHtyIGRDaG9zcCwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0NCmRDaG8gPC0gdGlkeV9kYiAlPiUNCiAgZmlsdGVyKGxvY2F0aW9uID09ICJEb2xuw60gQ2hvbXV0b3ZrYSIpDQoNCmRDaG8gJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjUsIGhqdXN0ID0gLTAuMSkgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJEb2xuw60gQ2hvbXV0b3ZrYTogUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KYGBgDQoNCg0KYGBge3IgZENob3NwQWxsLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQ0KZENobyAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCmdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLixhY2N1cmFjeSA9IDJMKSwNCiAgICAgICAgICAgICAgICAgeT0gLi5wcm9wLi4gKSwgc3RhdD0gImNvdW50Iiwgdmp1c3QgPSAtMC41LCBoanVzdCA9IC0wLjEpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiRG9sbsOtIENob211dG92a2E6IFBlcmNlbnRhZ2Ugb2YgZWFjaCBwcmV5IGluIHRoZSBkaWV0IikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkNCmBgYA0KDQojIyBEaWV0IGJ5IHNlYXNvbg0KDQoNCmBgYHtyIGRDaG9TdHJ9DQoNCmRmU3VtbWFyeShkQ2hvKQ0KDQpgYGANCg0KDQojIyMgVG90YWwgcHJvcG9ydGlvbnMNCg0KYGBge3IgZENob1NlYXNvbiwgZWNobz1UUlVFfQ0KDQpkQ2hvICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzZWFzb24gLCBmaWxsID0gc3BlY2llcykpICsNCiAgI2ZhY2V0X2dyaWQoLiB+IHNlYXNvbikrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcCA9IFRSVUUpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJTcGVjaWVzIHByb3BvcnRpb24iKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNwZWNpZXMiKSArDQogICN0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkRvbG7DrSBDaG9tdXRvdmthOiBEaWV0IGJ5IFNlYXNvbiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpDQoNCmBgYA0KDQojIyMgUGxvdCB3aXRoIGZpeGVkIHNjYWxlcywgbm90IGx1bXBlZA0KDQpgYGB7ciBkQ2hvc3BTZWFzb24sIGVjaG89VFJVRSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTN9DQoNCmRDaG8gJT4lDQogICNtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lIA0KICAjZHBseXI6OmZpbHRlcihzZWFzb24gIT0gIldpbnRlciIpICU+JSANCiAgI2RwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lIA0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9pbmZyZXEoc3BlY2llcykpICU+JQ0KICBnZ3Bsb3QoIGFlcyh4PSBzcGVjaWVzLCBncm91cCA9IGxvY2F0aW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyANCiAgDQogIGdlb21fYmFyKGFlcyh5ID0gLi5wcm9wLi4sIGZpbGwgPSBmYWN0b3IoLi54Li4pKSwgc3RhdD0iY291bnQiLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSAgKyAgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IDAsIGhqdXN0ID0gLTAuMSxzaXplPTMpICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGZhY2V0X3dyYXAofiBzZWFzb24pICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJEb2xuw60gQ2hvbXV0b3ZrYTogT3R0ZXIgZGlldCBieSBzZWFzb24iKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KYGBgDQoNCiMgSG9ybsOtIENob211dG92a2ENCg0KIyMgUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQNCg0KYGBge3IgaENobywgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0NCmhDaG8gPC0gdGlkeV9kYiAlPiUNCiAgZmlsdGVyKGxvY2F0aW9uID09ICJIb3Juw60gQ2hvbXV0b3ZrYSIpDQoNCmhDaG8gJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIyBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIGdncGxvdCggYWVzKHg9IHNwZWNpZXMsIGdyb3VwID0gbG9jYXRpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIA0KICANCiAgZ2VvbV9iYXIoYWVzKHkgPSAuLnByb3AuLiwgZmlsbCA9IGZhY3RvciguLnguLikpLCBzdGF0PSJjb3VudCIsIHNob3cubGVnZW5kID0gRkFMU0UpICArIA0KICBnZW9tX3RleHQoYWVzKCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudCguLnByb3AuLixhY2N1cmFjeSA9IDJMKSwNCiAgICAgICAgICAgICAgICAgeT0gLi5wcm9wLi4gKSwgc3RhdD0gImNvdW50Iiwgdmp1c3QgPSAwLCBoanVzdCA9IC0wLjEsIHNpemU9MykgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJIb3Juw60gQ2hvbXV0b3ZrYTogUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KYGBgDQoNCiMjIyBMdW1wZWQNCmBgYHtyIGhDaG9MdW1wZWQsIGVjaG89VFJVRSwgZmlnLmhlaWdodD0zLCBmaWcud2lkdGg9OX0NCmhDaG8gJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2luZnJlcShzcGVjaWVzKSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLjUsIGhqdXN0ID0gLTAuMSkgKw0KICBsYWJzKHkgPSAiIiwgeCA9IiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJIb3Juw60gQ2hvbXV0b3ZrYTogUGVyY2VudGFnZSBvZiBlYWNoIHByZXkgaW4gdGhlIGRpZXQiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KYGBgDQoNCg0KIyMgRGlldCBieSBzZWFzb24NCg0KV2Ugc2hvdWxkbid0IGhhdmUgc3VtbWVyIGludG8gYWNjb3VudC4gQXV0dW1uIGlzIGFsc28gaW4gdGhlIGxpbWl0Lg0KDQpgYGB7ciBoQ2hvU3RyfQ0KDQpkZlN1bW1hcnkoaENobykNCg0KYGBgDQoNCg0KIyMjIFRvdGFsIHByb3BvcnRpb25zDQoNCmBgYHtyIGhDaG9TZWFzb25BbGwsIGVjaG89VFJVRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTB9DQpoQ2hvICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6OmZpbHRlcihzZWFzb24gIT0gIlN1bW1lciIpICU+JSANCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uICwgZmlsbCA9IHNwZWNpZXMpKSArDQogICNmYWNldF9ncmlkKC4gfiBzZWFzb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3AgPSBUUlVFKSArDQogIHNjYWxlX3lfY29udGludW91cygiU3BlY2llcyBwcm9wb3J0aW9uIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTcGVjaWVzIikgKw0KICAjdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJIb3Juw60gQ2hvbXV0b3ZrYTogRGlldCBieSBTZWFzb24iKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSsNCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQ0KDQpgYGANCg0KIyMjIFBsb3Qgd2l0aCBmaXhlZCBzY2FsZXMsIG5vdCBsdW1wZWQNCg0KYGBge3IgaENob3NwU2Vhc29uLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0yMH0NCg0KaENobyAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoc2Vhc29uICE9ICJTdW1tZXIiKSAlPiUgDQogICNkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JSANCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfaW5mcmVxKHNwZWNpZXMpKSAlPiUNCiAgZ2dwbG90KCBhZXMoeD0gc3BlY2llcywgZ3JvdXAgPSBsb2NhdGlvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsgDQogIA0KICBnZW9tX2JhcihhZXMoeSA9IC4ucHJvcC4uLCBmaWxsID0gZmFjdG9yKC4ueC4uKSksIHN0YXQ9ImNvdW50Iiwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgICsgDQogIGdlb21fdGV4dChhZXMoIGxhYmVsID0gc2NhbGVzOjpwZXJjZW50KC4ucHJvcC4uLGFjY3VyYWN5ID0gMkwpLA0KICAgICAgICAgICAgICAgICB5PSAuLnByb3AuLiApLCBzdGF0PSAiY291bnQiLCB2anVzdCA9IC0wLCBoanVzdCA9IDApICsNCiAgbGFicyh5ID0gIiIsIHggPSIiKSArDQogIGZhY2V0X3dyYXAofiBzZWFzb24pICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJIb3Juw60gQ2hvbXV0b3ZrYTogT3R0ZXIgZGlldCBieSBzZWFzb24iKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKQ0KYGBgDQoNCg0KIyBTSVpFDQoNCg0KIyMgRGlldCBieSBsb2NhdGlvbiBhbmQgc2l6ZQ0KDQpQbG90IGFsbCB0b2dldGhlciBqdXN0IHRvIHNlZSBpZiB0aGUgZGF0YSBsb29rcyByaWdodC4NCg0KYGBge3IgcGxvdF9hbGwsIGVjaG89VFJVRSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9DQoNCnRpZHlfZGIgJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lIA0KICAjIGdyb3VwIGJ5IHN0cmV0Y2ggYW5kIGxvY2F0aW9uIGJlZm9yZSBsdW1waW5nIHNvIHRoYXQgMC4wNSBhcHBsaWVzIHRvIGVhY2ggc3RyZXRjaCBzZXBhcmF0ZWRseQ0KICAjIGRwbHlyOjpncm91cF9ieShzdHJldGNoLGxvY2F0aW9uKSAlPiUNCiAgIyBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogICMgdW5ncm91cCgpICU+JQ0KICAjIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICAjIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGw9c2l6ZSkpICsNCiAgZmFjZXRfZ3JpZCguIH4gbG9jYXRpb24pKw0KICBnZW9tX2JhcihuYS5ybSA9IFRSVUUpKw0KICB0aGVtZV9idygpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJTYW1wbGVzIGNvbGxlY3RlZCIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSBHcm91cCIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnkiKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmx1bXBlZF9maXNoICU+JQ0KICBkcm9wX25hKHNpemUpICU+JSANCiAgZHBseXI6OmZpbHRlcihzcGVjaWVzID09ICJGaXNoIikgJT4lDQogZ2dwbG90KGFlcyh4ID0gbG9jYXRpb24sIGZpbGwgPSBzaXplKSkgKw0KICAjZmFjZXRfZ3JpZCguIH4gbG9jYXRpb24pKw0KICBnZW9tX2JhciggcG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCIiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgbGFicyhmaWxsID0gIlNpemUiKSArDQogICN0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICMgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeTogU2l6ZSBkaXN0cmlidXRpb24iKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiUGFpcmVkIikgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9VFJVRSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCg0KDQpgYGANCg0KDQojIyBBbGwgdG9nZXRoZXIgYXMgcHJvcG9ydGlvbg0KDQpKdXN0IHRoZSBmaXNoIHdpdGggc2l6ZSBtZWFzdXJlbWVudHMsIHBvb2xpbmcgNSUgbGVzcyBjb21tb24NCg0KYGBge3IgcGxvdF9wcm9wLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQ0KDQp0aWR5X2RiICU+JQ0KICBkcm9wX25hKHNpemUpICU+JQ0KICAjIGdyb3VwIGJ5IHN0cmV0Y2ggYW5kIGxvY2F0aW9uIGJlZm9yZSBsdW1waW5nIHNvIHRoYXQgMC4wNSBhcHBsaWVzIHRvIGVhY2ggc3RyZXRjaCBzZXBhcmF0ZWRseQ0KICBkcGx5cjo6Z3JvdXBfYnkobG9jYXRpb24pICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGw9c2l6ZSkpICsNCiAgZmFjZXRfZ3JpZCguIH4gbG9jYXRpb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAiKSArDQogICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeSIpICsNCiAgY29vcmRfZmxpcCgpDQogIyBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpDQoNCg0KYGBgDQoNCg0KDQojIyBIb3Juw60gQmlsaW5hIA0KDQojIyMgTHVtcGVkIGRhdGEuDQoNCmBgYHtyIGhiaWxpbmFTaXplLCBlY2hvPVRSVUV9DQpoQmlsaW5hICU+JQ0KICBkcm9wX25hKHNpemUpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzLCBmaWxsID0gc2l6ZSkpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wID0gRkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkhvcm7DrSBCw61saW5hIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQpgYGANCg0KIyMjIE5vdCBsdW1wZWQNCg0KYGBge3IgYmlsaW5hU2l6ZSwgZWNobz1UUlVFfQ0KaEJpbGluYSAlPiUNCiAgZHJvcF9uYShzaXplKSAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGwgPSBzaXplKSkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3AgPSBGQUxTRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gc2l6ZSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSBHcm91cCAoY20pIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiSG9ybsOtIELDrWxpbmEiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCmBgYA0KDQojIyMgQnkgc2Vhc29uDQoNCmBgYHtyIGJpbGluYVNpemVBbGwsIGVjaG89VFJVRSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9DQoNCmhCaWxpbmEgJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGwgPSBzaXplKSkgKw0KICBmYWNldF93cmFwKC4gfiBzZWFzb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3AgPSBUUlVFKSArDQogIHNjYWxlX3lfY29udGludW91cygiUHJvcG9ydGlvbiBzaXplIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTaXplIEdyb3VwIChjbSkiKSArDQogICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJIb3Juw60gQsOtbGluYSwgZGlldCBieSBzZWFzb24iKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KYGBgDQoNCg0KIyMgRG9sbsOtIELDrWxpbmENCg0KIyMjIEx1bXBlZCBkYXRhLg0KDQpgYGB7ciBkQmlsaW5hU2l6ZSwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0NCmRCaWxpbmEgJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGwgPSBzaXplKSkgKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3AgPSBGQUxTRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gc2l6ZSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSBHcm91cCAoY20pIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiRG9sbsOtIELDrWxpbmEiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KDQoNCmBgYA0KDQojIyMgTm90IGx1bXBlZA0KDQpgYGB7ciBkYmlsaW5hU2l6ZSwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD0xMX0NCmRCaWxpbmEgJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lDQogICNtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzLCBmaWxsID0gc2l6ZSkpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wID0gRkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkRvbG7DrSBCw61saW5hIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQpgYGANCg0KIyMjIEJ5IHNlYXNvbg0KDQpgYGB7ciBkYmlsaW5hU2l6ZUFsbCwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0NCg0KZEJpbGluYSAlPiUNCiAgZHJvcF9uYShzaXplKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbCA9IHNpemUpKSArDQogIGZhY2V0X3dyYXAoLiB+IHNlYXNvbikrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcCA9IFRSVUUpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkRvbG7DrSBCw61saW5hLCBkaWV0IGJ5IHNlYXNvbiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQpgYGANCg0KDQoNCiMjIFDFmcOtc2XEjW5pY2UgDQoNCiMjIyBOb3QgTHVtcGVkDQoNCmBgYHtyIHByaXMsIGVjaG89VFJVRSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9DQpwcmlzICU+JQ0KICBkcm9wX25hKHNpemUpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbD1zaXplKSkgKw0KICAjZmFjZXRfZ3JpZCguIH4gbG9jYXRpb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIlDFmcOtc2XEjW5pY2UiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KYGBgDQoNCiMjIyBMdW1wZWQNCg0KYGBge3IgcHJzTHVtcGVkLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMn0NCnByaXMgJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGw9c2l6ZSkpICsNCiAgI2ZhY2V0X2dyaWQoLiB+IGxvY2F0aW9uKSsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wPUZBTFNFKSArDQogIHNjYWxlX3lfY29udGludW91cygiUHJvcG9ydGlvbiBzaXplIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTaXplIEdyb3VwIChjbSkiKSArDQogICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJQxZnDrXNlxI1uaWNlIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCmBgYA0KDQoNCmBgYHtyIHByaXNMLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTEyfQ0KcHJpcyAlPiUNCiAgZHJvcF9uYShzaXplKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogICNtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGw9c2l6ZSkpICsNCiAgZmFjZXRfd3JhcCguIH4gc2Vhc29uKSsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wPUZBTFNFKSArDQogIHNjYWxlX3lfY29udGludW91cygiUHJvcG9ydGlvbiBzaXplIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnMoZmlsbCA9ICJTaXplIEdyb3VwIChjbSkiKSArDQogICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh0aXRsZSA9ICJQxZnDrXNlxI1uaWNlLCBkaWV0IGJ5IHNlYXNvbiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQpgYGANCg0KIyMgSmV6ZXJvIE1pbGFkYQ0KDQpNaW5pbmcgcmVjb3ZlcmVkIGFyZWENCg0KIyMjIE5vdCBsdW1wZWQNCg0KYGBge3IgamV6c2l6ZSwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMH0NCmpleiA8LSB0aWR5X2RiICU+JQ0KICBmaWx0ZXIobG9jYXRpb24gPT0gImplemVybyBNaWxhZGEiKQ0KDQpqZXogJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KICAjbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzLCBmaWxsPXNpemUpKSArDQogICNmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gc2l6ZSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSBHcm91cCAoY20pIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiamV6ZXJvIE1pbGFkYSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQpgYGANCg0KIyMjIEx1bXBlZA0KDQpgYGB7ciBqZXpMLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTExfQ0KamV6ICU+JQ0KICBkcm9wX25hKHNpemUpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzLCBmaWxsPXNpemUpKSArDQogICNmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gc2l6ZSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSBHcm91cCAoY20pIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiamV6ZXJvIE1pbGFkYSIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQpgYGANCg0KDQoNCmBgYHtyIGpleiwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMn0NCmpleiAlPiUNCiAgZHJvcF9uYShzaXplKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbD1zaXplKSkgKw0KICBmYWNldF93cmFwKC4gfiBzZWFzb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkplemVybyBNaWxhZGEsIGRpZXQgYnkgc2Vhc29uIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCmBgYA0KDQoNCiMjIEhvcm7DrSBDaG9tdXRvdmthDQoNCiMjIyBOb3QgbHVtcGVkDQpgYGB7ciBoY2hvU2l6ZSwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0NCmhDaG8gJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lDQogIA0KICAjbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbD1zaXplKSkgKw0KICMgZmFjZXRfZ3JpZCguIH4gc3RyZXRjaCkrDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIlByb3BvcnRpb24gc2l6ZSIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSBHcm91cCAoY20pIikgKw0KICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGxhYnModGl0bGUgPSAiSG9ybsOtIENob211dG92a2EiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KYGBgDQoNCg0KYGBge3IgaGNobywgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMX0NCmhDaG8gJT4lDQogIGRyb3BfbmEoc2l6ZSkgJT4lDQogICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiU3VtbWVyIikgJT4lIA0KIyAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbD1zaXplKSkgKw0KICBmYWNldF93cmFwKC4gfiBzZWFzb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkhvcm7DrSBDaG9tdXRvdmthLCBkaWV0IGJ5IHNlYXNvbiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmBgYA0KDQoNCiMjIERvbG7DrSBDaG9tdXRvdmthDQoNCiMjIyBOb3QgbHVtcGVkDQpgYGB7ciBkY2hvU2l6ZSwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0NCg0KZENobyAlPiUNCiAgZHJvcF9uYShzaXplKSAlPiUNCiAgI211dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGw9c2l6ZSkpICsNCiAjIGZhY2V0X2dyaWQoLiB+IHN0cmV0Y2gpKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkRvbG7DrSBDaG9tdXRvdmthIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCmBgYA0KDQoNCmBgYHtyIGRjaG9TLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTExfQ0KZENobyAlPiUNCiAgZHJvcF9uYShzaXplKSAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKHNlYXNvbiAhPSAiU3VtbWVyIikgJT4lIA0KIyAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbD1zaXplKSkgKw0KICBmYWNldF93cmFwKC4gfiBzZWFzb24pKw0KICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3A9RkFMU0UpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJQcm9wb3J0aW9uIHNpemUiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiAgbGFicyhmaWxsID0gIlNpemUgR3JvdXAgKGNtKSIpICsNCiAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICBsYWJzKHRpdGxlID0gIkRvbG7DrSBDaG9tdXRvdmthLCBkaWV0IGJ5IHNlYXNvbiIpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCmBgYA0KDQojIEhvdyBkbyB1cHBlciBhbmQgbG93ZXIgY291cnNlcyBvZiB0aGUgc3RyZWFtcyBjb21wYXJlID8NCg0KIyMgRGlmZmVyZW5jZXMgaW4gc3BlY2llcw0KDQpgYGB7ciBjb3Vyc2UtY29tcGFyaXNvbi1zcH0NCg0KI2ZpbHRlciB1cHBlcg0KDQojIHVwcGVyIDwtIHRpZHlfZGIgJT4lDQojICAgZHBseXI6OmZpbHRlcihzdHJldGNoID09ICJVcHBlciIpDQojDQojDQojIHVwcGVyICU+JQ0KIyAgIGRwbHlyOjpncm91cF9ieShsb2NhdGlvbikgJT4lDQojICAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfbHVtcF9wcm9wKHNwZWNpZXMsMC4wNSkpICU+JQ0KIyAgIHVuZ3JvdXAoKSAlPiUNCiMgICBtdXRhdGUoc3BlY2llcyA9IGZjdF9yZW9yZGVyKHNwZWNpZXMsIGRlc2Moc3BlY2llcykpKSAlPiUNCiMgICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVsZXZlbChzcGVjaWVzLCAiT3RoZXIiLCBhZnRlciA9IEluZikpICU+JQ0KIyAgIGdncGxvdChhZXMoeCA9bG9jYXRpb24gLCBmaWxsID0gc3BlY2llcykpICsNCiMgICAjZmFjZXRfZ3JpZCguIH4gc2Vhc29uKSsNCiMgICBzY2FsZV9maWxsX2Rpc2NyZXRlKGRyb3AgPSBUUlVFKSArDQojICAgc2NhbGVfeV9jb250aW51b3VzKCIiKSArDQojICAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KIyAgIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQojICAgbGFicyhmaWxsID0gIlNwZWNpZXMiKSArDQojICAgIyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KIyAgIGxhYnModGl0bGUgPSAiRGlldDogU3BlY2llcyBwcm9wb3J0aW9uIGluIHVwcGVyIGNvdXJzZXMgb2YgdGhlIHN0cmVhbXMiKSArDQojICAgI2Nvb3JkX2ZsaXAoKSArDQojICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KIyAgIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQojICAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiMgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQojDQojICNmaWx0ZXIgbG93ZXINCiMNCiMgbG93ZXIgPC0gdGlkeV9kYiAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKHN0cmV0Y2ggPT0gIkxvd2VyIikNCiMNCiMNCiMgbG93ZXIgJT4lDQojICAgZHBseXI6Omdyb3VwX2J5KGxvY2F0aW9uKSAlPiUNCiMgICBtdXRhdGUoc3BlY2llcyA9IGZjdF9sdW1wX3Byb3Aoc3BlY2llcywwLjA1KSkgJT4lDQojICAgdW5ncm91cCgpICU+JQ0KIyAgIG11dGF0ZShzcGVjaWVzID0gZmN0X3Jlb3JkZXIoc3BlY2llcywgZGVzYyhzcGVjaWVzKSkpICU+JQ0KIyAgIGRwbHlyOjptdXRhdGUoc3BlY2llcyA9IGZjdF9yZWxldmVsKHNwZWNpZXMsICJPdGhlciIsIGFmdGVyID0gSW5mKSkgJT4lDQojICAgZ2dwbG90KGFlcyh4ID1sb2NhdGlvbiAsIGZpbGwgPSBzcGVjaWVzKSkgKw0KIyAgICNmYWNldF9ncmlkKC4gfiBzZWFzb24pKw0KIyAgIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcCA9IFRSVUUpICsNCiMgICBzY2FsZV95X2NvbnRpbnVvdXMoIiIpICsNCiMgICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQojICAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpICsNCiMgICBsYWJzKGZpbGwgPSAiU3BlY2llcyIpICsNCiMgICAjIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQojICAgbGFicyh0aXRsZSA9ICJEaWV0OiBTcGVjaWVzIHByb3BvcnRpb24gaW4gbG93ZXIgY291cnNlcyBvZiB0aGUgc3RyZWFtcyIpICsNCiMgICAjY29vcmRfZmxpcCgpICsNCiMgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQojICAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiMgICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkgKw0KIyAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCiMNCiMNCg0KDQoNCg0KYGBgDQoNCg0KIyMgRGlmZmVyZW5jZXMgaW4gc2l6ZQ0KDQpgYGB7ciBjb3Vyc2UtY29tcGFyaXNvbi1zaXplfQ0KDQojICNmaWx0ZXIgdXBwZXINCiMNCiMgdXBwZXIgPC0gdGlkeV9kYiAlPiUNCiMgICBkcGx5cjo6ZmlsdGVyKHN0cmV0Y2ggPT0gIlVwcGVyIikNCiMNCiMNCiMgdXBwZXIgJT4lDQojICAgZHJvcF9uYShzaXplKSAlPiUNCiMgICBkcGx5cjo6Z3JvdXBfYnkobG9jYXRpb24pICU+JQ0KIyAgIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiMgICB1bmdyb3VwKCkgJT4lDQojICAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQojICAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUNCiMgICBnZ3Bsb3QoYWVzKHggPXNwZWNpZXMgLCBmaWxsID0gc2l6ZSkpICsNCiMgICBmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQojICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wID0gVFJVRSkgKw0KIyAgIHNjYWxlX3lfY29udGludW91cygiIikgKw0KIyAgIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiMgICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KIyAgIGxhYnMoZmlsbCA9ICJTaXplIikgKw0KIyAgICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiMgICBsYWJzKHRpdGxlID0gIkRpZXQ6IFNpemUgcHJvcG9ydGlvbiBpbiB1cHBlciBjb3Vyc2VzIG9mIHRoZSBzdHJlYW1zIikgKw0KIyAgIGNvb3JkX2ZsaXAoKSArDQojICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KIyAgIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQojICAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiMgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQojDQojICNmaWx0ZXIgbG93ZXINCiMNCiMgbG93ZXIgPC0gdGlkeV9kYiAlPiUNCiMgICBkcm9wX25hKHNpemUpICU+JQ0KIyAgIGRwbHlyOjpmaWx0ZXIoc3RyZXRjaCA9PSAiTG93ZXIiKQ0KIw0KIw0KIyBsb3dlciAlPiUNCiMgICBkcGx5cjo6Z3JvdXBfYnkobG9jYXRpb24pICU+JQ0KIyAgIG11dGF0ZShzcGVjaWVzID0gZmN0X2x1bXBfcHJvcChzcGVjaWVzLDAuMDUpKSAlPiUNCiMgICB1bmdyb3VwKCkgJT4lDQojICAgbXV0YXRlKHNwZWNpZXMgPSBmY3RfcmVvcmRlcihzcGVjaWVzLCBkZXNjKHNwZWNpZXMpKSkgJT4lDQojICAgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmN0X3JlbGV2ZWwoc3BlY2llcywgIk90aGVyIiwgYWZ0ZXIgPSBJbmYpKSAlPiUNCiMgICBnZ3Bsb3QoYWVzKHggPXNwZWNpZXMgLCBmaWxsID0gc2l6ZSkpICsNCiMgICBmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQojICAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wID0gVFJVRSkgKw0KIyAgIHNjYWxlX3lfY29udGludW91cygiIikgKw0KIyAgIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiMgICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKw0KIyAgIGxhYnMoZmlsbCA9ICJTaXplIikgKw0KIyAgICMgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiMgICBsYWJzKHRpdGxlID0gIkRpZXQ6IFNpemUgcHJvcG9ydGlvbiBpbiBsb3dlciBjb3Vyc2VzIG9mIHRoZSBzdHJlYW1zIikgKw0KIyAgIGNvb3JkX2ZsaXAoKSArDQojICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KIyAgIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQojICAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiMgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpDQoNCg0KDQoNCg0KDQpgYGANCg0KIyBKdXN0IHNhbG1vbmlkIHNpemUNCg0KYGBge3Igc2l6ZV9zYWxtb25pZCwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTR9DQoNCnRpZHlfZGIgJT4lDQogZHBseXI6OmZpbHRlcihzcGVjaWVzID09ICJTYWxtb25pZHMiKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbCA9IHNpemUpKSArDQogIGZhY2V0X2dyaWQoLiB+IGxvY2F0aW9uKSsNCiAgZ2VvbV9iYXIoIHBvc2l0aW9uID0gImRvZGdlIikrDQogIHNjYWxlX3lfY29udGludW91cygiIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1OVUxMKSArDQogIGxhYnMoZmlsbCA9ICJTaXplIikgKw0KICAjdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAjIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnk6IFNpemUgZGlzdHJpYnV0aW9uIG9mIHNhbG1vbmlkcyIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQoNCmBgYA0KDQoNCg0KDQoNCg0KIyBDb21wYXJpbmcgc2l6ZSBkaXN0cmlidXRpb24gZm9yIG5hdHVyYWwgc3AgdnMgc3RvY2tlZCBzcA0KDQpgYGB7ciBzYWxtb0dvYmlvLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMn0NCnNhbG1vX3ZzX2dvYmlvIDwtIGMoIlNhbG1vbmlkcyIsICJHb2JpbyBhIFJvbWFub2dvYmlvIHNwLiIpDQpzYWxtb192c190aW5jYSA8LSBjKCJTYWxtb25pZHMiLCAiVGluY2EgdGluY2EiKQ0Kc2FsbW9fdnNfcGVyY2EgPC0gYygiU2FsbW9uaWRzIiwgIlBlcmNhIGZsdXZpYXRpbGlzIikNCnNhbG1vX3ZzX2xldWNpc2N1cyA8LSBjKCJTYWxtb25pZHMiLCAiTGV1Y2lzY3VzIGNlcGhhbHVzIikNCnNhbG1vX3ZzX3J1dGlsdXMgPC0gYygiU2FsbW9uaWRzIiwgIlJ1dGlsdXMgcnV0aWx1cyIpDQoNCnRpZHlfZGIgJT4lDQogZHBseXI6OmZpbHRlcihzcGVjaWVzICVpbiUgc2FsbW9fdnNfZ29iaW8pICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBzcGVjaWVzLCBmaWxsID0gc2l6ZSkpICsNCiAgZmFjZXRfZ3JpZCguIH4gbG9jYXRpb24pKw0KICBnZW9tX2JhciggcG9zaXRpb24gPSAiZG9kZ2UiKSsNCiAgc2NhbGVfeV9jb250aW51b3VzKCIiKSArDQogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsNCiAgbGFicyhmaWxsID0gIlNpemUiKSArDQogICN0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKw0KICMgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeTogU2l6ZSBkaXN0cmlidXRpb24gb2Ygc2FsbW9uaWRzIGFuZCBHb2JpbyBzcCIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCmBgYA0KDQoNCmBgYHtyIHNhbG1vVGluY2EsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTEyfQ0KdGlkeV9kYiAlPiUNCiBkcGx5cjo6ZmlsdGVyKHNwZWNpZXMgJWluJSBzYWxtb192c190aW5jYSkgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGwgPSBzaXplKSkgKw0KICBmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQogIGdlb21fYmFyKCBwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIiIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIyBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIktydXNuZSBIb3J5OiBTaXplIGRpc3RyaWJ1dGlvbiBvZiBzYWxtb25pZHMgYW5kIFRpbmNhIHRpbmNhIikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wPUZBTFNFKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KYGBgDQoNCg0KYGBge3Igc2FsbW9QZXJjYSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MTJ9DQp0aWR5X2RiICU+JQ0KIGRwbHlyOjpmaWx0ZXIoc3BlY2llcyAlaW4lIHNhbG1vX3ZzX3BlcmNhKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gc3BlY2llcywgZmlsbCA9IHNpemUpKSArDQogIGZhY2V0X2dyaWQoLiB+IGxvY2F0aW9uKSsNCiAgZ2VvbV9iYXIoIHBvc2l0aW9uID0gImRvZGdlIikrDQogIHNjYWxlX3lfY29udGludW91cygiIikgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArDQogIGxhYnMoZmlsbCA9ICJTaXplIikgKw0KICAjdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgY29vcmRfZmxpcCgpICsNCiAgbGFicyh0aXRsZSA9ICJLcnVzbmUgSG9yeTogU2l6ZSBkaXN0cmlidXRpb24gb2Ygc2FsbW9uaWRzIGFuZCBQZXJjYSBmbHV2aWF0aWxpcyIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCg0KDQpgYGANCg0KDQoNCmBgYHtyIHNhbG1vTGV1Y2lzY3VzLCBmaWcuaGVpZ2h0PTQsIGZpZy53aWR0aD0xMn0NCg0KDQp0aWR5X2RiICU+JQ0KIGRwbHlyOjpmaWx0ZXIoc3BlY2llcyAlaW4lIHNhbG1vX3ZzX2xldWNpc2N1cykgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGwgPSBzaXplKSkgKw0KICBmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQogIGdlb21fYmFyKCBwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIiIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiS3J1c25lIEhvcnk6IFNpemUgZGlzdHJpYnV0aW9uIG9mIHNhbG1vbmlkcyBhbmQgTGV1Y2lzY3VzIGNlcGhhbHVzIikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhaXJlZCIpICsNCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShkcm9wPUZBTFNFKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQ0KYGBgDQoNCg0KYGBge3Igc2FsbW9SdXRpbHVzLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMn0NCnRpZHlfZGIgJT4lDQogZHBseXI6OmZpbHRlcihzcGVjaWVzICVpbiUgc2FsbW9fdnNfcnV0aWx1cykgJT4lDQogIGdncGxvdChhZXMoeCA9IHNwZWNpZXMsIGZpbGwgPSBzaXplKSkgKw0KICBmYWNldF9ncmlkKC4gfiBsb2NhdGlvbikrDQogIGdlb21fYmFyKCBwb3NpdGlvbiA9ICJkb2RnZSIpKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoIiIpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKw0KICBsYWJzKGZpbGwgPSAiU2l6ZSIpICsNCiAgI3RoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArDQogIyBjb29yZF9mbGlwKCkgKw0KICBsYWJzKHRpdGxlID0gIktydXNuZSBIb3J5OiBTaXplIGRpc3RyaWJ1dGlvbiBvZiBzYWxtb25pZHMgYW5kIFJ1dGlsdXMgcnV0aWx1cyIpICsNCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYWlyZWQiKSArDQogIHNjYWxlX2ZpbGxfZGlzY3JldGUoZHJvcD1GQUxTRSkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKSArDQogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg==