library(ggplot2)
options(warn=-1)

Read dataset

fish_data <- read.csv("fish_data.csv")

Plot 1: Scatter Plot

I want to understand the impact of pH of the water with the life span of fish. The color of each point is determined by the habitat type where the fish were observed. As both of them pH of the water andlife span are numerical variables, I think scatter plot will best describe the actual relationship. Observed a decreasing trend in life span as the pH of water increases to 8. that mean as the pH of water increases towards 8, the life span of fish tends to decrease.

ggplot(fish_data, aes(x = ph_of_water, y = life_span,color = habitat)) +
  geom_point(size = 1, alpha = 0.7) +
  labs(title = "Scatter Plot",
       color = "Habitat") +
  theme_minimal()

Plot 2: Histogram

Fish prefer water with a pH around 6.5 to 7 in idle water, rivers, and slow-moving water. Ponds have the highest frequency at pH 7 and 7.5 to around 8. Lakes show the highest frequency at pH 6.5, 7, and 7.5. This suggests that these habitats have water conditions suitable for the fish that live in them..


# Create histograms and distribution curves for ph_of_water by habitat
ggplot(fish_data, aes(x = ph_of_water, fill = habitat)) +
  geom_histogram(bins = 10, alpha = 0.7, position = "identity") +
  facet_wrap(~habitat, scales = "free") +
  labs(title = "Histogram and Distribution Curve of pH of Water by Habitat",
       x = "pH of Water",
       y = "Frequency",
       caption = "Source: Fish Data") +
  scale_fill_manual(values = c("#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854")) +
  theme_minimal()

Plot 3 : Scatter plot with color-coded points

Analysis of Average Length and Average Weight by Habitat.

Habitat Variations- The points across different habitats show a similar distribution, and there are no evident clusters or groups that would suggest habitat-specific patterns in the relationship between average length and average weight.

Outliers- No outliers or individual data points stand out as deviating significantly from the overall trend.

Spread of Points- The spread of points appears relatively consistent among habitats, indicating a comparable variability in the relationship between average length and average weight across all observed environments.

ggplot(fish_data, aes(x = average_length, y = average_weight, color = habitat)) +
  geom_point(size = 1, alpha = 0.5) +
  labs(title = "Scatter Plot",
       x = "Average Length",
       y = "Average Weight",
       color = "Habitat") +
  theme_minimal()

Plot 4: Bar plot of habitat counts

The bar plot illustrates the distribution of habitat categories in the dataset, providing insights into the frequency of each habitat type. Lakes and ponds appear to be the most common, with higher counts reflected by taller bars. Idlewater, while present, is relatively less common based on the shorter bar height.

ggplot(fish_data, aes(x = habitat)) +
 geom_bar(fill = "skyblue", color = "black") +
  labs(title = "Bar Plot of Habitat Counts",
       x = "Habitat",
       y = "Count") +
  theme_minimal()

Plot 5: Boxplot with datapoints on them

Here we can see the average weight of fish on habitat idlewater, lakes and rivers are more then 10 where average weight of ponds and slowmoving waters are equal 10.

Define a custom color palette

my_palette <- c("#440154", "#31688e", "#35b779", "#fde725")
ggplot(fish_data, aes(x = habitat, y = average_weight, color = habitat)) +
  geom_boxplot(aes(group = habitat), fill = "lightgray", alpha = 0.8, width = 0.5) +
  geom_jitter(position = position_jitter(width = 0.3), size = 0.5, alpha = 0.7) +
  stat_summary(
    fun = mean,
    geom = "point",
    shape = 3,
    size = 4,
    position = position_dodge(width = 0.5),
    color = "red"
  ) +
  labs(title = "Boxplot of Average Weight by Habitat",
       x = "Habitat",
       y = "Average Weight",
       color = "Habitat") +
  theme_minimal() +
  theme(legend.position = "bottom") +
  theme(
    plot.title = element_text(size = 12, face = "bold"),
    axis.title = element_text(size = 12),
    axis.text = element_text(size = 12),
    legend.title = element_text(size = 12),
    legend.text = element_text(size = 12),
    plot.background = element_rect(fill = "white"),
    panel.background = element_rect(fill = "white"),
    legend.background = element_rect(fill = "white"),
    panel.grid.major = element_line(color = "lightgray", size = 0.2),
    panel.grid.minor = element_blank(),
    axis.line = element_line(color = "black", size = 0.2),
    legend.key = element_rect(fill = "white"),
    legend.key.size = unit(0.5, "cm"),
    legend.key.width = unit(0.5, "cm"),
    legend.spacing.x = unit(0.2, "cm"),
    legend.spacing.y = unit(0.1, "cm"),
    legend.box.margin = margin(0, 0, 0, 0)
  ) 
Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
Please use the `linewidth` argument instead.

Plot 6: Ridge plot average weight by habitat

Here peak are the central tendency of average weights. Peak of slowmoving waters,lakes and rivers are almost 10.Peak of ponds are less then 10. Peak of idewater are more then 10. Wider ridges indicate higher variability. Here wide of all the habitat are almost same that means they donot have any significanct difference in the variable.

create a colour plot

my_palette <- c("#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854")
ggplot(fish_data, aes(x = average_weight, y = habitat, fill = habitat)) +
  geom_density_ridges(alpha = 0.5, rel_min_height = 0.01) +
  scale_fill_manual(values = c("#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854")) +
  labs(title = "Ridge Plot of Average Weight by Habitat",
       x = "Average Weight",
       y = "Habitat") +
  theme_minimal() +
  theme(legend.position = "bottom") +
  theme(
    plot.title = element_text(size = 12, face = "bold"),
    axis.title = element_text(size = 12),
    axis.text = element_text(size = 12),
    legend.title = element_blank(),
    legend.text = element_text(size = 12),
    panel.background = element_rect(fill = "white"),
    panel.grid.major = element_line(color = "lightgray", size = 0.2),
    panel.grid.minor = element_blank(),
    axis.line = element_line(color = "black", size = 0.2)
  )

Plot 7: Violin plot of lifespan by habitat

The median is represented by the central point or thickened region within each violin. It indicates the middle value of the life span distribution for a specific habitat. Here median of idlewater is around 5, lakes, ponds, rivers are around 20. And slowmoving waters are more then 20.

Create a color palette for the plot

my_palette <- c("#66c2a5", "#fc8d62", "#8da0cb", "#e78ac3", "#a6d854")

Create the violin plot

ggplot(fish_data, aes(x = factor(habitat), y = life_span, fill = factor(habitat))) +
  geom_violin(trim = FALSE, scale = "width", width = 0.8, alpha = 0.5) +
  geom_jitter(width = 0.2, aes(color = factor(habitat)), size = 1, alpha = 0.5) +
  scale_fill_manual(values = my_palette) +
  scale_color_manual(values = my_palette) +
  theme_minimal() +
  labs(title = "Violin Plot of Life Span by Habitat",
       x = "Habitat",
       y = "Life Span") +
  theme(legend.position = "bottom",
        legend.title = element_blank(),
        legend.key = element_blank(),
        legend.background = element_blank()) +
  theme(plot.title = element_text(size = 12, face = "bold"),
        axis.title = element_text(size = 12),
        axis.text = element_text(size = 12),
        legend.text = element_text(size = 12),
        panel.background = element_rect(fill = "white"),
        panel.grid.major = element_line(color = "lightgray", size = 0.2),
        panel.grid.minor = element_blank(),
        axis.line = element_line(color = "black", size = 0.2)
  )

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKYGBge3J9Cm9wdGlvbnMod2Fybj0tMSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkoZ2dyaWRnZXMpCgpgYGAKCgojIFJlYWQgZGF0YXNldAoKYGBge3J9CmZpc2hfZGF0YSA8LSByZWFkLmNzdigiZmlzaF9kYXRhLmNzdiIpCmBgYAoKCiMgUGxvdCAxOiBTY2F0dGVyIFBsb3QKCkkgd2FudCB0byB1bmRlcnN0YW5kIHRoZSBpbXBhY3Qgb2YgcEggb2YgdGhlIHdhdGVyIHdpdGggdGhlIGxpZmUgc3BhbiBvZiBmaXNoLiBUaGUgY29sb3Igb2YgZWFjaCBwb2ludCBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBoYWJpdGF0IHR5cGUgd2hlcmUgdGhlIGZpc2ggd2VyZSBvYnNlcnZlZC4gQXMgYm90aCBvZiB0aGVtIHBIIG9mIHRoZSB3YXRlciBhbmRsaWZlIHNwYW4gIGFyZSBudW1lcmljYWwgdmFyaWFibGVzLCBJIHRoaW5rIHNjYXR0ZXIgcGxvdCB3aWxsIGJlc3QgZGVzY3JpYmUgdGhlIGFjdHVhbCByZWxhdGlvbnNoaXAuIE9ic2VydmVkIGEgZGVjcmVhc2luZyB0cmVuZCBpbiBsaWZlIHNwYW4gYXMgdGhlIHBIIG9mIHdhdGVyIGluY3JlYXNlcyB0byA4LiB0aGF0IG1lYW4gYXMgdGhlIHBIIG9mIHdhdGVyIGluY3JlYXNlcyB0b3dhcmRzIDgsIHRoZSBsaWZlIHNwYW4gb2YgZmlzaCB0ZW5kcyB0byBkZWNyZWFzZS4KCmBgYHtyfQpnZ3Bsb3QoZmlzaF9kYXRhLCBhZXMoeCA9IHBoX29mX3dhdGVyLCB5ID0gbGlmZV9zcGFuLGNvbG9yID0gaGFiaXRhdCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAxLCBhbHBoYSA9IDAuNykgKwogIGxhYnModGl0bGUgPSAiU2NhdHRlciBQbG90IiwKICAgICAgIGNvbG9yID0gIkhhYml0YXQiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKIyBQbG90IDI6IEhpc3RvZ3JhbQoKRmlzaCBwcmVmZXIgd2F0ZXIgd2l0aCBhIHBIIGFyb3VuZCA2LjUgdG8gNyBpbiBpZGxlIHdhdGVyLCByaXZlcnMsIGFuZCBzbG93LW1vdmluZyB3YXRlci4gUG9uZHMgaGF2ZSB0aGUgaGlnaGVzdCBmcmVxdWVuY3kgYXQgcEggNyBhbmQgNy41IHRvIGFyb3VuZCA4LiBMYWtlcyBzaG93IHRoZSBoaWdoZXN0IGZyZXF1ZW5jeSBhdCBwSCA2LjUsIDcsIGFuZCA3LjUuIFRoaXMgc3VnZ2VzdHMgdGhhdCB0aGVzZSBoYWJpdGF0cyBoYXZlIHdhdGVyIGNvbmRpdGlvbnMgc3VpdGFibGUgZm9yIHRoZSBmaXNoIHRoYXQgbGl2ZSBpbiB0aGVtLi4KCgpgYGB7cn0KCiMgQ3JlYXRlIGhpc3RvZ3JhbXMgYW5kIGRpc3RyaWJ1dGlvbiBjdXJ2ZXMgZm9yIHBoX29mX3dhdGVyIGJ5IGhhYml0YXQKZ2dwbG90KGZpc2hfZGF0YSwgYWVzKHggPSBwaF9vZl93YXRlciwgZmlsbCA9IGhhYml0YXQpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwLCBhbHBoYSA9IDAuNywgcG9zaXRpb24gPSAiaWRlbnRpdHkiKSArCiAgZmFjZXRfd3JhcCh+aGFiaXRhdCwgc2NhbGVzID0gImZyZWUiKSArCiAgbGFicyh0aXRsZSA9ICJIaXN0b2dyYW0gYW5kIERpc3RyaWJ1dGlvbiBDdXJ2ZSBvZiBwSCBvZiBXYXRlciBieSBIYWJpdGF0IiwKICAgICAgIHggPSAicEggb2YgV2F0ZXIiLAogICAgICAgeSA9ICJGcmVxdWVuY3kiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEZpc2ggRGF0YSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCIjNjZjMmE1IiwgIiNmYzhkNjIiLCAiIzhkYTBjYiIsICIjZTc4YWMzIiwgIiNhNmQ4NTQiKSkgKwogIHRoZW1lX21pbmltYWwoKQoKYGBgCgoKIyBQbG90IDMgOiBTY2F0dGVyIHBsb3Qgd2l0aCBjb2xvci1jb2RlZCBwb2ludHMgCiMjIyMgQW5hbHlzaXMgb2YgQXZlcmFnZSBMZW5ndGggYW5kIEF2ZXJhZ2UgV2VpZ2h0IGJ5IEhhYml0YXQuIApIYWJpdGF0IFZhcmlhdGlvbnMtIFRoZSBwb2ludHMgYWNyb3NzIGRpZmZlcmVudCBoYWJpdGF0cyBzaG93IGEgc2ltaWxhciBkaXN0cmlidXRpb24sIGFuZCB0aGVyZSBhcmUgbm8gZXZpZGVudCBjbHVzdGVycyBvciBncm91cHMgdGhhdCB3b3VsZCBzdWdnZXN0IGhhYml0YXQtc3BlY2lmaWMgcGF0dGVybnMgaW4gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGF2ZXJhZ2UgbGVuZ3RoIGFuZCBhdmVyYWdlIHdlaWdodC4gCgpPdXRsaWVycy0gTm8gb3V0bGllcnMgb3IgaW5kaXZpZHVhbCBkYXRhIHBvaW50cyBzdGFuZCBvdXQgYXMgZGV2aWF0aW5nIHNpZ25pZmljYW50bHkgZnJvbSB0aGUgb3ZlcmFsbCB0cmVuZC4KClNwcmVhZCBvZiBQb2ludHMtIFRoZSBzcHJlYWQgb2YgcG9pbnRzIGFwcGVhcnMgcmVsYXRpdmVseSBjb25zaXN0ZW50IGFtb25nIGhhYml0YXRzLCBpbmRpY2F0aW5nIGEgY29tcGFyYWJsZSB2YXJpYWJpbGl0eSBpbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYXZlcmFnZSBsZW5ndGggYW5kIGF2ZXJhZ2Ugd2VpZ2h0IGFjcm9zcyBhbGwgb2JzZXJ2ZWQgZW52aXJvbm1lbnRzLgoKYGBge3J9CmdncGxvdChmaXNoX2RhdGEsIGFlcyh4ID0gYXZlcmFnZV9sZW5ndGgsIHkgPSBhdmVyYWdlX3dlaWdodCwgY29sb3IgPSBoYWJpdGF0KSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDEsIGFscGhhID0gMC41KSArCiAgbGFicyh0aXRsZSA9ICJTY2F0dGVyIFBsb3QiLAogICAgICAgeCA9ICJBdmVyYWdlIExlbmd0aCIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgV2VpZ2h0IiwKICAgICAgIGNvbG9yID0gIkhhYml0YXQiKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKIyBQbG90IDQ6IEJhciBwbG90IG9mIGhhYml0YXQgY291bnRzCgpUaGUgYmFyIHBsb3QgaWxsdXN0cmF0ZXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBoYWJpdGF0IGNhdGVnb3JpZXMgaW4gdGhlIGRhdGFzZXQsIHByb3ZpZGluZyBpbnNpZ2h0cyBpbnRvIHRoZSBmcmVxdWVuY3kgb2YgZWFjaCBoYWJpdGF0IHR5cGUuIExha2VzIGFuZCBwb25kcyBhcHBlYXIgdG8gYmUgdGhlIG1vc3QgY29tbW9uLCB3aXRoIGhpZ2hlciBjb3VudHMgcmVmbGVjdGVkIGJ5IHRhbGxlciBiYXJzLiBJZGxld2F0ZXIsIHdoaWxlIHByZXNlbnQsIGlzIHJlbGF0aXZlbHkgbGVzcyBjb21tb24gYmFzZWQgb24gdGhlIHNob3J0ZXIgYmFyIGhlaWdodC4KCmBgYHtyfQpnZ3Bsb3QoZmlzaF9kYXRhLCBhZXMoeCA9IGhhYml0YXQpKSArCiBnZW9tX2JhcihmaWxsID0gInNreWJsdWUiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHRpdGxlID0gIkJhciBQbG90IG9mIEhhYml0YXQgQ291bnRzIiwKICAgICAgIHggPSAiSGFiaXRhdCIsCiAgICAgICB5ID0gIkNvdW50IikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCiMgUGxvdCA1OiBCb3hwbG90IHdpdGggZGF0YXBvaW50cyBvbiB0aGVtCkhlcmUgd2UgY2FuIHNlZSB0aGUgYXZlcmFnZSB3ZWlnaHQgb2YgZmlzaCBvbiBoYWJpdGF0IGlkbGV3YXRlciwgbGFrZXMgYW5kIHJpdmVycyBhcmUgbW9yZSB0aGVuIDEwIHdoZXJlIGF2ZXJhZ2Ugd2VpZ2h0IG9mIHBvbmRzIGFuZCBzbG93bW92aW5nIHdhdGVycyBhcmUgZXF1YWwgMTAuCgoKRGVmaW5lIGEgY3VzdG9tIGNvbG9yIHBhbGV0dGUKYGBge3J9Cm15X3BhbGV0dGUgPC0gYygiIzQ0MDE1NCIsICIjMzE2ODhlIiwgIiMzNWI3NzkiLCAiI2ZkZTcyNSIpCmBgYAoKYGBge3J9CmdncGxvdChmaXNoX2RhdGEsIGFlcyh4ID0gaGFiaXRhdCwgeSA9IGF2ZXJhZ2Vfd2VpZ2h0LCBjb2xvciA9IGhhYml0YXQpKSArCiAgZ2VvbV9ib3hwbG90KGFlcyhncm91cCA9IGhhYml0YXQpLCBmaWxsID0gImxpZ2h0Z3JheSIsIGFscGhhID0gMC44LCB3aWR0aCA9IDAuNSkgKwogIGdlb21faml0dGVyKHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMC4zKSwgc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjcpICsKICBzdGF0X3N1bW1hcnkoCiAgICBmdW4gPSBtZWFuLAogICAgZ2VvbSA9ICJwb2ludCIsCiAgICBzaGFwZSA9IDMsCiAgICBzaXplID0gNCwKICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpLAogICAgY29sb3IgPSAicmVkIgogICkgKwogIGxhYnModGl0bGUgPSAiQm94cGxvdCBvZiBBdmVyYWdlIFdlaWdodCBieSBIYWJpdGF0IiwKICAgICAgIHggPSAiSGFiaXRhdCIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgV2VpZ2h0IiwKICAgICAgIGNvbG9yID0gIkhhYml0YXQiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwogIHRoZW1lKAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIpLAogICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiksCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG9yID0gImxpZ2h0Z3JheSIsIHNpemUgPSAwLjIpLAogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJibGFjayIsIHNpemUgPSAwLjIpLAogICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiksCiAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuNSwgImNtIiksCiAgICBsZWdlbmQua2V5LndpZHRoID0gdW5pdCgwLjUsICJjbSIpLAogICAgbGVnZW5kLnNwYWNpbmcueCA9IHVuaXQoMC4yLCAiY20iKSwKICAgIGxlZ2VuZC5zcGFjaW5nLnkgPSB1bml0KDAuMSwgImNtIiksCiAgICBsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbigwLCAwLCAwLCAwKQogICkgCmBgYAoKIyBQbG90IDY6IFJpZGdlIHBsb3QgYXZlcmFnZSB3ZWlnaHQgYnkgaGFiaXRhdApIZXJlIHBlYWsgYXJlIHRoZSBjZW50cmFsIHRlbmRlbmN5IG9mIGF2ZXJhZ2Ugd2VpZ2h0cy4gUGVhayBvZiBzbG93bW92aW5nIHdhdGVycyxsYWtlcyBhbmQgcml2ZXJzIGFyZSBhbG1vc3QgMTAuUGVhayBvZiBwb25kcyBhcmUgbGVzcyB0aGVuIDEwLiBQZWFrIG9mIGlkZXdhdGVyIGFyZSBtb3JlIHRoZW4gMTAuCldpZGVyIHJpZGdlcyBpbmRpY2F0ZSBoaWdoZXIgdmFyaWFiaWxpdHkuIEhlcmUgd2lkZSBvZiBhbGwgdGhlIGhhYml0YXQgYXJlIGFsbW9zdCBzYW1lIHRoYXQgbWVhbnMgdGhleSBkb25vdCBoYXZlIGFueSBzaWduaWZpY2FuY3QgZGlmZmVyZW5jZSBpbiB0aGUgdmFyaWFibGUuCgpjcmVhdGUgYSBjb2xvdXIgcGxvdApgYGB7cn0KbXlfcGFsZXR0ZSA8LSBjKCIjNjZjMmE1IiwgIiNmYzhkNjIiLCAiIzhkYTBjYiIsICIjZTc4YWMzIiwgIiNhNmQ4NTQiKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZmlzaF9kYXRhLCBhZXMoeCA9IGF2ZXJhZ2Vfd2VpZ2h0LCB5ID0gaGFiaXRhdCwgZmlsbCA9IGhhYml0YXQpKSArCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcyhhbHBoYSA9IDAuNSwgcmVsX21pbl9oZWlnaHQgPSAwLjAxKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzY2YzJhNSIsICIjZmM4ZDYyIiwgIiM4ZGEwY2IiLCAiI2U3OGFjMyIsICIjYTZkODU0IikpICsKICBsYWJzKHRpdGxlID0gIlJpZGdlIFBsb3Qgb2YgQXZlcmFnZSBXZWlnaHQgYnkgSGFiaXRhdCIsCiAgICAgICB4ID0gIkF2ZXJhZ2UgV2VpZ2h0IiwKICAgICAgIHkgPSAiSGFiaXRhdCIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgdGhlbWUoCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJib2xkIiksCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSwKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAibGlnaHRncmF5Iiwgc2l6ZSA9IDAuMiksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuMikKICApCmBgYAoKIyBQbG90IDc6IFZpb2xpbiBwbG90IG9mIGxpZmVzcGFuIGJ5IGhhYml0YXQKClRoZSBtZWRpYW4gaXMgcmVwcmVzZW50ZWQgYnkgdGhlIGNlbnRyYWwgcG9pbnQgb3IgdGhpY2tlbmVkIHJlZ2lvbiB3aXRoaW4gZWFjaCB2aW9saW4uIEl0IGluZGljYXRlcyB0aGUgbWlkZGxlIHZhbHVlIG9mIHRoZSBsaWZlIHNwYW4gZGlzdHJpYnV0aW9uIGZvciBhIHNwZWNpZmljIGhhYml0YXQuIEhlcmUgbWVkaWFuIG9mIGlkbGV3YXRlciBpcyBhcm91bmQgNSwgbGFrZXMsIHBvbmRzLCByaXZlcnMgIGFyZSBhcm91bmQgMjAuIEFuZCBzbG93bW92aW5nIHdhdGVycyBhcmUgbW9yZSB0aGVuIDIwLgoKQ3JlYXRlIGEgY29sb3IgcGFsZXR0ZSBmb3IgdGhlIHBsb3QKYGBge3J9Cm15X3BhbGV0dGUgPC0gYygiIzY2YzJhNSIsICIjZmM4ZDYyIiwgIiM4ZGEwY2IiLCAiI2U3OGFjMyIsICIjYTZkODU0IikKCmBgYAoKQ3JlYXRlIHRoZSB2aW9saW4gcGxvdApgYGB7cn0KZ2dwbG90KGZpc2hfZGF0YSwgYWVzKHggPSBmYWN0b3IoaGFiaXRhdCksIHkgPSBsaWZlX3NwYW4sIGZpbGwgPSBmYWN0b3IoaGFiaXRhdCkpKSArCiAgZ2VvbV92aW9saW4odHJpbSA9IEZBTFNFLCBzY2FsZSA9ICJ3aWR0aCIsIHdpZHRoID0gMC44LCBhbHBoYSA9IDAuNSkgKwogIGdlb21faml0dGVyKHdpZHRoID0gMC4yLCBhZXMoY29sb3IgPSBmYWN0b3IoaGFiaXRhdCkpLCBzaXplID0gMSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteV9wYWxldHRlKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG15X3BhbGV0dGUpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnModGl0bGUgPSAiVmlvbGluIFBsb3Qgb2YgTGlmZSBTcGFuIGJ5IEhhYml0YXQiLAogICAgICAgeCA9ICJIYWJpdGF0IiwKICAgICAgIHkgPSAiTGlmZSBTcGFuIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ3aGl0ZSIpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAibGlnaHRncmF5Iiwgc2l6ZSA9IDAuMiksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC4yKQogICkKYGBgCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo=