Analýza makroekonomických ukazovateľov
Úvod do problému, stanovenie hypotéz
Rozhodla som sa modelovať hodnotu akciového indexu (Stock Index
Value) v závislosti od makroekonomických premenných: inflácie (Inflation
Rate (%)), rastu HDP (GDP Growth Rate (%)), nezamestnanosti
(Unemployment Rate (%)), a úrokovej sadzby (Interest Rate (%)).
Pracovná hypotéza predpokladá:
Inflation Rate (%) – negatívny vplyv na akciový index.
GDP Growth Rate (%) – pozitívny vplyv.
Unemployment Rate (%) – negatívny vplyv.
Interest Rate (%) – negatívny vplyv.
Cieľom analýzy je overiť, ktoré premenné štatisticky významne
ovplyvňujú Stock Index Value a posúdiť vhodnosť lineárneho regresného
modelu.
Načítanie knižníc
library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
library(carData)
library(cowplot)
library(ggplot2)
rm(list=ls())
Načitanie dát
data <- read.csv("economic_indicators_dataset_2010_2023.csv")
Výber premennych
macro <- data[, c("Inflation.Rate....",
"GDP.Growth.Rate....",
"Unemployment.Rate....",
"Interest.Rate....",
"Stock.Index.Value")]
summary(macro)
Inflation.Rate.... GDP.Growth.Rate.... Unemployment.Rate.... Interest.Rate.... Stock.Index.Value
Min. :0.000 Min. :-5.000 Min. : 2.000 Min. :-0.980 Min. : 1017
1st Qu.:2.525 1st Qu.:-1.170 1st Qu.: 4.258 1st Qu.: 2.027 1st Qu.:11588
Median :5.205 Median : 2.580 Median : 6.865 Median : 4.975 Median :20996
Mean :5.085 Mean : 2.415 Mean : 6.907 Mean : 4.698 Mean :20926
3rd Qu.:7.710 3rd Qu.: 5.445 3rd Qu.: 9.502 3rd Qu.: 7.353 3rd Qu.:30825
Max. :9.990 Max. : 9.930 Max. :11.970 Max. :10.000 Max. :39982
Imputácia mediánov
column_medians <- sapply(macro, median, na.rm = TRUE)
macro_imp <- macro
for (col in names(macro)) {
macro_imp[[col]][is.na(macro_imp[[col]])] <- column_medians[col]
}
macro <- macro_imp
Boxploty
num_plots <- length(names(macro))
par(mfrow = c(2, 3))
par(mar = c(4, 4, 2, 1))
for (col in names(macro)) {
boxplot(macro[[col]], main = col, xlab = "Hodnota", col = "lightblue")
}
mtext("Boxploty makroekonomických premenných", outer = TRUE, cex = 1.4, font = 2)

Teraz sme:
Skontrolovali štruktúru dát.
Vybrali relevantné premenné.
Doplnili chýbajúce hodnoty mediánmi.
Vykreslili boxploty pre jednotlivé premenné, aby sme
identifikovali potenciálne odľahlé hodnoty.
Pozorovania ukázali, že väčšina dát je v očakávanom rozsahu. Inflácia
a úroková sadzba majú mierne rozšírené rozptýlenie, ale nie je
extrémne.
Lineárna regresia – model 1
model <- lm(Stock.Index.Value ~ Inflation.Rate.... +
GDP.Growth.Rate.... +
Unemployment.Rate.... +
Interest.Rate....,
data = macro)
summary(model)
Call:
lm(formula = Stock.Index.Value ~ Inflation.Rate.... + GDP.Growth.Rate.... +
Unemployment.Rate.... + Interest.Rate...., data = macro)
Residuals:
Min 1Q Median 3Q Max
-20623.1 -9434.3 104.2 9972.6 19610.5
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 23055.78 1678.73 13.734 <2e-16 ***
Inflation.Rate.... -37.23 167.90 -0.222 0.825
GDP.Growth.Rate.... -26.39 121.94 -0.216 0.829
Unemployment.Rate.... -152.38 166.52 -0.915 0.361
Interest.Rate.... -175.40 157.57 -1.113 0.266
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 11090 on 495 degrees of freedom
Multiple R-squared: 0.00455, Adjusted R-squared: -0.003494
F-statistic: 0.5656 on 4 and 495 DF, p-value: 0.6877
Lineárny model odhadovaný pre Stock Index Value na základe premenných
Inflation Rate, GDP Growth Rate, Unemployment Rate a Interest Rate
ukazuje, že žiadna z vysvetľujúcich premenných nie je štatisticky
významná. Intercept je vysoko významný, ale všetky koeficienty ostatných
premenných majú p-hodnoty výrazne vyššie ako 0,05. Hodnota R-squared je
extrémne nízka (0,00455), čo naznačuje, že model nevysvetľuje
variabilitu Stock Index Value.
Reziduá modelu sa pohybujú približne medzi −20623 a +19610 a ich
medián je veľmi blízko nule, čo naznačuje stredné centrovanie
reziduí.
Diagnostické grafy pre model 1
par(mfrow = c(2, 2))
plot(model)
mtext("Diagnostické grafy regresného modelu", outer = TRUE, cex = 1.2, font = 2)

Residuals vs Fitted
- Väčšina reziduí je rozptýlená okolo nuly bez výrazného
systematického skreslenia, aj keď vidíme niektoré extrémne body.
Q-Q plot
- Reziduá sú približne normálne rozložené, hoci na okrajoch grafu
možno pozorovať mierne odchýlky – niekoľko extrémnych hodnôt.
Scale-Location
- Variancia reziduí je relatívne stabilná; nie sú výrazné známky
heteroskedasticity.
Residuals vs Leverage
- Väčšina bodov má nízku páku a štandardizované reziduá sa pohybujú
medzi −2 a +2. Žiadne pozorovanie nevybočuje výrazne z Cookovej
vzdialenosti.
Jarque–Bera test normality
residuals_model <- residuals(model)
jb_test <- jarque.bera.test(residuals_model)
jb_test
Jarque Bera Test
data: residuals_model
X-squared = 26.622, df = 2, p-value = 1.656e-06
Hodnota testu JB = 26,622 s p-hodnotou 1,656e-06 naznačuje, že
reziduá nie sú úplne normálne rozložené. Odchýlky môžu byť spôsobené
extrémnymi hodnotami alebo špičatými rozdeleniami.
Outlier test
outlier_test <- outlierTest(model)
outlier_test
No Studentized residuals with Bonferroni p < 0.05
Largest |rstudent|:
Jedno pozorovanie bolo označené ako potenciálny odľahlý bod (rstudent
= −1,8766), ale p-hodnota po Bonferroni korekcii nie je k dispozícii.
Tento bod môže mierne ovplyvniť odhad koeficientov.
Heteroskedasticita – grafy pre model 1
p1 <- ggplot(macro, aes(x = GDP.Growth.Rate...., y = resid(model)^2)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "GDP Growth (%)",
y = "Reziduá²",
title = "Reziduá² vs GDP Growth") +
theme_minimal()
p2 <- ggplot(macro, aes(x = Inflation.Rate...., y = resid(model)^2)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Inflation Rate (%)",
y = "Reziduá²",
title = "Reziduá² vs Inflation") +
theme_minimal()
plot_grid(p1, p2)

Na grafoch “Reziduá vs GDP Growth” a “Reziduá vs Inflation” môžeme
pozorovať, že ružová vyhladená krivka zostáva relatívne plochá a rozptyl
reziduí sa s hodnotami premenných výrazne nemení. Menšie kolísanie
naznačuje len slabé náznaky heteroskedasticity, ktoré však nie sú
výrazné. Celkovo možno teda usúdiť, že v modeli sa heteroskedasticita
výrazne nevyskytuje a rozptyl náhodnej zložky zostáva približne
konštantný.
Oprava modelu (model 2) + vylúčenie problem
shift <- abs(min(macro$GDP.Growth.Rate...., na.rm = TRUE)) + 0.01
model2 <- lm(Stock.Index.Value ~
I(log(GDP.Growth.Rate.... + shift)) +
Unemployment.Rate.... +
Interest.Rate....,
data = macro)
summary(model2)
Call:
lm(formula = Stock.Index.Value ~ I(log(GDP.Growth.Rate.... +
shift)) + Unemployment.Rate.... + Interest.Rate...., data = macro)
Residuals:
Min 1Q Median 3Q Max
-20968.9 -9345.4 -62.7 9908.4 19840.0
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 23669.9 1683.6 14.059 <2e-16 ***
I(log(GDP.Growth.Rate.... + shift)) -517.9 533.4 -0.971 0.332
Unemployment.Rate.... -148.3 166.2 -0.892 0.373
Interest.Rate.... -174.3 157.2 -1.109 0.268
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 11060 on 496 degrees of freedom
Multiple R-squared: 0.006244, Adjusted R-squared: 0.0002336
F-statistic: 1.039 on 3 and 496 DF, p-value: 0.375
Po logaritmickej transformácii GDP Growth Rate a odstránení Inflation
Rate model ukazuje podobný obraz: žiadna z premenných (okrem interceptu)
nie je štatisticky významná. Koeficienty sú stále nízke a p-hodnoty
vyššie než 0,05. R-squared je veľmi nízke (0,0062), čo znamená, že model
stále nevysvetľuje variabilitu Stock Index Value.
Reziduá sú podobne rozptýlené a medián je blízko nuly.
Diagnostické grafy pre model 2
par(mfrow = c(2, 2))
plot(model2)
mtext("Diagnostické grafy - Model 2 (log GDP)", outer = TRUE, cex = 1.2, font = 2)

Residuals vs Fitted
- Podobne ako pri model 1, reziduá sú rozptýlené okolo nuly, bez
výrazných systematických odchýlok.
Q-Q plot
- Reziduá sú približne normálne rozložené, mierne odchýlky na
okrajoch.
Scale-Location
- Variancia reziduí je stabilná, nenaznačuje heteroskedasticitu.
Residuals vs Leverage
- Väčšina bodov má nízku páku, žiadne výrazne ovplyvňujúce
pozorovanie.
Heteroskedasticita – grafy pre model 2
p3 <- ggplot(macro, aes(x = log(GDP.Growth.Rate.... + 1), y = resid(model2)^2)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "log(GDP Growth)",
y = "Reziduá²",
title = "Reziduá² vs log(GDP Growth)") +
theme_minimal()
p4 <- ggplot(macro, aes(x = Unemployment.Rate...., y = resid(model2)^2)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Unemployment Rate (%)",
y = "Reziduá²",
title = "Reziduá² vs Unemployment") +
theme_minimal()
plot_grid(p3, p4)

Po logaritmickej transformácii premennej GDP Growth sa ružová krivka
vyrovnala a rozptyl reziduí sa stal rovnomernejším, čo naznačuje, že
transformácia znížila heteroskedasticitu. Premenná Unemployment Rate
nevykazuje viditeľné známky heteroskedasticity, takže celkovo možno
povedať, že nový model má stabilnejší rozptyl reziduí a lepšiu štruktúru
ako pôvodný.
Breusch-Pagan test pre model 1 aj model 2
studentized Breusch-Pagan test
data: model
BP = 2.9462, df = 4, p-value = 0.5669
studentized Breusch-Pagan test
data: model2
BP = 2.3352, df = 3, p-value = 0.5058
- Pre model 1: BP = 2,9462, p = 0,5669
- Pre model 2: BP = 2,3352, p = 0,5058
Výsledky Breusch–Paganovho testu pre model 1 (p = 0.5669) aj model 2
(p = 0.5058) naznačujú, že nemáme dostatok dôkazov na zamietnutie
nulovej hypotézy homoskedasticity. Rozptyl rezíduí sa javí ako približne
konštantný a nevykazuje systematickú závislosť od vysvetľujúcich
premenných.
Z toho možno konštatovať, že reziduá oboch modelov spĺňajú predpoklad
homoskedasticity, čo indikuje, že odhady regresných koeficientov sú
efektívne a nie je potrebné aplikovať korekcie na
heteroskedasticitu.
LS0tDQp0aXRsZTogIsOabG9oYV82Ig0KYXV0aG9yOiAiWXVsaWlhIEx5c3l0c2lhIg0KZGF0ZTogIk5vdmVtYmVyIDIwMjUiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdGhlbWU6IHVuaXRlZA0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KZWRpdG9yX29wdGlvbnM6DQogIG1hcmtkb3duOg0KICAgIHdyYXA6IDcyDQotLS0NCg0KIyBBbmFsw716YSBtYWtyb2Vrb25vbWlja8O9Y2ggdWthem92YXRlxL5vdg0KDQojIyDDmnZvZCBkbyBwcm9ibMOpbXUsIHN0YW5vdmVuaWUgaHlwb3TDqXoNCg0KUm96aG9kbGEgc29tIHNhIG1vZGVsb3ZhxaUgaG9kbm90dSBha2Npb3bDqWhvIGluZGV4dSAoU3RvY2sgSW5kZXggVmFsdWUpIHYgesOhdmlzbG9zdGkgb2QgbWFrcm9la29ub21pY2vDvWNoIHByZW1lbm7DvWNoOiBpbmZsw6FjaWUgKEluZmxhdGlvbiBSYXRlICglKSksIHJhc3R1IEhEUCAoR0RQIEdyb3d0aCBSYXRlICglKSksIG5lemFtZXN0bmFub3N0aSAoVW5lbXBsb3ltZW50IFJhdGUgKCUpKSwgYSDDunJva292ZWogc2FkemJ5IChJbnRlcmVzdCBSYXRlICglKSkuDQoNClByYWNvdm7DoSBoeXBvdMOpemEgcHJlZHBva2xhZMOhOg0KDQotIEluZmxhdGlvbiBSYXRlICglKSDigJMgbmVnYXTDrXZueSB2cGx5diBuYSBha2Npb3bDvSBpbmRleC4NCg0KLSBHRFAgR3Jvd3RoIFJhdGUgKCUpIOKAkyBwb3ppdMOtdm55IHZwbHl2Lg0KDQotIFVuZW1wbG95bWVudCBSYXRlICglKSDigJMgbmVnYXTDrXZueSB2cGx5di4NCg0KLSBJbnRlcmVzdCBSYXRlICglKSDigJMgbmVnYXTDrXZueSB2cGx5di4NCg0KQ2llxL5vbSBhbmFsw716eSBqZSBvdmVyacWlLCBrdG9yw6kgcHJlbWVubsOpIMWhdGF0aXN0aWNreSB2w716bmFtbmUgb3ZwbHl2xYh1asO6IFN0b2NrIEluZGV4IFZhbHVlIGEgcG9zw7pkacWlIHZob2Rub3PFpSBsaW5lw6FybmVobyByZWdyZXNuw6lobyBtb2RlbHUuDQoNCiMjIE5hxI3DrXRhbmllIGtuacW+bsOtYw0KDQpgYGB7cn0NCmxpYnJhcnkoem9vKQ0KbGlicmFyeSh0c2VyaWVzKQ0KbGlicmFyeShsbXRlc3QpDQpsaWJyYXJ5KHNhbmR3aWNoKQ0KbGlicmFyeShjYXIpDQpsaWJyYXJ5KGNhckRhdGEpDQpsaWJyYXJ5KGNvd3Bsb3QpDQpsaWJyYXJ5KGdncGxvdDIpDQpybShsaXN0PWxzKCkpDQpgYGANCg0KIyMgTmHEjWl0YW5pZSBkw6F0DQoNCmBgYHtyfQ0KZGF0YSA8LSByZWFkLmNzdigiZWNvbm9taWNfaW5kaWNhdG9yc19kYXRhc2V0XzIwMTBfMjAyMy5jc3YiKQ0KYGBgDQoNCiMjIFbDvWJlciBwcmVtZW5ueWNoDQoNCmBgYHtyfQ0KbWFjcm8gPC0gZGF0YVssIGMoIkluZmxhdGlvbi5SYXRlLi4uLiIsDQogICAgICAgICAgICAgICAgICAiR0RQLkdyb3d0aC5SYXRlLi4uLiIsDQogICAgICAgICAgICAgICAgICAiVW5lbXBsb3ltZW50LlJhdGUuLi4uIiwNCiAgICAgICAgICAgICAgICAgICJJbnRlcmVzdC5SYXRlLi4uLiIsDQogICAgICAgICAgICAgICAgICAiU3RvY2suSW5kZXguVmFsdWUiKV0NCg0Kc3VtbWFyeShtYWNybykNCmBgYA0KDQojIyBJbXB1dMOhY2lhIG1lZGnDoW5vdg0KDQpgYGB7cn0NCmNvbHVtbl9tZWRpYW5zIDwtIHNhcHBseShtYWNybywgbWVkaWFuLCBuYS5ybSA9IFRSVUUpDQoNCm1hY3JvX2ltcCA8LSBtYWNybw0KZm9yIChjb2wgaW4gbmFtZXMobWFjcm8pKSB7DQogIG1hY3JvX2ltcFtbY29sXV1baXMubmEobWFjcm9faW1wW1tjb2xdXSldIDwtIGNvbHVtbl9tZWRpYW5zW2NvbF0NCn0NCg0KbWFjcm8gPC0gbWFjcm9faW1wDQpgYGANCg0KIyMgQm94cGxvdHkNCg0KYGBge3J9DQpudW1fcGxvdHMgPC0gbGVuZ3RoKG5hbWVzKG1hY3JvKSkNCnBhcihtZnJvdyA9IGMoMiwgMykpDQpwYXIobWFyID0gYyg0LCA0LCAyLCAxKSkNCg0KZm9yIChjb2wgaW4gbmFtZXMobWFjcm8pKSB7DQogIGJveHBsb3QobWFjcm9bW2NvbF1dLCBtYWluID0gY29sLCB4bGFiID0gIkhvZG5vdGEiLCBjb2wgPSAibGlnaHRibHVlIikNCn0NCg0KbXRleHQoIkJveHBsb3R5IG1ha3JvZWtvbm9taWNrw71jaCBwcmVtZW5uw71jaCIsIG91dGVyID0gVFJVRSwgY2V4ID0gMS40LCBmb250ID0gMikNCnBhcihtZnJvdyA9IGMoMSwgMSkpDQpgYGANClRlcmF6IHNtZToNCg0KLSBTa29udHJvbG92YWxpIMWhdHJ1a3TDunJ1IGTDoXQuDQoNCi0gVnlicmFsaSByZWxldmFudG7DqSBwcmVtZW5uw6kuDQoNCi0gRG9wbG5pbGkgY2jDvWJhasO6Y2UgaG9kbm90eSBtZWRpw6FubWkuDQoNCi0gVnlrcmVzbGlsaSBib3hwbG90eSBwcmUgamVkbm90bGl2w6kgcHJlbWVubsOpLCBhYnkgc21lIGlkZW50aWZpa292YWxpIHBvdGVuY2nDoWxuZSBvZMS+YWhsw6kgaG9kbm90eS4NCg0KUG96b3JvdmFuaWEgdWvDoXphbGksIMW+ZSB2w6TEjcWhaW5hIGTDoXQgamUgdiBvxI1ha8OhdmFub20gcm96c2FodS4gSW5mbMOhY2lhIGEgw7pyb2tvdsOhIHNhZHpiYSBtYWrDuiBtaWVybmUgcm96xaHDrXJlbsOpIHJvenB0w71sZW5pZSwgYWxlIG5pZSBqZSBleHRyw6ltbmUuDQoNCiMjIExpbmXDoXJuYSByZWdyZXNpYSDigJMgbW9kZWwgMQ0KDQpgYGB7cn0NCm1vZGVsIDwtIGxtKFN0b2NrLkluZGV4LlZhbHVlIH4gSW5mbGF0aW9uLlJhdGUuLi4uICsNCiAgICAgICAgICAgICAgR0RQLkdyb3d0aC5SYXRlLi4uLiArDQogICAgICAgICAgICAgIFVuZW1wbG95bWVudC5SYXRlLi4uLiArDQogICAgICAgICAgICAgIEludGVyZXN0LlJhdGUuLi4uLA0KICAgICAgICAgICAgZGF0YSA9IG1hY3JvKQ0KDQpzdW1tYXJ5KG1vZGVsKQ0KYGBgDQpMaW5lw6FybnkgbW9kZWwgb2RoYWRvdmFuw70gcHJlIFN0b2NrIEluZGV4IFZhbHVlIG5hIHrDoWtsYWRlIHByZW1lbm7DvWNoIEluZmxhdGlvbiBSYXRlLCBHRFAgR3Jvd3RoIFJhdGUsIFVuZW1wbG95bWVudCBSYXRlIGEgSW50ZXJlc3QgUmF0ZSB1a2F6dWplLCDFvmUgxb5pYWRuYSB6IHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2ggbmllIGplIMWhdGF0aXN0aWNreSB2w716bmFtbsOhLiBJbnRlcmNlcHQgamUgdnlzb2tvIHbDvXpuYW1uw70sIGFsZSB2xaFldGt5IGtvZWZpY2llbnR5IG9zdGF0bsO9Y2ggcHJlbWVubsO9Y2ggbWFqw7ogcC1ob2Rub3R5IHbDvXJhem5lIHZ5xaHFoWllIGFrbyAwLDA1LiBIb2Rub3RhIFItc3F1YXJlZCBqZSBleHRyw6ltbmUgbsOtemthICgwLDAwNDU1KSwgxI1vIG5hem5hxI11amUsIMW+ZSBtb2RlbCBuZXZ5c3ZldMS+dWplIHZhcmlhYmlsaXR1IFN0b2NrIEluZGV4IFZhbHVlLg0KDQpSZXppZHXDoSBtb2RlbHUgc2EgcG9oeWJ1asO6IHByaWJsacW+bmUgbWVkemkg4oiSMjA2MjMgYSArMTk2MTAgYSBpY2ggbWVkacOhbiBqZSB2ZcS+bWkgYmzDrXprbyBudWxlLCDEjW8gbmF6bmHEjXVqZSBzdHJlZG7DqSBjZW50cm92YW5pZSByZXppZHXDrS4NCg0KIyMgRGlhZ25vc3RpY2vDqSBncmFmeSBwcmUgbW9kZWwgMQ0KDQpgYGB7cn0NCnBhcihtZnJvdyA9IGMoMiwgMikpDQpwbG90KG1vZGVsKQ0KbXRleHQoIkRpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1Iiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjIsIGZvbnQgPSAyKQ0KcGFyKG1mcm93ID0gYygxLCAxKSkNCmBgYA0KDQojIyMjIFJlc2lkdWFscyB2cyBGaXR0ZWQNCg0KLSBWw6TEjcWhaW5hIHJlemlkdcOtIGplIHJvenB0w71sZW7DoSBva29sbyBudWx5IGJleiB2w71yYXpuw6lobyBzeXN0ZW1hdGlja8OpaG8gc2tyZXNsZW5pYSwgYWoga2XEjyB2aWTDrW1lIG5pZWt0b3LDqSBleHRyw6ltbmUgYm9keS4NCg0KIyMjIyBRLVEgcGxvdCANCg0KLSBSZXppZHXDoSBzw7ogcHJpYmxpxb5uZSBub3Jtw6FsbmUgcm96bG/FvmVuw6ksIGhvY2kgbmEgb2tyYWpvY2ggZ3JhZnUgbW/Fvm5vIHBvem9yb3ZhxaUgbWllcm5lIG9kY2jDvWxreSDigJMgbmlla2/EvmtvIGV4dHLDqW1ueWNoIGhvZG7DtHQuDQoNCiMjIyMgU2NhbGUtTG9jYXRpb24NCg0KLSBWYXJpYW5jaWEgcmV6aWR1w60gamUgcmVsYXTDrXZuZSBzdGFiaWxuw6E7IG5pZSBzw7ogdsO9cmF6bsOpIHpuw6Fta3kgaGV0ZXJvc2tlZGFzdGljaXR5Lg0KDQojIyMjIFJlc2lkdWFscyB2cyBMZXZlcmFnZQ0KDQotIFbDpMSNxaFpbmEgYm9kb3YgbcOhIG7DrXprdSBww6FrdSBhIMWhdGFuZGFyZGl6b3ZhbsOpIHJlemlkdcOhIHNhIHBvaHlidWrDuiBtZWR6aSDiiJIyIGEgKzIuIMW9aWFkbmUgcG96b3JvdmFuaWUgbmV2eWJvxI11amUgdsO9cmF6bmUgeiBDb29rb3ZlaiB2emRpYWxlbm9zdGkuDQoNCiMjIEphcnF1ZeKAk0JlcmEgdGVzdCBub3JtYWxpdHkNCg0KYGBge3J9DQpyZXNpZHVhbHNfbW9kZWwgPC0gcmVzaWR1YWxzKG1vZGVsKQ0KamJfdGVzdCA8LSBqYXJxdWUuYmVyYS50ZXN0KHJlc2lkdWFsc19tb2RlbCkNCmpiX3Rlc3QNCmBgYA0KSG9kbm90YSB0ZXN0dSBKQiA9IDI2LDYyMiBzIHAtaG9kbm90b3UgMSw2NTZlLTA2IG5hem5hxI11amUsIMW+ZSByZXppZHXDoSBuaWUgc8O6IMO6cGxuZSBub3Jtw6FsbmUgcm96bG/FvmVuw6kuIE9kY2jDvWxreSBtw7TFvnUgYnnFpSBzcMO0c29iZW7DqSBleHRyw6ltbnltaSBob2Rub3RhbWkgYWxlYm8gxaFwacSNYXTDvW1pIHJvemRlbGVuaWFtaS4NCg0KIyMgT3V0bGllciB0ZXN0DQoNCmBgYHtyfQ0Kb3V0bGllcl90ZXN0IDwtIG91dGxpZXJUZXN0KG1vZGVsKQ0Kb3V0bGllcl90ZXN0DQpgYGANCg0KSmVkbm8gcG96b3JvdmFuaWUgYm9sbyBvem5hxI1lbsOpIGFrbyBwb3RlbmNpw6Fsbnkgb2TEvmFobMO9IGJvZCAocnN0dWRlbnQgPSDiiJIxLDg3NjYpLCBhbGUgcC1ob2Rub3RhIHBvIEJvbmZlcnJvbmkga29yZWtjaWkgbmllIGplIGsgZGlzcG96w61jaWkuIFRlbnRvIGJvZCBtw7TFvmUgbWllcm5lIG92cGx5dm5pxaUgb2RoYWQga29lZmljaWVudG92Lg0KDQojIyBIZXRlcm9za2VkYXN0aWNpdGEg4oCTIGdyYWZ5IHByZSBtb2RlbCAxDQoNCmBgYHtyfQ0KcDEgPC0gZ2dwbG90KG1hY3JvLCBhZXMoeCA9IEdEUC5Hcm93dGguUmF0ZS4uLi4sIHkgPSByZXNpZChtb2RlbCleMikpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiKSArDQogIGxhYnMoeCA9ICJHRFAgR3Jvd3RoICglKSIsDQogICAgICAgeSA9ICJSZXppZHXDocKyIiwNCiAgICAgICB0aXRsZSA9ICJSZXppZHXDocKyIHZzIEdEUCBHcm93dGgiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpwMiA8LSBnZ3Bsb3QobWFjcm8sIGFlcyh4ID0gSW5mbGF0aW9uLlJhdGUuLi4uLCB5ID0gcmVzaWQobW9kZWwpXjIpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKw0KICBsYWJzKHggPSAiSW5mbGF0aW9uIFJhdGUgKCUpIiwNCiAgICAgICB5ID0gIlJlemlkdcOhwrIiLA0KICAgICAgIHRpdGxlID0gIlJlemlkdcOhwrIgdnMgSW5mbGF0aW9uIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KcGxvdF9ncmlkKHAxLCBwMikNCmBgYA0KTmEgZ3JhZm9jaCAiUmV6aWR1w6EgdnMgR0RQIEdyb3d0aCIgYSAiUmV6aWR1w6EgdnMgSW5mbGF0aW9uIiBtw7TFvmVtZSBwb3pvcm92YcWlLCDFvmUgcnXFvm92w6EgdnlobGFkZW7DoSBrcml2a2Egem9zdMOhdmEgcmVsYXTDrXZuZSBwbG9jaMOhIGEgcm96cHR5bCByZXppZHXDrSBzYSBzIGhvZG5vdGFtaSBwcmVtZW5uw71jaCB2w71yYXpuZSBuZW1lbsOtLiBNZW7FoWllIGtvbMOtc2FuaWUgbmF6bmHEjXVqZSBsZW4gc2xhYsOpIG7DoXpuYWt5IGhldGVyb3NrZWRhc3RpY2l0eSwga3RvcsOpIHbFoWFrIG5pZSBzw7ogdsO9cmF6bsOpLiBDZWxrb3ZvIG1vxb5ubyB0ZWRhIHVzw7pkacWlLCDFvmUgdiBtb2RlbGkgc2EgaGV0ZXJvc2tlZGFzdGljaXRhIHbDvXJhem5lIG5ldnlza3l0dWplIGEgcm96cHR5bCBuw6Fob2RuZWogemxvxb5reSB6b3N0w6F2YSBwcmlibGnFvm5lIGtvbsWhdGFudG7DvS4NCg0KIyMgT3ByYXZhIG1vZGVsdSAobW9kZWwgMikgKyB2eWzDusSNZW5pZSBwcm9ibGVtDQoNCmBgYHtyfQ0Kc2hpZnQgPC0gYWJzKG1pbihtYWNybyRHRFAuR3Jvd3RoLlJhdGUuLi4uLCBuYS5ybSA9IFRSVUUpKSArIDAuMDENCg0KbW9kZWwyIDwtIGxtKFN0b2NrLkluZGV4LlZhbHVlIH4NCiAgICAgICAgICAgICAgIEkobG9nKEdEUC5Hcm93dGguUmF0ZS4uLi4gKyBzaGlmdCkpICsNCiAgICAgICAgICAgICAgIFVuZW1wbG95bWVudC5SYXRlLi4uLiArDQogICAgICAgICAgICAgICBJbnRlcmVzdC5SYXRlLi4uLiwNCiAgICAgICAgICAgICBkYXRhID0gbWFjcm8pDQoNCnN1bW1hcnkobW9kZWwyKQ0KYGBgDQpQbyBsb2dhcml0bWlja2VqIHRyYW5zZm9ybcOhY2lpIEdEUCBHcm93dGggUmF0ZSBhIG9kc3Ryw6FuZW7DrSBJbmZsYXRpb24gUmF0ZSBtb2RlbCB1a2F6dWplIHBvZG9ibsO9IG9icmF6OiDFvmlhZG5hIHogcHJlbWVubsO9Y2ggKG9rcmVtIGludGVyY2VwdHUpIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DoS4gS29lZmljaWVudHkgc8O6IHN0w6FsZSBuw616a2UgYSBwLWhvZG5vdHkgdnnFocWhaWUgbmXFviAwLDA1LiBSLXNxdWFyZWQgamUgdmXEvm1pIG7DrXprZSAoMCwwMDYyKSwgxI1vIHpuYW1lbsOhLCDFvmUgbW9kZWwgc3TDoWxlIG5ldnlzdmV0xL51amUgdmFyaWFiaWxpdHUgU3RvY2sgSW5kZXggVmFsdWUuDQoNClJlemlkdcOhIHPDuiBwb2RvYm5lIHJvenB0w71sZW7DqSBhIG1lZGnDoW4gamUgYmzDrXprbyBudWx5Lg0KDQojIyBEaWFnbm9zdGlja8OpIGdyYWZ5IHByZSBtb2RlbCAyDQoNCmBgYHtyfQ0KcGFyKG1mcm93ID0gYygyLCAyKSkNCnBsb3QobW9kZWwyKQ0KbXRleHQoIkRpYWdub3N0aWNrw6kgZ3JhZnkgLSBNb2RlbCAyIChsb2cgR0RQKSIsIG91dGVyID0gVFJVRSwgY2V4ID0gMS4yLCBmb250ID0gMikNCnBhcihtZnJvdyA9IGMoMSwgMSkpDQpgYGANCiMjIyMgUmVzaWR1YWxzIHZzIEZpdHRlZA0KDQotIFBvZG9ibmUgYWtvIHByaSBtb2RlbCAxLCByZXppZHXDoSBzw7ogcm96cHTDvWxlbsOpIG9rb2xvIG51bHksIGJleiB2w71yYXpuw71jaCBzeXN0ZW1hdGlja8O9Y2ggb2RjaMO9bG9rLg0KDQojIyMjIFEtUSBwbG90DQoNCi0gUmV6aWR1w6Egc8O6IHByaWJsacW+bmUgbm9ybcOhbG5lIHJvemxvxb5lbsOpLCBtaWVybmUgb2RjaMO9bGt5IG5hIG9rcmFqb2NoLg0KDQojIyMjIFNjYWxlLUxvY2F0aW9uDQoNCi0gVmFyaWFuY2lhIHJlemlkdcOtIGplIHN0YWJpbG7DoSwgbmVuYXpuYcSNdWplIGhldGVyb3NrZWRhc3RpY2l0dS4NCg0KIyMjIyBSZXNpZHVhbHMgdnMgTGV2ZXJhZ2UNCg0KLSBWw6TEjcWhaW5hIGJvZG92IG3DoSBuw616a3UgcMOha3UsIMW+aWFkbmUgdsO9cmF6bmUgb3ZwbHl2xYh1asO6Y2UgcG96b3JvdmFuaWUuDQoNCiMjIEhldGVyb3NrZWRhc3RpY2l0YSDigJMgZ3JhZnkgcHJlIG1vZGVsIDINCg0KYGBge3J9DQpwMyA8LSBnZ3Bsb3QobWFjcm8sIGFlcyh4ID0gbG9nKEdEUC5Hcm93dGguUmF0ZS4uLi4gKyAxKSwgeSA9IHJlc2lkKG1vZGVsMileMikpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiKSArDQogIGxhYnMoeCA9ICJsb2coR0RQIEdyb3d0aCkiLA0KICAgICAgIHkgPSAiUmV6aWR1w6HCsiIsDQogICAgICAgdGl0bGUgPSAiUmV6aWR1w6HCsiB2cyBsb2coR0RQIEdyb3d0aCkiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpwNCA8LSBnZ3Bsb3QobWFjcm8sIGFlcyh4ID0gVW5lbXBsb3ltZW50LlJhdGUuLi4uLCB5ID0gcmVzaWQobW9kZWwyKV4yKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsNCiAgbGFicyh4ID0gIlVuZW1wbG95bWVudCBSYXRlICglKSIsDQogICAgICAgeSA9ICJSZXppZHXDocKyIiwNCiAgICAgICB0aXRsZSA9ICJSZXppZHXDocKyIHZzIFVuZW1wbG95bWVudCIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCnBsb3RfZ3JpZChwMywgcDQpDQpgYGANClBvIGxvZ2FyaXRtaWNrZWogdHJhbnNmb3Jtw6FjaWkgcHJlbWVubmVqIEdEUCBHcm93dGggc2EgcnXFvm92w6Ega3JpdmthIHZ5cm92bmFsYSBhIHJvenB0eWwgcmV6aWR1w60gc2Egc3RhbCByb3Zub21lcm5lasWhw61tLCDEjW8gbmF6bmHEjXVqZSwgxb5lIHRyYW5zZm9ybcOhY2lhIHpuw63FvmlsYSBoZXRlcm9za2VkYXN0aWNpdHUuIA0KUHJlbWVubsOhIFVuZW1wbG95bWVudCBSYXRlIG5ldnlrYXp1amUgdmlkaXRlxL5uw6kgem7DoW1reSBoZXRlcm9za2VkYXN0aWNpdHksIHRha8W+ZSBjZWxrb3ZvIG1vxb5ubyBwb3ZlZGHFpSwgxb5lIG5vdsO9IG1vZGVsIG3DoSBzdGFiaWxuZWrFocOtIHJvenB0eWwgcmV6aWR1w60gYSBsZXDFoWl1IMWhdHJ1a3TDunJ1IGFrbyBww7R2b2Ruw70uDQoNCiMjIEJyZXVzY2gtUGFnYW4gdGVzdCBwcmUgbW9kZWwgMSBhaiBtb2RlbCAyDQoNCmBgYHtyfQ0KYnB0ZXN0KG1vZGVsKQ0KYnB0ZXN0KG1vZGVsMikNCmBgYA0KLSBQcmUgbW9kZWwgMTogQlAgPSAyLDk0NjIsIHAgPSAwLDU2NjkNCi0gUHJlIG1vZGVsIDI6IEJQID0gMiwzMzUyLCBwID0gMCw1MDU4DQoNClbDvXNsZWRreSBCcmV1c2No4oCTUGFnYW5vdmhvIHRlc3R1IHByZSBtb2RlbCAxIChwID0gMC41NjY5KSBhaiBtb2RlbCAyIChwID0gMC41MDU4KSBuYXpuYcSNdWrDuiwgxb5lIG5lbcOhbWUgZG9zdGF0b2sgZMO0a2F6b3YgbmEgemFtaWV0bnV0aWUgbnVsb3ZlaiBoeXBvdMOpenkgaG9tb3NrZWRhc3RpY2l0eS4gUm96cHR5bCByZXrDrWR1w60gc2EgamF2w60gYWtvIHByaWJsacW+bmUga29uxaF0YW50bsO9IGEgbmV2eWthenVqZSBzeXN0ZW1hdGlja8O6IHrDoXZpc2xvc8WlIG9kIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2guDQoNClogdG9obyBtb8W+bm8ga29uxaF0YXRvdmHFpSwgxb5lIHJlemlkdcOhIG9ib2NoIG1vZGVsb3Ygc3DEusWIYWrDuiBwcmVkcG9rbGFkIGhvbW9za2VkYXN0aWNpdHksIMSNbyBpbmRpa3VqZSwgxb5lIG9kaGFkeSByZWdyZXNuw71jaCBrb2VmaWNpZW50b3Ygc8O6IGVmZWt0w612bmUgYSBuaWUgamUgcG90cmVibsOpIGFwbGlrb3ZhxaUga29yZWtjaWUgbmEgaGV0ZXJvc2tlZGFzdGljaXR1Lg0KDQoNCg0KDQoNCiA=