Data


data <- data %>%
  filter(year != 2016)  


# b) excluding countries with <= 3 years of data:

minimum_years <- data %>%
  group_by(country) %>%
  summarize(rows = n(), 
            years = rows / 12) %>%
  arrange(years)


data <- data %>%
  filter(!(country %in% head(minimum_years$country, 7)))

# Making age ordinal
data$age <- factor(data$age, 
                   ordered = T, 
                   levels = c("5-14 years",
                              "15-24 years", 
                              "25-34 years", 
                              "35-54 years", 
                              "55-74 years", 
                              "75+ years"))

data$country <- as.factor(data$country)
data$age <- as.factor(data$age)
data$sex <- as.factor(data$sex)
data %>% head() %>% knitr::kable()
country year sex age suicides_no population gdp_for_year suicides_per_100K gdp_per_capita
Albania 1987 male 15-24 years 21 312900 2156624900 6.71 796
Albania 1987 male 35-54 years 16 308000 2156624900 5.19 796
Albania 1987 female 15-24 years 14 289700 2156624900 4.83 796
Albania 1987 male 75+ years 1 21800 2156624900 4.59 796
Albania 1987 male 25-34 years 9 274300 2156624900 3.28 796
Albania 1987 female 75+ years 1 35600 2156624900 2.81 796


data %>% dim()
[1] 27492     9
data %>% summary()
      country           year          sex                 age        suicides_no     
 Argentina:  372   Min.   :1985   female:13746   5-14 years :4582   Min.   :    0.0  
 Austria  :  372   1st Qu.:1995   male  :13746   15-24 years:4582   1st Qu.:    3.0  
 Belgium  :  372   Median :2002                  25-34 years:4582   Median :   25.0  
 Brazil   :  372   Mean   :2001                  35-54 years:4582   Mean   :  244.9  
 Chile    :  372   3rd Qu.:2008                  55-74 years:4582   3rd Qu.:  133.0  
 Colombia :  372   Max.   :2015                  75+ years  :4582   Max.   :22338.0  
 (Other)  :25260                                                                     
   population        gdp_for_year       suicides_per_100K gdp_per_capita  
 Min.   :     278   Min.   :4.692e+07   Min.   :  0.00    Min.   :   251  
 1st Qu.:   99298   1st Qu.:9.025e+09   1st Qu.:  0.95    1st Qu.:  3418  
 Median :  436562   Median :4.819e+10   Median :  6.04    Median :  9283  
 Mean   : 1861366   Mean   :4.497e+11   Mean   : 12.87    Mean   : 16799  
 3rd Qu.: 1503556   3rd Qu.:2.617e+11   3rd Qu.: 16.68    3rd Qu.: 24870  
 Max.   :43805214   Max.   :1.812e+13   Max.   :224.97    Max.   :126352  
                                                                          

Global Analysis

Global Trend

# the global rate over the time period will be useful:

average <- (sum(as.numeric(data$suicides_no)) / sum(as.numeric(data$population))) * 100000
data %>%
  group_by(year) %>%
  summarize(population = sum(population), 
            suicides = sum(suicides_no), 
            suicides_per_100k = (suicides / population) * 100000) %>%
  ggplot(aes(x = year, y = suicides_per_100k)) + 
  geom_line(col = "coral", size = 1) + 
  geom_point(col = "coral", size = 2) + 
  geom_hline(yintercept = average, linetype = 2, color = "brown", size = 1) +
  labs(title = "Global Suicides per 100k",
       subtitle = "Trend over time, 1985 - 2015.",
       x = "Year", 
       y = "Suicides per 100k") + 
  scale_x_continuous(breaks = seq(1985, 2015, 5) , minor_breaks = FALSE) + 
  scale_y_continuous(breaks = seq(10, 20))

Insights

The peak global suicide rate reached 15.3 deaths per 100k population in 1995. Since then, it has steadily decreased, reaching 11.5 deaths per 100k in 2015. This represents a reduction of approximately 25% over the course of 20 years.

Sex

sex_plot <- data %>%
  group_by(sex) %>%
  summarize(suicide_per_100k = (sum(as.numeric(suicides_no)) / sum(as.numeric(population))) * 100000) %>%
ggplot(aes(x = sex, y = suicide_per_100k, fill = sex)) + 
  geom_bar(stat = "identity") + 
  labs(title = "Global suicides (per 100k), by Sex",
       x = "Sex", 
       y = "Suicides per 100k") +
  theme(legend.position = "none") + 
  scale_y_continuous(breaks = seq(0, 25), minor_breaks = F)

### with time
sex_time_plot <- data %>%
  group_by(year, sex) %>%
  summarize(suicide_per_100k = (sum(as.numeric(suicides_no)) / sum(as.numeric(population))) * 100000) %>%
  ggplot(aes(x = year, y = suicide_per_100k, col = factor(sex))) + 
  facet_grid(sex ~ ., scales = "free_y") + 
  geom_line() + 
  geom_point() + 
  labs(title = "Trends Over Time, by Sex", 
       x = "Year", 
       y = "Suicides per 100k", 
       color = "Sex") + 
  theme(legend.position = "none") + 
  scale_x_continuous(breaks = seq(1985, 2015, 5), minor_breaks = F)

grid.arrange(sex_plot, sex_time_plot, ncol = 2)

Insights

The global suicide rate has consistently been approximately 3.5 times higher for men compared to women. Both male and female suicide rates reached their highest point in 1995 and have been declining since then. This ratio of 3.5:1 (male to female) has remained relatively stable since the mid-1990s. However, during the 1980s, this ratio was as low as 2.7:1 (male to female).

Age

age_plot <- data %>%
  group_by(age) %>%
  summarize(suicide_per_100k = (sum(as.numeric(suicides_no)) / sum(as.numeric(population))) * 100000) %>%
  ggplot(aes(x = age, y = suicide_per_100k, fill = age)) + 
  geom_bar(stat = "identity") + 
  labs(title = "Global suicides per 100k, by Age",
       x = "Age", 
       y = "Suicides per 100k") +
  theme(legend.position = "none") + 
  scale_y_continuous(breaks = seq(0, 30, 1), minor_breaks = F) +
  theme(
    text = element_text(size = 10) ,
    axis.text.x = element_text(angle=45) , legend.position="none")

### with time
age_time_plot <- data %>%
  group_by(year, age) %>%
  summarize(suicide_per_100k = (sum(as.numeric(suicides_no)) / sum(as.numeric(population))) * 100000) %>%
  ggplot(aes(x = year, y = suicide_per_100k, col = age)) + 
  facet_grid(age ~ ., scales = "free_y") + 
  geom_line() + 
  geom_point() + 
  labs(title = "Trends Over Time, by Age", 
       x = "Year", 
       y = "Suicides per 100k", 
       color = "Age") + 
  theme(legend.position = "none") + 
  scale_x_continuous(breaks = seq(1985, 2015, 5), minor_breaks = F)


grid.arrange(age_plot, age_time_plot, ncol = 2)

Insights

Globally, there is a clear correlation between age and the likelihood of suicide, with the risk increasing as individuals get older. Moreover, starting from 1995, there has been a consistent linear decrease in the suicide rate for individuals aged 15 and above. Notably, the suicide rate among individuals aged 75 and older has declined by over 50% since 1990. In contrast, the suicide rate in the ‘5-14’ age category has remained relatively stable and low, with less than 1 per 100k population per year.

Country

Overall

country <- data %>%
  group_by(country) %>%
  summarize(
            suicide_per_100k = (sum(as.numeric(suicides_no)) / sum(as.numeric(population))) * 100000) %>%
  arrange(desc(suicide_per_100k))

country$country <- factor(country$country, 
                          ordered = T, 
                          levels = rev(country$country))

kable(country) 
country suicide_per_100k
Lithuania 41.4641006
Russian Federation 32.7772066
Sri Lanka 30.4839387
Belarus 30.3446849
Hungary 30.0224072
Latvia 28.4710108
Kazakhstan 26.8986144
Slovenia 26.3604769
Estonia 25.9645245
Ukraine 24.8703975
Finland 23.7286200
Japan 21.9205801
Belgium 20.6925347
Austria 20.6761930
Guyana 20.6452838
Croatia 20.1285551
France 19.6992767
Republic of Korea 19.3166521
Serbia 19.1683634
Suriname 18.6094161
Switzerland 17.4786980
Czech Republic 16.6037953
Cuba 16.4494134
Poland 16.0587863
Bulgaria 15.6885430
Uruguay 15.6276498
Luxembourg 15.1160072
Sweden 14.9548512
Germany 14.3841922
New Zealand 13.9518285
Denmark 13.6358508
Norway 13.2777918
Iceland 13.1217940
Canada 13.0210902
Trinidad and Tobago 12.9276557
Australia 12.9265987
United States 12.8384592
Romania 12.6829028
Slovakia 12.0151604
Mauritius 11.7090106
Ireland 11.5332736
Kyrgyzstan 11.3653939
Singapore 10.7053679
Netherlands 10.6147679
Chile 9.5632835
El Salvador 9.3701103
Portugal 9.2096414
Puerto Rico 8.5807853
Spain 8.1620246
Montenegro 8.0893073
Aruba 8.0179284
Argentina 7.9363085
United Kingdom 7.8679282
Italy 7.7000953
Turkmenistan 7.4617040
Uzbekistan 7.1548906
Kiribati 7.1466520
Seychelles 7.0361053
Thailand 6.9563081
Costa Rica 6.6473023
Israel 6.5256158
Nicaragua 6.3416289
Ecuador 6.0000931
Saint Lucia 5.8815707
Belize 5.5334579
Malta 5.2104659
Saint Vincent and Grenadines 5.0868414
Panama 4.9569022
Colombia 4.7908647
Brazil 4.6665699
Mexico 4.0079566
Greece 3.9127341
Paraguay 3.8373912
Fiji 3.7130265
Cyprus 3.4507703
Georgia 3.4444886
Albania 3.1608267
Barbados 2.8485485
Bahrain 2.7635314
Guatemala 2.6686723
Qatar 2.5740911
Armenia 2.4523624
Turkey 2.0990775
Philippines 2.0026887
United Arab Emirates 1.7040034
Kuwait 1.6914729
Grenada 1.6752826
Azerbaijan 1.4813450
Bahamas 1.4183212
South Africa 0.8384769
Maldives 0.6895967
Antigua and Barbuda 0.5527005
Jamaica 0.4660373
country %>% 
  # slice_max( order_by =suicide_per_100k , n= 50 ) %>%
ggplot( aes(x = country, y = suicide_per_100k , fill =suicide_per_100k ))  + 
  geom_bar(stat = "identity" ) + 
  geom_hline(yintercept = average, linetype = 2, color = "brown", size = 1) +
  labs(title = "Global suicides per 100k, by Country",
       x = "Country", 
       y = "Suicides per 100k") +
  coord_flip() +
  scale_y_continuous(breaks = seq(0, 45, 2)) +
    scale_fill_gradient(low = "sienna1", high = "sienna4") +  # Change the color scale here

  theme(
    text = element_text(size = 10 ) ,
    axis.text.y = element_text(size=7) , 
    axis.text.x = element_text(angle=45) , legend.position="none" )

Insights

Lithuania has consistently maintained the highest suicide rate by a significant margin, with a rate exceeding 41 suicides per 100k population per year.

Map

library(ggplot2)
library(maps)
library(RColorBrewer)
df_subset <- data %>% group_by(country ) %>% summarize(suicides_per_100K = mean(suicides_per_100K))

# Load world map dataset
world_map <- map_data("world")

# Merge data with world map dataset
merged_data <- merge(world_map, df_subset, by.x = "region", by.y = "country", all.x = TRUE)

 
# Choose a color palette
palette <- colorRampPalette(brewer.pal(9, "YlOrRd"))
merged_data   <- merged_data %>% filter(  region != "Russia" )
# Create the plot
p <- ggplot() +
  geom_polygon(data = merged_data, aes(x = long, y = lat, group = group, fill = suicides_per_100K) ) +
  scale_fill_gradientn(colors = palette(100), name = "suicides per 100K") +
  coord_map() +
theme_void()

plotly::ggplotly(p)


Modeling

country_mean_gdp <- data %>%
  group_by(country) %>%
  summarize(suicide_per_100k = (sum(as.numeric(suicides_no)) / sum(as.numeric(population))) * 100000, 
            gdp_per_capita = mean(gdp_per_capita))

ggplot(country_mean_gdp, aes(x = gdp_per_capita, y = suicide_per_100k)) + 
  geom_point() + 
  scale_x_continuous(labels=scales::dollar_format(prefix="$"), breaks = seq(0, 70000, 10000)) + 
  labs(title = "Correlation between GDP (per capita) and Suicides per 100k", 
       subtitle = "Plot containing every country",
       x = "GDP (per capita)", 
       y = "Suicides per 100k") 

The presence of several high leverage and residual countries, such as Lithuania (located in the top left quadrant),

Below, I provide an assessment of the statistics for this model after removing the outliers.

model1 <- lm(suicide_per_100k ~ gdp_per_capita, data = country_mean_gdp)

gdp_suicide_no_outliers <- model1 %>%
  augment() %>%
  arrange(desc(.cooksd)) %>%
  filter(.cooksd < 4/nrow(.)) %>% # removes 5/93 countries
  inner_join(country_mean_gdp, 
             by = c("suicide_per_100k" ="suicide_per_100k"  , "gdp_per_capita" ="gdp_per_capita")) %>%
  dplyr::select(country,  suicide_per_100k ,gdp_per_capita)

model2 <- lm(suicide_per_100k  ~ gdp_per_capita, data = gdp_suicide_no_outliers)

summary(model2)

Call:
lm(formula = suicide_per_100k ~ gdp_per_capita, data = gdp_suicide_no_outliers)

Residuals:
    Min      1Q  Median      3Q     Max 
-11.769  -5.145  -1.724   3.227  20.221 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)    8.772e+00  1.119e+00   7.839 1.12e-11 ***
gdp_per_capita 1.115e-04  5.015e-05   2.223   0.0288 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.331 on 86 degrees of freedom
Multiple R-squared:  0.05436,   Adjusted R-squared:  0.04337 
F-statistic: 4.944 on 1 and 86 DF,  p-value: 0.02881

The model’s p-value is 0.0288 < 0.05, allowing us to reject the hypothesis that a country’s GDP (per capita) has no association with its suicide rate (per 100k).

The r-squared value is 0.0544, indicating that GDP (per capita) explains only a small portion of the overall variance in suicide rate.

Results

Richer countries tend to have higher suicide rates, indicating a weak yet significant positive linear relationship

ggplot(gdp_suicide_no_outliers, aes(x = gdp_per_capita, y = suicide_per_100k)) + 
  geom_point() + 
  geom_smooth(method = "lm", aes(group = 1)) + 
  scale_x_continuous(labels=scales::dollar_format(prefix="$"), breaks = seq(0, 70000, 10000)) + 
  labs(title = "Correlation between GDP (per capita) and Suicides per 100k", 
       subtitle = "Plot with high CooksD countries removed (5/93 total)",
       x = "GDP (per capita)", 
       y = "Suicides per 100k") + 
  theme(legend.position = "none")

LS0tDQp0aXRsZTogIkVEQV9Db3Vyc2UiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQogDQogDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmtuaXRyOjpvcHRzX2NodW5rJHNldChtZXNzYWdlID0gIEZBTFNFKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSAgRkFMU0UpDQprbml0cjo6b3B0c19jaHVuayRzZXQoZXJyb3IgPSAgRkFMU0UpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSAsd2FybmluZz1GQUxTRSAsIGVycm9yPUZBTFNFICwgZWNobz1GQUxTRX0NCmxpYnJhcnkoY29uZmxpY3RlZCkNCmNvbmZsaWN0c19wcmVmZXIoZHBseXI6OmZpbHRlcigpKQ0KDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJlcG9ydCkNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeShjb3VudHJ5Y29kZSkgIyBjb250aW5lbnQNCmxpYnJhcnkodGlkeXZlcnNlKSAjIGdlbmVyYWwNCmxpYnJhcnkoZ2dhbHQpICMgZHVtYmJlbGwgcGxvdHMNCmxpYnJhcnkoY291bnRyeWNvZGUpICMgY29udGluZW50DQpsaWJyYXJ5KHJ3b3JsZG1hcCkgIyBxdWljayBjb3VudHJ5LWxldmVsIGhlYXQgbWFwcw0KbGlicmFyeShncmlkRXh0cmEpICMgcGxvdHMNCmxpYnJhcnkoYnJvb20pICMgc2lnbmlmaWNhbnQgdHJlbmRzIHdpdGhpbiBjb3VudHJpZXMNCmxpYnJhcnkoa25pdHIpICMgc2lnbmlmaWNhbnQgdHJlbmRzIHdpdGhpbiBjb3VudHJpZXMNCg0KdGhlbWVfc2V0KHRoZW1lX2xpZ2h0KCkpDQpgYGANCg0KIA0KYGBge3IgLCBtZXNzYWdlPUZBTFNFICx3YXJuaW5nPUZBTFNFICwgZXJyb3I9RkFMU0UgLCBlY2hvPUZBTFNFfQ0KIA0KbGlicmFyeShyZWFkcikNCmRhdGEgPC0gcmVhZF9jc3YoImRhdGEvc3VpY2lkZXMuY3N2IikgICU+JQ0KICByZW5hbWUoZ2RwX2Zvcl95ZWFyID0gYGdkcF9mb3JfeWVhciAoJClgLCANCiAgc3VpY2lkZXNfcGVyXzEwMEsgPSBgc3VpY2lkZXMvMTAwayBwb3BgLCANCiAgICAgICAgIGdkcF9wZXJfY2FwaXRhID0gYGdkcF9wZXJfY2FwaXRhICgkKWApICAgIA0KIA0KZGF0YSA8LSBkYXRhICU+JSAgIA0KICBkcGx5cjo6c2VsZWN0KGNvdW50cnkgLHllYXIgLCBzZXggLCBhZ2UgLCANCiAgICAgICAgICAgICAgICBzdWljaWRlc19ubyAsIHBvcHVsYXRpb24gLA0KICAgICAgICAgICAgICAgIGdkcF9mb3JfeWVhciAgLHN1aWNpZGVzX3Blcl8xMDBLICwgIGdkcF9wZXJfY2FwaXRhLA0KICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICApDQpgYGANCg0KDQogDQoNCg0KIA0KDQoNCiMgRGF0YSANCmBgYHtyfQ0KDQpkYXRhIDwtIGRhdGEgJT4lDQogIGZpbHRlcih5ZWFyICE9IDIwMTYpICANCg0KDQojIGIpIGV4Y2x1ZGluZyBjb3VudHJpZXMgd2l0aCA8PSAzIHllYXJzIG9mIGRhdGE6DQoNCm1pbmltdW1feWVhcnMgPC0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lDQogIHN1bW1hcml6ZShyb3dzID0gbigpLCANCiAgICAgICAgICAgIHllYXJzID0gcm93cyAvIDEyKSAlPiUNCiAgYXJyYW5nZSh5ZWFycykNCg0KDQpkYXRhIDwtIGRhdGEgJT4lDQogIGZpbHRlcighKGNvdW50cnkgJWluJSBoZWFkKG1pbmltdW1feWVhcnMkY291bnRyeSwgNykpKQ0KDQojIE1ha2luZyBhZ2Ugb3JkaW5hbA0KZGF0YSRhZ2UgPC0gZmFjdG9yKGRhdGEkYWdlLCANCiAgICAgICAgICAgICAgICAgICBvcmRlcmVkID0gVCwgDQogICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiNS0xNCB5ZWFycyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTUtMjQgeWVhcnMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyNS0zNCB5ZWFycyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjM1LTU0IHllYXJzIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNTUtNzQgeWVhcnMiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI3NSsgeWVhcnMiKSkNCg0KZGF0YSRjb3VudHJ5IDwtIGFzLmZhY3RvcihkYXRhJGNvdW50cnkpDQpkYXRhJGFnZSA8LSBhcy5mYWN0b3IoZGF0YSRhZ2UpDQpkYXRhJHNleCA8LSBhcy5mYWN0b3IoZGF0YSRzZXgpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KZGF0YSAlPiUgaGVhZCgpICU+JSBrbml0cjo6a2FibGUoKQ0KDQoNCmRhdGEgJT4lIGRpbSgpDQoNCmRhdGEgJT4lIHN1bW1hcnkoKQ0KYGBgDQoNCg0KIyAqKkdsb2JhbCBBbmFseXNpcyoqDQoNCiMjICoqR2xvYmFsIFRyZW5kKioNCg0KDQoNCmBgYHtyfQ0KIyB0aGUgZ2xvYmFsIHJhdGUgb3ZlciB0aGUgdGltZSBwZXJpb2Qgd2lsbCBiZSB1c2VmdWw6DQoNCmF2ZXJhZ2UgPC0gKHN1bShhcy5udW1lcmljKGRhdGEkc3VpY2lkZXNfbm8pKSAvIHN1bShhcy5udW1lcmljKGRhdGEkcG9wdWxhdGlvbikpKSAqIDEwMDAwMA0KZGF0YSAlPiUNCiAgZ3JvdXBfYnkoeWVhcikgJT4lDQogIHN1bW1hcml6ZShwb3B1bGF0aW9uID0gc3VtKHBvcHVsYXRpb24pLCANCiAgICAgICAgICAgIHN1aWNpZGVzID0gc3VtKHN1aWNpZGVzX25vKSwgDQogICAgICAgICAgICBzdWljaWRlc19wZXJfMTAwayA9IChzdWljaWRlcyAvIHBvcHVsYXRpb24pICogMTAwMDAwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0geWVhciwgeSA9IHN1aWNpZGVzX3Blcl8xMDBrKSkgKyANCiAgZ2VvbV9saW5lKGNvbCA9ICJjb3JhbCIsIHNpemUgPSAxKSArIA0KICBnZW9tX3BvaW50KGNvbCA9ICJjb3JhbCIsIHNpemUgPSAyKSArIA0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBhdmVyYWdlLCBsaW5ldHlwZSA9IDIsIGNvbG9yID0gImJyb3duIiwgc2l6ZSA9IDEpICsNCiAgbGFicyh0aXRsZSA9ICJHbG9iYWwgU3VpY2lkZXMgcGVyIDEwMGsiLA0KICAgICAgIHN1YnRpdGxlID0gIlRyZW5kIG92ZXIgdGltZSwgMTk4NSAtIDIwMTUuIiwNCiAgICAgICB4ID0gIlllYXIiLCANCiAgICAgICB5ID0gIlN1aWNpZGVzIHBlciAxMDBrIikgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxOTg1LCAyMDE1LCA1KSAsIG1pbm9yX2JyZWFrcyA9IEZBTFNFKSArIA0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwLCAyMCkpDQpgYGANCg0KKioqSW5zaWdodHMqKioNCg0KVGhlIHBlYWsgZ2xvYmFsIHN1aWNpZGUgcmF0ZSByZWFjaGVkIDE1LjMgZGVhdGhzIHBlciAxMDBrIHBvcHVsYXRpb24gaW4gMTk5NS4gU2luY2UgdGhlbiwgaXQgaGFzIHN0ZWFkaWx5IGRlY3JlYXNlZCwgcmVhY2hpbmcgMTEuNSBkZWF0aHMgcGVyIDEwMGsgaW4gMjAxNS4gVGhpcyByZXByZXNlbnRzIGEgcmVkdWN0aW9uIG9mIGFwcHJveGltYXRlbHkgMjUlIG92ZXIgdGhlIGNvdXJzZSBvZiAyMCB5ZWFycy4NCg0KDQoNCiMjICoqU2V4KioNCmBgYHtyfQ0Kc2V4X3Bsb3QgPC0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkoc2V4KSAlPiUNCiAgc3VtbWFyaXplKHN1aWNpZGVfcGVyXzEwMGsgPSAoc3VtKGFzLm51bWVyaWMoc3VpY2lkZXNfbm8pKSAvIHN1bShhcy5udW1lcmljKHBvcHVsYXRpb24pKSkgKiAxMDAwMDApICU+JQ0KZ2dwbG90KGFlcyh4ID0gc2V4LCB5ID0gc3VpY2lkZV9wZXJfMTAwaywgZmlsbCA9IHNleCkpICsgDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArIA0KICBsYWJzKHRpdGxlID0gIkdsb2JhbCBzdWljaWRlcyAocGVyIDEwMGspLCBieSBTZXgiLA0KICAgICAgIHggPSAiU2V4IiwgDQogICAgICAgeSA9ICJTdWljaWRlcyBwZXIgMTAwayIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDI1KSwgbWlub3JfYnJlYWtzID0gRikNCg0KIyMjIHdpdGggdGltZQ0Kc2V4X3RpbWVfcGxvdCA8LSBkYXRhICU+JQ0KICBncm91cF9ieSh5ZWFyLCBzZXgpICU+JQ0KICBzdW1tYXJpemUoc3VpY2lkZV9wZXJfMTAwayA9IChzdW0oYXMubnVtZXJpYyhzdWljaWRlc19ubykpIC8gc3VtKGFzLm51bWVyaWMocG9wdWxhdGlvbikpKSAqIDEwMDAwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBzdWljaWRlX3Blcl8xMDBrLCBjb2wgPSBmYWN0b3Ioc2V4KSkpICsgDQogIGZhY2V0X2dyaWQoc2V4IH4gLiwgc2NhbGVzID0gImZyZWVfeSIpICsgDQogIGdlb21fbGluZSgpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBsYWJzKHRpdGxlID0gIlRyZW5kcyBPdmVyIFRpbWUsIGJ5IFNleCIsIA0KICAgICAgIHggPSAiWWVhciIsIA0KICAgICAgIHkgPSAiU3VpY2lkZXMgcGVyIDEwMGsiLCANCiAgICAgICBjb2xvciA9ICJTZXgiKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTk4NSwgMjAxNSwgNSksIG1pbm9yX2JyZWFrcyA9IEYpDQoNCmdyaWQuYXJyYW5nZShzZXhfcGxvdCwgc2V4X3RpbWVfcGxvdCwgbmNvbCA9IDIpDQpgYGANCg0KKioqSW5zaWdodHMqKioNCg0KVGhlIGdsb2JhbCBzdWljaWRlIHJhdGUgaGFzIGNvbnNpc3RlbnRseSBiZWVuIGFwcHJveGltYXRlbHkgMy41IHRpbWVzIGhpZ2hlciBmb3IgbWVuIGNvbXBhcmVkIHRvIHdvbWVuLiBCb3RoIG1hbGUgYW5kIGZlbWFsZSBzdWljaWRlIHJhdGVzIHJlYWNoZWQgdGhlaXIgaGlnaGVzdCBwb2ludCBpbiAxOTk1IGFuZCBoYXZlIGJlZW4gZGVjbGluaW5nIHNpbmNlIHRoZW4uIFRoaXMgcmF0aW8gb2YgMy41OjEgKG1hbGUgdG8gZmVtYWxlKSBoYXMgcmVtYWluZWQgcmVsYXRpdmVseSBzdGFibGUgc2luY2UgdGhlIG1pZC0xOTkwcy4gSG93ZXZlciwgZHVyaW5nIHRoZSAxOTgwcywgdGhpcyByYXRpbyB3YXMgYXMgbG93IGFzIDIuNzoxIChtYWxlIHRvIGZlbWFsZSkuDQoNCg0KDQojIyAqKkFnZSoqDQoNCmBgYHtyfQ0KYWdlX3Bsb3QgPC0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkoYWdlKSAlPiUNCiAgc3VtbWFyaXplKHN1aWNpZGVfcGVyXzEwMGsgPSAoc3VtKGFzLm51bWVyaWMoc3VpY2lkZXNfbm8pKSAvIHN1bShhcy5udW1lcmljKHBvcHVsYXRpb24pKSkgKiAxMDAwMDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBhZ2UsIHkgPSBzdWljaWRlX3Blcl8xMDBrLCBmaWxsID0gYWdlKSkgKyANCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsgDQogIGxhYnModGl0bGUgPSAiR2xvYmFsIHN1aWNpZGVzIHBlciAxMDBrLCBieSBBZ2UiLA0KICAgICAgIHggPSAiQWdlIiwgDQogICAgICAgeSA9ICJTdWljaWRlcyBwZXIgMTAwayIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArIA0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDMwLCAxKSwgbWlub3JfYnJlYWtzID0gRikgKw0KICB0aGVtZSgNCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkgLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1KSAsIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNCiMjIyB3aXRoIHRpbWUNCmFnZV90aW1lX3Bsb3QgPC0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgYWdlKSAlPiUNCiAgc3VtbWFyaXplKHN1aWNpZGVfcGVyXzEwMGsgPSAoc3VtKGFzLm51bWVyaWMoc3VpY2lkZXNfbm8pKSAvIHN1bShhcy5udW1lcmljKHBvcHVsYXRpb24pKSkgKiAxMDAwMDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gc3VpY2lkZV9wZXJfMTAwaywgY29sID0gYWdlKSkgKyANCiAgZmFjZXRfZ3JpZChhZ2UgfiAuLCBzY2FsZXMgPSAiZnJlZV95IikgKyANCiAgZ2VvbV9saW5lKCkgKyANCiAgZ2VvbV9wb2ludCgpICsgDQogIGxhYnModGl0bGUgPSAiVHJlbmRzIE92ZXIgVGltZSwgYnkgQWdlIiwgDQogICAgICAgeCA9ICJZZWFyIiwgDQogICAgICAgeSA9ICJTdWljaWRlcyBwZXIgMTAwayIsIA0KICAgICAgIGNvbG9yID0gIkFnZSIpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyANCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxOTg1LCAyMDE1LCA1KSwgbWlub3JfYnJlYWtzID0gRikNCg0KDQpncmlkLmFycmFuZ2UoYWdlX3Bsb3QsIGFnZV90aW1lX3Bsb3QsIG5jb2wgPSAyKQ0KYGBgDQoNCioqKkluc2lnaHRzKioqDQoNCkdsb2JhbGx5LCB0aGVyZSBpcyBhIGNsZWFyIGNvcnJlbGF0aW9uIGJldHdlZW4gYWdlIGFuZCB0aGUgbGlrZWxpaG9vZCBvZiBzdWljaWRlLCB3aXRoIHRoZSByaXNrIGluY3JlYXNpbmcgYXMgaW5kaXZpZHVhbHMgZ2V0IG9sZGVyLiBNb3Jlb3Zlciwgc3RhcnRpbmcgZnJvbSAxOTk1LCB0aGVyZSBoYXMgYmVlbiBhIGNvbnNpc3RlbnQgbGluZWFyIGRlY3JlYXNlIGluIHRoZSBzdWljaWRlIHJhdGUgZm9yIGluZGl2aWR1YWxzIGFnZWQgMTUgYW5kIGFib3ZlLiBOb3RhYmx5LCB0aGUgc3VpY2lkZSByYXRlIGFtb25nIGluZGl2aWR1YWxzIGFnZWQgNzUgYW5kIG9sZGVyIGhhcyBkZWNsaW5lZCBieSBvdmVyIDUwJSBzaW5jZSAxOTkwLiBJbiBjb250cmFzdCwgdGhlIHN1aWNpZGUgcmF0ZSBpbiB0aGUgJzUtMTQnIGFnZSBjYXRlZ29yeSBoYXMgcmVtYWluZWQgcmVsYXRpdmVseSBzdGFibGUgYW5kIGxvdywgd2l0aCBsZXNzIHRoYW4gMSBwZXIgMTAwayBwb3B1bGF0aW9uIHBlciB5ZWFyLg0KDQojIyAqKkNvdW50cnkqKg0KDQojIyMgKipPdmVyYWxsKioNCmBgYHtyIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSAxMn0NCmNvdW50cnkgPC0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lDQogIHN1bW1hcml6ZSgNCiAgICAgICAgICAgIHN1aWNpZGVfcGVyXzEwMGsgPSAoc3VtKGFzLm51bWVyaWMoc3VpY2lkZXNfbm8pKSAvIHN1bShhcy5udW1lcmljKHBvcHVsYXRpb24pKSkgKiAxMDAwMDApICU+JQ0KICBhcnJhbmdlKGRlc2Moc3VpY2lkZV9wZXJfMTAwaykpDQoNCmNvdW50cnkkY291bnRyeSA8LSBmYWN0b3IoY291bnRyeSRjb3VudHJ5LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZCA9IFQsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByZXYoY291bnRyeSRjb3VudHJ5KSkNCg0Ka2FibGUoY291bnRyeSkgDQpjb3VudHJ5ICU+JSANCiAgIyBzbGljZV9tYXgoIG9yZGVyX2J5ID1zdWljaWRlX3Blcl8xMDBrICwgbj0gNTAgKSAlPiUNCmdncGxvdCggYWVzKHggPSBjb3VudHJ5LCB5ID0gc3VpY2lkZV9wZXJfMTAwayAsIGZpbGwgPXN1aWNpZGVfcGVyXzEwMGsgKSkgICsgDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiICkgKyANCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gYXZlcmFnZSwgbGluZXR5cGUgPSAyLCBjb2xvciA9ICJicm93biIsIHNpemUgPSAxKSArDQogIGxhYnModGl0bGUgPSAiR2xvYmFsIHN1aWNpZGVzIHBlciAxMDBrLCBieSBDb3VudHJ5IiwNCiAgICAgICB4ID0gIkNvdW50cnkiLCANCiAgICAgICB5ID0gIlN1aWNpZGVzIHBlciAxMDBrIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDQ1LCAyKSkgKw0KICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gInNpZW5uYTEiLCBoaWdoID0gInNpZW5uYTQiKSArICAjIENoYW5nZSB0aGUgY29sb3Igc2NhbGUgaGVyZQ0KDQogIHRoZW1lKA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwICkgLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9NykgLCANCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT00NSkgLCBsZWdlbmQucG9zaXRpb249Im5vbmUiICkNCmBgYA0KDQoqKipJbnNpZ2h0cyoqKg0KDQoqTGl0aHVhbmlhIGhhcyBjb25zaXN0ZW50bHkgbWFpbnRhaW5lZCB0aGUgaGlnaGVzdCBzdWljaWRlIHJhdGUgYnkgYSBzaWduaWZpY2FudCBtYXJnaW4sIHdpdGggYSByYXRlIGV4Y2VlZGluZyA0MSBzdWljaWRlcyBwZXIgMTAwayBwb3B1bGF0aW9uIHBlciB5ZWFyLioNCg0KIyMjIE1hcCANCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KG1hcHMpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmRmX3N1YnNldCA8LSBkYXRhICU+JSBncm91cF9ieShjb3VudHJ5ICkgJT4lIHN1bW1hcml6ZShzdWljaWRlc19wZXJfMTAwSyA9IG1lYW4oc3VpY2lkZXNfcGVyXzEwMEspKQ0KDQojIExvYWQgd29ybGQgbWFwIGRhdGFzZXQNCndvcmxkX21hcCA8LSBtYXBfZGF0YSgid29ybGQiKQ0KDQojIE1lcmdlIGRhdGEgd2l0aCB3b3JsZCBtYXAgZGF0YXNldA0KbWVyZ2VkX2RhdGEgPC0gbWVyZ2Uod29ybGRfbWFwLCBkZl9zdWJzZXQsIGJ5LnggPSAicmVnaW9uIiwgYnkueSA9ICJjb3VudHJ5IiwgYWxsLnggPSBUUlVFKQ0KDQogDQojIENob29zZSBhIGNvbG9yIHBhbGV0dGUNCnBhbGV0dGUgPC0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKDksICJZbE9yUmQiKSkNCm1lcmdlZF9kYXRhICAgPC0gbWVyZ2VkX2RhdGEgJT4lIGZpbHRlciggIHJlZ2lvbiAhPSAiUnVzc2lhIiApDQojIENyZWF0ZSB0aGUgcGxvdA0KcCA8LSBnZ3Bsb3QoKSArDQogIGdlb21fcG9seWdvbihkYXRhID0gbWVyZ2VkX2RhdGEsIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCwgZmlsbCA9IHN1aWNpZGVzX3Blcl8xMDBLKSApICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4oY29sb3JzID0gcGFsZXR0ZSgxMDApLCBuYW1lID0gInN1aWNpZGVzIHBlciAxMDBLIikgKw0KICBjb29yZF9tYXAoKSArDQp0aGVtZV92b2lkKCkNCg0KcGxvdGx5OjpnZ3Bsb3RseShwKQ0KYGBgDQoNCg0KDQoNClwNCg0KIyBNb2RlbGluZw0KDQpgYGB7cn0NCmNvdW50cnlfbWVhbl9nZHAgPC0gZGF0YSAlPiUNCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lDQogIHN1bW1hcml6ZShzdWljaWRlX3Blcl8xMDBrID0gKHN1bShhcy5udW1lcmljKHN1aWNpZGVzX25vKSkgLyBzdW0oYXMubnVtZXJpYyhwb3B1bGF0aW9uKSkpICogMTAwMDAwLCANCiAgICAgICAgICAgIGdkcF9wZXJfY2FwaXRhID0gbWVhbihnZHBfcGVyX2NhcGl0YSkpDQoNCmdncGxvdChjb3VudHJ5X21lYW5fZ2RwLCBhZXMoeCA9IGdkcF9wZXJfY2FwaXRhLCB5ID0gc3VpY2lkZV9wZXJfMTAwaykpICsgDQogIGdlb21fcG9pbnQoKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6ZG9sbGFyX2Zvcm1hdChwcmVmaXg9IiQiKSwgYnJlYWtzID0gc2VxKDAsIDcwMDAwLCAxMDAwMCkpICsgDQogIGxhYnModGl0bGUgPSAiQ29ycmVsYXRpb24gYmV0d2VlbiBHRFAgKHBlciBjYXBpdGEpIGFuZCBTdWljaWRlcyBwZXIgMTAwayIsIA0KICAgICAgIHN1YnRpdGxlID0gIlBsb3QgY29udGFpbmluZyBldmVyeSBjb3VudHJ5IiwNCiAgICAgICB4ID0gIkdEUCAocGVyIGNhcGl0YSkiLCANCiAgICAgICB5ID0gIlN1aWNpZGVzIHBlciAxMDBrIikgDQpgYGANCg0KDQoNClRoZSBwcmVzZW5jZSBvZiBzZXZlcmFsIGhpZ2ggbGV2ZXJhZ2UgYW5kIHJlc2lkdWFsIGNvdW50cmllcywgc3VjaCBhcyBMaXRodWFuaWEgKGxvY2F0ZWQgaW4gdGhlIHRvcCBsZWZ0IHF1YWRyYW50KSwgIA0KDQpCZWxvdywgSSBwcm92aWRlIGFuIGFzc2Vzc21lbnQgb2YgdGhlIHN0YXRpc3RpY3MgZm9yIHRoaXMgbW9kZWwgYWZ0ZXIgcmVtb3ZpbmcgdGhlIG91dGxpZXJzLg0KDQpgYGB7cn0NCm1vZGVsMSA8LSBsbShzdWljaWRlX3Blcl8xMDBrIH4gZ2RwX3Blcl9jYXBpdGEsIGRhdGEgPSBjb3VudHJ5X21lYW5fZ2RwKQ0KDQpnZHBfc3VpY2lkZV9ub19vdXRsaWVycyA8LSBtb2RlbDEgJT4lDQogIGF1Z21lbnQoKSAlPiUNCiAgYXJyYW5nZShkZXNjKC5jb29rc2QpKSAlPiUNCiAgZmlsdGVyKC5jb29rc2QgPCA0L25yb3coLikpICU+JSAjIHJlbW92ZXMgNS85MyBjb3VudHJpZXMNCiAgaW5uZXJfam9pbihjb3VudHJ5X21lYW5fZ2RwLCANCiAgICAgICAgICAgICBieSA9IGMoInN1aWNpZGVfcGVyXzEwMGsiID0ic3VpY2lkZV9wZXJfMTAwayIgICwgImdkcF9wZXJfY2FwaXRhIiA9ImdkcF9wZXJfY2FwaXRhIikpICU+JQ0KICBkcGx5cjo6c2VsZWN0KGNvdW50cnksICBzdWljaWRlX3Blcl8xMDBrICxnZHBfcGVyX2NhcGl0YSkNCg0KbW9kZWwyIDwtIGxtKHN1aWNpZGVfcGVyXzEwMGsgIH4gZ2RwX3Blcl9jYXBpdGEsIGRhdGEgPSBnZHBfc3VpY2lkZV9ub19vdXRsaWVycykNCg0Kc3VtbWFyeShtb2RlbDIpDQpgYGANCg0KVGhlIG1vZGVsJ3MgcC12YWx1ZSBpcyAwLjAyODggPCAwLjA1LCBhbGxvd2luZyB1cyB0byByZWplY3QgdGhlIGh5cG90aGVzaXMgdGhhdCBhIGNvdW50cnkncyBHRFAgKHBlciBjYXBpdGEpIGhhcyBubyBhc3NvY2lhdGlvbiB3aXRoIGl0cyBzdWljaWRlIHJhdGUgKHBlciAxMDBrKS4NCg0KVGhlIHItc3F1YXJlZCB2YWx1ZSBpcyAwLjA1NDQsIGluZGljYXRpbmcgdGhhdCBHRFAgKHBlciBjYXBpdGEpIGV4cGxhaW5zIG9ubHkgYSBzbWFsbCBwb3J0aW9uIG9mIHRoZSBvdmVyYWxsIHZhcmlhbmNlIGluIHN1aWNpZGUgcmF0ZS4NCg0KKipSZXN1bHRzKioNCg0KUmljaGVyIGNvdW50cmllcyB0ZW5kIHRvIGhhdmUgaGlnaGVyIHN1aWNpZGUgcmF0ZXMsIGluZGljYXRpbmcgYSB3ZWFrIHlldCBzaWduaWZpY2FudCBwb3NpdGl2ZSBsaW5lYXIgcmVsYXRpb25zaGlwDQoNCg0KDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZ2RwX3N1aWNpZGVfbm9fb3V0bGllcnMsIGFlcyh4ID0gZ2RwX3Blcl9jYXBpdGEsIHkgPSBzdWljaWRlX3Blcl8xMDBrKSkgKyANCiAgZ2VvbV9wb2ludCgpICsgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGFlcyhncm91cCA9IDEpKSArIA0KICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6ZG9sbGFyX2Zvcm1hdChwcmVmaXg9IiQiKSwgYnJlYWtzID0gc2VxKDAsIDcwMDAwLCAxMDAwMCkpICsgDQogIGxhYnModGl0bGUgPSAiQ29ycmVsYXRpb24gYmV0d2VlbiBHRFAgKHBlciBjYXBpdGEpIGFuZCBTdWljaWRlcyBwZXIgMTAwayIsIA0KICAgICAgIHN1YnRpdGxlID0gIlBsb3Qgd2l0aCBoaWdoIENvb2tzRCBjb3VudHJpZXMgcmVtb3ZlZCAoNS85MyB0b3RhbCkiLA0KICAgICAgIHggPSAiR0RQIChwZXIgY2FwaXRhKSIsIA0KICAgICAgIHkgPSAiU3VpY2lkZXMgcGVyIDEwMGsiKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGANCg0KDQoNCg0KDQoNCg0KDQo=