Import súboru
Naimportujeme si dataset s údajmi všetkých krajín.
# import the dataset and create a data.frame udaje
udaje_svet <- read.csv("udaje/Life-Expectancy-Data-Updated.csv",header=TRUE,sep=",",dec=".",check.names = TRUE)
head(udaje_svet)
udaje_svet <- udaje_svet[-992,]
Vyberieme si len pozorovania pre Albánsko.
# z databázy udaje_svet si vyberieme len tie pozorovania, ktoré sa týkajú Abánska
udaje <- subset(udaje_svet, Country == "Albania")
Zvolíme si tri premenné ktoré chceme pozorovať, nainštalujeme
potrebné knižnice a vytvoríme regresný model.
# vyrovnanie priebehu očakávanej dĺžky dožitia v čase
model <- lm(Life_expectancy ~ Alcohol_consumption+Adult_mortality+Incidents_HIV,data = udaje)
library(broom)
library(knitr)
library(kableExtra)
# koeficienty regresie
tidy(model) %>%
kable(digits = 3, caption = "Odhadnuté koeficienty regresie") %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE)
Odhadnuté koeficienty regresie
| term |
estimate |
std.error |
statistic |
p.value |
| (Intercept) |
105.254 |
3.678 |
28.614 |
0.000 |
| Alcohol_consumption |
-0.018 |
0.202 |
-0.091 |
0.929 |
| Adult_mortality |
-0.339 |
0.042 |
-8.006 |
0.000 |
| Incidents_HIV |
-44.297 |
31.242 |
-1.418 |
0.184 |
# kvalita vyrovnania
glance(model) %>%
kable(digits = 3, caption = "Ukazovatele kvality vyrovnania") %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE)
Ukazovatele kvality vyrovnania
| r.squared |
adj.r.squared |
sigma |
statistic |
p.value |
df |
logLik |
AIC |
BIC |
deviance |
df.residual |
nobs |
| 0.953 |
0.941 |
0.299 |
74.885 |
0 |
3 |
-0.847 |
11.694 |
15.234 |
0.983 |
11 |
15 |
NA
Pre x vyberieme tri už zvolené premenné z dát, vypočítame medzi nimi
korelačnú maticu s ignorovaním chýbajúcich hodnôt a výsledné korelácie
zaokrúhlime na štyri desatinné miesta.
# výber premenných
X <- udaje[, c("Alcohol_consumption", "Adult_mortality", "Incidents_HIV")]
# výpočet korelačnej matice
cor_matrix <- cor(X, use = "complete.obs")
# zaokrúhlenie
round(cor_matrix, 4)
Alcohol_consumption Adult_mortality Incidents_HIV
Alcohol_consumption 1.0000 0.0106 0.4130
Adult_mortality 0.0106 1.0000 -0.8066
Incidents_HIV 0.4130 -0.8066 1.0000
Vidíme, že najsilnejší vzťah je medzi Adult_mortality a Incidents_HIV
(korelácia −0.8066), čo znamená silnú negatívnu závislosť, keď jedna
premenná rastie, druhá klesá.
Vzťah medzi Alcohol_consumption a Incidents_HIV je stredne silný
pozitívny (0.4130) a medzi Alcohol_consumption a Adult_mortality je
takmer nulový (0.0106), teda prakticky žiadny.
S pomocou knižnice knitr si môžeme vytvoriť aj vizuálne krajšiu a
prehľadnejšiu tabuľku pre korelačnú maticu.
library(knitr)
round(cor_matrix, 4) %>%
kable(caption = "Korelačná matica")
Korelačná matica
|
Alcohol_consumption |
Adult_mortality |
Incidents_HIV |
| Alcohol_consumption |
1.0000 |
0.0106 |
0.4130 |
| Adult_mortality |
0.0106 |
1.0000 |
-0.8066 |
| Incidents_HIV |
0.4130 |
-0.8066 |
1.0000 |
Následne spravíme cor testy kedy ždy kombinujeme každú premennú s
každou a pozorujeme výsledky p- value.
cor.test (udaje$Adult_mortality, udaje$Alcohol_consumption)
Pearson's product-moment correlation
data: udaje$Adult_mortality and udaje$Alcohol_consumption
t = 0.038131, df = 13, p-value = 0.9702
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.5044203 0.5200209
sample estimates:
cor
0.0105751
cor.test (udaje$Alcohol_consumption, udaje$Incidents_HIV)
Pearson's product-moment correlation
data: udaje$Alcohol_consumption and udaje$Incidents_HIV
t = 1.6351, df = 13, p-value = 0.126
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.1258822 0.7636995
sample estimates:
cor
0.4130138
cor.test (udaje$Adult_mortality, udaje$Incidents_HIV )
Pearson's product-moment correlation
data: udaje$Adult_mortality and udaje$Incidents_HIV
t = -4.9197, df = 13, p-value = 0.0002801
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
-0.9332439 -0.5015452
sample estimates:
cor
-0.8065793
Medzi premennými Adult_mortality a Alcohol_consumption je p-value
0.9702, čo je veľmi vysoká hodnota, takže vzťah nie je štatisticky
významný. Medzi Alcohol_consumption a Incidents_HIV je p-value 0.126, čo
je tiež viac ako 0.05, preto ani tento vzťah nie je štatisticky
významný. Naopak medzi Adult_mortality a Incidents_HIV je p-value
0.0002801, čo je menej ako 0.05, takže tento vzťah je štatisticky
významný.
Multicollinearity detection and testing
V prípade potreby nainštalujeme balík corrplot, následne ho načítame
a zobrazíme korelačnú maticu ako graf s číselnými hodnotami v hornej
časti.
if (!requireNamespace("corrplot", quietly = TRUE)) {
install.packages("corrplot")}
library(corrplot)
corrplot(cor_matrix, method = "number", type = "upper")

Vidíme výrazný vzťah medzi Adult_mortality a Incidience_HIV s
hodnotou -0.81, ktorá sa zobrazuje červenou farbou.
Variance Inflation Factor
Pre premennú \(x_j\) definujeme
\[
VIF_j = \frac{1}{1-R_j^2},
\]
kde \(R_j^2\) je koeficient
determinácie z pomocnej regresie, v ktorej je \(x_j\) vysvetľovaná ostatnými
regresormi.
Ak je \(R_j^2\) blízko jednej, potom
je \(VIF_j\) veľký a premenná \(x_j\) je silno lineárne vysvetliteľná
ostatnými premennými.
V prípade potreby nainštalujeme balík car. # install.packages(“car”)
# run once if not installed
Urobíme načítanie balíka car, následne vypočítame hodnoty VIF
(Variance Inflation Factors) pre model model a zobrazíme ich, aby sme
posúdili multikolinearitu medzi premennými.
library(car)
# Variance Inflation Factors
vif_values <- vif(model)
vif_values
Alcohol_consumption Adult_mortality Incidents_HIV
2.035214 4.830860 5.823734
Interpretation:
- \(VIF_j = 1\): žiadna
multikolinearita,
- \(1 < VIF_j < 5\): mierna
multikolinearita
- \(VIF_j \geq 5\): silná
multikolinearita (niektorí autori používajú prísnejší prah \(VIF_j \geq 10\)).
Číslo podmienenosti
Číslo podmienenosti je založené na vlastných číslach matice \(X'X\). Ak sú vlastné čísla veľmi
rozdielne, matica je zle podmienená.
\[
\kappa = \sqrt{\frac{\lambda_{\max}}{\lambda_{\min}}}.
\]
Urobíme štandardizáciu premenných v matici X, následne
vypočítame vlastné čísla korelačnej matice a z nich určíme podmienené
číslo (condition number), ktoré nám slúži na posúdenie multikolinearity
a stability modelu, a potom zobrazíme vlastné čísla aj výsledné
podmienené číslo.
X_scaled <- scale(X)
eigen_values <- eigen(cor(X_scaled))$values
condition_number <- sqrt(max(eigen_values) / min(eigen_values))
eigen_values
condition_number
Interpretácia čísla podmienenosti: - \(\kappa \approx 1\): žiadna
multikolinearita, - \(\kappa > 10\):
mierna multikolinearita, - \(\kappa >
30\): silná multikolinearita.
Malá p-hodnota znamená, že zamietame hypotézu \(R=I_k\), teda medzi vysvetľujúcimi
premennými existuje štatisticky významná korelačná štruktúra.
Eliminácia problému multikolinearity
Multikolinearita nie je porušením exogenity. Nie je teda automaticky
dôvodom na zamietnutie OLS modelu. Problém je hlavne inferenčný: veľké
štandardné chyby a nestabilné individuálne koeficienty.
Možné riešenia:
- získať viac dát,
- odstrániť alebo spojiť silno korelované premenné,
- transformovať premenné,
- použiť teoretické obmedzenia,
- použiť regularizačné metódy, napríklad ridge regresiu.
Odstránenie jednej z korelovaných premenných
Ak sú dve premenné takmer rovnaké a ekonomická teória nevyžaduje obe,
môžeme jednu z nich vynechať. Odstránime premennú Adult_mortality a
pozorujeme výsledky.
model_reduced <- lm(Life_expectancy ~ Alcohol_consumption + Incidents_HIV, data = udaje)
summary(model)
Call:
lm(formula = Life_expectancy ~ Alcohol_consumption + Adult_mortality +
Incidents_HIV, data = udaje)
Residuals:
Min 1Q Median 3Q Max
-0.30738 -0.07191 0.00501 0.06394 0.33087
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 80.406412 0.629177 127.796 < 2e-16 ***
Alcohol_consumption -0.009374 0.038803 -0.242 0.813
Adult_mortality -0.056383 0.002029 -27.784 2.92e-12 ***
Incidents_HIV 1.342110 0.899627 1.492 0.162
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.1938 on 12 degrees of freedom
Multiple R-squared: 0.9876, Adjusted R-squared: 0.9845
F-statistic: 318.6 on 3 and 12 DF, p-value: 1.06e-11
summary(model_reduced)
Call:
lm(formula = Life_expectancy ~ Alcohol_consumption + Incidents_HIV,
data = udaje)
Residuals:
Min 1Q Median 3Q Max
-1.4850 -1.0324 -0.5959 0.9277 2.5740
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 65.54601 2.57299 25.475 1.76e-12 ***
Alcohol_consumption -0.08151 0.30065 -0.271 0.791
Incidents_HIV 10.91938 6.45281 1.692 0.114
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1.505 on 13 degrees of freedom
Multiple R-squared: 0.19, Adjusted R-squared: 0.06535
F-statistic: 1.524 on 2 and 13 DF, p-value: 0.2542
V pôvodnom modeli, kde boli zahrnuté všetky tri premenné
(Alcohol_consumption, Adult_mortality a Incidents_HIV), model
vysvetľoval veľmi vysokú časť variability v očakávanej dĺžke života,
keďže R² = 0.9876 a model bol celkovo štatisticky významný (p-value ≈
1.06e-11). Z jednotlivých premenných sa však ako štatisticky významná
ukázala iba Adult_mortality (p < 0.001), zatiaľ čo
Alcohol_consumption aj Incidents_HIV neboli významné.
Po odstránení premennej Adult_mortality sa model výrazne zhoršil,
keďže R² kleslo na 0.19 a upravené R² dokonca na 0.065, čo znamená, že
model už vysvetľuje len malú časť variability. Celý model už nie je
štatisticky významný (p-value = 0.2542) a ani jednotlivé premenné
(Alcohol_consumption a Incidents_HIV) nie sú štatisticky významné.
Adult_mortality je teda kľúčová premenná v modeli, bez nej model
stráca vysvetľovaciu silu a výrazne sa zhoršuje jeho kvalita.
LS0tCnRpdGxlOiAiTXVsdGlrb2xpbmVhcml0YSB2IGxpbmXDoXJuZWogcmVncmVzaWkiCmF1dGhvcjogIk5hdMOhbGlhIEt1bm92w6EiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKLS0tCiMjICBJbXBvcnQgc8O6Ym9ydQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKc2V0LnNlZWQoMTIzKQpgYGAKCk5haW1wb3J0dWplbWUgc2kgZGF0YXNldCBzIMO6ZGFqbWkgdsWhZXRrw71jaCBrcmFqw61uLgpgYGB7cn0KIyBpbXBvcnQgdGhlIGRhdGFzZXQgYW5kIGNyZWF0ZSBhIGRhdGEuZnJhbWUgdWRhamUKdWRhamVfc3ZldCA8LSByZWFkLmNzdigidWRhamUvTGlmZS1FeHBlY3RhbmN5LURhdGEtVXBkYXRlZC5jc3YiLGhlYWRlcj1UUlVFLHNlcD0iLCIsZGVjPSIuIixjaGVjay5uYW1lcyA9IFRSVUUpCmhlYWQodWRhamVfc3ZldCkKIHVkYWplX3N2ZXQgPC0gdWRhamVfc3ZldFstOTkyLF0KYGBgCgpWeWJlcmllbWUgc2kgbGVuIHBvem9yb3ZhbmlhIHByZSBBbGLDoW5za28uCmBgYHtyfQojIHogZGF0YWLDoXp5IHVkYWplX3N2ZXQgc2kgdnliZXJpZW1lIGxlbiB0aWUgcG96b3JvdmFuaWEsIGt0b3LDqSBzYSB0w71rYWrDuiBBYsOhbnNrYSAKdWRhamUgPC0gc3Vic2V0KHVkYWplX3N2ZXQsIENvdW50cnkgPT0gIkFsYmFuaWEiKQpgYGAKClp2b2zDrW1lIHNpIHRyaSBwcmVtZW5uw6kga3RvcsOpIGNoY2VtZSBwb3pvcm92YcWlLCBuYWluxaF0YWx1amVtZSBwb3RyZWJuw6kga25pxb5uaWNlIGEgdnl0dm9yw61tZSByZWdyZXNuw70gbW9kZWwuCmBgYHtyfQojIHZ5cm92bmFuaWUgcHJpZWJlaHUgb8SNYWvDoXZhbmVqIGTEusW+a3kgZG/Fvml0aWEgdiDEjWFzZQptb2RlbCA8LSBsbShMaWZlX2V4cGVjdGFuY3kgfiBBbGNvaG9sX2NvbnN1bXB0aW9uK0FkdWx0X21vcnRhbGl0eStJbmNpZGVudHNfSElWLGRhdGEgPSB1ZGFqZSkKbGlicmFyeShicm9vbSkKbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQoKIyBrb2VmaWNpZW50eSByZWdyZXNpZQp0aWR5KG1vZGVsKSAlPiUKICBrYWJsZShkaWdpdHMgPSAzLCBjYXB0aW9uID0gIk9kaGFkbnV0w6kga29lZmljaWVudHkgcmVncmVzaWUiKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRkFMU0UpCgojIGt2YWxpdGEgdnlyb3ZuYW5pYQpnbGFuY2UobW9kZWwpICU+JQogIGthYmxlKGRpZ2l0cyA9IDMsIGNhcHRpb24gPSAiVWthem92YXRlbGUga3ZhbGl0eSB2eXJvdm5hbmlhIikgJT4lCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEZBTFNFKQoKYGBgClByZSB4IHZ5YmVyaWVtZSB0cmkgdcW+IHp2b2xlbsOpIHByZW1lbm7DqSB6IGTDoXQsIHZ5cG/EjcOtdGFtZSBtZWR6aSBuaW1pIGtvcmVsYcSNbsO6IG1hdGljdSBzIGlnbm9yb3ZhbsOtbSBjaMO9YmFqw7pjaWNoIGhvZG7DtHQgYSB2w71zbGVkbsOpIGtvcmVsw6FjaWUgemFva3LDumhsaW1lIG5hIMWhdHlyaSBkZXNhdGlubsOpIG1pZXN0YS4KYGBge3J9CiMgdsO9YmVyIHByZW1lbm7DvWNoClggPC0gdWRhamVbLCBjKCJBbGNvaG9sX2NvbnN1bXB0aW9uIiwgIkFkdWx0X21vcnRhbGl0eSIsICJJbmNpZGVudHNfSElWIildCgojIHbDvXBvxI1ldCBrb3JlbGHEjW5laiBtYXRpY2UKY29yX21hdHJpeCA8LSBjb3IoWCwgdXNlID0gImNvbXBsZXRlLm9icyIpCgojIHphb2tyw7pobGVuaWUKcm91bmQoY29yX21hdHJpeCwgNCkKYGBgClZpZMOtbWUsIMW+ZSBuYWpzaWxuZWrFocOtIHZ6xaVhaCBqZSBtZWR6aSBBZHVsdF9tb3J0YWxpdHkgYSBJbmNpZGVudHNfSElWIChrb3JlbMOhY2lhIOKIkjAuODA2NiksIMSNbyB6bmFtZW7DoSBzaWxuw7ogbmVnYXTDrXZudSB6w6F2aXNsb3PFpSwga2XEjyBqZWRuYSBwcmVtZW5uw6EgcmFzdGllLCBkcnVow6Ega2xlc8OhLgoKVnrFpWFoIG1lZHppIEFsY29ob2xfY29uc3VtcHRpb24gYSBJbmNpZGVudHNfSElWIGplIHN0cmVkbmUgc2lsbsO9IHBveml0w612bnkgKDAuNDEzMCkgYSBtZWR6aSBBbGNvaG9sX2NvbnN1bXB0aW9uIGEgQWR1bHRfbW9ydGFsaXR5IGplIHRha21lciBudWxvdsO9ICgwLjAxMDYpLCB0ZWRhIHByYWt0aWNreSDFvmlhZG55LgoKCgoKUyBwb21vY291IGtuacW+bmljZSBrbml0ciBzaSBtw7TFvmVtZSB2eXR2b3JpxaUgYWogdml6dcOhbG5lIGtyYWrFoWl1IGEgcHJlaMS+YWRuZWrFoWl1IHRhYnXEvmt1IHByZSBrb3JlbGHEjW7DuiBtYXRpY3UuCmBgYHtyfQpsaWJyYXJ5KGtuaXRyKQpyb3VuZChjb3JfbWF0cml4LCA0KSAlPiUKICBrYWJsZShjYXB0aW9uID0gIktvcmVsYcSNbsOhIG1hdGljYSIpCmBgYAoKCgpOw6FzbGVkbmUgc3ByYXbDrW1lIGNvciB0ZXN0eSBrZWR5IMW+ZHkga29tYmludWplbWUga2HFvmTDuiBwcmVtZW5uw7ogcyBrYcW+ZG91IGEgcG96b3J1amVtZSB2w71zbGVka3kgcC0gdmFsdWUuCmBgYHtyfQpjb3IudGVzdCAodWRhamUkQWR1bHRfbW9ydGFsaXR5LCB1ZGFqZSRBbGNvaG9sX2NvbnN1bXB0aW9uKQpjb3IudGVzdCAodWRhamUkQWxjb2hvbF9jb25zdW1wdGlvbiwgdWRhamUkSW5jaWRlbnRzX0hJVikKY29yLnRlc3QgKHVkYWplJEFkdWx0X21vcnRhbGl0eSwgdWRhamUkSW5jaWRlbnRzX0hJViApCmBgYApNZWR6aSBwcmVtZW5uw71taSBBZHVsdF9tb3J0YWxpdHkgYSBBbGNvaG9sX2NvbnN1bXB0aW9uIGplIHAtdmFsdWUgMC45NzAyLCDEjW8gamUgdmXEvm1pIHZ5c29rw6EgaG9kbm90YSwgdGFrxb5lIHZ6xaVhaCBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70uIE1lZHppIEFsY29ob2xfY29uc3VtcHRpb24gYSBJbmNpZGVudHNfSElWIGplIHAtdmFsdWUgMC4xMjYsIMSNbyBqZSB0aWXFviB2aWFjIGFrbyAwLjA1LCBwcmV0byBhbmkgdGVudG8gdnrFpWFoIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4gTmFvcGFrIG1lZHppIEFkdWx0X21vcnRhbGl0eSBhIEluY2lkZW50c19ISVYgamUgcC12YWx1ZSAwLjAwMDI4MDEsIMSNbyBqZSBtZW5laiBha28gMC4wNSwgdGFrxb5lIHRlbnRvIHZ6xaVhaCBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4KCgojIE11bHRpY29sbGluZWFyaXR5IGRldGVjdGlvbiBhbmQgdGVzdGluZwpWIHByw61wYWRlIHBvdHJlYnkgbmFpbsWhdGFsdWplbWUgYmFsw61rIGNvcnJwbG90LCBuw6FzbGVkbmUgaG8gbmHEjcOtdGFtZSBhIHpvYnJhesOtbWUga29yZWxhxI1uw7ogbWF0aWN1IGFrbyBncmFmIHMgxI3DrXNlbG7DvW1pIGhvZG5vdGFtaSB2IGhvcm5laiDEjWFzdGkuCgpgYGB7ciBjb3JyZWxhdGlvbi1wbG90fQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImNvcnJwbG90IiwgcXVpZXRseSA9IFRSVUUpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiY29ycnBsb3QiKX0KCmxpYnJhcnkoY29ycnBsb3QpCgpjb3JycGxvdChjb3JfbWF0cml4LCBtZXRob2QgPSAibnVtYmVyIiwgdHlwZSA9ICJ1cHBlciIpCmBgYApWaWTDrW1lIHbDvXJhem7DvSB2esWlYWggbWVkemkgQWR1bHRfbW9ydGFsaXR5IGEgSW5jaWRpZW5jZV9ISVYgcyBob2Rub3RvdSAtMC44MSwga3RvcsOhIHNhIHpvYnJhenVqZSDEjWVydmVub3UgZmFyYm91LgoKIyMgIFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3IKClByZSBwcmVtZW5uw7ogXCh4X2pcKSBkZWZpbnVqZW1lCgpcWwpWSUZfaiA9IFxmcmFjezF9ezEtUl9qXjJ9LApcXQoKa2RlIFwoUl9qXjJcKSBqZSBrb2VmaWNpZW50IGRldGVybWluw6FjaWUgeiBwb21vY25laiByZWdyZXNpZSwgdiBrdG9yZWogamUgXCh4X2pcKSB2eXN2ZXTEvm92YW7DoSBvc3RhdG7DvW1pIHJlZ3Jlc29ybWkuCgpBayBqZSBcKFJfal4yXCkgYmzDrXprbyBqZWRuZWosIHBvdG9tIGplIFwoVklGX2pcKSB2ZcS+a8O9IGEgcHJlbWVubsOhIFwoeF9qXCkgamUgc2lsbm8gbGluZcOhcm5lIHZ5c3ZldGxpdGXEvm7DoSBvc3RhdG7DvW1pIHByZW1lbm7DvW1pLgoKViBwcsOtcGFkZSBwb3RyZWJ5IG5haW7FoXRhbHVqZW1lIGJhbMOtayBjYXIuCiMgaW5zdGFsbC5wYWNrYWdlcygiY2FyIikgICMgcnVuIG9uY2UgaWYgbm90IGluc3RhbGxlZAoKVXJvYsOtbWUgbmHEjcOtdGFuaWUgYmFsw61rYSBjYXIsIG7DoXNsZWRuZSB2eXBvxI3DrXRhbWUgaG9kbm90eSBWSUYgKFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3JzKSBwcmUgbW9kZWwgbW9kZWwgYSB6b2JyYXrDrW1lIGljaCwgYWJ5IHNtZSBwb3PDumRpbGkgbXVsdGlrb2xpbmVhcml0dSBtZWR6aSBwcmVtZW5uw71taS4KYGBge3J9CmxpYnJhcnkoY2FyKQojIFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3JzCnZpZl92YWx1ZXMgPC0gdmlmKG1vZGVsKQoKdmlmX3ZhbHVlcwpgYGAKCioqSW50ZXJwcmV0YXRpb246KioKCi0gXChWSUZfaiA9IDFcKTogxb5pYWRuYSBtdWx0aWtvbGluZWFyaXRhLAotIFwoMSA8IFZJRl9qIDwgNVwpOiBtaWVybmEgbXVsdGlrb2xpbmVhcml0YQotIFwoVklGX2ogXGdlcSA1XCk6IHNpbG7DoSBtdWx0aWtvbGluZWFyaXRhIChuaWVrdG9yw60gYXV0b3JpIHBvdcW+w612YWrDuiBwcsOtc25lasWhw60gcHJhaCBcKFZJRl9qIFxnZXEgMTBcKSkuCgojIyAgxIzDrXNsbyBwb2RtaWVuZW5vc3RpCgrEjMOtc2xvIHBvZG1pZW5lbm9zdGkgamUgemFsb8W+ZW7DqSBuYSB2bGFzdG7DvWNoIMSNw61zbGFjaCBtYXRpY2UgXChYJ1hcKS4gQWsgc8O6IHZsYXN0bsOpIMSNw61zbGEgdmXEvm1pIHJvemRpZWxuZSwgbWF0aWNhIGplIHpsZSBwb2RtaWVuZW7DoS4KClxbClxrYXBwYSA9IFxzcXJ0e1xmcmFje1xsYW1iZGFfe1xtYXh9fXtcbGFtYmRhX3tcbWlufX19LgpcXQoKVXJvYsOtbWUgxaF0YW5kYXJkaXrDoWNpdSBwcmVtZW5uw71jaCB2IG1hdGljaSBgWGAsIG7DoXNsZWRuZSB2eXBvxI3DrXRhbWUgdmxhc3Ruw6kgxI3DrXNsYSBrb3JlbGHEjW5laiBtYXRpY2UgYSB6IG5pY2ggdXLEjcOtbWUgcG9kbWllbmVuw6kgxI3DrXNsbyAoY29uZGl0aW9uIG51bWJlciksIGt0b3LDqSBuw6FtIHNsw7rFvmkgbmEgcG9zw7pkZW5pZSBtdWx0aWtvbGluZWFyaXR5IGEgc3RhYmlsaXR5IG1vZGVsdSwgYSBwb3RvbSB6b2JyYXrDrW1lIHZsYXN0bsOpIMSNw61zbGEgYWogdsO9c2xlZG7DqSBwb2RtaWVuZW7DqSDEjcOtc2xvLgoKYGBge3IgY29uZGl0aW9uLW51bWJlcn0KWF9zY2FsZWQgPC0gc2NhbGUoWCkKZWlnZW5fdmFsdWVzIDwtIGVpZ2VuKGNvcihYX3NjYWxlZCkpJHZhbHVlcwoKY29uZGl0aW9uX251bWJlciA8LSBzcXJ0KG1heChlaWdlbl92YWx1ZXMpIC8gbWluKGVpZ2VuX3ZhbHVlcykpCmVpZ2VuX3ZhbHVlcwpjb25kaXRpb25fbnVtYmVyCmBgYAoKICAKKipJbnRlcnByZXTDoWNpYSDEjcOtc2xhIHBvZG1pZW5lbm9zdGk6KiogCi0gXChca2FwcGEgXGFwcHJveCAxXCk6IMW+aWFkbmEgbXVsdGlrb2xpbmVhcml0YSwKLSBcKFxrYXBwYSA+IDEwXCk6IG1pZXJuYSBtdWx0aWtvbGluZWFyaXRhLAotIFwoXGthcHBhID4gMzBcKTogc2lsbsOhIG11bHRpa29saW5lYXJpdGEuCgogIApNYWzDoSBwLWhvZG5vdGEgem5hbWVuw6EsIMW+ZSB6YW1pZXRhbWUgaHlwb3TDqXp1IFwoUj1JX2tcKSwgdGVkYSBtZWR6aSB2eXN2ZXTEvnVqw7pjaW1pIHByZW1lbm7DvW1pIGV4aXN0dWplIMWhdGF0aXN0aWNreSB2w716bmFtbsOhIGtvcmVsYcSNbsOhIMWhdHJ1a3TDunJhLgoKCiMgIEVsaW1pbsOhY2lhIHByb2Jsw6ltdSBtdWx0aWtvbGluZWFyaXR5CgpNdWx0aWtvbGluZWFyaXRhIG5pZSBqZSBwb3J1xaFlbsOtbSBleG9nZW5pdHkuIE5pZSBqZSB0ZWRhIGF1dG9tYXRpY2t5IGTDtHZvZG9tIG5hIHphbWlldG51dGllIE9MUyBtb2RlbHUuIFByb2Jsw6ltIGplIGhsYXZuZSBpbmZlcmVuxI1uw706IHZlxL5rw6kgxaF0YW5kYXJkbsOpIGNoeWJ5IGEgbmVzdGFiaWxuw6kgaW5kaXZpZHXDoWxuZSBrb2VmaWNpZW50eS4KCk1vxb5uw6kgcmllxaFlbmlhOgoKMS4gesOtc2thxaUgdmlhYyBkw6F0LAoyLiBvZHN0csOhbmnFpSBhbGVibyBzcG9qacWlIHNpbG5vIGtvcmVsb3ZhbsOpIHByZW1lbm7DqSwKMy4gdHJhbnNmb3Jtb3ZhxaUgcHJlbWVubsOpLAo0LiBwb3XFvmnFpSB0ZW9yZXRpY2vDqSBvYm1lZHplbmlhLAo1LiBwb3XFvmnFpSByZWd1bGFyaXphxI1uw6kgbWV0w7NkeSwgbmFwcsOta2xhZCByaWRnZSByZWdyZXNpdS4KCiMjICBPZHN0csOhbmVuaWUgamVkbmVqIHoga29yZWxvdmFuw71jaCBwcmVtZW5uw71jaAoKQWsgc8O6IGR2ZSBwcmVtZW5uw6kgdGFrbWVyIHJvdm5ha8OpIGEgZWtvbm9taWNrw6EgdGXDs3JpYSBuZXZ5xb5hZHVqZSBvYmUsIG3DtMW+ZW1lIGplZG51IHogbmljaCB2eW5lY2hhxaUuIE9kc3Ryw6FuaW1lIHByZW1lbm7DuiBBZHVsdF9tb3J0YWxpdHkgYSBwb3pvcnVqZW1lIHbDvXNsZWRreS4KCmBgYHtyIHJlZHVjZWQtbW9kZWx9Cm1vZGVsX3JlZHVjZWQgPC0gbG0oTGlmZV9leHBlY3RhbmN5IH4gQWxjb2hvbF9jb25zdW1wdGlvbiArIEluY2lkZW50c19ISVYsIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWwpCnN1bW1hcnkobW9kZWxfcmVkdWNlZCkKYGBgCgpWIHDDtHZvZG5vbSBtb2RlbGksIGtkZSBib2xpIHphaHJudXTDqSB2xaFldGt5IHRyaSBwcmVtZW5uw6kgKEFsY29ob2xfY29uc3VtcHRpb24sIEFkdWx0X21vcnRhbGl0eSBhIEluY2lkZW50c19ISVYpLCBtb2RlbCB2eXN2ZXTEvm92YWwgdmXEvm1pIHZ5c29rw7ogxI1hc8WlIHZhcmlhYmlsaXR5IHYgb8SNYWvDoXZhbmVqIGTEusW+a2Ugxb5pdm90YSwga2XEj8W+ZSBSwrIgPSAwLjk4NzYgYSBtb2RlbCBib2wgY2Vsa292byDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSAocC12YWx1ZSDiiYggMS4wNmUtMTEpLiBaIGplZG5vdGxpdsO9Y2ggcHJlbWVubsO9Y2ggc2EgdsWhYWsgYWtvIMWhdGF0aXN0aWNreSB2w716bmFtbsOhIHVrw6F6YWxhIGliYSBBZHVsdF9tb3J0YWxpdHkgKHAgPCAwLjAwMSksIHphdGlhxL4gxI1vIEFsY29ob2xfY29uc3VtcHRpb24gYWogSW5jaWRlbnRzX0hJViBuZWJvbGkgdsO9em5hbW7DqS4KClBvIG9kc3Ryw6FuZW7DrSBwcmVtZW5uZWogQWR1bHRfbW9ydGFsaXR5IHNhIG1vZGVsIHbDvXJhem5lIHpob3LFoWlsLCBrZcSPxb5lIFLCsiBrbGVzbG8gbmEgMC4xOSBhIHVwcmF2ZW7DqSBSwrIgZG9rb25jYSBuYSAwLjA2NSwgxI1vIHpuYW1lbsOhLCDFvmUgbW9kZWwgdcW+IHZ5c3ZldMS+dWplIGxlbiBtYWzDuiDEjWFzxaUgdmFyaWFiaWxpdHkuIENlbMO9IG1vZGVsIHXFviBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gKHAtdmFsdWUgPSAwLjI1NDIpIGEgYW5pIGplZG5vdGxpdsOpIHByZW1lbm7DqSAoQWxjb2hvbF9jb25zdW1wdGlvbiBhIEluY2lkZW50c19ISVYpIG5pZSBzw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6kuCgpBZHVsdF9tb3J0YWxpdHkgamUgdGVkYSBrxL7DusSNb3bDoSBwcmVtZW5uw6EgdiBtb2RlbGksIGJleiBuZWogbW9kZWwgc3Ryw6FjYSB2eXN2ZXTEvm92YWNpdSBzaWx1IGEgdsO9cmF6bmUgc2EgemhvcsWhdWplIGplaG8ga3ZhbGl0YS4K