# Najprv inštalácia balíkov (iba raz)
install.packages("zoo")
trying URL 'http://rspm/default/__linux__/focal/latest/src/contrib/zoo_1.8-14.tar.gz'
Content type 'application/x-gzip' length 1018553 bytes (994 KB)
==================================================
downloaded 994 KB
The downloaded source packages are in
‘/tmp/RtmpeRarTf/downloaded_packages’
install.packages("tseries")
trying URL 'http://rspm/default/__linux__/focal/latest/src/contrib/tseries_0.10-58.tar.gz'
Content type 'application/x-gzip' length 373247 bytes (364 KB)
==================================================
downloaded 364 KB
The downloaded source packages are in
‘/tmp/RtmpeRarTf/downloaded_packages’
install.packages("lmtest")
trying URL 'http://rspm/default/__linux__/focal/latest/src/contrib/lmtest_0.9-40.tar.gz'
Content type 'application/x-gzip' length 399624 bytes (390 KB)
==================================================
downloaded 390 KB
The downloaded source packages are in
‘/tmp/RtmpeRarTf/downloaded_packages’
install.packages("sandwich")
trying URL 'http://rspm/default/__linux__/focal/latest/src/contrib/sandwich_3.1-1.tar.gz'
Content type 'application/x-gzip' length 1505348 bytes (1.4 MB)
==================================================
downloaded 1.4 MB
The downloaded source packages are in
‘/tmp/RtmpeRarTf/downloaded_packages’
trying URL 'http://rspm/default/__linux__/focal/latest/src/contrib/car_3.1-3.tar.gz'
Content type 'application/x-gzip' length 1510899 bytes (1.4 MB)
==================================================
downloaded 1.4 MB
The downloaded source packages are in
‘/tmp/RtmpeRarTf/downloaded_packages’
# Načítanie balíkov
library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
PRÍPRAVA ÚDAJOV
V tejto časti sme z datasetu vybrali tri dôležité ukazovatele:
populáciu v roku 2020, rozlohu krajiny a hustotu obyvateľstva. Pretože
údaje obsahovali chýbajúce hodnoty, doplnili sme ich pomocou mediánu,
aby analýza nebola skreslená ani prerušená NA hodnotami. Následne sme
všetky premenné prekonvertovali na číselný formát, aby sa dali ďalej
štatisticky spracovať. Výsledkom je čistý a kompletný dataset vhodný na
následné regresné modelovanie.
# Načítanie dát
udaje <- read.csv("world_population.csv", dec=".", sep=",", header = TRUE)
# Výber údajov z roku 2020 (nie 2015 — podľa tvojho datasetu)
# a výber premenných, ktoré si používala v predošlom cvičení:
# - 2020 Population
# - Area (km2)
# - Density (per km2)
udaje.2020 <- udaje[, c("X2020.Population", "Area..km..", "Density..per.km..")]
# Konverzia na numerické hodnoty (niektoré môžu byť ako text)
udaje.2020 <- as.data.frame(lapply(udaje.2020, as.numeric))
IMPUTÁCIA DÁT – DOPLNENIE NA MEDIÁN
# Výpočet mediánov pre každý stĺpec
column_medians <- sapply(udaje.2020, median, na.rm = TRUE)
# Imputácia
udaje_imputed <- udaje.2020
for (col in names(udaje.2020)) {
udaje_imputed[[col]][is.na(udaje_imputed[[col]])] <- column_medians[col]
}
# Aktuálne upravený dataset
udaje.2020 <- udaje_imputed
udaje <- udaje.2020
KONTROLA
summary(udaje)
sum(is.na(udaje))
ZÁKLADNÁ REGRESIA – UPRAVENÁ NA WORLD POPULATION DÁTA
V regresnom modeli sme skúmali, ako populácia a rozloha krajiny
ovplyvňujú hustotu obyvateľstva. Výsledky ukazujú, či existuje
matematický vzťah medzi veľkosťou populácie, územím krajiny a tým, koľko
ľudí žije na km². Koeficienty modelu ukazujú smer a silu týchto vzťahov,
a štatistická významnosť (p-hodnoty) naznačuje, či sú premenné skutočne
dôležitými prediktormi. Celkovo model pomáha pochopiť, ktoré faktory
najviac prispievajú k hustote obyvateľstva.
attach(udaje)
# Lineárny model: hustota ako funkcia populácie a rozlohy
model <- lm(Density..per.km.. ~ 1 + X2020.Population + Area..km.., data = udaje)
summary(model)
1. Test RESET (test chyby špecifikácie Ramseyho regresnej rovnice -
Ramsey Reset Test)
Myšlienka: Nech pôvodný model má tvar \[y_t = \beta_0 + \beta_1 x_{t10} + \dots +\beta_k
x_{tk} + u_t\] \[y_t = \beta_0 +
\beta_1 x_{t10} + \dots +\beta_k x_{tk} + \gamma_2\hat y_t^2 +
\gamma_3\hat{y}_t^3 + u_t\] Budeme testovať hypotézu
\(H_0:\) model je správne
špecifikovaný (\(\gamma_2 = \gamma_3 =
0\))
oproti
\(H_1:\) model je nesprávne
špecifikovaný (\(\gamma_2 \ne 0 \quad
\text{alebo} \quad \gamma_3 \ne 0\))
# Suppose your model is:
model <- lm(Density..per.km.. ~ 1 + X2020.Population + Area..km.., data = udaje)
# RESET test from 'lmtest' package:
library(lmtest)
resettest(model)
Interpretácia
Null hypotéza (H0): Model je správne špecifikovaný
(nechýbajú nelineárne vzťahy ani dôležité premenné).
Alternatívna hypotéza (H1): Model je nesprávne
špecifikovaný (chýbajú premenné alebo nelineárne vzťahy).
p-value = 0.2507 → vyššie ako bežnú hladinu
významnosti (napr. 0.05).
RESET test overuje, či je model správne špecifikovaný, teda či mu
nechýbajú dôležité premenné alebo nelineárne vzťahy. V našom prípade je
p-hodnota 0.25, čo znamená, že nemáme dôkaz o nesprávnej špecifikácii.
Model Density ~ Population + Area je teda vhodný a nie je potrebné
pridávať ďalšie členy.
2. Grafická analýza
Graf Residuals vs. Fitted
Grafy C+R **
\[y_t = \beta_0 + \beta_1 x_{t1} + \dots
+\beta_k x_{tk} + u_t\] Túto rovnicu najprv odhadneme a potom
vykresľujeme grafy, kde výraz component+residual (C+R) plot vykresľuje
na zvislej osi \(\hat{\beta}_ix_{ti}+e_t\) a na vodorovnej
osi vykresľuje hodnoty \(x_{ti}\)

Graf – 2020 Population
Väčšina bodov je veľmi blízko osi 0 → populácia väčšiny
krajín/území je relatívne nízka (v porovnaní s extrémami).
Niekoľko vzdialených bodov (outlierov) predstavuje veľmi veľké
populácie.
Fialová čiara (lineárny model) mierne stúpa → model
predpokladá pozitívnu, ale slabú lineárnu závislosť.
Modrá LOESS krivka je takmer plochá → skutočný nelineárny
trend je prakticky nulový.
Interpretácia:
Populácia nemá výrazný lineárny ani nelineárny efekt na hustotu
obyvateľstva v tomto modeli. Outliery môžu skresľovať fit.
Graf – Area (km²)
Situácia je podobná – väčšina území má malú rozlohu, pár extrémne
veľkých štátov vytvára outliery.
Lineárny model (fialová čiara) mierne klesá → väčšia rozloha
môže súvisieť s nižšou hustotou.
LOESS (modrá krivka) je tiež mierne klesajúca, ale takmer
plochá.
Interpretácia:
Rozloha má slabý negatívny vzťah s hustotou, čo je logicky očakávané,
ale závislosť je veľmi slabá. Nelineárny efekt sa prakticky
neprejavuje.
3. Nelineárna špecifikácia
\[y_t = \beta_0 + \beta_1 x_{t10} + \dots
+\beta_k x_{tk} + \dots + \gamma_i\hat x_{ik}^2 + \dots + \gamma_j\hat
x_{jk}^2 + \dots + u_t\]
model <- lm(Density..per.km.. ~ X2020.Population + Area..km.., data = udaje)
model_kvadr <- lm(Density..per.km.. ~
X2020.Population + Area..km.. +
I(X2020.Population^2) + I(Area..km..^2),
data = udaje)
summary(model_kvadr)
anova(model, model_kvadr)
library(lmtest)
resettest(model_kvadr)
Kvadratický regresný model ukázal, že žiadna z premenných
(populácia, rozloha ani ich kvadratické členy) nie je štatisticky
významným prediktorom hustoty obyvateľstva. Hodnota R² takmer nulová a
záporné upravené R² potvrdzujú, že model nedokáže vysvetliť variabilitu
hustoty. ANOVA test ukázal, že pridanie kvadratických členov model
nezlepšuje. RESET test síce nenaznačil chybnú špecifikáciu modelu, no
samotný model je pre predikciu hustoty nevhodný.
model_kvadr <- lm(Density..per.km.. ~ X2020.Population + Area..km.. + I(X2020.Population^2),
data = udaje)
summary(model_kvadr)
Reziduá majú veľmi široký rozsah, pričom maximum výrazne
prevyšuje ostatné hodnoty, čo naznačuje prítomnosť extrémnych odľahlých
pozorovaní v dátach. Žiadny z koeficientov vysvetľujúcich premenných nie
je štatisticky významný (p-hodnoty sú vysoko nad 0.05), takže populácia,
rozloha ani kvadratický člen populácie nevysvetľujú hustotu
obyvateľstva. Veľmi nízke R² a záporné upravené R² ukazujú, že model
prakticky nedokáže zachytiť variabilitu závislej premennej a je menej
vhodný než triviálny model bez prediktorov. Nízka hodnota
F-štatistiky a vysoká p-hodnota potvrdzujú, že model ako celok nie je
štatisticky významný.
5. Použitie rozšíreného RESET testu
model_rozsireny <- lm(Density..per.km.. ~
X2020.Population +
Area..km.. +
I(X2020.Population^2) +
I(Area..km..^2),
data = udaje)
summary(model_rozsireny)
anova(model,model_rozsireny)
resettest(model_rozsireny)
LS0tCnRpdGxlOiAiUHLDoWNhIHMgZGF0YWLDoXpvdSAtIFdvcmxkIHBvcHVsYXRpb24iCmF1dGhvcjogIkJhcmJvcmEgS3VjaMOhcmlrb3bDoSAgPGJyPiIKZGF0ZTogIk5vdmVtYmVyIDIwMjUiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGNzczogY3VzdG9tLmNzcwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQplZGl0b3Jfb3B0aW9uczoKICBtYXJrZG93bjoKICAgIHdyYXA6IDcyCi0tLQoKCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCmBgYHtyfQojIE5hanBydiBpbsWhdGFsw6FjaWEgYmFsw61rb3YgKGliYSByYXopCmluc3RhbGwucGFja2FnZXMoInpvbyIpCmluc3RhbGwucGFja2FnZXMoInRzZXJpZXMiKQppbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQppbnN0YWxsLnBhY2thZ2VzKCJzYW5kd2ljaCIpCmluc3RhbGwucGFja2FnZXMoImNhciIpCgojIE5hxI3DrXRhbmllIGJhbMOta292CmxpYnJhcnkoem9vKQpsaWJyYXJ5KHRzZXJpZXMpCmxpYnJhcnkobG10ZXN0KQpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGNhcikKYGBgCiMgUFLDjVBSQVZBIMOaREFKT1YKCipWIHRlanRvIMSNYXN0aSBzbWUgeiBkYXRhc2V0dSB2eWJyYWxpIHRyaSBkw7RsZcW+aXTDqSB1a2F6b3ZhdGVsZTogcG9wdWzDoWNpdSB2IHJva3UgMjAyMCwgcm96bG9odSBrcmFqaW55IGEgaHVzdG90dSBvYnl2YXRlxL5zdHZhLiBQcmV0b8W+ZSDDumRhamUgb2JzYWhvdmFsaSBjaMO9YmFqw7pjZSBob2Rub3R5LCBkb3BsbmlsaSBzbWUgaWNoIHBvbW9jb3UgbWVkacOhbnUsIGFieSBhbmFsw716YSBuZWJvbGEgc2tyZXNsZW7DoSBhbmkgcHJlcnXFoWVuw6EgTkEgaG9kbm90YW1pLiBOw6FzbGVkbmUgc21lIHbFoWV0a3kgcHJlbWVubsOpIHByZWtvbnZlcnRvdmFsaSBuYSDEjcOtc2VsbsO9IGZvcm3DoXQsIGFieSBzYSBkYWxpIMSPYWxlaiDFoXRhdGlzdGlja3kgc3ByYWNvdmHFpS4gVsO9c2xlZGtvbSBqZSDEjWlzdMO9IGEga29tcGxldG7DvSBkYXRhc2V0IHZob2Ruw70gbmEgbsOhc2xlZG7DqSByZWdyZXNuw6kgbW9kZWxvdmFuaWUuKgoKYGBge3J9CiMgTmHEjcOtdGFuaWUgZMOhdAp1ZGFqZSA8LSByZWFkLmNzdigid29ybGRfcG9wdWxhdGlvbi5jc3YiLCBkZWM9Ii4iLCBzZXA9IiwiLCBoZWFkZXIgPSBUUlVFKQoKIyBWw71iZXIgw7pkYWpvdiB6IHJva3UgMjAyMCAobmllIDIwMTUg4oCUIHBvZMS+YSB0dm9qaG8gZGF0YXNldHUpCiMgYSB2w71iZXIgcHJlbWVubsO9Y2gsIGt0b3LDqSBzaSBwb3XFvsOtdmFsYSB2IHByZWRvxaFsb20gY3ZpxI1lbsOtOgojIC0gMjAyMCBQb3B1bGF0aW9uCiMgLSBBcmVhIChrbTIpCiMgLSBEZW5zaXR5IChwZXIga20yKQoKdWRhamUuMjAyMCA8LSB1ZGFqZVssIGMoIlgyMDIwLlBvcHVsYXRpb24iLCAiQXJlYS4ua20uLiIsICJEZW5zaXR5Li5wZXIua20uLiIpXQoKIyBLb252ZXJ6aWEgbmEgbnVtZXJpY2vDqSBob2Rub3R5IChuaWVrdG9yw6kgbcO0xb51IGJ5xaUgYWtvIHRleHQpCnVkYWplLjIwMjAgPC0gYXMuZGF0YS5mcmFtZShsYXBwbHkodWRhamUuMjAyMCwgYXMubnVtZXJpYykpCmBgYAoKIyBJTVBVVMOBQ0lBIETDgVQg4oCTIERPUExORU5JRSBOQSBNRURJw4FOCgpgYGB7cn0KIyBWw71wb8SNZXQgbWVkacOhbm92IHByZSBrYcW+ZMO9IHN0xLpwZWMKY29sdW1uX21lZGlhbnMgPC0gc2FwcGx5KHVkYWplLjIwMjAsIG1lZGlhbiwgbmEucm0gPSBUUlVFKQoKIyBJbXB1dMOhY2lhCnVkYWplX2ltcHV0ZWQgPC0gdWRhamUuMjAyMApmb3IgKGNvbCBpbiBuYW1lcyh1ZGFqZS4yMDIwKSkgewogIHVkYWplX2ltcHV0ZWRbW2NvbF1dW2lzLm5hKHVkYWplX2ltcHV0ZWRbW2NvbF1dKV0gPC0gY29sdW1uX21lZGlhbnNbY29sXQp9CgojIEFrdHXDoWxuZSB1cHJhdmVuw70gZGF0YXNldAp1ZGFqZS4yMDIwIDwtIHVkYWplX2ltcHV0ZWQKdWRhamUgPC0gdWRhamUuMjAyMApgYGAKCiMgS09OVFJPTEEKCmBgYHtyfQpzdW1tYXJ5KHVkYWplKQpzdW0oaXMubmEodWRhamUpKQpgYGAKCiMgWsOBS0xBRE7DgSBSRUdSRVNJQSDigJMgVVBSQVZFTsOBIE5BIFdPUkxEIFBPUFVMQVRJT04gRMOBVEEKCipWIHJlZ3Jlc25vbSBtb2RlbGkgc21lIHNrw7ptYWxpLCBha28gcG9wdWzDoWNpYSBhIHJvemxvaGEga3JhamlueSBvdnBseXbFiHVqw7ogaHVzdG90dSBvYnl2YXRlxL5zdHZhLiBWw71zbGVka3kgdWthenVqw7osIMSNaSBleGlzdHVqZSBtYXRlbWF0aWNrw70gdnrFpWFoIG1lZHppIHZlxL5rb3PFpW91IHBvcHVsw6FjaWUsIMO6emVtw61tIGtyYWppbnkgYSB0w71tLCBrb8S+a28gxL51ZMOtIMW+aWplIG5hIGttwrIuIEtvZWZpY2llbnR5IG1vZGVsdSB1a2F6dWrDuiBzbWVyIGEgc2lsdSB0w71jaHRvIHZ6xaVhaG92LCBhIMWhdGF0aXN0aWNrw6EgdsO9em5hbW5vc8WlIChwLWhvZG5vdHkpIG5hem5hxI11amUsIMSNaSBzw7ogcHJlbWVubsOpIHNrdXRvxI1uZSBkw7RsZcW+aXTDvW1pIHByZWRpa3Rvcm1pLiBDZWxrb3ZvIG1vZGVsIHBvbcOhaGEgcG9jaG9wacWlLCBrdG9yw6kgZmFrdG9yeSBuYWp2aWFjIHByaXNwaWV2YWrDuiBrIGh1c3RvdGUgb2J5dmF0ZcS+c3R2YS4qCgpgYGB7cn0KYXR0YWNoKHVkYWplKQoKIyBMaW5lw6FybnkgbW9kZWw6IGh1c3RvdGEgYWtvIGZ1bmtjaWEgcG9wdWzDoWNpZSBhIHJvemxvaHkKbW9kZWwgPC0gbG0oRGVuc2l0eS4ucGVyLmttLi4gfiAxICsgWDIwMjAuUG9wdWxhdGlvbiArIEFyZWEuLmttLi4sIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWwpCmBgYAoKCiMjIyAxLiBUZXN0IFJFU0VUICh0ZXN0IGNoeWJ5IMWhcGVjaWZpa8OhY2llIFJhbXNleWhvIHJlZ3Jlc25laiByb3ZuaWNlIC0gUmFtc2V5IFJlc2V0IFRlc3QpCgpNecWhbGllbmthOiBOZWNoIHDDtHZvZG7DvSBtb2RlbCBtw6EgdHZhcgokJHlfdCA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfe3QxMH0gKyBcZG90cyArXGJldGFfayB4X3t0a30gKyB1X3QkJAokJHlfdCA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfe3QxMH0gKyBcZG90cyArXGJldGFfayB4X3t0a30gKyBcZ2FtbWFfMlxoYXQgeV90XjIgKyBcZ2FtbWFfM1xoYXR7eX1fdF4zICsgdV90JCQKQnVkZW1lIHRlc3RvdmHFpSBoeXBvdMOpenUgCgokSF8wOiQgbW9kZWwgamUgc3Byw6F2bmUgxaFwZWNpZmlrb3ZhbsO9ICgkXGdhbW1hXzIgPSBcZ2FtbWFfMyA9IDAkKQoKb3Byb3RpCgokSF8xOiQgbW9kZWwgamUgbmVzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70gKCRcZ2FtbWFfMiBcbmUgMCAgXHF1YWQgXHRleHR7YWxlYm99ICBccXVhZCBcZ2FtbWFfMyBcbmUgMCQpCgpgYGB7cn0KIyBTdXBwb3NlIHlvdXIgbW9kZWwgaXM6Cm1vZGVsIDwtIGxtKERlbnNpdHkuLnBlci5rbS4uIH4gMSArIFgyMDIwLlBvcHVsYXRpb24gKyBBcmVhLi5rbS4uLCBkYXRhID0gdWRhamUpCgoKIyBSRVNFVCB0ZXN0IGZyb20gJ2xtdGVzdCcgcGFja2FnZToKbGlicmFyeShsbXRlc3QpCnJlc2V0dGVzdChtb2RlbCkKYGBgCgojIyMgSW50ZXJwcmV0w6FjaWEKKipOdWxsIGh5cG90w6l6YSAoSDApOioqIE1vZGVsIGplIHNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSAobmVjaMO9YmFqw7ogbmVsaW5lw6FybmUgdnrFpWFoeSBhbmkgZMO0bGXFvml0w6kgcHJlbWVubsOpKS4KCioqQWx0ZXJuYXTDrXZuYSBoeXBvdMOpemEgKEgxKToqKiBNb2RlbCBqZSBuZXNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSAoY2jDvWJhasO6IHByZW1lbm7DqSBhbGVibyBuZWxpbmXDoXJuZSB2esWlYWh5KS4KCioqcC12YWx1ZSA9IDAuMjUwNyDihpIqKiB2ecWhxaFpZSBha28gYmXFvm7DuiBobGFkaW51IHbDvXpuYW1ub3N0aSAobmFwci4gMC4wNSkuCgoqUkVTRVQgdGVzdCBvdmVydWplLCDEjWkgamUgbW9kZWwgc3Byw6F2bmUgxaFwZWNpZmlrb3ZhbsO9LCB0ZWRhIMSNaSBtdSBuZWNow71iYWrDuiBkw7RsZcW+aXTDqSBwcmVtZW5uw6kgYWxlYm8gbmVsaW5lw6FybmUgdnrFpWFoeS4gViBuYcWhb20gcHLDrXBhZGUgamUgcC1ob2Rub3RhIDAuMjUsIMSNbyB6bmFtZW7DoSwgxb5lIG5lbcOhbWUgZMO0a2F6IG8gbmVzcHLDoXZuZWogxaFwZWNpZmlrw6FjaWkuIE1vZGVsIERlbnNpdHkgfiBQb3B1bGF0aW9uICsgQXJlYSBqZSB0ZWRhIHZob2Ruw70gYSBuaWUgamUgcG90cmVibsOpIHByaWTDoXZhxaUgxI9hbMWhaWUgxI1sZW55LioKCgoKIyMjIDIuIEdyYWZpY2vDoSBhbmFsw716YQoKIyMjIyBHcmFmICpSZXNpZHVhbHMgdnMuIEZpdHRlZCoKYGBge3J9CnBsb3QobW9kZWwsIHdoaWNoID0gMSkKYGBgCgojIyMjIEdyYWZ5IEMrUiAqKgokJHlfdCA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfe3QxfSArIFxkb3RzICtcYmV0YV9rIHhfe3RrfSArIHVfdCQkClTDunRvIHJvdm5pY3UgbmFqcHJ2IG9kaGFkbmVtZSBhIHBvdG9tIHZ5a3Jlc8S+dWplbWUgZ3JhZnksIGtkZSB2w71yYXogY29tcG9uZW50K3Jlc2lkdWFsIChDK1IpIHBsb3QgdnlrcmVzxL51amUgbmEgenZpc2xlaiBvc2kgJFxoYXR7XGJldGF9X2l4X3t0aX0rZV90JCBhIG5hIHZvZG9yb3ZuZWogb3NpIHZ5a3Jlc8S+dWplIGhvZG5vdHkgJHhfe3RpfSQKYGBge3J9CmNhcjo6Y3JQbG90cyhtb2RlbCkKYGBgCgojIyMgR3JhZiDigJMgMjAyMCBQb3B1bGF0aW9uCgoqVsOkxI3FoWluYSBib2RvdiBqZSB2ZcS+bWkgYmzDrXprbyBvc2kgMCog4oaSIHBvcHVsw6FjaWEgdsOkxI3FoWlueSBrcmFqw61uL8O6emVtw60gamUgcmVsYXTDrXZuZSBuw616a2EgKHYgcG9yb3ZuYW7DrSBzIGV4dHLDqW1hbWkpLgoKTmlla2/EvmtvIHZ6ZGlhbGVuw71jaCBib2RvdiAob3V0bGllcm92KSBwcmVkc3RhdnVqZSB2ZcS+bWkgdmXEvmvDqSBwb3B1bMOhY2llLgoKKkZpYWxvdsOhIMSNaWFyYSAobGluZcOhcm55IG1vZGVsKSBtaWVybmUgc3TDunBhKiDihpIgbW9kZWwgcHJlZHBva2xhZMOhIHBveml0w612bnUsIGFsZSBzbGFiw7ogbGluZcOhcm51IHrDoXZpc2xvc8WlLgoKKk1vZHLDoSBMT0VTUyBrcml2a2EgamUgdGFrbWVyIHBsb2Now6EqIOKGkiBza3V0b8SNbsO9IG5lbGluZcOhcm55IHRyZW5kIGplIHByYWt0aWNreSBudWxvdsO9LgoKIyMjIyBJbnRlcnByZXTDoWNpYToKUG9wdWzDoWNpYSBuZW3DoSB2w71yYXpuw70gbGluZcOhcm55IGFuaSBuZWxpbmXDoXJueSBlZmVrdCBuYSBodXN0b3R1IG9ieXZhdGXEvnN0dmEgdiB0b210byBtb2RlbGkuCk91dGxpZXJ5IG3DtMW+dSBza3Jlc8S+b3ZhxaUgZml0LgoKCiMjIyBHcmFmIOKAkyBBcmVhIChrbcKyKQoKU2l0dcOhY2lhIGplIHBvZG9ibsOhIOKAkyB2w6TEjcWhaW5hIMO6emVtw60gbcOhIG1hbMO6IHJvemxvaHUsIHDDoXIgZXh0csOpbW5lIHZlxL5rw71jaCDFoXTDoXRvdiB2eXR2w6FyYSBvdXRsaWVyeS4KCipMaW5lw6FybnkgbW9kZWwgKGZpYWxvdsOhIMSNaWFyYSkgbWllcm5lIGtsZXPDoSog4oaSIHbDpMSNxaFpYSByb3psb2hhIG3DtMW+ZSBzw7p2aXNpZcWlIHMgbmnFvsWhb3UgaHVzdG90b3UuCgoqTE9FU1MgKG1vZHLDoSBrcml2a2EpKiBqZSB0aWXFviBtaWVybmUga2xlc2Fqw7pjYSwgYWxlIHRha21lciBwbG9jaMOhLgoKIyMjIyBJbnRlcnByZXTDoWNpYToKUm96bG9oYSBtw6Egc2xhYsO9IG5lZ2F0w612bnkgdnrFpWFoIHMgaHVzdG90b3UsIMSNbyBqZSBsb2dpY2t5IG/EjWFrw6F2YW7DqSwgYWxlIHrDoXZpc2xvc8WlIGplIHZlxL5taSBzbGFiw6EuCk5lbGluZcOhcm55IGVmZWt0IHNhIHByYWt0aWNreSBuZXByZWphdnVqZS4KCgojIyAzLiBOZWxpbmXDoXJuYSDFoXBlY2lmaWvDoWNpYQokJHlfdCA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfe3QxMH0gKyBcZG90cyArXGJldGFfayB4X3t0a30gKyBcZG90cyArIFxnYW1tYV9pXGhhdCB4X3tpa31eMiArIFxkb3RzICsgXGdhbW1hX2pcaGF0IHhfe2prfV4yICsgXGRvdHMgKyB1X3QkJApgYGB7cn0KCm1vZGVsIDwtIGxtKERlbnNpdHkuLnBlci5rbS4uIH4gWDIwMjAuUG9wdWxhdGlvbiArIEFyZWEuLmttLi4sIGRhdGEgPSB1ZGFqZSkKCm1vZGVsX2t2YWRyIDwtIGxtKERlbnNpdHkuLnBlci5rbS4uIH4gCiAgICAgICAgICAgICAgICAgICAgWDIwMjAuUG9wdWxhdGlvbiArIEFyZWEuLmttLi4gKwogICAgICAgICAgICAgICAgICAgIEkoWDIwMjAuUG9wdWxhdGlvbl4yKSArIEkoQXJlYS4ua20uLl4yKSwKICAgICAgICAgICAgICAgICAgZGF0YSA9IHVkYWplKQoKc3VtbWFyeShtb2RlbF9rdmFkcikKCmFub3ZhKG1vZGVsLCBtb2RlbF9rdmFkcikKCmxpYnJhcnkobG10ZXN0KQpyZXNldHRlc3QobW9kZWxfa3ZhZHIpCmBgYAoqS3ZhZHJhdGlja8O9IHJlZ3Jlc27DvSBtb2RlbCB1a8OhemFsLCDFvmUgxb5pYWRuYSB6IHByZW1lbm7DvWNoIChwb3B1bMOhY2lhLCByb3psb2hhIGFuaSBpY2gga3ZhZHJhdGlja8OpIMSNbGVueSkgbmllIGplIMWhdGF0aXN0aWNreSB2w716bmFtbsO9bSBwcmVkaWt0b3JvbSBodXN0b3R5IG9ieXZhdGXEvnN0dmEuIEhvZG5vdGEgUsKyIHRha21lciBudWxvdsOhIGEgesOhcG9ybsOpIHVwcmF2ZW7DqSBSwrIgcG90dnJkenVqw7osIMW+ZSBtb2RlbCBuZWRva8Ohxb5lIHZ5c3ZldGxpxaUgdmFyaWFiaWxpdHUgaHVzdG90eS4gQU5PVkEgdGVzdCB1a8OhemFsLCDFvmUgcHJpZGFuaWUga3ZhZHJhdGlja8O9Y2ggxI1sZW5vdiBtb2RlbCBuZXpsZXDFoXVqZS4gUkVTRVQgdGVzdCBzw61jZSBuZW5hem5hxI1pbCBjaHlibsO6IMWhcGVjaWZpa8OhY2l1IG1vZGVsdSwgbm8gc2Ftb3Ruw70gbW9kZWwgamUgcHJlIHByZWRpa2NpdSBodXN0b3R5IG5ldmhvZG7DvS4qCgpgYGB7cn0KbW9kZWxfa3ZhZHIgPC0gbG0oRGVuc2l0eS4ucGVyLmttLi4gfiBYMjAyMC5Qb3B1bGF0aW9uICsgQXJlYS4ua20uLiArIEkoWDIwMjAuUG9wdWxhdGlvbl4yKSwgCiAgICAgICAgICAgICAgICAgIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWxfa3ZhZHIpCmBgYAoqUmV6aWR1w6EgbWFqw7ogdmXEvm1pIMWhaXJva8O9IHJvenNhaCwgcHJpxI1vbSBtYXhpbXVtIHbDvXJhem5lIHByZXZ5xaF1amUgb3N0YXRuw6kgaG9kbm90eSwgxI1vIG5hem5hxI11amUgcHLDrXRvbW5vc8WlIGV4dHLDqW1ueWNoIG9kxL5haGzDvWNoIHBvem9yb3ZhbsOtIHYgZMOhdGFjaC4gxb1pYWRueSB6IGtvZWZpY2llbnRvdiB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSAocC1ob2Rub3R5IHPDuiB2eXNva28gbmFkIDAuMDUpLCB0YWvFvmUgcG9wdWzDoWNpYSwgcm96bG9oYSBhbmkga3ZhZHJhdGlja8O9IMSNbGVuIHBvcHVsw6FjaWUgbmV2eXN2ZXTEvnVqw7ogaHVzdG90dSBvYnl2YXRlxL5zdHZhLiBWZcS+bWkgbsOtemtlIFLCsiBhIHrDoXBvcm7DqSB1cHJhdmVuw6kgUsKyIHVrYXp1asO6LCDFvmUgbW9kZWwgcHJha3RpY2t5IG5lZG9rw6HFvmUgemFjaHl0acWlIHZhcmlhYmlsaXR1IHrDoXZpc2xlaiBwcmVtZW5uZWogYSBqZSBtZW5laiB2aG9kbsO9IG5lxb4gdHJpdmnDoWxueSBtb2RlbCBiZXogcHJlZGlrdG9yb3YuICoqTsOtemthIGhvZG5vdGEgRi3FoXRhdGlzdGlreSBhIHZ5c29rw6EgcC1ob2Rub3RhIHBvdHZyZHp1asO6LCDFvmUgbW9kZWwgYWtvIGNlbG9rIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSoqLioKCiMjIyA1LiBQb3XFvml0aWUgcm96xaHDrXJlbsOpaG8gUkVTRVQgdGVzdHUKYGBge3J9Cm1vZGVsX3JvenNpcmVueSA8LSBsbShEZW5zaXR5Li5wZXIua20uLiB+IAogICAgICAgICAgICAgICAgICAgICAgICBYMjAyMC5Qb3B1bGF0aW9uICsgCiAgICAgICAgICAgICAgICAgICAgICAgIEFyZWEuLmttLi4gKyAKICAgICAgICAgICAgICAgICAgICAgICAgSShYMjAyMC5Qb3B1bGF0aW9uXjIpICsgCiAgICAgICAgICAgICAgICAgICAgICAgIEkoQXJlYS4ua20uLl4yKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWxfcm96c2lyZW55KQpgYGAKYGBge3J9CmFub3ZhKG1vZGVsLG1vZGVsX3JvenNpcmVueSkKcmVzZXR0ZXN0KG1vZGVsX3JvenNpcmVueSkKYGBgCiMjIyA2LiBUcmFuc2Zvcm3DoWNpYSBwb21vY291IGR1bW15IHByZW1lbm5laiBhIGxpbmXDoXJuZWogbG9tZW5laiBmdW5rY2llCjEuIHpsb20gdiBhdXRvbsOzbW5vbSDEjWxlbmUgJFxiZXRhXzAkIGEgdG8gbmFzbGVkb3Zub3UgxaFwZWNpZmlrw6FjaW91CiQkeV90ID0gXGJldGFfMCArIFxiZXRhX0QgRCsgXGJldGFfMSB4X3t0MX0gKyBcZG90cyArXGJldGFfayB4X3t0a30gKyB1X3QkJArEjW8gaW50ZXJwcmV0dWplbWUgYWtvIHBvc3VuIHJlZ3Jlc25laiBwcmlhbWt5IChyZWdyZXNuZWogbmFkcm92aW55KSBvICRcYmV0YV9EJCBqZWRub3RpZWsgcG96ZMS6xb4genZpc2xlaiBvc2kgYSB0byBsZW4gdiBwb3pvcm92YW5pYWNoLCBhayBqZSBzcGxuZW7DoSBwb2RtaWVua2EgJERfdCA9IDEkCjIuIHpsb20gdiBza2xvbmUgcmVncmVzbmVqIHByaWFta3kgKG5hZHJvdmlueSkgYSB0byBsZW4gdiBwb3pvcm92YW5pYWNoLCBhayBqZSBzcGxuZW7DoSBwb2RtaWVua2EgJERfdCA9IDEkLCDEjW8gZG9zaWFobmVtZSBuYXNsZWRvdm5vdSDFoXBlY2lmaWvDoWNpb3UKJCR5X3QgPSBcYmV0YV8wICsgIFxiZXRhXzEgeF97dDF9ICsgXGRvdHMgKyBcYmV0YV97aX14X3t0aX0gKyBcYmV0YV97RGl9RF90eF97dGl9KyBcZG90cyArIFxiZXRhX2sgeF97dGt9ICsgdV90JCQKa2RlIHRlZGEgc2tsb24gcHJpYW1reSBwb3pkxLrFviBwcmVtZW5uZSAkeF97dGl9JCBqZSAkXGJldGFfaSQgYWxlIGxlbiB2IHByw61wYWRlICREX3Q9MCQsIGluYWsgamUgdGVuIHNrbG9uIHJvdm7DvSAkXGJldGFfaStcYmV0YV97RF9pfSQuCgpgYGB7cn0KIyBEdW1teSBwcmVtZW5uw6EgcG9kxL5hIHBvcHVsw6FjaWUg4oCTIG7DrXprYSB2cy4gdnlzb2vDoSBwb3B1bMOhY2lhIAp1ZGFqZSREVU0gPC0gaWZlbHNlKHVkYWplJFgyMDIwLlBvcHVsYXRpb24gPCBtZWRpYW4odWRhamUkWDIwMjAuUG9wdWxhdGlvbiwgbmEucm0gPSBUUlVFKSwgCiAgICAgICAgICAgICAgICAgICAgMCwgMSkKCiMgTGluZcOhcm55IG1vZGVsIHMgZHVtbXkgcHJlbWVubm91Cm1vZGVsRF9hdXRvIDwtIGxtKERlbnNpdHkuLnBlci5rbS4uIH4gRFVNICsgWDIwMjAuUG9wdWxhdGlvbiArIEFyZWEuLmttLi4sIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWxEX2F1dG8pCmBgYAoqTW9kZWwgdWthenVqZSwgxb5lIMW+aWFkbmEgeiBwcmVtZW5uw71jaCDigJMgYW5pIGR1bW15IHByZW1lbm7DoSwgcG9wdWzDoWNpYSDEjWkgcm96bG9oYSDigJMgbmllIGplIMWhdGF0aXN0aWNreSB2w716bmFtbsO9bSBwcmVkaWt0b3JvbSBodXN0b3R5IG9ieXZhdGXEvnN0dmEuIEhvZG5vdHkgUsKyIGFqIHVwcmF2ZW7DqWhvIFLCsiBzw7ogdGFrbWVyIG51bG92w6ksIMSNbyB6bmFtZW7DoSwgxb5lIG1vZGVsIG5lZG9rw6HFvmUgdnlzdmV0bGnFpSB2YXJpYWJpbGl0dSBkw6F0LiBJbnRlcmNlcHQgamUgamVkaW7DvSB2w716bmFtbsO9IHBhcmFtZXRlciwgxI1vIG5hem5hxI11amUsIMW+ZSB2eXN2ZXTEvnVqw7pjZSBwcmVtZW5uw6kgbmVwcmlzcGlldmFqw7ogayBwcmVkaWtjaWkgbmFkIHLDoW1lYyBwcmllbWVybmVqIGhvZG5vdHkuIENlbGtvdm8gbW9kZWwgYWtvIGNlbG9rIG9ww6TFpSBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIMSNbyBwb3R2cmR6dWplIGFqIHZ5c29rw6EgcC1ob2Rub3RhIEYtxaF0YXRpc3Rpa3kuKgoKYGBge3J9CiMgUHLDrWtsYWQ6IHByZWRpa2NpYSBEZW5zaXR5IG5hIHrDoWtsYWRlIFBvcHVsYXRpb24gYSBBcmVhCm1vZGVsRF9za2xvbiA8LSBsbShEZW5zaXR5Li5wZXIua20uLiB+IFgyMDIwLlBvcHVsYXRpb24gKyBBcmVhLi5rbS4uLCBkYXRhPXVkYWplKQpzdW1tYXJ5KG1vZGVsRF9za2xvbikKYGBgCipNb2RlbCBzYSBzbmHFvmlsIHByZWRpa292YcWlIGh1c3RvdHUgb2J5dmF0ZcS+c3R2YSAoRGVuc2l0eS4ucGVyLmttLi4pIG5hIHrDoWtsYWRlIHBvcHVsw6FjaWUgKFgyMDIwLlBvcHVsYXRpb24pIGEgcm96bG9oeSAoQXJlYS4ua20uLikuIEhvZG5vdHkga29lZmljaWVudG92IHVrYXp1asO6LCDFvmUgYW5pIHBvcHVsw6FjaWEsIGFuaSByb3psb2hhIG5lbWFqw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnBseXYgbmEgaHVzdG90dSAocC1ob2Rub3R5IDAuOTgxIGEgMC4zODcsIHRlZGEgdmXEvm1pIHZ5c29rbykuIE7DrXprZSBSLXNxdWFyZWQgKDAuMDA0KSB6bmFtZW7DoSwgxb5lIG1vZGVsIHZ5c3ZldMS+dWplIGxlbiB2ZcS+bWkgbWFsw7ogxI1hc8WlIHZhcmlhYmlsaXR5IGh1c3RvdHksIHByYWt0aWNreSB6YW5lZGJhdGXEvm7Dui4gQ2Vsa292byB0ZWRhIHRlbnRvIGxpbmXDoXJueSBtb2RlbCBuaWUgamUgdmhvZG7DvSBuYSBwcmVkaWtjaXUgaHVzdG90eSBvYnl2YXRlxL5zdHZhIHogdMO9Y2h0byBwcmVtZW5uw71jaC4qCgpgYGB7cn0KYW5vdmEobW9kZWwsIG1vZGVsRF9za2xvbikKcmVzZXR0ZXN0KG1vZGVsRF9za2xvbikKYGBgCipWIGtvbWJpbsOhY2lpIHMgcHJlZGNow6FkemFqw7pjaW0gc3VtbWFyeSgpLCBrZGUgbW9kZWwgdnlzdmV0xL5vdmFsIGxlbiB6YW5lZGJhdGXEvm7DuiDEjWFzxaUgdmFyaWFiaWxpdHkgKFLCsiDiiYggMC4wMDQpLCB0byB6bmFtZW7DoTogbW9kZWwgamUgbGluZcOhcm5lICoqc3Byw6F2bmUgxaFwZWNpZmlrb3ZhbsO9KiosIGFsZSBqZSAqKnByYWt0aWNreSBuZXBvdcW+aXRlxL5uw70qKiwgcHJldG/FvmUgcHJlZGlrdG9yeSBwb3B1bMOhY2lhIGEgcm96bG9oYSB2ZcS+bWkgbmV2eXN2ZXTEvnVqw7ogaHVzdG90dS4qCgojIyMgNy4gQm94LUNveG92IHRyYW5zZm9ybWHEjW7DvSB0ZXN0CmBgYHtyfQpsaWJyYXJ5KE1BU1MpCmJveGNveChtb2RlbCkKYGBgCipaIHRvaHRvIGdyYWZ1IHZ5cGzDvXZhLCDFvmUgbmFqcHJhdmRlcG9kb2JuZWrFoWlhIGhvZG5vdGEgcGFyYW1ldHJhIM67IGJvbGEgw7pzcGXFoW5lIG9kaGFkbnV0w6EgcG9tb2NvdSBtZXTDs2R5IG1heGltw6FsbmVqIHZpZXJvaG9kbm9zdGkgKE1MRSkuIEludGVydmFsIHNwb8S+YWhsaXZvc3RpIG9rb2xvIHRlanRvIGhvZG5vdHkgbsOhbSB1a2F6dWplLCB2IGFrb20gcm96c2FodSBzYSBzIHZ5c29rb3UgaXN0b3RvdSAobmFwci4gOTUgJSkgbmFjaMOhZHphIHNrdXRvxI1uw70gcGFyYW1ldGVyLiBUbyB6bmFtZW7DoSwgxb5lIG1vZGVsIGplIGRvYnJlIHByaXNww7Rzb2JlbsO9IGTDoXRhbSBhIG3DoW1lIGt2YW50aWZpa292YW7DuiBtaWVydSBuZWlzdG90eSBvaMS+YWRuZSBvZGhhZHUgzrsuKgoKYGBge3J9CiMgVHJhbnNmb3Jtw6FjaWEgesOhdmlzbGVqIHByZW1lbm5laiAobmFwci4gbW9jbmluYSAxLjgpCm1vZGVsX2xhbWJkYSA8LSBsbShJKChgRGVuc2l0eS4ucGVyLmttLi5gXjEuOCAtIDEpLzEuOCkgfiBgWDIwMjAuUG9wdWxhdGlvbmAgKyBgQXJlYS4ua20uLmAsIGRhdGEgPSB1ZGFqZSkKCiMgVsO9cGlzIHbDvXNsZWRrb3YgbW9kZWx1CnN1bW1hcnkobW9kZWxfbGFtYmRhKQoKIyBSRVNFVCB0ZXN0IHByZSBrb250cm9sdSDFoXBlY2lmaWvDoWNpZSBtb2RlbHUKbGlicmFyeShsbXRlc3QpCnJlc2V0dGVzdChtb2RlbF9sYW1iZGEpCmBgYAoqZlJFU0VUIHRlc3QgcyBwLWhvZG5vdG91IDAuNTUwNSBuYXpuYcSNdWplLCDFvmUgbGluZcOhcm55IHR2YXIgbW9kZWx1IGplIMWhdGF0aXN0aWNreSBzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70gYSBuaWUgamUgZMO0a2F6IHBvdHJlYnkgbmVsaW5lw6FybnljaCB0cmFuc2Zvcm3DoWNpw60gcHJlZGlrdG9yb3YuKgoKCgoKCgoKCgoKCgoKCgoK