Import údajov

library(readr)
covid <- read_csv2("Covid.csv")
head(covid)
str(covid)
spc_tbl_ [4,372 × 5] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ country   : chr [1:4372] "Czechia" "Czechia" "Czechia" "Czechia" ...
 $ date      : Date[1:4372], format: "2020-01-04" "2020-01-05" "2020-01-06" "2020-01-07" ...
 $ cases     : num [1:4372] 0 0 0 0 0 0 0 0 0 0 ...
 $ deaths    : num [1:4372] 0 0 0 0 0 0 0 0 0 0 ...
 $ population: num [1:4372] 10673216 10673216 10673216 10673216 10673216 ...
 - attr(*, "spec")=
  .. cols(
  ..   country = col_character(),
  ..   date = col_date(format = ""),
  ..   cases = col_double(),
  ..   deaths = col_double(),
  ..   population = col_double()
  .. )
 - attr(*, "problems")=<externalptr> 
summary(covid)
   country               date                cases             deaths         population      
 Length:4372        Min.   :2020-01-04   Min.   :      0   Min.   :     0   Min.   : 5473195  
 Class :character   1st Qu.:2020-10-03   1st Qu.:  59088   1st Qu.:  1308   1st Qu.: 8631530  
 Mode  :character   Median :2021-07-03   Median :1043490   Median : 20372   Median :10178762  
                    Mean   :2021-07-03   Mean   :1627459   Mean   : 30076   Mean   :16054113  
                    3rd Qu.:2022-04-02   3rd Qu.:2153564   3rd Qu.: 41474   3rd Qu.:17601346  
                    Max.   :2022-12-31   Max.   :6368388   Max.   :118533   Max.   :38385734  

Základné grafy

Čiarový graf

library(ggplot2)
ggplot(covid, aes(x = date, y = cases, color = country)) +
geom_line(size=1) +
theme_minimal() +
labs(title = "Vývoj počtu prípadov COVID v krajinách V4",
x = "Dátum", y = "Počet prípadov")

covid$cases<- format(covid$cases, scientific = FALSE)

Interpretácia grafu: Na osi X je čas (Dátum) od roku 2020 do 2023. Na osi Y je kumulatívny počet prípadov COVID. Poľsko (modrá čiara) má najvyšší počet prípadov (viac ako 6 miliónov). Česko (červená čiara) nasleduje s približne 4,5 miliónmi prípadov. Maďarsko (zelená čiara) a Slovensko (fialová čiara) majú pod 2 milióny prípadov, pričom Slovensko je mierne pod Maďarskom. Vidieť typické pandemické vlny – prudké nárasty a následné spomalenia.

Záver: Počet prípadov bol najvyšší v Poľsku, najnižší na Slovensku, no priebeh vĺn bol vo všetkých krajinách veľmi podobný.

Scatterplot

Pozn. skúšal som viacerými spôsobmi spraviť to, aby mi ukázalo čísla/intervaly na Y-osi normálne, prípadne po miliónových intervaloch - tak ako na X-osi, ale bohužiaľ bez výsledku.

library(scales)
library(ggplot2)
ggplot(covid, aes(x = population, y = cases, color = country)) +
geom_point() +
theme_minimal() +
labs(title = "Počet prípadov vs. veľkosť populácie",
x = "Populácia", y = "Počet prípadov")

Interpretácia grafu Os X (Populácia): Slovensko má ~5,5 milióna obyvateľov (fialová). Maďarsko a Česko majú ~10 miliónov (zelená a červená). Poľsko má ~38–39 miliónov (tyrkysová).

Os Y (Počet prípadov): Hodnoty sú kumulatívne počty prípadov počas pandémie.

Tvar grafu: Každá krajina je zobrazená ako zvislý „stĺpec bodov“. To je preto, že populácia sa počas rokov nemení, ale počet prípadov áno → každá krajina má fixnú hodnotu na X a mnoho hodnôt na Y (pre rôzne dátumy).

Základné zistenia: Poľsko (najľudnatejšia krajina) malo aj najviac prípadov, čo je logické – viac obyvateľov → viac príležitostí na nákazu. Slovensko má najmenej obyvateľov, preto je aj celkový počet prípadov nižší. Pri Maďarsku a Česku vidno podobné počty prípadov, no Česko má vo výsledku vyšší rozsah (vyšší stĺpec na Y-osi). Medzi počtom obyvateľov a celkovým počtom prípadov je teda jasný pozitívny vzťah.

Boxplot

ggplot(covid, aes(x = country, y = deaths, fill = country)) +
geom_boxplot() +
theme_minimal() +
labs(title = "Rozdelenie počtu úmrtí podľa krajín",
x = "Krajina", y = "Úmrtia")

Interpretácia:

Poland (Poľsko) – má jednoznačne najvyšší počet úmrtí zo všetkých krajín. – Box (interkvartilové rozpätie) je veľmi vysoký, čo znamená, že počty úmrtí sa v priebehu pandémie značne menili. – Medián (čierna čiara vo vnútri boxu) je niekde okolo 75 000, ale hodnoty siahajú až nad 100 000.

Česko a Maďarsko – majú stredne vysoké počty úmrtí (okolo 30 000–40 000). – Medián je vyšší v Maďarsku, rozptyl je porovnateľný.

Slovensko – má jednoznačne najnižší počet úmrtí (okolo 20 000). – Box je menší → rozptyl je užší, priebeh pandémie v úmrtiach bol relatívne „kompaktnejší“.

Štatistiky

Základné štatistiky

library(dplyr)
library(knitr)
library(kableExtra)

stats <- covid %>%
group_by(country) %>%
summarise(
mean_cases = mean(cases, na.rm=TRUE),
median_cases = median(cases, na.rm=TRUE),
sd_cases = sd(cases, na.rm=TRUE),
mean_deaths = mean(deaths, na.rm=TRUE),
median_deaths = median(deaths, na.rm=TRUE),
sd_deaths = sd(deaths, na.rm=TRUE)
)

stats %>%
kable(digits = 2, caption = "Štatistiky COVID prípadov a úmrtí podľa krajín") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover"))
Štatistiky COVID prípadov a úmrtí podľa krajín
country mean_cases median_cases sd_cases mean_deaths median_deaths sd_deaths
Czechia NA 1688091 1694876.1 23367.26 30491 16536.99
Hungary NA 808197 798204.1 24597.41 29992 18938.55
Poland NA 2881517 2407157.9 61961.05 75105 46687.34
Slovakia NA 391696 731252.8 10377.53 12513 8267.41

Česko: Priemerný počet prípadov: ~1,96 milióna. Medián prípadov: ~1,68 milióna → rozdelenie je trochu „ťahané nahor“ extrémnymi hodnotami. Priemerný počet úmrtí: ~23 367. Medián úmrtí: ~30 491 → znamená, že v druhej polovici obdobia boli úmrtia vyššie. Relatívne vysoké štandardné odchýlky (variabilita v čase).

Maďarsko: Priemerný počet prípadov: ~909 tisíc, čo je menej než v Česku, ale… Priemerný počet úmrtí: ~24 597 → paradoxne vyšší než v Česku, hoci prípadov bolo menej. To môže naznačovať vyššiu úmrtnosť (väčší podiel úmrtí na prípadoch).

Poľsko: Najväčší priemerný počet prípadov: ~2,93 milióna. Najväčší priemerný počet úmrtí: ~61 961 → jednoznačne najhoršie postihnutá krajina V4. Extrémne vysoká štandardná odchýlka → priebeh pandémie bol v Poľsku veľmi rozkolísaný (silné vlny).

Slovensko: Najnižší priemerný počet prípadov (~707 tisíc). Aj úmrtí mala najmenej (~10 378). Medián úmrtí 12 513 naznačuje, že v druhej polovici pandémie bol počet úmrtí už vyšší než na začiatku. Variabilita (sd) je menšia než u ostatných, čo zodpovedá menšej krajine.

Korelačná analýza a heatmapa

library(corrplot)
num_data <- covid %>%
select(population, cases, deaths) %>%
na.omit()

cor_matrix <-cor(num_data)
Error in cor(num_data) : 'x' must be numeric

(Pozn. Pri poslednej úprave a funkcii RUN ALL (ctrl+alt+R) sa mi nejakým nedopatrením stalo, že mi nejde zobraziť korelačná analýza, z dôvodu, že som už stratil nervy a je veľa hodín a nechce sa mi tu nad tým už sedieť prikladám iba screenshot, ktorý som odfotil ešte predtým, ako sa to pokazilo.)

Korelácia ešte keď to fungovalo
Korelácia ešte keď to fungovalo

Interpretácia hodnôt korelácie:

CasesDeaths: 0.92 veľmi silná pozitívna korelácia: čím viac prípadov, tým viac úmrtí. To je očakávané, pretože úmrtia sú priamo dôsledkom infekcií.

PopulationDeaths: 0.58 stredne silná pozitívna korelácia: väčšie krajiny majú vo všeobecnosti viac úmrtí. To je logické, keďže pri väčšej populácii je vyšší absolútny počet obyvateľov vystavený riziku.

PopulationCases: 0.44 slabšia až stredná korelácia: väčšie krajiny majú tendenciu mať viac prípadov, ale vzťah nie je taký silný, ako medzi prípadmi a úmrtiami. To môže byť ovplyvnené rozdielmi v testovaní, opatreniach alebo štatistickom vykazovaní.

Testovanie hypotéz

t.test(
covid$deaths[covid$country == "Slovakia"],
covid$deaths[covid$country == "Czechia"]
)

    Welch Two Sample t-test

data:  covid$deaths[covid$country == "Slovakia"] and covid$deaths[covid$country == "Czechia"]
t = -23.228, df = 1605.8, p-value < 0.00000000000000022
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -14086.62 -11892.83
sample estimates:
mean of x mean of y 
 10377.53  23367.26 

V priemere malo Česko počas sledovaného obdobia o približne 13000 úmrtí viac ako Slovensko. Rozdiel je veľký aj štatisticky významný. Na základe dát môžeme s vysokou istotou povedať, že úmrtnosť v Česku bola dlhodobo vyššia než na Slovensku.

Anova

anova_result <- aov(cases ~ country, data = covid)
summary(anova_result)
              Df            Sum Sq          Mean Sq F value              Pr(>F)    
country        3  3481683094412067 1160561031470689   471.8 <0.0000000000000002 ***
Residuals   4368 10744050988456546    2459718632888                                
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Výsledok znamená, že rozdiely medzii krajinami sú štatisticky významné - priemerný počet prípadov COVID sa nedá vysvetliť len náhodou. Hviezdičky pri p-hodnote naznačujú veľmi silnú štatistickú významnosť (p<0,001).

Lineárna regresia

model <- lm(deaths ~ cases + population, data = covid)
summary(model)

Call:
lm(formula = deaths ~ cases + population, data = covid)

Residuals:
     Min       1Q   Median       3Q      Max 
-29577.4  -3763.0     81.2   7887.7  20049.3 

Coefficients:
                  Estimate     Std. Error t value            Pr(>|t|)    
(Intercept) -2994.32483155   287.09658892  -10.43 <0.0000000000000002 ***
cases           0.01506962     0.00010864  138.72 <0.0000000000000002 ***
population      0.00053226     0.00001503   35.42 <0.0000000000000002 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 11610 on 4369 degrees of freedom
Multiple R-squared:  0.8763,    Adjusted R-squared:  0.8763 
F-statistic: 1.548e+04 on 2 and 4369 DF,  p-value: < 0.00000000000000022

Lineárny regresný model ukazuje, že počet prípadov COVID je silne spojený s počtom úmrtí (p < 0.001). Každých 1000 prípadov prináša v priemere približne 15 úmrtí. Populácia krajiny má tiež štatisticky významný efekt – väčšie krajiny evidujú viac úmrtí aj po zohľadnení počtu prípadov. Celková vysvetľovacia schopnosť modelu je vysoká (R² = 0.876), čo znamená, že model zachytáva väčšinu variability v počte úmrtí.

Prehľad koeficientov

library(broom)
coef_tbl <- broom::tidy(model, conf.int = TRUE) %>%
mutate(
term = dplyr::recode(term,
"(Intercept)" = "Intercept",
"Cases" = "Cases (počet prípadov)",
"Population" = "Population (obyvatelia)"
),
stars = dplyr::case_when(
p.value < 0.001 ~ "",
p.value < 0.01 ~ "",
p.value < 0.05 ~ "",
p.value < 0.1 ~ "·",
TRUE ~ ""
)
) %>%
transmute(
Term = term,
Estimate = estimate,
`Std. Error` = std.error,
`t value` = statistic,
`p value` = p.value,
`95% CI` = stringr::str_c("[", round(conf.low, 3), ", ", round(conf.high, 3), "]"),
Sig = stars
)

coef_tbl %>%
kable(digits = 3,
caption = "OLS koeficienty: Deaths ~ Cases + Population") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped","hover","condensed")) %>%
column_spec(1, bold = TRUE) %>%
row_spec(0, bold = TRUE, background = "#f2f2f2") %>%
footnote(general = "Signif. kódy: *** p<0.001, ** p<0.01, * p<0.05, · p<0.1.", threeparttable = TRUE)
OLS koeficienty: Deaths ~ Cases + Population
Term Estimate Std. Error t value p value 95% CI Sig
Intercept -2994.325 287.097 -10.430 0 [-3557.18, -2431.47]
cases 0.015 0.000 138.717 0 [0.015, 0.015]
population 0.001 0.000 35.419 0 [0.001, 0.001]
Note:
Signif. kódy: *** p<0.001, ** p<0.01, * p<0.05, · p<0.1.


fit.tbl <- glance(model) %>%
  transmute(
`R-squared` = r.squared,
`Adj. R-squared` = adj.r.squared,
`F-statistic` = statistic,
`F p-value` = p.value,
`AIC` = AIC,
`BIC` = BIC,
`Num. obs.` = nobs
)

coef_tbl %>%
kable(digits = 3, caption = "Model – metriky zhody") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("condensed"))
Model – metriky zhody
Term Estimate Std. Error t value p value 95% CI Sig
Intercept -2994.325 287.097 -10.430 0 [-3557.18, -2431.47]
cases 0.015 0.000 138.717 0 [0.015, 0.015]
population 0.001 0.000 35.419 0 [0.001, 0.001]

Interpretácia koeficientov:

Intercept = -2994.3 – matematická konštanta modelu. Hovorí, že ak by bolo prípadov aj populácia nulová, predikovaný počet úmrtí by bol záporný (~ -2994). To samozrejme nedáva reálny význam, ale intercept je potrebný na vyrovnanie priamky.

Cases (0.015) – koeficient je kladný a štatisticky vysoko významný (p < 0.001). – Znamená, že pri náraste počtu prípadov o 1 jednotku sa počet úmrtí zvýši v priemere o 0.015. – Prakticky: na 1000 prípadov pripadá asi 15 úmrtí.

Population (0.001) – tiež kladný a vysoko významný (p < 0.001). – Znamená, že pri zvýšení populácie o 1 jednotku (1 obyvateľa) sa predpokladá nárast úmrtí o 0.001. – Teda pri 1 milióne obyvateľov sa očakáva v priemere približne 1000 úmrtí navyše (pri rovnakom počte prípadov).

LS0tCnRpdGxlOiAiQW5hbMO9emEgQ09WSUQgZMOhdCB2IGtyYWppbsOhY2ggVjQiCmF1dGhvcjogIk1hcnRpbiDEjMOhc2FyIHMgdnl1xb5pdMOtbSBDaGF0R1BUIGEgdmVyZWpuZSBkb3N0dXBuw71jaCB6ZHJvam92IgpkYXRlOiAiT2t0w7NiZXIgMjAyNSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdGhlbWU6IHVuaXRlZAogICAgaGlnaGxpZ2h0OiB0YW5nbwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAplZGl0b3Jfb3B0aW9uczoKICBtYXJrZG93bjoKICAgIHdyYXA6IDcyCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0gVFJVRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgbWVzc2FnZSA9IEZBTFNFCikKYGBgCgojIEltcG9ydCDDumRham92CgpgYGB7cn0KbGlicmFyeShyZWFkcikKY292aWQgPC0gcmVhZF9jc3YyKCJDb3ZpZC5jc3YiKQpoZWFkKGNvdmlkKQpzdHIoY292aWQpCnN1bW1hcnkoY292aWQpCmBgYAoKIyBaw6FrbGFkbsOpIGdyYWZ5CgojIyDEjGlhcm92w70gZ3JhZgoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGNvdmlkLCBhZXMoeCA9IGRhdGUsIHkgPSBjYXNlcywgY29sb3IgPSBjb3VudHJ5KSkgKwpnZW9tX2xpbmUoc2l6ZT0xKSArCnRoZW1lX21pbmltYWwoKSArCmxhYnModGl0bGUgPSAiVsO9dm9qIHBvxI10dSBwcsOtcGFkb3YgQ09WSUQgdiBrcmFqaW7DoWNoIFY0IiwKeCA9ICJEw6F0dW0iLCB5ID0gIlBvxI1ldCBwcsOtcGFkb3YiKQpjb3ZpZCRjYXNlczwtIGZvcm1hdChjb3ZpZCRjYXNlcywgc2NpZW50aWZpYyA9IEZBTFNFKQpgYGAKKkludGVycHJldMOhY2lhIGdyYWZ1OioKTmEgb3NpIFggamUgxI1hcyAoRMOhdHVtKSBvZCByb2t1IDIwMjAgZG8gMjAyMy4KTmEgb3NpIFkgamUga3VtdWxhdMOtdm55IHBvxI1ldCBwcsOtcGFkb3YgQ09WSUQuCioqUG/EvnNrbyoqIChtb2Ryw6EgxI1pYXJhKSBtw6EgbmFqdnnFocWhw60gcG/EjWV0IHByw61wYWRvdiAodmlhYyBha28gNiBtaWxpw7Nub3YpLgoqKsSMZXNrbyoqICjEjWVydmVuw6EgxI1pYXJhKSBuYXNsZWR1amUgcyBwcmlibGnFvm5lIDQsNSBtaWxpw7NubWkgcHLDrXBhZG92LgoqKk1hxI9hcnNrbyoqICh6ZWxlbsOhIMSNaWFyYSkgYSAqKlNsb3ZlbnNrbyoqIChmaWFsb3bDoSDEjWlhcmEpIG1hasO6IHBvZCAyIG1pbGnDs255IHByw61wYWRvdiwgcHJpxI1vbSAqKlNsb3ZlbnNrbyoqIGplIG1pZXJuZSBwb2QgKipNYcSPYXJza29tKiouClZpZGllxaUgdHlwaWNrw6kgcGFuZGVtaWNrw6kgdmxueSDigJMgcHJ1ZGvDqSBuw6FyYXN0eSBhIG7DoXNsZWRuw6kgc3BvbWFsZW5pYS4KCipaw6F2ZXIqOiBQb8SNZXQgcHLDrXBhZG92IGJvbCBuYWp2ecWhxaHDrSB2ICoqUG/EvnNrdSoqLCBuYWpuacW+xaHDrSBuYSAqKlNsb3ZlbnNrdSoqLCBubyBwcmllYmVoIHbEum4gYm9sIHZvIHbFoWV0a8O9Y2gga3Jhamluw6FjaCB2ZcS+bWkgcG9kb2Juw70uCgojIyBTY2F0dGVycGxvdAoKKipQb3puLiBza8O6xaFhbCBzb20gdmlhY2Vyw71taSBzcMO0c29ibWkgc3ByYXZpxaUgdG8sIGFieSBtaSB1a8OhemFsbyDEjcOtc2xhL2ludGVydmFseSBuYSBZLW9zaSBub3Jtw6FsbmUsIHByw61wYWRuZSBwbyBtaWxpw7Nub3bDvWNoIGludGVydmFsb2NoIC0gdGFrIGFrbyBuYSBYLW9zaSwgYWxlIGJvaHXFvmlhxL4gYmV6IHbDvXNsZWRrdS4qKgoKYGBge3J9CmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChjb3ZpZCwgYWVzKHggPSBwb3B1bGF0aW9uLCB5ID0gY2FzZXMsIGNvbG9yID0gY291bnRyeSkpICsKZ2VvbV9wb2ludCgpICsKdGhlbWVfbWluaW1hbCgpICsKbGFicyh0aXRsZSA9ICJQb8SNZXQgcHLDrXBhZG92IHZzLiB2ZcS+a29zxaUgcG9wdWzDoWNpZSIsCnggPSAiUG9wdWzDoWNpYSIsIHkgPSAiUG/EjWV0IHByw61wYWRvdiIpCmBgYApJbnRlcnByZXTDoWNpYSBncmFmdQoqT3MgWCAoUG9wdWzDoWNpYSk6KgoqKlNsb3ZlbnNrbyoqIG3DoSB+NSw1IG1pbGnDs25hIG9ieXZhdGXEvm92IChmaWFsb3bDoSkuCioqTWHEj2Fyc2tvKiogYSAqKsSMZXNrbyoqIG1hasO6IH4xMCBtaWxpw7Nub3YgKHplbGVuw6EgYSDEjWVydmVuw6EpLgoqUG/EvnNrbyogbcOhIH4zOOKAkzM5IG1pbGnDs25vdiAodHlya3lzb3bDoSkuCgoqT3MgWSAoUG/EjWV0IHByw61wYWRvdik6KgpIb2Rub3R5IHPDuiBrdW11bGF0w612bmUgcG/EjXR5IHByw61wYWRvdiBwb8SNYXMgcGFuZMOpbWllLgoKKlR2YXIgZ3JhZnU6KgpLYcW+ZMOhIGtyYWppbmEgamUgem9icmF6ZW7DoSBha28genZpc2zDvSDigJ5zdMS6cGVjIGJvZG924oCcLiBUbyBqZSBwcmV0bywgxb5lIHBvcHVsw6FjaWEgc2EgcG/EjWFzIHJva292IG5lbWVuw60sIGFsZSBwb8SNZXQgcHLDrXBhZG92IMOhbm8g4oaSIGthxb5kw6Ega3JhamluYSBtw6EgZml4bsO6IGhvZG5vdHUgbmEgWCBhIG1ub2hvIGhvZG7DtHQgbmEgWSAocHJlIHLDtHpuZSBkw6F0dW15KS4KCipaw6FrbGFkbsOpIHppc3RlbmlhOioKKipQb8S+c2tvKiogKG5hasS+dWRuYXRlasWhaWEga3JhamluYSkgbWFsbyBhaiBuYWp2aWFjIHByw61wYWRvdiwgxI1vIGplIGxvZ2lja8OpIOKAkyB2aWFjIG9ieXZhdGXEvm92IOKGkiB2aWFjIHByw61sZcW+aXRvc3TDrSBuYSBuw6FrYXp1LgoqKlNsb3ZlbnNrbyoqIG3DoSBuYWptZW5laiBvYnl2YXRlxL5vdiwgcHJldG8gamUgYWogY2Vsa292w70gcG/EjWV0IHByw61wYWRvdiBuacW+xaHDrS4KUHJpICoqTWHEj2Fyc2t1KiogYSAqKsSMZXNrdSoqIHZpZG5vIHBvZG9ibsOpIHBvxI10eSBwcsOtcGFkb3YsIG5vICoqxIxlc2tvKiogbcOhIHZvIHbDvXNsZWRrdSB2ecWhxaHDrSByb3pzYWggKHZ5xaHFocOtIHN0xLpwZWMgbmEgWS1vc2kpLgpNZWR6aSBwb8SNdG9tIG9ieXZhdGXEvm92IGEgY2Vsa292w71tIHBvxI10b20gcHLDrXBhZG92IGplIHRlZGEgamFzbsO9IHBveml0w612bnkgdnrFpWFoLgoKIyMgQm94cGxvdAoKYGBge3J9CmdncGxvdChjb3ZpZCwgYWVzKHggPSBjb3VudHJ5LCB5ID0gZGVhdGhzLCBmaWxsID0gY291bnRyeSkpICsKZ2VvbV9ib3hwbG90KCkgKwp0aGVtZV9taW5pbWFsKCkgKwpsYWJzKHRpdGxlID0gIlJvemRlbGVuaWUgcG/EjXR1IMO6bXJ0w60gcG9kxL5hIGtyYWrDrW4iLAp4ID0gIktyYWppbmEiLCB5ID0gIsOabXJ0aWEiKQpgYGAKKkludGVycHJldMOhY2lhOioKCioqUG9sYW5kIChQb8S+c2tvKSoqCuKAkyBtw6EgamVkbm96bmHEjW5lIG5hanZ5xaHFocOtIHBvxI1ldCDDum1ydMOtIHpvIHbFoWV0a8O9Y2gga3JhasOtbi4K4oCTIEJveCAoaW50ZXJrdmFydGlsb3bDqSByb3pww6R0aWUpIGplIHZlxL5taSB2eXNva8O9LCDEjW8gem5hbWVuw6EsIMW+ZSBwb8SNdHkgw7ptcnTDrSBzYSB2IHByaWViZWh1IHBhbmTDqW1pZSB6bmHEjW5lIG1lbmlsaS4K4oCTIE1lZGnDoW4gKMSNaWVybmEgxI1pYXJhIHZvIHZuw7p0cmkgYm94dSkgamUgbmlla2RlIG9rb2xvIDc1IDAwMCwgYWxlIGhvZG5vdHkgc2lhaGFqw7ogYcW+IG5hZCAxMDAgMDAwLgoKKirEjGVza28qKiBhICoqTWHEj2Fyc2tvKioK4oCTIG1hasO6IHN0cmVkbmUgdnlzb2vDqSBwb8SNdHkgw7ptcnTDrSAob2tvbG8gMzAgMDAw4oCTNDAgMDAwKS4K4oCTIE1lZGnDoW4gamUgdnnFocWhw60gdiBNYcSPYXJza3UsIHJvenB0eWwgamUgcG9yb3ZuYXRlxL5uw70uCgoqKlNsb3ZlbnNrbyoqCuKAkyBtw6EgamVkbm96bmHEjW5lIG5ham5pxb7FocOtIHBvxI1ldCDDum1ydMOtIChva29sbyAyMCAwMDApLgrigJMgQm94IGplIG1lbsWhw60g4oaSIHJvenB0eWwgamUgdcW+xaHDrSwgcHJpZWJlaCBwYW5kw6ltaWUgdiDDum1ydGlhY2ggYm9sIHJlbGF0w612bmUg4oCea29tcGFrdG5lasWhw63igJwuCgojIMWgdGF0aXN0aWt5CgojIyBaw6FrbGFkbsOpIMWhdGF0aXN0aWt5CgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKc3RhdHMgPC0gY292aWQgJT4lCmdyb3VwX2J5KGNvdW50cnkpICU+JQpzdW1tYXJpc2UoCm1lYW5fY2FzZXMgPSBtZWFuKGNhc2VzLCBuYS5ybT1UUlVFKSwKbWVkaWFuX2Nhc2VzID0gbWVkaWFuKGNhc2VzLCBuYS5ybT1UUlVFKSwKc2RfY2FzZXMgPSBzZChjYXNlcywgbmEucm09VFJVRSksCm1lYW5fZGVhdGhzID0gbWVhbihkZWF0aHMsIG5hLnJtPVRSVUUpLAptZWRpYW5fZGVhdGhzID0gbWVkaWFuKGRlYXRocywgbmEucm09VFJVRSksCnNkX2RlYXRocyA9IHNkKGRlYXRocywgbmEucm09VFJVRSkKKQoKc3RhdHMgJT4lCmthYmxlKGRpZ2l0cyA9IDIsIGNhcHRpb24gPSAixaB0YXRpc3Rpa3kgQ09WSUQgcHLDrXBhZG92IGEgw7ptcnTDrSBwb2TEvmEga3JhasOtbiIpICU+JQprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpCmBgYAoKKirEjGVza286KioKUHJpZW1lcm7DvSBwb8SNZXQgcHLDrXBhZG92OiB+MSw5NiBtaWxpw7NuYS4KTWVkacOhbiBwcsOtcGFkb3Y6IH4xLDY4IG1pbGnDs25hIOKGkiByb3pkZWxlbmllIGplIHRyb2NodSDigJ7FpWFoYW7DqSBuYWhvcuKAnCBleHRyw6ltbnltaSBob2Rub3RhbWkuClByaWVtZXJuw70gcG/EjWV0IMO6bXJ0w606IH4yMyAzNjcuCk1lZGnDoW4gw7ptcnTDrTogfjMwIDQ5MSDihpIgem5hbWVuw6EsIMW+ZSB2IGRydWhlaiBwb2xvdmljaSBvYmRvYmlhIGJvbGkgw7ptcnRpYSB2ecWhxaFpZS4KUmVsYXTDrXZuZSB2eXNva8OpIMWhdGFuZGFyZG7DqSBvZGNow71sa3kgKHZhcmlhYmlsaXRhIHYgxI1hc2UpLgoKKipNYcSPYXJza286KioKUHJpZW1lcm7DvSBwb8SNZXQgcHLDrXBhZG92OiB+OTA5IHRpc8OtYywgxI1vIGplIG1lbmVqIG5lxb4gdiDEjGVza3UsIGFsZeKApgpQcmllbWVybsO9IHBvxI1ldCDDum1ydMOtOiB+MjQgNTk3IOKGkiBwYXJhZG94bmUgdnnFocWhw60gbmXFviB2IMSMZXNrdSwgaG9jaSBwcsOtcGFkb3YgYm9sbyBtZW5lai4KVG8gbcO0xb5lIG5hem5hxI1vdmHFpSB2ecWhxaFpdSDDum1ydG5vc8WlICh2w6TEjcWhw60gcG9kaWVsIMO6bXJ0w60gbmEgcHLDrXBhZG9jaCkuCgoqKlBvxL5za286KioKTmFqdsOkxI3FocOtIHByaWVtZXJuw70gcG/EjWV0IHByw61wYWRvdjogfjIsOTMgbWlsacOzbmEuCk5hanbDpMSNxaHDrSBwcmllbWVybsO9IHBvxI1ldCDDum1ydMOtOiB+NjEgOTYxIOKGkiBqZWRub3puYcSNbmUgbmFqaG9yxaFpZSBwb3N0aWhudXTDoSBrcmFqaW5hIFY0LgpFeHRyw6ltbmUgdnlzb2vDoSDFoXRhbmRhcmRuw6Egb2RjaMO9bGthIOKGkiBwcmllYmVoIHBhbmTDqW1pZSBib2wgdiBQb8S+c2t1IHZlxL5taSByb3prb2zDrXNhbsO9IChzaWxuw6kgdmxueSkuCgoqKlNsb3ZlbnNrbzoqKgpOYWpuacW+xaHDrSBwcmllbWVybsO9IHBvxI1ldCBwcsOtcGFkb3YgKH43MDcgdGlzw61jKS4KQWogw7ptcnTDrSBtYWxhIG5ham1lbmVqICh+MTAgMzc4KS4KTWVkacOhbiDDum1ydMOtIDEyIDUxMyBuYXpuYcSNdWplLCDFvmUgdiBkcnVoZWogcG9sb3ZpY2kgcGFuZMOpbWllIGJvbCBwb8SNZXQgw7ptcnTDrSB1xb4gdnnFocWhw60gbmXFviBuYSB6YcSNaWF0a3UuClZhcmlhYmlsaXRhIChzZCkgamUgbWVuxaFpYSBuZcW+IHUgb3N0YXRuw71jaCwgxI1vIHpvZHBvdmVkw6EgbWVuxaFlaiBrcmFqaW5lLgoKIyMgS29yZWxhxI1uw6EgYW5hbMO9emEgYSBoZWF0bWFwYQoKYGBge3J9CmxpYnJhcnkoY29ycnBsb3QpCm51bV9kYXRhIDwtIGNvdmlkICU+JQpzZWxlY3QocG9wdWxhdGlvbiwgY2FzZXMsIGRlYXRocykgJT4lCm5hLm9taXQoKQoKY29yX21hdHJpeCA8LWNvcihudW1fZGF0YSkKY29ycnBsb3QoY29yX21hdHJpeCwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsCnRsLmNvbCA9ICJibGFjayIsIHRsLnNydCA9IDQ1LCBhZGRDb2VmLmNvbCA9ICJibGFjayIpCmBgYAoKKihQb3puLiBQcmkgcG9zbGVkbmVqIMO6cHJhdmUgYSBmdW5rY2lpIFJVTiBBTEwgKGN0cmwrYWx0K1IpIHNhIG1pIG5lamFrw71tIG5lZG9wYXRyZW7DrW0gc3RhbG8sIMW+ZSBtaSBuZWpkZSB6b2JyYXppxaUga29yZWxhxI1uw6EgYW5hbMO9emEsIHogZMO0dm9kdSwgxb5lIHNvbSB1xb4gc3RyYXRpbCBuZXJ2eSBhIGplIHZlxL5hIGhvZMOtbiBhIG5lY2hjZSBzYSBtaSB0dSBuYWQgdMO9bSB1xb4gc2VkaWXFpSBwcmlrbGFkw6FtIGliYSBzY3JlZW5zaG90LCBrdG9yw70gc29tIG9kZm90aWwgZcWhdGUgcHJlZHTDvW0sIGFrbyBzYSB0byBwb2themlsby4pKgoKIVtLb3JlbMOhY2lhIGXFoXRlIGtlxI8gdG8gZnVuZ292YWxvXShLb3JlbMOhY2lpYS5wbmcpCgoqSW50ZXJwcmV0w6FjaWEgaG9kbsO0dCBrb3JlbMOhY2llOioKCioqQ2FzZXMqKiDigJMgKipEZWF0aHMqKjogMC45Mgp2ZcS+bWkgc2lsbsOhIHBveml0w612bmEga29yZWzDoWNpYTogxI3DrW0gdmlhYyBwcsOtcGFkb3YsIHTDvW0gdmlhYyDDum1ydMOtLgpUbyBqZSBvxI1ha8OhdmFuw6ksIHByZXRvxb5lIMO6bXJ0aWEgc8O6IHByaWFtbyBkw7RzbGVka29tIGluZmVrY2nDrS4KCioqUG9wdWxhdGlvbioqIOKAkyAqKkRlYXRocyoqOiAwLjU4CnN0cmVkbmUgc2lsbsOhIHBveml0w612bmEga29yZWzDoWNpYTogdsOkxI3FoWllIGtyYWppbnkgbWFqw7ogdm8gdsWhZW9iZWNub3N0aSB2aWFjIMO6bXJ0w60uClRvIGplIGxvZ2lja8OpLCBrZcSPxb5lIHByaSB2w6TEjcWhZWogcG9wdWzDoWNpaSBqZSB2ecWhxaHDrSBhYnNvbMO6dG55IHBvxI1ldCBvYnl2YXRlxL5vdiB2eXN0YXZlbsO9IHJpemlrdS4KCioqUG9wdWxhdGlvbioqIOKAkyAqKkNhc2VzKio6IDAuNDQKc2xhYsWhaWEgYcW+IHN0cmVkbsOhIGtvcmVsw6FjaWE6IHbDpMSNxaFpZSBrcmFqaW55IG1hasO6IHRlbmRlbmNpdSBtYcWlIHZpYWMgcHLDrXBhZG92LCBhbGUgdnrFpWFoIG5pZSBqZSB0YWvDvSBzaWxuw70sIGFrbyBtZWR6aSBwcsOtcGFkbWkgYSDDum1ydGlhbWkuClRvIG3DtMW+ZSBiecWlIG92cGx5dm5lbsOpIHJvemRpZWxtaSB2IHRlc3RvdmFuw60sIG9wYXRyZW5pYWNoIGFsZWJvIMWhdGF0aXN0aWNrb20gdnlrYXpvdmFuw60uCgojIyBUZXN0b3ZhbmllIGh5cG90w6l6CgpgYGB7cn0KdC50ZXN0KApjb3ZpZCRkZWF0aHNbY292aWQkY291bnRyeSA9PSAiU2xvdmFraWEiXSwKY292aWQkZGVhdGhzW2NvdmlkJGNvdW50cnkgPT0gIkN6ZWNoaWEiXQopCmBgYAoKViBwcmllbWVyZSBtYWxvIMSMZXNrbyBwb8SNYXMgc2xlZG92YW7DqWhvIG9iZG9iaWEgbyBwcmlibGnFvm5lIDEzMDAwIMO6bXJ0w60gdmlhYyBha28gU2xvdmVuc2tvLgpSb3pkaWVsIGplIHZlxL5rw70gYWogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70uCk5hIHrDoWtsYWRlIGTDoXQgbcO0xb5lbWUgcyB2eXNva291IGlzdG90b3UgcG92ZWRhxaUsIMW+ZSDDum1ydG5vc8WlIHYgxIxlc2t1IGJvbGEgZGxob2RvYm8gdnnFocWhaWEgbmXFviBuYSBTbG92ZW5za3UuCgoKIyMgQW5vdmEKYGBge3J9CmFub3ZhX3Jlc3VsdCA8LSBhb3YoY2FzZXMgfiBjb3VudHJ5LCBkYXRhID0gY292aWQpCnN1bW1hcnkoYW5vdmFfcmVzdWx0KQpgYGAKClbDvXNsZWRvayB6bmFtZW7DoSwgxb5lIHJvemRpZWx5IG1lZHppaSBrcmFqaW5hbWkgc8O6IMWhdGF0aXN0aWNreSB2w716bmFtbsOpIC0gcHJpZW1lcm7DvSBwb8SNZXQgcHLDrXBhZG92IENPVklEIHNhIG5lZMOhIHZ5c3ZldGxpxaUgbGVuIG7DoWhvZG91LgpIdmllemRpxI1reSBwcmkgcC1ob2Rub3RlIG5hem5hxI11asO6IHZlxL5taSBzaWxuw7ogxaF0YXRpc3RpY2vDuiB2w716bmFtbm9zxaUgKHA8MCwwMDEpLgoKIyMgTGluZcOhcm5hIHJlZ3Jlc2lhCgpgYGB7cn0KbW9kZWwgPC0gbG0oZGVhdGhzIH4gY2FzZXMgKyBwb3B1bGF0aW9uLCBkYXRhID0gY292aWQpCnN1bW1hcnkobW9kZWwpCmBgYAoKTGluZcOhcm55IHJlZ3Jlc27DvSBtb2RlbCB1a2F6dWplLCDFvmUgcG/EjWV0IHByw61wYWRvdiBDT1ZJRCBqZSBzaWxuZSBzcG9qZW7DvSBzIHBvxI10b20gw7ptcnTDrSAocCA8IDAuMDAxKS4gS2HFvmTDvWNoIDEwMDAgcHLDrXBhZG92IHByaW7DocWhYSB2IHByaWVtZXJlIHByaWJsacW+bmUgMTUgw7ptcnTDrS4gUG9wdWzDoWNpYSBrcmFqaW55IG3DoSB0aWXFviDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBlZmVrdCDigJMgdsOkxI3FoWllIGtyYWppbnkgZXZpZHVqw7ogdmlhYyDDum1ydMOtIGFqIHBvIHpvaMS+YWRuZW7DrSBwb8SNdHUgcHLDrXBhZG92LiBDZWxrb3bDoSB2eXN2ZXTEvm92YWNpYSBzY2hvcG5vc8WlIG1vZGVsdSBqZSB2eXNva8OhIChSwrIgPSAwLjg3NiksIMSNbyB6bmFtZW7DoSwgxb5lIG1vZGVsIHphY2h5dMOhdmEgdsOkxI3FoWludSB2YXJpYWJpbGl0eSB2IHBvxI10ZSDDum1ydMOtLgoKIyMgUHJlaMS+YWQga29lZmljaWVudG92CgpgYGB7cn0KbGlicmFyeShicm9vbSkKY29lZl90YmwgPC0gYnJvb206OnRpZHkobW9kZWwsIGNvbmYuaW50ID0gVFJVRSkgJT4lCm11dGF0ZSgKdGVybSA9IGRwbHlyOjpyZWNvZGUodGVybSwKIihJbnRlcmNlcHQpIiA9ICJJbnRlcmNlcHQiLAoiQ2FzZXMiID0gIkNhc2VzIChwb8SNZXQgcHLDrXBhZG92KSIsCiJQb3B1bGF0aW9uIiA9ICJQb3B1bGF0aW9uIChvYnl2YXRlbGlhKSIKKSwKc3RhcnMgPSBkcGx5cjo6Y2FzZV93aGVuKApwLnZhbHVlIDwgMC4wMDEgfiAiIiwKcC52YWx1ZSA8IDAuMDEgfiAiIiwKcC52YWx1ZSA8IDAuMDUgfiAiIiwKcC52YWx1ZSA8IDAuMSB+ICLCtyIsClRSVUUgfiAiIgopCikgJT4lCnRyYW5zbXV0ZSgKVGVybSA9IHRlcm0sCkVzdGltYXRlID0gZXN0aW1hdGUsCmBTdGQuIEVycm9yYCA9IHN0ZC5lcnJvciwKYHQgdmFsdWVgID0gc3RhdGlzdGljLApgcCB2YWx1ZWAgPSBwLnZhbHVlLApgOTUlIENJYCA9IHN0cmluZ3I6OnN0cl9jKCJbIiwgcm91bmQoY29uZi5sb3csIDMpLCAiLCAiLCByb3VuZChjb25mLmhpZ2gsIDMpLCAiXSIpLApTaWcgPSBzdGFycwopCgpjb2VmX3RibCAlPiUKa2FibGUoZGlnaXRzID0gMywKY2FwdGlvbiA9ICJPTFMga29lZmljaWVudHk6IERlYXRocyB+IENhc2VzICsgUG9wdWxhdGlvbiIpICU+JQprYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBGQUxTRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwiaG92ZXIiLCJjb25kZW5zZWQiKSkgJT4lCmNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUUlVFKSAlPiUKcm93X3NwZWMoMCwgYm9sZCA9IFRSVUUsIGJhY2tncm91bmQgPSAiI2YyZjJmMiIpICU+JQpmb290bm90ZShnZW5lcmFsID0gIlNpZ25pZi4ga8OzZHk6ICoqKiBwPDAuMDAxLCAqKiBwPDAuMDEsICogcDwwLjA1LCDCtyBwPDAuMS4iLCB0aHJlZXBhcnR0YWJsZSA9IFRSVUUpCgoKZml0LnRibCA8LSBnbGFuY2UobW9kZWwpICU+JQogIHRyYW5zbXV0ZSgKYFItc3F1YXJlZGAgPSByLnNxdWFyZWQsCmBBZGouIFItc3F1YXJlZGAgPSBhZGouci5zcXVhcmVkLApgRi1zdGF0aXN0aWNgID0gc3RhdGlzdGljLApgRiBwLXZhbHVlYCA9IHAudmFsdWUsCmBBSUNgID0gQUlDLApgQklDYCA9IEJJQywKYE51bS4gb2JzLmAgPSBub2JzCikKCmNvZWZfdGJsICU+JQprYWJsZShkaWdpdHMgPSAzLCBjYXB0aW9uID0gIk1vZGVsIOKAkyBtZXRyaWt5IHpob2R5IikgJT4lCmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFLCBib290c3RyYXBfb3B0aW9ucyA9IGMoImNvbmRlbnNlZCIpKQpgYGAKCipJbnRlcnByZXTDoWNpYSBrb2VmaWNpZW50b3Y6KgoKKipJbnRlcmNlcHQqKiA9IC0yOTk0LjMK4oCTIG1hdGVtYXRpY2vDoSBrb27FoXRhbnRhIG1vZGVsdS4gSG92b3LDrSwgxb5lIGFrIGJ5IGJvbG8gcHLDrXBhZG92IGFqIHBvcHVsw6FjaWEgbnVsb3bDoSwgcHJlZGlrb3ZhbsO9IHBvxI1ldCDDum1ydMOtIGJ5IGJvbCB6w6Fwb3Juw70gKH4gLTI5OTQpLiBUbyBzYW1venJlam1lIG5lZMOhdmEgcmXDoWxueSB2w716bmFtLCBhbGUgaW50ZXJjZXB0IGplIHBvdHJlYm7DvSBuYSB2eXJvdm5hbmllIHByaWFta3kuCgoqKkNhc2VzKiogKDAuMDE1KQrigJMga29lZmljaWVudCBqZSBrbGFkbsO9IGEgxaF0YXRpc3RpY2t5IHZ5c29rbyB2w716bmFtbsO9IChwIDwgMC4wMDEpLgrigJMgWm5hbWVuw6EsIMW+ZSBwcmkgbsOhcmFzdGUgcG/EjXR1IHByw61wYWRvdiBvIDEgamVkbm90a3Ugc2EgcG/EjWV0IMO6bXJ0w60genbDvcWhaSB2IHByaWVtZXJlIG8gMC4wMTUuCuKAkyBQcmFrdGlja3k6IG5hIDEwMDAgcHLDrXBhZG92IHByaXBhZMOhIGFzaSAxNSDDum1ydMOtLgoKKipQb3B1bGF0aW9uKiogKDAuMDAxKQrigJMgdGllxb4ga2xhZG7DvSBhIHZ5c29rbyB2w716bmFtbsO9IChwIDwgMC4wMDEpLgrigJMgWm5hbWVuw6EsIMW+ZSBwcmkgenbDvcWhZW7DrSBwb3B1bMOhY2llIG8gMSBqZWRub3RrdSAoMSBvYnl2YXRlxL5hKSBzYSBwcmVkcG9rbGFkw6EgbsOhcmFzdCDDum1ydMOtIG8gMC4wMDEuCuKAkyBUZWRhIHByaSAxIG1pbGnDs25lIG9ieXZhdGXEvm92IHNhIG/EjWFrw6F2YSB2IHByaWVtZXJlIHByaWJsacW+bmUgMTAwMCDDum1ydMOtIG5hdnnFoWUgKHByaSByb3ZuYWtvbSBwb8SNdGUgcHLDrXBhZG92KS4=