1. Úvod a údaje
Cieľom tejto úlohy je analyzovať vzťahy medzi logaritmickými dennými
výnosmi vybraného akciového titulu a výnosmi ďalších finančných aktív.
Konkrétne sa zameriavame na spoločnosť Apple (AAPL) a skúmame, do akej
miery sa jej denné výnosy dajú vysvetliť vývojom na trhu so zlatom
(GLD), energetickým sektorom (XLE) a celkovým trhovým indexom S&P
500 (SPY).
Výber aktív umožňuje porovnať správanie technologickej akcie s
rôznymi časťami finančného trhu — komoditami, sektorovými ETF a širokým
trhovým benchmarkom. Použitím denných logaritmických výnosov eliminujeme
vplyv úrovne cien a získavame časový rad vhodný na ekonometrickú
analýzu.
Úvod do problému a stanovenie hypotéz
Denné výnosy akciových titulov reagujú na široké spektrum faktorov,
ktoré zahŕňajú celkový trhový sentiment, vývoj v jednotlivých sektoroch
aj pohyby alternatívnych aktív. Technologické spoločnosti, medzi ktoré
patrí aj Apple (AAPL), bývajú typicky veľmi citlivé na zmeny vo
výkonnosti celého trhu, ale ich správanie môže byť ovplyvnené aj
špecifickými segmentmi, ako sú komodity alebo odvetvové ETF. V tejto
úlohe preto analyzujeme, ako sa denné logaritmické výnosy spoločnosti
Apple vyvíjajú v závislosti od výnosov troch ďalších aktív: indexu
S&P 500 reprezentovaného ETF SPY, zlata prostredníctvom ETF GLD a
energetického sektora cez ETF XLE. Cieľom je zistiť, či zmeny v týchto
aktívach dokážu štatisticky významne vysvetliť správanie sa výnosov
Apple a či má najväčší vplyv práve celkový trh, ako by naznačovala
ekonomická intuícia.
Naša pracovná hypotéza predpokladá, že všetky tri vysvetľujúce
premenné – výnosy indexu SPY, výnosy zlata (GLD) a výnosy energetického
sektora (XLE) – majú štatisticky významný vplyv na denné logaritmické
výnosy spoločnosti Apple (AAPL). Očakávame pritom, že výnosy trhu
reprezentované ETF SPY budú mať pozitívny vplyv, keďže Apple je súčasťou
indexu S&P 500 a jeho cena spravidla rastie v súlade s celkovým
trhovým sentimentom.
V prípade výnosov zlata predpokladáme, že vplyv môže byť buď mierne
negatívny, alebo veľmi slabý, keďže zlato často funguje ako bezpečné
aktívum a jeho výnosy sa môžu pohybovať opačne než akciové trhy. Pri
energetickom sektore očakávame, že jeho výnosy budú mať kladný vplyv na
výnosy Apple, keďže rast energetického sektora býva spojený s lepším
makroekonomickým prostredím, vyššou ekonomickou aktivitou a celkovo
pozitívnym sentimentom investorov.
Pracovná hypotéza teda tvrdí, že všetky tri koeficienty v regresnom
modeli sú štatisticky významné, pričom odhadovaný koeficient pri SPY by
mal byť kladný, koeficient pri XLE taktiež kladný a koeficient pri GLD
mierne záporný alebo blízko nule. Spoločná nulová hypotéza tvrdí, že
žiadna z vysvetľujúcich premenných nevysvetľuje správanie výnosov Apple,
čo znamená, že všetky koeficienty sú rovné nule; túto hypotézu testujeme
F-testom v rámci lineárneho regresného modelu.
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\))
Import údajov
Na začiatok si importujeme údaje. Vybrala som si dáta o cene akcií
spoločnosti Apple a ETF’s, ktoré opisujú vývoj trhu zlata (GLD),
energetického sektora (XLE) a (SPY), ktoré kopíruje trh S&P 500.
Dáta sú za obdobie 1.1.2024-1.1.2025. Údaje sú stiahnuté priamo z
internetu, z databázy YahooFinance. Tieto hodnoty predstavujú vývoj
cien, na ktorom budeme následne analyzovať logaritmické výnosnosti a
vzájomné vzťahy medzi výnosnosťami daných aktív.
tickers <- c("AAPL", "GLD", "XLE", "SPY") # Apple, Gold ETF, Energy ETF, S&P500 ETF
getSymbols(tickers, from = "2024-01-01", to = "2025-01-01")
[1] "AAPL" "GLD" "XLE" "SPY"
data <- merge(Cl(AAPL), Cl(GLD), Cl(XLE), Cl(SPY))
colnames(data) <- tickers
ret <- na.omit(diff(log(data)))
colnames(ret) <- paste0(colnames(ret), "_ret")
ret_df <- na.omit(as.data.frame(ret))
head(ret_df)
Deskriptívna štatistika
V nasledujúcej časti vykonávame deskriptívnu štatistiku denných
logaritmických výnosov štyroch finančných aktív, aby sme získali
základný prehľad o ich rozdelení a volatilite.
AAPL_ret GLD_ret XLE_ret SPY_ret
Min. :-0.049366 Min. :-0.0363355 Min. :-3.276e-02 Min. :-0.030257
1st Qu.:-0.006736 1st Qu.:-0.0042584 1st Qu.:-6.372e-03 1st Qu.:-0.003000
Median : 0.001595 Median : 0.0016010 Median : 1.543e-03 Median : 0.001093
Mean : 0.001193 Mean : 0.0009509 Mean : 4.302e-05 Mean : 0.000857
3rd Qu.: 0.009288 3rd Qu.: 0.0073401 3rd Qu.: 6.793e-03 3rd Qu.: 0.005756
Max. : 0.070131 Max. : 0.0221408 Max. : 3.691e-02 Max. : 0.024561
Apple
Rozpätie výnosov sa pohybuje od –4,94 % po +7,01 %, čo z aktív robí
najvolatilnejšie. Priemerný denný výnos (0,12 %) aj medián (0,16 %) sú
pozitívne a naznačujú mierny rastový trend, zatiaľ čo bežné denné pohyby
(IQR) sa pohybujú do ±1 %.
Gold
Výnosy zlata kolíšu medzi –3,63 % a +2,21 %, čo je menej ako pri
AAPL. Priemer (0,095 %) aj medián (0,16 %) sú mierne pozitívne. Nižší
IQR potvrdzuje stabilnejší charakter zlata ako defenzívneho aktíva.
XLE
Rozpätie od –3,28 % do +3,69 % naznačuje výraznejšiu volatilitu
typickú pre energetický sektor. Priemerný výnos je takmer nulový, čo
odráža neutrálne dlhodobé smerovanie. Medián (0,15 %) je pozitívny, no
variabilita je vyššia ako pri SPY či GLD.
SPY
S&P 500 má najnižšie rozpätie výnosov (–3,02 % až +2,45 %) aj
najmenšie medzikvartilové rozpätie, čo potvrdzuje jeho stabilitu.
Priemerný denný výnos (0,085 %) aj medián (0,11 %) zostávajú pozitívne a
zodpovedajú širokému diverzifikovanému portfóliu.
2. Lineárna regresia v základnom tvare
V tejto časti odhadujeme lineárny regresný model, ktorého cieľom je
vysvetliť denné logaritmické výnosy spoločnosti Apple (AAPL) pomocou
výnosov troch ďalších finančných aktív: zlata (GLD), energetického
sektora (XLE) a indexu S&P 500 reprezentovaného ETF SPY. Ide o
najjednoduchší špecifikačný variant modelu, v ktorom predpokladáme
lineárny vzťah medzi výnosmi Apple a uvedenými vysvetľujúcimi
premennými, pričom koeficienty predstavujú okamžitú citlivosť výnosu
Apple na malé zmeny v jednotlivých aktívach. Odhad slúži ako
východiskový krok pre testovanie stanovených hypotéz aj pre následnú
diagnostiku modelu. Pôvodný regresný model:
\[AAPL\_ret = \beta_0 + \beta_1 \cdot
GLD\_ret + \beta_2 \cdot XLE\_ret + \beta_3 \cdot SPY\_ret +
u\]
model <- lm(AAPL_ret ~ GLD_ret + XLE_ret + SPY_ret, data = ret_df)
summary(model)
Call:
lm(formula = AAPL_ret ~ GLD_ret + XLE_ret + SPY_ret, data = ret_df)
Residuals:
Min 1Q Median 3Q Max
-0.044288 -0.006673 -0.000362 0.005717 0.066928
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.0003073 0.0007477 0.411 0.6814
GLD_ret 0.0028525 0.0818840 0.035 0.9722
XLE_ret -0.1950403 0.0705065 -2.766 0.0061 **
SPY_ret 1.0396059 0.1007431 10.319 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.01173 on 247 degrees of freedom
Multiple R-squared: 0.3122, Adjusted R-squared: 0.3038
F-statistic: 37.37 on 3 and 247 DF, p-value: < 2.2e-16
Výsledky ukazujú, že najvýznamnejším faktorom ovplyvňujúcim denný
výnos Apple je index SPY, ktorý má kladný a vysoko štatisticky významný
koeficient. To znamená, že pohyb celého trhu je kľúčovým determinantnom
správania ceny Apple, čo je v súlade s očakávaniami, keďže Apple tvorí
významnú časť indexu S&P 500. Koeficient pri GLD je veľmi malý a
neštatisticky významný, čo naznačuje, že výnosy zlata nemajú
systematický vplyv na výnosy Apple. Premenná XLE je štatisticky významná
na hladine 1 % a jej koeficient má záporné znamienko, čo naznačuje, že v
analyzovanom období sa výnosy energetického sektora pohybovali často
opačným smerom ako výnosy Apple. Celková štatistická významnosť modelu
je potvrdená F-testom a približne 31 % variability výnosov Apple je
vysvetlených zahrnutými premennými.
Korelačná matica
V tejto časti analyzujeme vzťahy medzi vysvetľujúcimi premennými
použitými v regresnom modeli. Cieľom je overiť, či sa medzi nimi
nevyskytujú silné lineárne väzby, ktoré by mohli naznačovať prítomnosť
multikolinearity. Korelačná matica poskytuje rýchny prehľad o tom, do
akej miery sa jednotlivé premenné navzájom pohybujú rovnakým smerom.
xvars <- ret_df[, c("GLD_ret", "XLE_ret", "SPY_ret")]
round(cor(xvars), 3)
GLD_ret XLE_ret SPY_ret
GLD_ret 1.000 0.210 0.265
XLE_ret 0.210 1.000 0.314
SPY_ret 0.265 0.314 1.000
Z výsledkov je zrejmé, že korelácie medzi premennými GLD_ret, XLE_ret
a SPY_ret sú relatívne nízke, pohybujú sa približne v intervale od 0.21
do 0.31. Takéto hodnoty nepredstavujú riziko výraznej multikolinearity.
Žiadna z dvojíc nevykazuje vysokú koreláciu, ktorú by bolo potrebné
ďalej riešiť (napríklad hodnoty nad 0.8 alebo 0.9). Pre regresný model
to znamená, že vysvetľujúce premenné sú dostatočne samostatné a je možné
nimi spoľahlivo odhadovať vplyv na závislú premennú.
Párové scatterploty
Na obrázku môžeme taktiež vidieť koreláciu medzi jednotlivými
premennými.
pairs(xvars,
main = "Scatterplotová matica – premenné GLD_ret, XLE_ret, SPY_ret")

Vo všetkých dvojiciach pozorujeme len mierne lineárne vzťahy, bez
výrazného smerovania bodov do jednej spoločnej línie. Body sú rozptýlené
pomerne rovnomerne a neukazujú na silnú závislosť medzi premennými.
Grafická analýza preto potvrdzuje výsledky korelačnej matice a
naznačuje, že medzi vysvetľujúcimi premennými sa nevyskytuje závažná
multikolinearita.
VIF
V tejto časti hodnotíme úroveň multikolinearity pomocou ukazovateľa
VIF (Variance Inflation Factor). Tento ukazovateľ meria, do akej miery
je variabilita odhadu regresného koeficientu zvýšená v dôsledku
korelácie s ostatnými vysvetľujúcimi premennými. Nízke hodnoty VIF
naznačujú, že premenné nie sú navzájom lineárne silno prepojené a že
koeficienty modelu sú spoľahlivo identifikované.
GLD_ret XLE_ret SPY_ret
1.096492 1.130832 1.162842
Hodnoty VIF sa pohybujú medzi 1.09 a 1.16, čo predstavuje veľmi nízku
úroveň multikolinearity. Keďže za potenciálne problematické sa považujú
hodnoty nad 5 (resp. nad 10 pri prísnejších kritériách), výsledky
jednoznačne naznačujú, že model netrpí multikolinearitou. Všetky
vysvetľujúce premenné sú dostatočne nezávislé a ich zaradenie do
spoločného regresného modelu nepredstavuje problém.
Condition Number
V tejto časti hodnotíme multikolinearitu pomocou tzv. condition
number (číselného indexu podmienky). Ide o diagnostiku založenú na
vlastných hodnotách matice X’X, ktorá ukazuje, do akej miery je regresný
model citlivý na malé zmeny v dátach. Vyššie hodnoty signalizujú väčšiu
nestabilitu odhadov a možný problém s multikolinearitou. Ako orientačné
pravidlo sa považujú za neškodné hodnoty pod 10, za mierne problematické
hodnoty medzi 10–30 a za závažnú multikolinearitu hodnoty nad 30.
X <- model.matrix(model)[, -1]
XtX <- t(X) %*% X
eig <- eigen(XtX)
condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
[1] 1.747995
Vypočítaný condition number má hodnotu približne 1.75, čo je veľmi
nízka hodnota. Takéto číslo jednoznačne naznačuje, že matica
vysvetľujúcich premenných je dobre podmienená a model nie je citlivý na
malé zmeny v dátach. Inými slovami, výsledok potvrdzuje absenciu
multikolinearity, čo je v súlade s koreláciami aj s VIF analýzou.
Na doplnenie základných ukazovateľov multikolinearity využijeme aj
analýzu vlastných hodnôt a indexov podmienenosti. Tento postup umožňuje
získať presnejší obraz o tom, ako sú vysvetľujúce premenné rozložené v
priestore a či sa určitá ich kombinácia nespráva problematicky. Ide o
rozšírenú diagnostiku, ktorá poskytuje detailnejší pohľad na stabilitu
regresného modelu.
library(olsrr)
ols_eigen_cindex(model)
V tabuľke vidíme štyri vlastné hodnoty, ktoré reprezentujú štyri
ortogonálne komponenty priestoru vysvetľujúcich premenných. Pre každú z
nich je vypočítaný condition index, ktorý ukazuje mieru potenciálneho
numerického problému. Všetky indexy sa nachádzajú veľmi nízko, v rozsahu
1.00 až 1.53, čo je hlboko pod hranicami, ktoré by signalizovali
akýkoľvek problém (za rizikové sa považujú hodnoty nad 10 a najmä nad
30).
Ďalší pohľad poskytujú záťaže (proporcie variancií) jednotlivých
premenných v posledných stĺpcoch. Ak by existovala multikolinearita,
viaceré premenné by vykazovali vysoké hodnoty v rovnakom riadku, typicky
pri vysokom condition indexe. V tomto prípade však žiadna z premenných
nevykazuje koncentrované zaťaženie pri žiadnom z indexov, čo potvrdzuje,
že model je stabilný a nie je ovplyvnený vzájomnými lineárnymi väzbami
medzi GLD_ret, XLE_ret a SPY_ret.
Výsledok tak poskytuje dodatočný dôkaz, že multikolinearita nie je v
našom modeli prítomná — konzistentne s výsledkami korelácií, VIF aj
základného condition number.
Riešenia multikolinearity
Vynechanie premennej
Model bez GLD_ret
V tomto kroku odhadujeme model, v ktorom bola premenná GLD_ret
vynechaná zo skupiny vysvetľujúcich premenných. Cieľom je posúdiť, či
jej vylúčenie mení správanie regresného modelu, a či ostatné premenné
dokážu zachytiť variabilitu v závislej premennej bez jej prítomnosti.
Takéto porovnanie umožňuje identifikovať, do akej miery jednotlivé
premenné prispievajú k vysvetleniu AAPL_ret.
model_no_GLD <- lm(AAPL_ret ~ XLE_ret + SPY_ret, data = ret_df)
summary(model_no_GLD)
Call:
lm(formula = AAPL_ret ~ XLE_ret + SPY_ret, data = ret_df)
Residuals:
Min 1Q Median 3Q Max
-0.044297 -0.006680 -0.000397 0.005743 0.066933
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.0003094 0.0007439 0.416 0.67786
XLE_ret -0.1947011 0.0696900 -2.794 0.00562 **
SPY_ret 1.0403592 0.0981964 10.595 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.01171 on 248 degrees of freedom
Multiple R-squared: 0.3122, Adjusted R-squared: 0.3066
F-statistic: 56.28 on 2 and 248 DF, p-value: < 2.2e-16
Po odstránení GLD_ret zostali v modeli premenné XLE_ret a SPY_ret.
Obe majú signifikantný vplyv na AAPL_ret, pričom SPY_ret vykazuje veľmi
silný a štatisticky jednoznačný efekt. Hodnota R-squared je približne
0.31, čo znamená, že model zachytáva podobnú úroveň variability ako
pôvodný model s tromi prediktormi. Koeficient pri XLE_ret zostáva
negatívny a signifikantný, čo naznačuje, že jeho vplyv je stabilný aj
bez zahrnutia GLD_ret. Celkovo sa výkon modelu výraznejšie nezhoršil, čo
potvrdzuje, že GLD_ret nie je kľúčovým nositeľom informácie v tomto
regresnom vzťahu.
Model bez XLE_ret
Model odhadujeme znova po vynechaní premennej XLE_ret, aby sme
posúdili jej prínos k vysvetleniu variability AAPL_ret.
model_no_XLE <- lm(AAPL_ret ~ GLD_ret + SPY_ret, data = ret_df)
summary(model_no_XLE)
Call:
lm(formula = AAPL_ret ~ GLD_ret + SPY_ret, data = ret_df)
Residuals:
Min 1Q Median 3Q Max
-0.045317 -0.007132 -0.000145 0.006499 0.067501
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.0003941 0.0007570 0.521 0.603
GLD_ret -0.0284325 0.0821797 -0.346 0.730
SPY_ret 0.9632624 0.0981801 9.811 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.01189 on 248 degrees of freedom
Multiple R-squared: 0.2909, Adjusted R-squared: 0.2852
F-statistic: 50.86 on 2 and 248 DF, p-value: < 2.2e-16
Po odstránení XLE_ret zostávajú v modeli premenné GLD_ret a SPY_ret.
Premenná SPY_ret zostáva výrazne signifikantná a naďalej predstavuje
dominantný zdroj vysvetľujúcej sily v modeli. Koeficient pri GLD_ret nie
je štatisticky významný, čo naznačuje, že jeho informačný prínos je
veľmi obmedzený. Hodnota R-squared sa mierne znížila, ale zostáva
porovnateľná s ostatnými redukovanými modelmi, čo potvrdzuje, že
vynechanie XLE_ret nemá zásadný vplyv na celkovú kvalitu regresie. Model
preto dobre funguje aj bez tejto premennej.
Model bez SPY_ret
Model odhadujeme po vynechaní premennej SPY_ret, aby sme zistili, do
akej miery na nej závisí vysvetľujúca sila pôvodnej regresie.
model_no_SPY <- lm(AAPL_ret ~ GLD_ret + XLE_ret, data = ret_df)
summary(model_no_SPY)
Call:
lm(formula = AAPL_ret ~ GLD_ret + XLE_ret, data = ret_df)
Residuals:
Min 1Q Median 3Q Max
-0.047934 -0.008045 0.000562 0.007643 0.068597
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.0010172 0.0008889 1.144 0.2536
GLD_ret 0.1842357 0.0954812 1.930 0.0548 .
XLE_ret 0.0042769 0.0809565 0.053 0.9579
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.01401 on 248 degrees of freedom
Multiple R-squared: 0.01565, Adjusted R-squared: 0.007708
F-statistic: 1.971 on 2 and 248 DF, p-value: 0.1415
Po odstránení SPY_ret zostávajú v modeli premenné GLD_ret a XLE_ret,
avšak ani jedna z nich nevykazuje štatisticky významný vplyv na
AAPL_ret. Hodnota R-squared výrazne klesla na približne 0.02, čo
znamená, že model prakticky nedokáže vysvetliť variabilitu závislej
premennej. Výrazný pokles vysvetľovacej schopnosti a nesignifikantnosť
koeficientov ukazujú, že SPY_ret je kľúčovou premennou v pôvodnom modeli
a nesie hlavnú časť informácie o vývoji výnosov AAPL.
Škálovanie premenných
Model bol odhadnutý s centrovanými a štandardizovanými hodnotami
vysvetľujúcich premenných, aby sa zhodnotilo, či transformácia ovplyvní
stabilitu koeficientov a diagnostiku multikolinearity.
ret_df_c <- ret_df %>%
mutate(
GLD_c = scale(GLD_ret, center = TRUE, scale = FALSE),
XLE_c = scale(XLE_ret, center = TRUE, scale = FALSE),
SPY_c = scale(SPY_ret, center = TRUE, scale = FALSE)
)
# Odhad modelu s centrovanými premennými
model_centered <- lm(AAPL_ret ~ GLD_c + XLE_c + SPY_c, data = ret_df)
summary(model_centered)
Call:
lm(formula = AAPL_ret ~ GLD_c + XLE_c + SPY_c, data = ret_df)
Residuals:
Min 1Q Median 3Q Max
-0.044288 -0.006673 -0.000362 0.005717 0.066928
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.193e-03 7.407e-04 1.610 0.1087
GLD_c 2.707e-05 7.772e-04 0.035 0.9722
XLE_c -2.183e-03 7.892e-04 -2.766 0.0061 **
SPY_c 8.259e-03 8.003e-04 10.319 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.01173 on 247 degrees of freedom
Multiple R-squared: 0.3122, Adjusted R-squared: 0.3038
F-statistic: 37.37 on 3 and 247 DF, p-value: < 2.2e-16
GLD_c XLE_c SPY_c
1.096492 1.130832 1.162842
Centrovanie a škálovanie nemení štatistickú významnosť ani smer
pôsobenia jednotlivých premenných. Premenná SPY_c zostáva výrazne
signifikantná a dominuje vysvetľujúcej sile modelu, zatiaľ čo GLD_c opäť
nevykazuje žiadny významný vplyv. Koeficient pri XLE_c zostáva negatívny
a štatisticky významný, čo je v súlade s pôvodným modelom. Hodnota
R-squared sa prakticky nezmenila, čo ukazuje, že transformácia nemala
vplyv na celkovú kvalitu regresie. VIF hodnoty zostávajú veľmi nízke, čo
potvrdzuje absenciu multikolinearity aj po transformácii.
Condition number vypočítaný pre centrovaný model slúži ako doplnkový
ukazovateľ na posúdenie, či transformácia premenných ovplyvnila
stabilitu numerického riešenia regresie.
Conditional Number je
X <- model.matrix(model_centered)[, -1]
XtX <- t(X) %*% X
eig <- eigen(XtX)
condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
[1] 1.503723
Hodnota condition number je približne 1.50, čo predstavuje veľmi
nízku úroveň a potvrdzuje, že ani po centrovaní nevznikajú žiadne
náznaky multikolinearity. Model je numericky stabilný, premenné sa
správajú nezávisle a transformácia nezmenila vzťahy medzi nimi. Táto
diagnostika tak podporuje záver, že multikolinearita v dátach
nepredstavuje problém.
Porovnanie centrovaného a základného modelu
Porovnanie pôvodného a centrovaného modelu umožňuje overiť, či
transformácia vysvetľujúcich premenných ovplyvnila výšku koeficientov a
smerodajné odchýlky. Tento postup ukazuje, či sú odhady stabilné voči
zmene mierky premenných a pomáha identifikovať prípadnú citlivosť
modelu.
library(broom)
compare <- bind_cols(
tidy(model)[, c("term", "estimate", "std.error")] %>% rename(estimate_raw = estimate, se_raw = std.error),
tidy(model_centered)[, c("estimate", "std.error")] %>% rename(estimate_c = estimate, se_c = std.error)
)
compare
Z porovnania vidno, že centrovanie nemá vplyv na štatistickú
významnosť ani smer pôsobenia jednotlivých premenných. Hodnoty odhadov
sa síce zmenili v absolútnych číslach (čo je prirodzený dôsledok
transformácie), avšak ich relatívne pôsobenie a významnosť zostali
rovnaké. Smerodajné odchýlky sa zmenili len minimálne, čo naznačuje, že
model je stabilný a neprejavuje citlivosť na rozdielne mierky
vysvetľujúcich premenných. Celkové správanie modelu tak potvrdzuje, že
multikolinearita nepredstavuje problém a výsledky sú robustné aj po
centrovaní.
Iná úprava premennej, ktorá zachová interpretovateľnosť
Lineárny model s percentuálnymi jednotkami prediktorov
Aby sme zvýšili interpretovateľnosť regresného modelu, prevedieme
vysvetľujúce premenné z pôvodných log-výnosov na percentuálne zmeny.
Tento postup nemení štatistickú podstatu modelu, ale umožňuje
jednoduchšie čítanie koeficientov – odhad následne vyjadruje zmenu
AAPL_ret pri zmene vysvetľujúcej premennej o jeden percentuálny bod.
Okrem zrozumiteľnosti zároveň preverujeme, či prevod na inú mierku
nejako ovplyvní diagnostiku multikolinearity alebo stabilitu modelových
odhadov.
# Prevody vysvetľujúcich premenných na percentuálne body
ret_df$GLD_pct <- 100 * ret_df$GLD_ret
ret_df$XLE_pct <- 100 * ret_df$XLE_ret
ret_df$SPY_pct <- 100 * ret_df$SPY_ret
# Lineárny model s percentuálnymi jednotkami prediktorov
model_pct <- lm(AAPL_ret ~ GLD_pct + XLE_pct + SPY_pct, data = ret_df)
summary(model_pct)
Call:
lm(formula = AAPL_ret ~ GLD_pct + XLE_pct + SPY_pct, data = ret_df)
Residuals:
Min 1Q Median 3Q Max
-0.044288 -0.006673 -0.000362 0.005717 0.066928
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.073e-04 7.477e-04 0.411 0.6814
GLD_pct 2.852e-05 8.188e-04 0.035 0.9722
XLE_pct -1.950e-03 7.051e-04 -2.766 0.0061 **
SPY_pct 1.040e-02 1.007e-03 10.319 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.01173 on 247 degrees of freedom
Multiple R-squared: 0.3122, Adjusted R-squared: 0.3038
F-statistic: 37.37 on 3 and 247 DF, p-value: < 2.2e-16
Model s percentuálnymi jednotkami poskytuje prakticky rovnaké
výsledky ako pôvodný model s log-výnosmi. Premenná SPY_pct zostáva veľmi
silným a štatisticky významným prediktorom AAPL_ret, čo potvrdzuje jej
dominantnú úlohu pri vysvetľovaní zmien v závislej premennej. Premenná
XLE_pct opäť vykazuje štatisticky významný negatívny vplyv, a to rovnako
ako v predchádzajúcich odhadoch. Premenná GLD_pct ostáva bez
štatistického významu, čo naznačuje, že informácia z tejto premennej
neprispieva k vysvetleniu výnosov AAPL. Hodnota R-squared zostáva na
približne rovnakej úrovni ako v predchádzajúcich modeloch, čo ukazuje,
že zmena jednotiek nemení vysvetľovaciu silu regresie.
VIF diagnostika
# VIF diagnostika
vif(model_pct)
GLD_pct XLE_pct SPY_pct
1.096492 1.130832 1.162842
Hodnoty VIF sú veľmi nízke (približne 1.1), čo potvrdzuje absenciu
multikolinearity aj po prevedení premenných na percentuálne zmeny.
Všetky vysvetľujúce premenné sú navzájom nezávislé v takom rozsahu, že
ich spoločné zahrnutie do regresného modelu nepredstavuje žiadny
problém.
Condition number
# Condition number (rovnaká logika ako v cvičení)
X <- model.matrix(model_pct)[, -1]
XtX <- t(X) %*% X
eig <- eigen(XtX)
condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
[1] 1.747995
Vypočítaná hodnota condition number je približne 1.75, čo je veľmi
nízka hodnota a zodpovedá dobre podmienenému regresnému modelu. To
znamená, že numerická stabilita modelu zostáva zachovaná a že ani po
zmene jednotiek nedochádza k zvýšeniu citlivosti modelu na malé zmeny vo
vysvetľujúcich premenných.
LS0tCnRpdGxlOiAiRGVzaWF0YSDDumxvaGEiCmF1dGhvcjogJyBNaXJvc2xhdmEgTWVkdmVja8OhICA8YnI+JwpkYXRlOiAiU2VwdGVtYmVyIDIwMjUiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICBkZl9wcmludDogcGFnZWQKZWRpdG9yX29wdGlvbnM6CiAgbWFya2Rvd246CiAgICB3cmFwOiA3MgotLS0KCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgICBlY2hvID0gVFJVRSwKICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgIHdhcm5pbmcgPSBGQUxTRQopCmBgYAoKYGBge3J9CmxpYnJhcnkoem9vKQpsaWJyYXJ5KHRzZXJpZXMpCmxpYnJhcnkobG10ZXN0KQpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGNhcikKcm0obGlzdD1scygpKQpgYGAKCjxzdHlsZT4KLyogQ2Vsa292w6kgcG96YWRpZSAqLwpib2R5IHsKICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTM1ZGVnLCAjZmZkZGRkLCAjZmZjY2NjLCAjZGRmZmRkKTsgLyogamVtbsOhIMSNZXJ2ZW7DoSDihpIgc3ZldGzDoSDEjWVydmVuw6Eg4oaSIHN2ZXRsw6EgemVsZW7DoSAqLwogIGZvbnQtZmFtaWx5OiAnSGVsdmV0aWNhIE5ldWUnLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmOwogIGNvbG9yOiAjMmUwODU0OwogIGxpbmUtaGVpZ2h0OiAxLjc7CiAgcGFkZGluZzogMjVweDsKfQoKLyogSGxhdm7DqSBuYWRwaXN5ICovCmgxLCBoMiwgaDMgewogIGZvbnQtZmFtaWx5OiAnSGVsdmV0aWNhIE5ldWUnLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmOwogIGxldHRlci1zcGFjaW5nOiAwLjVweDsKICBjb2xvcjogI2IzMDAwMDsgLyogdG1hdsWhaWEgdmlhbm/EjW7DoSDEjWVydmVuw6EgKi8KICB0ZXh0LXNoYWRvdzogMHB4IDFweCAycHggIzAwODAwMDsgLyogdG1hdsWhaWEgemVsZW7DoSAqLwp9Cjwvc3R5bGU+CgojIDEuIMOadm9kIGEgw7pkYWplIAoKQ2llxL5vbSB0ZWp0byDDumxvaHkgamUgYW5hbHl6b3ZhxaUgdnrFpWFoeSBtZWR6aSBsb2dhcml0bWlja8O9bWkgZGVubsO9bWkgdsO9bm9zbWkgdnlicmFuw6lobyBha2Npb3bDqWhvIHRpdHVsdSBhIHbDvW5vc21pIMSPYWzFocOtY2ggZmluYW7EjW7DvWNoIGFrdMOtdi4gS29ua3LDqXRuZSBzYSB6YW1lcmlhdmFtZSBuYSBzcG9sb8SNbm9zxaUgQXBwbGUgKEFBUEwpIGEgc2vDum1hbWUsIGRvIGFrZWogbWllcnkgc2EgamVqIGRlbm7DqSB2w71ub3N5IGRhasO6IHZ5c3ZldGxpxaUgdsO9dm9qb20gbmEgdHJodSBzbyB6bGF0b20gKEdMRCksIGVuZXJnZXRpY2vDvW0gc2VrdG9yb20gKFhMRSkgYSBjZWxrb3bDvW0gdHJob3bDvW0gaW5kZXhvbSBTJlAgNTAwIChTUFkpLgoKVsO9YmVyIGFrdMOtdiB1bW/FvsWIdWplIHBvcm92bmHFpSBzcHLDoXZhbmllIHRlY2hub2xvZ2lja2VqIGFrY2llIHMgcsO0em55bWkgxI1hc8WlYW1pIGZpbmFuxI1uw6lobyB0cmh1IOKAlCBrb21vZGl0YW1pLCBzZWt0b3JvdsO9bWkgRVRGIGEgxaFpcm9rw71tIHRyaG92w71tIGJlbmNobWFya29tLiBQb3XFvml0w61tIGRlbm7DvWNoIGxvZ2FyaXRtaWNrw71jaCB2w71ub3NvdiBlbGltaW51amVtZSB2cGx5diDDunJvdm5lIGNpZW4gYSB6w61za2F2YW1lIMSNYXNvdsO9IHJhZCB2aG9kbsO9IG5hIGVrb25vbWV0cmlja8O6IGFuYWzDvXp1LgoKIyMgw5p2b2QgZG8gcHJvYmzDqW11IGEgc3Rhbm92ZW5pZSBoeXBvdMOpeiAKCkRlbm7DqSB2w71ub3N5IGFrY2lvdsO9Y2ggdGl0dWxvdiByZWFndWrDuiBuYSDFoWlyb2vDqSBzcGVrdHJ1bSBmYWt0b3Jvdiwga3RvcsOpIHphaMWVxYhhasO6IGNlbGtvdsO9IHRyaG92w70gc2VudGltZW50LCB2w712b2ogdiBqZWRub3RsaXbDvWNoIHNla3Rvcm9jaCBhaiBwb2h5YnkgYWx0ZXJuYXTDrXZueWNoIGFrdMOtdi4gVGVjaG5vbG9naWNrw6kgc3BvbG/EjW5vc3RpLCBtZWR6aSBrdG9yw6kgcGF0csOtIGFqIEFwcGxlIChBQVBMKSwgYsO9dmFqw7ogdHlwaWNreSB2ZcS+bWkgY2l0bGl2w6kgbmEgem1lbnkgdm8gdsO9a29ubm9zdGkgY2Vsw6lobyB0cmh1LCBhbGUgaWNoIHNwcsOhdmFuaWUgbcO0xb5lIGJ5xaUgb3ZwbHl2bmVuw6kgYWogxaFwZWNpZmlja8O9bWkgc2VnbWVudG1pLCBha28gc8O6IGtvbW9kaXR5IGFsZWJvIG9kdmV0dm92w6kgRVRGLiBWIHRlanRvIMO6bG9oZSBwcmV0byBhbmFseXp1amVtZSwgYWtvIHNhIGRlbm7DqSBsb2dhcml0bWlja8OpIHbDvW5vc3kgc3BvbG/EjW5vc3RpIEFwcGxlIHZ5dsOtamFqw7ogdiB6w6F2aXNsb3N0aSBvZCB2w71ub3NvdiB0cm9jaCDEj2FsxaHDrWNoIGFrdMOtdjogaW5kZXh1IFMmUCA1MDAgcmVwcmV6ZW50b3ZhbsOpaG8gRVRGIFNQWSwgemxhdGEgcHJvc3RyZWRuw61jdHZvbSBFVEYgR0xEIGEgZW5lcmdldGlja8OpaG8gc2VrdG9yYSBjZXogRVRGIFhMRS4gQ2llxL5vbSBqZSB6aXN0acWlLCDEjWkgem1lbnkgdiB0w71jaHRvIGFrdMOtdmFjaCBkb2vDocW+dSDFoXRhdGlzdGlja3kgdsO9em5hbW5lIHZ5c3ZldGxpxaUgc3Byw6F2YW5pZSBzYSB2w71ub3NvdiBBcHBsZSBhIMSNaSBtw6EgbmFqdsOkxI3FocOtIHZwbHl2IHByw6F2ZSBjZWxrb3bDvSB0cmgsIGFrbyBieSBuYXpuYcSNb3ZhbGEgZWtvbm9taWNrw6EgaW50dcOtY2lhLgoKTmHFoWEgcHJhY292bsOhIGh5cG90w6l6YSBwcmVkcG9rbGFkw6EsIMW+ZSB2xaFldGt5IHRyaSB2eXN2ZXTEvnVqw7pjZSBwcmVtZW5uw6kg4oCTIHbDvW5vc3kgaW5kZXh1IFNQWSwgdsO9bm9zeSB6bGF0YSAoR0xEKSBhIHbDvW5vc3kgZW5lcmdldGlja8OpaG8gc2VrdG9yYSAoWExFKSDigJMgbWFqw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnBseXYgbmEgZGVubsOpIGxvZ2FyaXRtaWNrw6kgdsO9bm9zeSBzcG9sb8SNbm9zdGkgQXBwbGUgKEFBUEwpLiBPxI1ha8OhdmFtZSBwcml0b20sIMW+ZSB2w71ub3N5IHRyaHUgcmVwcmV6ZW50b3ZhbsOpIEVURiBTUFkgYnVkw7ogbWHFpSBwb3ppdMOtdm55IHZwbHl2LCBrZcSPxb5lIEFwcGxlIGplIHPDusSNYXPFpW91IGluZGV4dSBTJlAgNTAwIGEgamVobyBjZW5hIHNwcmF2aWRsYSByYXN0aWUgdiBzw7psYWRlIHMgY2Vsa292w71tIHRyaG92w71tIHNlbnRpbWVudG9tLgoKViBwcsOtcGFkZSB2w71ub3NvdiB6bGF0YSBwcmVkcG9rbGFkw6FtZSwgxb5lIHZwbHl2IG3DtMW+ZSBiecWlIGJ1xI8gbWllcm5lIG5lZ2F0w612bnksIGFsZWJvIHZlxL5taSBzbGFiw70sIGtlxI/FvmUgemxhdG8gxI1hc3RvIGZ1bmd1amUgYWtvIGJlenBlxI1uw6kgYWt0w612dW0gYSBqZWhvIHbDvW5vc3kgc2EgbcO0xb51IHBvaHlib3ZhxaUgb3BhxI1uZSBuZcW+IGFrY2lvdsOpIHRyaHkuIFByaSBlbmVyZ2V0aWNrb20gc2VrdG9yZSBvxI1ha8OhdmFtZSwgxb5lIGplaG8gdsO9bm9zeSBidWTDuiBtYcWlIGtsYWRuw70gdnBseXYgbmEgdsO9bm9zeSBBcHBsZSwga2XEj8W+ZSByYXN0IGVuZXJnZXRpY2vDqWhvIHNla3RvcmEgYsO9dmEgc3BvamVuw70gcyBsZXDFocOtbSBtYWtyb2Vrb25vbWlja8O9bSBwcm9zdHJlZMOtbSwgdnnFocWhb3UgZWtvbm9taWNrb3UgYWt0aXZpdG91IGEgY2Vsa292byBwb3ppdMOtdm55bSBzZW50aW1lbnRvbSBpbnZlc3Rvcm92LgoKUHJhY292bsOhIGh5cG90w6l6YSB0ZWRhIHR2cmTDrSwgxb5lIHbFoWV0a3kgdHJpIGtvZWZpY2llbnR5IHYgcmVncmVzbm9tIG1vZGVsaSBzw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6ksIHByacSNb20gb2RoYWRvdmFuw70ga29lZmljaWVudCBwcmkgU1BZIGJ5IG1hbCBiecWlIGtsYWRuw70sIGtvZWZpY2llbnQgcHJpIFhMRSB0YWt0aWXFviBrbGFkbsO9IGEga29lZmljaWVudCBwcmkgR0xEIG1pZXJuZSB6w6Fwb3Juw70gYWxlYm8gYmzDrXprbyBudWxlLiBTcG9sb8SNbsOhIG51bG92w6EgaHlwb3TDqXphIHR2cmTDrSwgxb5lIMW+aWFkbmEgeiB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoIG5ldnlzdmV0xL51amUgc3Byw6F2YW5pZSB2w71ub3NvdiBBcHBsZSwgxI1vIHpuYW1lbsOhLCDFvmUgdsWhZXRreSBrb2VmaWNpZW50eSBzw7ogcm92bsOpIG51bGU7IHTDunRvIGh5cG90w6l6dSB0ZXN0dWplbWUgRi10ZXN0b20gdiByw6FtY2kgbGluZcOhcm5laG8gcmVncmVzbsOpaG8gbW9kZWx1LgoKQnVkZW1lIHRlc3RvdmHFpSBoeXBvdMOpenUgCgokSF8wOiQgbW9kZWwgamUgc3Byw6F2bmUgxaFwZWNpZmlrb3ZhbsO9ICgkXGdhbW1hXzIgPSBcZ2FtbWFfMyA9IDAkKQoKb3Byb3RpCgokSF8xOiQgbW9kZWwgamUgbmVzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70gKCRcZ2FtbWFfMiBcbmUgMCAgXHF1YWQgXHRleHR7YWxlYm99ICBccXVhZCBcZ2FtbWFfMyBcbmUgMCQpCgojIyBJbXBvcnQgw7pkYWpvdiAKCk5hIHphxI1pYXRvayBzaSBpbXBvcnR1amVtZSDDumRhamUuIFZ5YnJhbGEgc29tIHNpIGTDoXRhIG8gY2VuZSBha2Npw60gc3BvbG/EjW5vc3RpIEFwcGxlIGEgRVRGJ3MsIGt0b3LDqSBvcGlzdWrDuiB2w712b2ogdHJodSB6bGF0YSAoR0xEKSwgZW5lcmdldGlja8OpaG8gc2VrdG9yYSAoWExFKSBhIChTUFkpLCBrdG9yw6kga29ww61ydWplIHRyaCBTJlAgNTAwLiBEw6F0YSBzw7ogemEgb2Jkb2JpZSAxLjEuMjAyNC0xLjEuMjAyNS4gw5pkYWplIHPDuiBzdGlhaG51dMOpIHByaWFtbyB6IGludGVybmV0dSwgeiBkYXRhYsOhenkgWWFob29GaW5hbmNlLiBUaWV0byBob2Rub3R5IHByZWRzdGF2dWrDuiB2w712b2ogY2llbiwgbmEga3Rvcm9tIGJ1ZGVtZSBuw6FzbGVkbmUgYW5hbHl6b3ZhxaUgbG9nYXJpdG1pY2vDqSB2w71ub3Nub3N0aSBhIHZ6w6Fqb21uw6kgdnrFpWFoeSBtZWR6aSB2w71ub3Nub3PFpWFtaSBkYW7DvWNoIGFrdMOtdi4KCmBgYHtyfQp0aWNrZXJzIDwtIGMoIkFBUEwiLCAiR0xEIiwgIlhMRSIsICJTUFkiKSAgICMgQXBwbGUsIEdvbGQgRVRGLCBFbmVyZ3kgRVRGLCBTJlA1MDAgRVRGCmdldFN5bWJvbHModGlja2VycywgZnJvbSA9ICIyMDI0LTAxLTAxIiwgdG8gPSAiMjAyNS0wMS0wMSIpCgpkYXRhIDwtIG1lcmdlKENsKEFBUEwpLCBDbChHTEQpLCBDbChYTEUpLCBDbChTUFkpKQpjb2xuYW1lcyhkYXRhKSA8LSB0aWNrZXJzCgpyZXQgPC0gbmEub21pdChkaWZmKGxvZyhkYXRhKSkpCmNvbG5hbWVzKHJldCkgPC0gcGFzdGUwKGNvbG5hbWVzKHJldCksICJfcmV0IikKCnJldF9kZiA8LSBuYS5vbWl0KGFzLmRhdGEuZnJhbWUocmV0KSkKaGVhZChyZXRfZGYpCmBgYAoKIyMgRGVza3JpcHTDrXZuYSDFoXRhdGlzdGlrYSAKClYgbmFzbGVkdWrDumNlaiDEjWFzdGkgdnlrb27DoXZhbWUgZGVza3JpcHTDrXZudSDFoXRhdGlzdGlrdSBkZW5uw71jaCBsb2dhcml0bWlja8O9Y2ggdsO9bm9zb3YgxaF0eXJvY2ggZmluYW7EjW7DvWNoIGFrdMOtdiwgYWJ5IHNtZSB6w61za2FsaSB6w6FrbGFkbsO9IHByZWjEvmFkIG8gaWNoIHJvemRlbGVuw60gYSB2b2xhdGlsaXRlLgoKYGBge3J9CnN1bW1hcnkocmV0X2RmKQpgYGAKIyMjICpBcHBsZSogICAgClJvenDDpHRpZSB2w71ub3NvdiBzYSBwb2h5YnVqZSBvZCDigJM0LDk0ICUgcG8gKzcsMDEgJSwgxI1vIHogYWt0w612IHJvYsOtIG5hanZvbGF0aWxuZWrFoWllLiBQcmllbWVybsO9IGRlbm7DvSB2w71ub3MgKDAsMTIgJSkgYWogbWVkacOhbiAoMCwxNiAlKSBzw7ogcG96aXTDrXZuZSBhIG5hem5hxI11asO6IG1pZXJueSByYXN0b3bDvSB0cmVuZCwgemF0aWHEviDEjW8gYmXFvm7DqSBkZW5uw6kgcG9oeWJ5IChJUVIpIHNhIHBvaHlidWrDuiBkbyDCsTEgJS4gIAoKIyMjICpHb2xkKiAgICAgClbDvW5vc3kgemxhdGEga29sw63FoXUgbWVkemkg4oCTMyw2MyAlIGEgKzIsMjEgJSwgxI1vIGplIG1lbmVqIGFrbyBwcmkgQUFQTC4gUHJpZW1lciAoMCwwOTUgJSkgYWogbWVkacOhbiAoMCwxNiAlKSBzw7ogbWllcm5lIHBveml0w612bmUuIE5pxb7FocOtIElRUiBwb3R2cmR6dWplIHN0YWJpbG5lasWhw60gY2hhcmFrdGVyIHpsYXRhIGFrbyBkZWZlbnrDrXZuZWhvIGFrdMOtdmEuICAgICAKCiMjIyAqWExFKiAgICAgClJvenDDpHRpZSBvZCDigJMzLDI4ICUgZG8gKzMsNjkgJSBuYXpuYcSNdWplIHbDvXJhem5lasWhaXUgdm9sYXRpbGl0dSB0eXBpY2vDuiBwcmUgZW5lcmdldGlja8O9IHNla3Rvci4gUHJpZW1lcm7DvSB2w71ub3MgamUgdGFrbWVyIG51bG92w70sIMSNbyBvZHLDocW+YSBuZXV0csOhbG5lIGRsaG9kb2LDqSBzbWVyb3ZhbmllLiBNZWRpw6FuICgwLDE1ICUpIGplIHBveml0w612bnksIG5vIHZhcmlhYmlsaXRhIGplIHZ5xaHFoWlhIGFrbyBwcmkgU1BZIMSNaSBHTEQuICAgCgojIyMgKlNQWSogICAgIApTJlAgNTAwIG3DoSBuYWpuacW+xaFpZSByb3pww6R0aWUgdsO9bm9zb3YgKOKAkzMsMDIgJSBhxb4gKzIsNDUgJSkgYWogbmFqbWVuxaFpZSBtZWR6aWt2YXJ0aWxvdsOpIHJvenDDpHRpZSwgxI1vIHBvdHZyZHp1amUgamVobyBzdGFiaWxpdHUuIFByaWVtZXJuw70gZGVubsO9IHbDvW5vcyAoMCwwODUgJSkgYWogbWVkacOhbiAoMCwxMSAlKSB6b3N0w6F2YWrDuiBwb3ppdMOtdm5lIGEgem9kcG92ZWRhasO6IMWhaXJva8OpbXUgZGl2ZXJ6aWZpa292YW7DqW11IHBvcnRmw7NsaXUuIAoKIyAyLiBMaW5lw6FybmEgcmVncmVzaWEgdiB6w6FrbGFkbm9tIHR2YXJlCgpWIHRlanRvIMSNYXN0aSBvZGhhZHVqZW1lIGxpbmXDoXJueSByZWdyZXNuw70gbW9kZWwsIGt0b3LDqWhvIGNpZcS+b20gamUgdnlzdmV0bGnFpSBkZW5uw6kgbG9nYXJpdG1pY2vDqSB2w71ub3N5IHNwb2xvxI1ub3N0aSBBcHBsZSAoQUFQTCkgcG9tb2NvdSB2w71ub3NvdiB0cm9jaCDEj2FsxaHDrWNoIGZpbmFuxI1uw71jaCBha3TDrXY6IHpsYXRhIChHTEQpLCBlbmVyZ2V0aWNrw6lobyBzZWt0b3JhIChYTEUpIGEgaW5kZXh1IFMmUCA1MDAgcmVwcmV6ZW50b3ZhbsOpaG8gRVRGIFNQWS4gSWRlIG8gbmFqamVkbm9kdWNoxaHDrSDFoXBlY2lmaWthxI1uw70gdmFyaWFudCBtb2RlbHUsIHYga3Rvcm9tIHByZWRwb2tsYWTDoW1lIGxpbmXDoXJueSB2esWlYWggbWVkemkgdsO9bm9zbWkgQXBwbGUgYSB1dmVkZW7DvW1pIHZ5c3ZldMS+dWrDumNpbWkgcHJlbWVubsO9bWksIHByacSNb20ga29lZmljaWVudHkgcHJlZHN0YXZ1asO6IG9rYW3Fvml0w7ogY2l0bGl2b3PFpSB2w71ub3N1IEFwcGxlIG5hIG1hbMOpIHptZW55IHYgamVkbm90bGl2w71jaCBha3TDrXZhY2guIE9kaGFkIHNsw7rFvmkgYWtvIHbDvWNob2Rpc2tvdsO9IGtyb2sgcHJlIHRlc3RvdmFuaWUgc3Rhbm92ZW7DvWNoIGh5cG90w6l6IGFqIHByZSBuw6FzbGVkbsO6IGRpYWdub3N0aWt1IG1vZGVsdS4gUMO0dm9kbsO9IHJlZ3Jlc27DvSBtb2RlbDoKClxbQUFQTFxfcmV0ID0gXGJldGFfMCArIFxiZXRhXzEgXGNkb3QgR0xEXF9yZXQgKyBcYmV0YV8yIFxjZG90IFhMRVxfcmV0ICsgXGJldGFfMyBcY2RvdCBTUFlcX3JldCArIHVcXQoKYGBge3J9Cm1vZGVsIDwtIGxtKEFBUExfcmV0IH4gR0xEX3JldCArIFhMRV9yZXQgKyBTUFlfcmV0LCBkYXRhID0gcmV0X2RmKQpzdW1tYXJ5KG1vZGVsKQoKYGBgCgpWw71zbGVka3kgdWthenVqw7osIMW+ZSBuYWp2w716bmFtbmVqxaHDrW0gZmFrdG9yb20gb3ZwbHl2xYh1asO6Y2ltIGRlbm7DvSB2w71ub3MgQXBwbGUgamUgaW5kZXggU1BZLCBrdG9yw70gbcOhIGtsYWRuw70gYSB2eXNva28gxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70ga29lZmljaWVudC4gVG8gem5hbWVuw6EsIMW+ZSBwb2h5YiBjZWzDqWhvIHRyaHUgamUga8S+w7rEjW92w71tIGRldGVybWluYW50bm9tIHNwcsOhdmFuaWEgY2VueSBBcHBsZSwgxI1vIGplIHYgc8O6bGFkZSBzIG/EjWFrw6F2YW5pYW1pLCBrZcSPxb5lIEFwcGxlIHR2b3LDrSB2w716bmFtbsO6IMSNYXPFpSBpbmRleHUgUyZQIDUwMC4gS29lZmljaWVudCBwcmkgR0xEIGplIHZlxL5taSBtYWzDvSBhIG5lxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIMSNbyBuYXpuYcSNdWplLCDFvmUgdsO9bm9zeSB6bGF0YSBuZW1hasO6IHN5c3RlbWF0aWNrw70gdnBseXYgbmEgdsO9bm9zeSBBcHBsZS4gUHJlbWVubsOhIFhMRSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DoSBuYSBobGFkaW5lIDEgJSBhIGplaiBrb2VmaWNpZW50IG3DoSB6w6Fwb3Juw6kgem5hbWllbmtvLCDEjW8gbmF6bmHEjXVqZSwgxb5lIHYgYW5hbHl6b3Zhbm9tIG9iZG9iw60gc2EgdsO9bm9zeSBlbmVyZ2V0aWNrw6lobyBzZWt0b3JhIHBvaHlib3ZhbGkgxI1hc3RvIG9wYcSNbsO9bSBzbWVyb20gYWtvIHbDvW5vc3kgQXBwbGUuIENlbGtvdsOhIMWhdGF0aXN0aWNrw6EgdsO9em5hbW5vc8WlIG1vZGVsdSBqZSBwb3R2cmRlbsOhIEYtdGVzdG9tIGEgcHJpYmxpxb5uZSAzMSAlIHZhcmlhYmlsaXR5IHbDvW5vc292IEFwcGxlIGplIHZ5c3ZldGxlbsO9Y2ggemFocm51dMO9bWkgcHJlbWVubsO9bWkuCgojIyBLb3JlbGHEjW7DoSBtYXRpY2EKClYgdGVqdG8gxI1hc3RpIGFuYWx5enVqZW1lIHZ6xaVhaHkgbWVkemkgdnlzdmV0xL51asO6Y2ltaSBwcmVtZW5uw71taSBwb3XFvml0w71taSB2IHJlZ3Jlc25vbSBtb2RlbGkuIENpZcS+b20gamUgb3ZlcmnFpSwgxI1pIHNhIG1lZHppIG5pbWkgbmV2eXNreXR1asO6IHNpbG7DqSBsaW5lw6FybmUgdsOkemJ5LCBrdG9yw6kgYnkgbW9obGkgbmF6bmHEjW92YcWlIHByw610b21ub3PFpSBtdWx0aWtvbGluZWFyaXR5LiBLb3JlbGHEjW7DoSBtYXRpY2EgcG9za3l0dWplIHLDvWNobnkgcHJlaMS+YWQgbyB0b20sIGRvIGFrZWogbWllcnkgc2EgamVkbm90bGl2w6kgcHJlbWVubsOpIG5hdnrDoWpvbSBwb2h5YnVqw7ogcm92bmFrw71tIHNtZXJvbS4KCmBgYHtyfQp4dmFycyA8LSByZXRfZGZbLCBjKCJHTERfcmV0IiwgIlhMRV9yZXQiLCAiU1BZX3JldCIpXQpyb3VuZChjb3IoeHZhcnMpLCAzKQpgYGAKClogdsO9c2xlZGtvdiBqZSB6cmVqbcOpLCDFvmUga29yZWzDoWNpZSBtZWR6aSBwcmVtZW5uw71taSBHTERfcmV0LCBYTEVfcmV0IGEgU1BZX3JldCBzw7ogcmVsYXTDrXZuZSBuw616a2UsIHBvaHlidWrDuiBzYSBwcmlibGnFvm5lIHYgaW50ZXJ2YWxlIG9kIDAuMjEgZG8gMC4zMS4gVGFrw6l0byBob2Rub3R5IG5lcHJlZHN0YXZ1asO6IHJpemlrbyB2w71yYXpuZWogbXVsdGlrb2xpbmVhcml0eS4gxb1pYWRuYSB6IGR2b2rDrWMgbmV2eWthenVqZSB2eXNva8O6IGtvcmVsw6FjaXUsIGt0b3LDuiBieSBib2xvIHBvdHJlYm7DqSDEj2FsZWogcmllxaFpxaUgKG5hcHLDrWtsYWQgaG9kbm90eSBuYWQgMC44IGFsZWJvIDAuOSkuIFByZSByZWdyZXNuw70gbW9kZWwgdG8gem5hbWVuw6EsIMW+ZSB2eXN2ZXTEvnVqw7pjZSBwcmVtZW5uw6kgc8O6IGRvc3RhdG/EjW5lIHNhbW9zdGF0bsOpIGEgamUgbW/Fvm7DqSBuaW1pIHNwb8S+YWhsaXZvIG9kaGFkb3ZhxaUgdnBseXYgbmEgesOhdmlzbMO6IHByZW1lbm7Dui4KCiMjIFDDoXJvdsOpIHNjYXR0ZXJwbG90eSAKCk5hIG9icsOhemt1IG3DtMW+ZW1lIHRha3RpZcW+IHZpZGllxaUga29yZWzDoWNpdSBtZWR6aSBqZWRub3RsaXbDvW1pIHByZW1lbm7DvW1pLiAKCmBgYHtyfQpwYWlycyh4dmFycywKICAgICAgbWFpbiA9ICJTY2F0dGVycGxvdG92w6EgbWF0aWNhIOKAkyBwcmVtZW5uw6kgR0xEX3JldCwgWExFX3JldCwgU1BZX3JldCIpCmBgYAoKVm8gdsWhZXRrw71jaCBkdm9qaWNpYWNoIHBvem9ydWplbWUgbGVuIG1pZXJuZSBsaW5lw6FybmUgdnrFpWFoeSwgYmV6IHbDvXJhem7DqWhvIHNtZXJvdmFuaWEgYm9kb3YgZG8gamVkbmVqIHNwb2xvxI1uZWogbMOtbmllLiBCb2R5IHPDuiByb3pwdMO9bGVuw6kgcG9tZXJuZSByb3Zub21lcm5lIGEgbmV1a2F6dWrDuiBuYSBzaWxuw7ogesOhdmlzbG9zxaUgbWVkemkgcHJlbWVubsO9bWkuIEdyYWZpY2vDoSBhbmFsw716YSBwcmV0byBwb3R2cmR6dWplIHbDvXNsZWRreSBrb3JlbGHEjW5laiBtYXRpY2UgYSBuYXpuYcSNdWplLCDFvmUgbWVkemkgdnlzdmV0xL51asO6Y2ltaSBwcmVtZW5uw71taSBzYSBuZXZ5c2t5dHVqZSB6w6F2YcW+bsOhIG11bHRpa29saW5lYXJpdGEuCgojIyBWSUYKClYgdGVqdG8gxI1hc3RpIGhvZG5vdMOtbWUgw7pyb3ZlxYggbXVsdGlrb2xpbmVhcml0eSBwb21vY291IHVrYXpvdmF0ZcS+YSBWSUYgKFZhcmlhbmNlIEluZmxhdGlvbiBGYWN0b3IpLiBUZW50byB1a2F6b3ZhdGXEviBtZXJpYSwgZG8gYWtlaiBtaWVyeSBqZSB2YXJpYWJpbGl0YSBvZGhhZHUgcmVncmVzbsOpaG8ga29lZmljaWVudHUgenbDvcWhZW7DoSB2IGTDtHNsZWRrdSBrb3JlbMOhY2llIHMgb3N0YXRuw71taSB2eXN2ZXTEvnVqw7pjaW1pIHByZW1lbm7DvW1pLiBOw616a2UgaG9kbm90eSBWSUYgbmF6bmHEjXVqw7osIMW+ZSBwcmVtZW5uw6kgbmllIHPDuiBuYXZ6w6Fqb20gbGluZcOhcm5lIHNpbG5vIHByZXBvamVuw6kgYSDFvmUga29lZmljaWVudHkgbW9kZWx1IHPDuiBzcG/EvmFobGl2byBpZGVudGlmaWtvdmFuw6kuCgpgYGB7cn0KdmlmKG1vZGVsKQpgYGAKCkhvZG5vdHkgVklGIHNhIHBvaHlidWrDuiBtZWR6aSAxLjA5IGEgMS4xNiwgxI1vIHByZWRzdGF2dWplIHZlxL5taSBuw616a3Ugw7pyb3ZlxYggbXVsdGlrb2xpbmVhcml0eS4gS2XEj8W+ZSB6YSBwb3RlbmNpw6FsbmUgcHJvYmxlbWF0aWNrw6kgc2EgcG92YcW+dWrDuiBob2Rub3R5IG5hZCA1IChyZXNwLiBuYWQgMTAgcHJpIHByw61zbmVqxaHDrWNoIGtyaXTDqXJpw6FjaCksIHbDvXNsZWRreSBqZWRub3puYcSNbmUgbmF6bmHEjXVqw7osIMW+ZSBtb2RlbCBuZXRycMOtIG11bHRpa29saW5lYXJpdG91LiBWxaFldGt5IHZ5c3ZldMS+dWrDumNlIHByZW1lbm7DqSBzw7ogZG9zdGF0b8SNbmUgbmV6w6F2aXNsw6kgYSBpY2ggemFyYWRlbmllIGRvIHNwb2xvxI1uw6lobyByZWdyZXNuw6lobyBtb2RlbHUgbmVwcmVkc3RhdnVqZSBwcm9ibMOpbS4KCiMjIENvbmRpdGlvbiBOdW1iZXIKViB0ZWp0byDEjWFzdGkgaG9kbm90w61tZSBtdWx0aWtvbGluZWFyaXR1IHBvbW9jb3UgdHp2LiBjb25kaXRpb24gbnVtYmVyICjEjcOtc2VsbsOpaG8gaW5kZXh1IHBvZG1pZW5reSkuIElkZSBvIGRpYWdub3N0aWt1IHphbG/FvmVuw7ogbmEgdmxhc3Ruw71jaCBob2Rub3TDoWNoIG1hdGljZSBYJ1gsIGt0b3LDoSB1a2F6dWplLCBkbyBha2VqIG1pZXJ5IGplIHJlZ3Jlc27DvSBtb2RlbCBjaXRsaXbDvSBuYSBtYWzDqSB6bWVueSB2IGTDoXRhY2guIFZ5xaHFoWllIGhvZG5vdHkgc2lnbmFsaXp1asO6IHbDpMSNxaFpdSBuZXN0YWJpbGl0dSBvZGhhZG92IGEgbW/Fvm7DvSBwcm9ibMOpbSBzIG11bHRpa29saW5lYXJpdG91LiBBa28gb3JpZW50YcSNbsOpIHByYXZpZGxvIHNhIHBvdmHFvnVqw7ogemEgbmXFoWtvZG7DqSBob2Rub3R5IHBvZCAxMCwgemEgbWllcm5lIHByb2JsZW1hdGlja8OpIGhvZG5vdHkgbWVkemkgMTDigJMzMCBhIHphIHrDoXZhxb5uw7ogbXVsdGlrb2xpbmVhcml0dSBob2Rub3R5IG5hZCAzMC4KCmBgYHtyfQpYIDwtIG1vZGVsLm1hdHJpeChtb2RlbClbLCAtMV0KWHRYIDwtIHQoWCkgJSolIFgKZWlnIDwtIGVpZ2VuKFh0WCkKCmNvbmRpdGlvbl9udW1iZXIgPC0gc3FydChtYXgoZWlnJHZhbHVlcykgLyBtaW4oZWlnJHZhbHVlcykpCmNvbmRpdGlvbl9udW1iZXIKYGBgCgpWeXBvxI3DrXRhbsO9IGNvbmRpdGlvbiBudW1iZXIgbcOhIGhvZG5vdHUgcHJpYmxpxb5uZSAxLjc1LCDEjW8gamUgdmXEvm1pIG7DrXprYSBob2Rub3RhLiBUYWvDqXRvIMSNw61zbG8gamVkbm96bmHEjW5lIG5hem5hxI11amUsIMW+ZSBtYXRpY2EgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBqZSBkb2JyZSBwb2RtaWVuZW7DoSBhIG1vZGVsIG5pZSBqZSBjaXRsaXbDvSBuYSBtYWzDqSB6bWVueSB2IGTDoXRhY2guIEluw71taSBzbG92YW1pLCB2w71zbGVkb2sgcG90dnJkenVqZSBhYnNlbmNpdSBtdWx0aWtvbGluZWFyaXR5LCDEjW8gamUgdiBzw7psYWRlIHMga29yZWzDoWNpYW1pIGFqIHMgVklGIGFuYWzDvXpvdS4KCk5hIGRvcGxuZW5pZSB6w6FrbGFkbsO9Y2ggdWthem92YXRlxL5vdiBtdWx0aWtvbGluZWFyaXR5IHZ5dcW+aWplbWUgYWogYW5hbMO9enUgdmxhc3Ruw71jaCBob2Ruw7R0IGEgaW5kZXhvdiBwb2RtaWVuZW5vc3RpLiBUZW50byBwb3N0dXAgdW1vxb7FiHVqZSB6w61za2HFpSBwcmVzbmVqxaHDrSBvYnJheiBvIHRvbSwgYWtvIHPDuiB2eXN2ZXTEvnVqw7pjZSBwcmVtZW5uw6kgcm96bG/FvmVuw6kgdiBwcmllc3RvcmUgYSDEjWkgc2EgdXLEjWl0w6EgaWNoIGtvbWJpbsOhY2lhIG5lc3Byw6F2YSBwcm9ibGVtYXRpY2t5LiBJZGUgbyByb3rFocOtcmVuw7ogZGlhZ25vc3Rpa3UsIGt0b3LDoSBwb3NreXR1amUgZGV0YWlsbmVqxaHDrSBwb2jEvmFkIG5hIHN0YWJpbGl0dSByZWdyZXNuw6lobyBtb2RlbHUuCgpgYGB7cn0KbGlicmFyeShvbHNycikKb2xzX2VpZ2VuX2NpbmRleChtb2RlbCkKYGBgCgpWIHRhYnXEvmtlIHZpZMOtbWUgxaF0eXJpIHZsYXN0bsOpIGhvZG5vdHksIGt0b3LDqSByZXByZXplbnR1asO6IMWhdHlyaSBvcnRvZ29uw6FsbmUga29tcG9uZW50eSBwcmllc3RvcnUgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaC4gUHJlIGthxb5kw7ogeiBuaWNoIGplIHZ5cG/EjcOtdGFuw70gY29uZGl0aW9uIGluZGV4LCBrdG9yw70gdWthenVqZSBtaWVydSBwb3RlbmNpw6FsbmVobyBudW1lcmlja8OpaG8gcHJvYmzDqW11LiBWxaFldGt5IGluZGV4eSBzYSBuYWNow6FkemFqw7ogdmXEvm1pIG7DrXprbywgdiByb3pzYWh1IDEuMDAgYcW+IDEuNTMsIMSNbyBqZSBobGJva28gcG9kIGhyYW5pY2FtaSwga3RvcsOpIGJ5IHNpZ25hbGl6b3ZhbGkgYWvDvWtvxL52ZWsgcHJvYmzDqW0gKHphIHJpemlrb3bDqSBzYSBwb3Zhxb51asO6IGhvZG5vdHkgbmFkIDEwIGEgbmFqbcOkIG5hZCAzMCkuCgrEjmFsxaHDrSBwb2jEvmFkIHBvc2t5dHVqw7ogesOhxaVhxb5lIChwcm9wb3JjaWUgdmFyaWFuY2nDrSkgamVkbm90bGl2w71jaCBwcmVtZW5uw71jaCB2IHBvc2xlZG7DvWNoIHN0xLpwY29jaC4gQWsgYnkgZXhpc3RvdmFsYSBtdWx0aWtvbGluZWFyaXRhLCB2aWFjZXLDqSBwcmVtZW5uw6kgYnkgdnlrYXpvdmFsaSB2eXNva8OpIGhvZG5vdHkgdiByb3ZuYWtvbSByaWFka3UsIHR5cGlja3kgcHJpIHZ5c29rb20gY29uZGl0aW9uIGluZGV4ZS4gViB0b210byBwcsOtcGFkZSB2xaFhayDFvmlhZG5hIHogcHJlbWVubsO9Y2ggbmV2eWthenVqZSBrb25jZW50cm92YW7DqSB6YcWlYcW+ZW5pZSBwcmkgxb5pYWRub20geiBpbmRleG92LCDEjW8gcG90dnJkenVqZSwgxb5lIG1vZGVsIGplIHN0YWJpbG7DvSBhIG5pZSBqZSBvdnBseXZuZW7DvSB2esOham9tbsO9bWkgbGluZcOhcm55bWkgdsOkemJhbWkgbWVkemkgR0xEX3JldCwgWExFX3JldCBhIFNQWV9yZXQuCgpWw71zbGVkb2sgdGFrIHBvc2t5dHVqZSBkb2RhdG/EjW7DvSBkw7RrYXosIMW+ZSBtdWx0aWtvbGluZWFyaXRhIG5pZSBqZSB2IG5hxaFvbSBtb2RlbGkgcHLDrXRvbW7DoSDigJQga29uemlzdGVudG5lIHMgdsO9c2xlZGthbWkga29yZWzDoWNpw60sIFZJRiBhaiB6w6FrbGFkbsOpaG8gY29uZGl0aW9uIG51bWJlci4KCiMgUmllxaFlbmlhIG11bHRpa29saW5lYXJpdHkKCiMjIFZ5bmVjaGFuaWUgcHJlbWVubmVqIAoKIyMjIE1vZGVsIGJleiBHTERfcmV0CgpWIHRvbXRvIGtyb2t1IG9kaGFkdWplbWUgbW9kZWwsIHYga3Rvcm9tIGJvbGEgcHJlbWVubsOhIEdMRF9yZXQgdnluZWNoYW7DoSB6byBza3VwaW55IHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2guIENpZcS+b20gamUgcG9zw7pkacWlLCDEjWkgamVqIHZ5bMO6xI1lbmllIG1lbsOtIHNwcsOhdmFuaWUgcmVncmVzbsOpaG8gbW9kZWx1LCBhIMSNaSBvc3RhdG7DqSBwcmVtZW5uw6kgZG9rw6HFvnUgemFjaHl0acWlIHZhcmlhYmlsaXR1IHYgesOhdmlzbGVqIHByZW1lbm5laiBiZXogamVqIHByw610b21ub3N0aS4gVGFrw6l0byBwb3Jvdm5hbmllIHVtb8W+xYh1amUgaWRlbnRpZmlrb3ZhxaUsIGRvIGFrZWogbWllcnkgamVkbm90bGl2w6kgcHJlbWVubsOpIHByaXNwaWV2YWrDuiBrIHZ5c3ZldGxlbml1IEFBUExfcmV0LgoKYGBge3J9Cm1vZGVsX25vX0dMRCA8LSBsbShBQVBMX3JldCB+IFhMRV9yZXQgKyBTUFlfcmV0LCBkYXRhID0gcmV0X2RmKQpzdW1tYXJ5KG1vZGVsX25vX0dMRCkKCmBgYAoKUG8gb2RzdHLDoW5lbsOtIEdMRF9yZXQgem9zdGFsaSB2IG1vZGVsaSBwcmVtZW5uw6kgWExFX3JldCBhIFNQWV9yZXQuIE9iZSBtYWrDuiBzaWduaWZpa2FudG7DvSB2cGx5diBuYSBBQVBMX3JldCwgcHJpxI1vbSBTUFlfcmV0IHZ5a2F6dWplIHZlxL5taSBzaWxuw70gYSDFoXRhdGlzdGlja3kgamVkbm96bmHEjW7DvSBlZmVrdC4gSG9kbm90YSBSLXNxdWFyZWQgamUgcHJpYmxpxb5uZSAwLjMxLCDEjW8gem5hbWVuw6EsIMW+ZSBtb2RlbCB6YWNoeXTDoXZhIHBvZG9ibsO6IMO6cm92ZcWIIHZhcmlhYmlsaXR5IGFrbyBww7R2b2Ruw70gbW9kZWwgcyB0cm9taSBwcmVkaWt0b3JtaS4gS29lZmljaWVudCBwcmkgWExFX3JldCB6b3N0w6F2YSBuZWdhdMOtdm55IGEgc2lnbmlmaWthbnRuw70sIMSNbyBuYXpuYcSNdWplLCDFvmUgamVobyB2cGx5diBqZSBzdGFiaWxuw70gYWogYmV6IHphaHJudXRpYSBHTERfcmV0LiBDZWxrb3ZvIHNhIHbDvWtvbiBtb2RlbHUgdsO9cmF6bmVqxaFpZSBuZXpob3LFoWlsLCDEjW8gcG90dnJkenVqZSwgxb5lIEdMRF9yZXQgbmllIGplIGvEvsO6xI1vdsO9bSBub3NpdGXEvm9tIGluZm9ybcOhY2llIHYgdG9tdG8gcmVncmVzbm9tIHZ6xaVhaHUuCgojIyMgTW9kZWwgYmV6IFhMRV9yZXQKCk1vZGVsIG9kaGFkdWplbWUgem5vdmEgcG8gdnluZWNoYW7DrSBwcmVtZW5uZWogWExFX3JldCwgYWJ5IHNtZSBwb3PDumRpbGkgamVqIHByw61ub3MgayB2eXN2ZXRsZW5pdSB2YXJpYWJpbGl0eSBBQVBMX3JldC4KCmBgYHtyfQptb2RlbF9ub19YTEUgPC0gbG0oQUFQTF9yZXQgfiBHTERfcmV0ICsgU1BZX3JldCwgZGF0YSA9IHJldF9kZikKc3VtbWFyeShtb2RlbF9ub19YTEUpCmBgYAoKUG8gb2RzdHLDoW5lbsOtIFhMRV9yZXQgem9zdMOhdmFqw7ogdiBtb2RlbGkgcHJlbWVubsOpIEdMRF9yZXQgYSBTUFlfcmV0LiBQcmVtZW5uw6EgU1BZX3JldCB6b3N0w6F2YSB2w71yYXpuZSBzaWduaWZpa2FudG7DoSBhIG5hxI9hbGVqIHByZWRzdGF2dWplIGRvbWluYW50bsO9IHpkcm9qIHZ5c3ZldMS+dWrDumNlaiBzaWx5IHYgbW9kZWxpLiBLb2VmaWNpZW50IHByaSBHTERfcmV0IG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSwgxI1vIG5hem5hxI11amUsIMW+ZSBqZWhvIGluZm9ybWHEjW7DvSBwcsOtbm9zIGplIHZlxL5taSBvYm1lZHplbsO9LiBIb2Rub3RhIFItc3F1YXJlZCBzYSBtaWVybmUgem7DrcW+aWxhLCBhbGUgem9zdMOhdmEgcG9yb3ZuYXRlxL5uw6EgcyBvc3RhdG7DvW1pIHJlZHVrb3ZhbsO9bWkgbW9kZWxtaSwgxI1vIHBvdHZyZHp1amUsIMW+ZSB2eW5lY2hhbmllIFhMRV9yZXQgbmVtw6EgesOhc2FkbsO9IHZwbHl2IG5hIGNlbGtvdsO6IGt2YWxpdHUgcmVncmVzaWUuIE1vZGVsIHByZXRvIGRvYnJlIGZ1bmd1amUgYWogYmV6IHRlanRvIHByZW1lbm5lai4KCiMjIyBNb2RlbCBiZXogU1BZX3JldAoKTW9kZWwgb2RoYWR1amVtZSBwbyB2eW5lY2hhbsOtIHByZW1lbm5laiBTUFlfcmV0LCBhYnkgc21lIHppc3RpbGksIGRvIGFrZWogbWllcnkgbmEgbmVqIHrDoXZpc8OtIHZ5c3ZldMS+dWrDumNhIHNpbGEgcMO0dm9kbmVqIHJlZ3Jlc2llLgoKYGBge3J9Cm1vZGVsX25vX1NQWSA8LSBsbShBQVBMX3JldCB+IEdMRF9yZXQgKyBYTEVfcmV0LCBkYXRhID0gcmV0X2RmKQpzdW1tYXJ5KG1vZGVsX25vX1NQWSkKYGBgCgpQbyBvZHN0csOhbmVuw60gU1BZX3JldCB6b3N0w6F2YWrDuiB2IG1vZGVsaSBwcmVtZW5uw6kgR0xEX3JldCBhIFhMRV9yZXQsIGF2xaFhayBhbmkgamVkbmEgeiBuaWNoIG5ldnlrYXp1amUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnBseXYgbmEgQUFQTF9yZXQuIEhvZG5vdGEgUi1zcXVhcmVkIHbDvXJhem5lIGtsZXNsYSBuYSBwcmlibGnFvm5lIDAuMDIsIMSNbyB6bmFtZW7DoSwgxb5lIG1vZGVsIHByYWt0aWNreSBuZWRva8Ohxb5lIHZ5c3ZldGxpxaUgdmFyaWFiaWxpdHUgesOhdmlzbGVqIHByZW1lbm5lai4gVsO9cmF6bsO9IHBva2xlcyB2eXN2ZXTEvm92YWNlaiBzY2hvcG5vc3RpIGEgbmVzaWduaWZpa2FudG5vc8WlIGtvZWZpY2llbnRvdiB1a2F6dWrDuiwgxb5lIFNQWV9yZXQgamUga8S+w7rEjW92b3UgcHJlbWVubm91IHYgcMO0dm9kbm9tIG1vZGVsaSBhIG5lc2llIGhsYXZuw7ogxI1hc8WlIGluZm9ybcOhY2llIG8gdsO9dm9qaSB2w71ub3NvdiBBQVBMLgoKIyMgxaBrw6Fsb3ZhbmllIHByZW1lbm7DvWNoCgpNb2RlbCBib2wgb2RoYWRudXTDvSBzIGNlbnRyb3ZhbsO9bWkgYSDFoXRhbmRhcmRpem92YW7DvW1pIGhvZG5vdGFtaSB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoLCBhYnkgc2EgemhvZG5vdGlsbywgxI1pIHRyYW5zZm9ybcOhY2lhIG92cGx5dm7DrSBzdGFiaWxpdHUga29lZmljaWVudG92IGEgZGlhZ25vc3Rpa3UgbXVsdGlrb2xpbmVhcml0eS4KCmBgYHtyfQpyZXRfZGZfYyA8LSByZXRfZGYgJT4lCiAgbXV0YXRlKAogICAgR0xEX2MgPSBzY2FsZShHTERfcmV0LCBjZW50ZXIgPSBUUlVFLCBzY2FsZSA9IEZBTFNFKSwKICAgIFhMRV9jID0gc2NhbGUoWExFX3JldCwgY2VudGVyID0gVFJVRSwgc2NhbGUgPSBGQUxTRSksCiAgICBTUFlfYyA9IHNjYWxlKFNQWV9yZXQsIGNlbnRlciA9IFRSVUUsIHNjYWxlID0gRkFMU0UpCiAgKQoKIyBPZGhhZCBtb2RlbHUgcyBjZW50cm92YW7DvW1pIHByZW1lbm7DvW1pCm1vZGVsX2NlbnRlcmVkIDwtIGxtKEFBUExfcmV0IH4gR0xEX2MgKyBYTEVfYyArIFNQWV9jLCBkYXRhID0gcmV0X2RmKQpzdW1tYXJ5KG1vZGVsX2NlbnRlcmVkKQp2aWYobW9kZWxfY2VudGVyZWQpCmBgYAoKQ2VudHJvdmFuaWUgYSDFoWvDoWxvdmFuaWUgbmVtZW7DrSDFoXRhdGlzdGlja8O6IHbDvXpuYW1ub3PFpSBhbmkgc21lciBww7Rzb2JlbmlhIGplZG5vdGxpdsO9Y2ggcHJlbWVubsO9Y2guIFByZW1lbm7DoSBTUFlfYyB6b3N0w6F2YSB2w71yYXpuZSBzaWduaWZpa2FudG7DoSBhIGRvbWludWplIHZ5c3ZldMS+dWrDumNlaiBzaWxlIG1vZGVsdSwgemF0aWHEviDEjW8gR0xEX2Mgb3DDpMWlIG5ldnlrYXp1amUgxb5pYWRueSB2w716bmFtbsO9IHZwbHl2LiBLb2VmaWNpZW50IHByaSBYTEVfYyB6b3N0w6F2YSBuZWdhdMOtdm55IGEgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIMSNbyBqZSB2IHPDumxhZGUgcyBww7R2b2Ruw71tIG1vZGVsb20uIEhvZG5vdGEgUi1zcXVhcmVkIHNhIHByYWt0aWNreSBuZXptZW5pbGEsIMSNbyB1a2F6dWplLCDFvmUgdHJhbnNmb3Jtw6FjaWEgbmVtYWxhIHZwbHl2IG5hIGNlbGtvdsO6IGt2YWxpdHUgcmVncmVzaWUuIFZJRiBob2Rub3R5IHpvc3TDoXZhasO6IHZlxL5taSBuw616a2UsIMSNbyBwb3R2cmR6dWplIGFic2VuY2l1IG11bHRpa29saW5lYXJpdHkgYWogcG8gdHJhbnNmb3Jtw6FjaWkuCgpDb25kaXRpb24gbnVtYmVyIHZ5cG/EjcOtdGFuw70gcHJlIGNlbnRyb3ZhbsO9IG1vZGVsIHNsw7rFvmkgYWtvIGRvcGxua292w70gdWthem92YXRlxL4gbmEgcG9zw7pkZW5pZSwgxI1pIHRyYW5zZm9ybcOhY2lhIHByZW1lbm7DvWNoIG92cGx5dm5pbGEgc3RhYmlsaXR1IG51bWVyaWNrw6lobyByaWXFoWVuaWEgcmVncmVzaWUuCgpDb25kaXRpb25hbCBOdW1iZXIgamUKCmBgYHtyfQpYIDwtIG1vZGVsLm1hdHJpeChtb2RlbF9jZW50ZXJlZClbLCAtMV0KWHRYIDwtIHQoWCkgJSolIFgKZWlnIDwtIGVpZ2VuKFh0WCkKCmNvbmRpdGlvbl9udW1iZXIgPC0gc3FydChtYXgoZWlnJHZhbHVlcykgLyBtaW4oZWlnJHZhbHVlcykpCmNvbmRpdGlvbl9udW1iZXIKYGBgCgpIb2Rub3RhIGNvbmRpdGlvbiBudW1iZXIgamUgcHJpYmxpxb5uZSAxLjUwLCDEjW8gcHJlZHN0YXZ1amUgdmXEvm1pIG7DrXprdSDDunJvdmXFiCBhIHBvdHZyZHp1amUsIMW+ZSBhbmkgcG8gY2VudHJvdmFuw60gbmV2em5pa2Fqw7ogxb5pYWRuZSBuw6F6bmFreSBtdWx0aWtvbGluZWFyaXR5LiBNb2RlbCBqZSBudW1lcmlja3kgc3RhYmlsbsO9LCBwcmVtZW5uw6kgc2Egc3Byw6F2YWrDuiBuZXrDoXZpc2xlIGEgdHJhbnNmb3Jtw6FjaWEgbmV6bWVuaWxhIHZ6xaVhaHkgbWVkemkgbmltaS4gVMOhdG8gZGlhZ25vc3Rpa2EgdGFrIHBvZHBvcnVqZSB6w6F2ZXIsIMW+ZSBtdWx0aWtvbGluZWFyaXRhIHYgZMOhdGFjaCBuZXByZWRzdGF2dWplIHByb2Jsw6ltLgoKIyMgUG9yb3ZuYW5pZSBjZW50cm92YW7DqWhvIGEgesOha2xhZG7DqWhvIG1vZGVsdSAKClBvcm92bmFuaWUgcMO0dm9kbsOpaG8gYSBjZW50cm92YW7DqWhvIG1vZGVsdSB1bW/FvsWIdWplIG92ZXJpxaUsIMSNaSB0cmFuc2Zvcm3DoWNpYSB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoIG92cGx5dm5pbGEgdsO9xaFrdSBrb2VmaWNpZW50b3YgYSBzbWVyb2Rham7DqSBvZGNow71sa3kuIFRlbnRvIHBvc3R1cCB1a2F6dWplLCDEjWkgc8O6IG9kaGFkeSBzdGFiaWxuw6kgdm/EjWkgem1lbmUgbWllcmt5IHByZW1lbm7DvWNoIGEgcG9tw6FoYSBpZGVudGlmaWtvdmHFpSBwcsOtcGFkbsO6IGNpdGxpdm9zxaUgbW9kZWx1LgoKYGBge3J9CmxpYnJhcnkoYnJvb20pCmNvbXBhcmUgPC0gYmluZF9jb2xzKAogIHRpZHkobW9kZWwpWywgYygidGVybSIsICJlc3RpbWF0ZSIsICJzdGQuZXJyb3IiKV0gJT4lIHJlbmFtZShlc3RpbWF0ZV9yYXcgPSBlc3RpbWF0ZSwgc2VfcmF3ID0gc3RkLmVycm9yKSwKICB0aWR5KG1vZGVsX2NlbnRlcmVkKVssIGMoImVzdGltYXRlIiwgInN0ZC5lcnJvciIpXSAlPiUgcmVuYW1lKGVzdGltYXRlX2MgPSBlc3RpbWF0ZSwgc2VfYyA9IHN0ZC5lcnJvcikKKQpjb21wYXJlCgpgYGAKClogcG9yb3ZuYW5pYSB2aWRubywgxb5lIGNlbnRyb3ZhbmllIG5lbcOhIHZwbHl2IG5hIMWhdGF0aXN0aWNrw7ogdsO9em5hbW5vc8WlIGFuaSBzbWVyIHDDtHNvYmVuaWEgamVkbm90bGl2w71jaCBwcmVtZW5uw71jaC4gSG9kbm90eSBvZGhhZG92IHNhIHPDrWNlIHptZW5pbGkgdiBhYnNvbMO6dG55Y2ggxI3DrXNsYWNoICjEjW8gamUgcHJpcm9kemVuw70gZMO0c2xlZG9rIHRyYW5zZm9ybcOhY2llKSwgYXbFoWFrIGljaCByZWxhdMOtdm5lIHDDtHNvYmVuaWUgYSB2w716bmFtbm9zxaUgem9zdGFsaSByb3ZuYWvDqS4gU21lcm9kYWpuw6kgb2RjaMO9bGt5IHNhIHptZW5pbGkgbGVuIG1pbmltw6FsbmUsIMSNbyBuYXpuYcSNdWplLCDFvmUgbW9kZWwgamUgc3RhYmlsbsO9IGEgbmVwcmVqYXZ1amUgY2l0bGl2b3PFpSBuYSByb3pkaWVsbmUgbWllcmt5IHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2guIENlbGtvdsOpIHNwcsOhdmFuaWUgbW9kZWx1IHRhayBwb3R2cmR6dWplLCDFvmUgbXVsdGlrb2xpbmVhcml0YSBuZXByZWRzdGF2dWplIHByb2Jsw6ltIGEgdsO9c2xlZGt5IHPDuiByb2J1c3Ruw6kgYWogcG8gY2VudHJvdmFuw60uCgojIyBJbsOhIMO6cHJhdmEgcHJlbWVubmVqLCBrdG9yw6EgemFjaG92w6EgaW50ZXJwcmV0b3ZhdGXEvm5vc8WlCgojIyMgTGluZcOhcm55IG1vZGVsIHMgcGVyY2VudHXDoWxueW1pIGplZG5vdGthbWkgcHJlZGlrdG9yb3YKCkFieSBzbWUgenbDvcWhaWxpIGludGVycHJldG92YXRlxL5ub3PFpSByZWdyZXNuw6lobyBtb2RlbHUsIHByZXZlZGllbWUgdnlzdmV0xL51asO6Y2UgcHJlbWVubsOpIHogcMO0dm9kbsO9Y2ggbG9nLXbDvW5vc292IG5hIHBlcmNlbnR1w6FsbmUgem1lbnkuIFRlbnRvIHBvc3R1cCBuZW1lbsOtIMWhdGF0aXN0aWNrw7ogcG9kc3RhdHUgbW9kZWx1LCBhbGUgdW1vxb7FiHVqZSBqZWRub2R1Y2jFoWllIMSNw610YW5pZSBrb2VmaWNpZW50b3Yg4oCTIG9kaGFkIG7DoXNsZWRuZSB2eWphZHJ1amUgem1lbnUgQUFQTF9yZXQgcHJpIHptZW5lIHZ5c3ZldMS+dWrDumNlaiBwcmVtZW5uZWogbyBqZWRlbiBwZXJjZW50dcOhbG55IGJvZC4gT2tyZW0genJvenVtaXRlxL5ub3N0aSB6w6Fyb3ZlxYggcHJldmVydWplbWUsIMSNaSBwcmV2b2QgbmEgaW7DuiBtaWVya3UgbmVqYWtvIG92cGx5dm7DrSBkaWFnbm9zdGlrdSBtdWx0aWtvbGluZWFyaXR5IGFsZWJvIHN0YWJpbGl0dSBtb2RlbG92w71jaCBvZGhhZG92LgoKYGBge3J9CiMgUHJldm9keSB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoIG5hIHBlcmNlbnR1w6FsbmUgYm9keQpyZXRfZGYkR0xEX3BjdCA8LSAxMDAgKiByZXRfZGYkR0xEX3JldAoKYGBgCgpgYGB7cn0KcmV0X2RmJFhMRV9wY3QgPC0gMTAwICogcmV0X2RmJFhMRV9yZXQKCmBgYAoKYGBge3J9CnJldF9kZiRTUFlfcGN0IDwtIDEwMCAqIHJldF9kZiRTUFlfcmV0CgpgYGAKCgpgYGB7cn0KbW9kZWxfcGN0IDwtIGxtKEFBUExfcmV0IH4gR0xEX3BjdCArIFhMRV9wY3QgKyBTUFlfcGN0LCBkYXRhID0gcmV0X2RmKQpzdW1tYXJ5KG1vZGVsX3BjdCkKCmBgYAoKTW9kZWwgcyBwZXJjZW50dcOhbG55bWkgamVkbm90a2FtaSBwb3NreXR1amUgcHJha3RpY2t5IHJvdm5ha8OpIHbDvXNsZWRreSBha28gcMO0dm9kbsO9IG1vZGVsIHMgbG9nLXbDvW5vc21pLiBQcmVtZW5uw6EgU1BZX3BjdCB6b3N0w6F2YSB2ZcS+bWkgc2lsbsO9bSBhIMWhdGF0aXN0aWNreSB2w716bmFtbsO9bSBwcmVkaWt0b3JvbSBBQVBMX3JldCwgxI1vIHBvdHZyZHp1amUgamVqIGRvbWluYW50bsO6IMO6bG9odSBwcmkgdnlzdmV0xL5vdmFuw60gem1pZW4gdiB6w6F2aXNsZWogcHJlbWVubmVqLiBQcmVtZW5uw6EgWExFX3BjdCBvcMOkxaUgdnlrYXp1amUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gbmVnYXTDrXZueSB2cGx5diwgYSB0byByb3ZuYWtvIGFrbyB2IHByZWRjaMOhZHphasO6Y2ljaCBvZGhhZG9jaC4gUHJlbWVubsOhIEdMRF9wY3Qgb3N0w6F2YSBiZXogxaF0YXRpc3RpY2vDqWhvIHbDvXpuYW11LCDEjW8gbmF6bmHEjXVqZSwgxb5lIGluZm9ybcOhY2lhIHogdGVqdG8gcHJlbWVubmVqIG5lcHJpc3BpZXZhIGsgdnlzdmV0bGVuaXUgdsO9bm9zb3YgQUFQTC4gSG9kbm90YSBSLXNxdWFyZWQgem9zdMOhdmEgbmEgcHJpYmxpxb5uZSByb3ZuYWtlaiDDunJvdm5pIGFrbyB2IHByZWRjaMOhZHphasO6Y2ljaCBtb2RlbG9jaCwgxI1vIHVrYXp1amUsIMW+ZSB6bWVuYSBqZWRub3RpZWsgbmVtZW7DrSB2eXN2ZXTEvm92YWNpdSBzaWx1IHJlZ3Jlc2llLgoKIyMjIFZJRiBkaWFnbm9zdGlrYQoKYGBge3J9Cgp2aWYobW9kZWxfcGN0KQoKYGBgCgpIb2Rub3R5IFZJRiBzw7ogdmXEvm1pIG7DrXprZSAocHJpYmxpxb5uZSAxLjEpLCDEjW8gcG90dnJkenVqZSBhYnNlbmNpdSBtdWx0aWtvbGluZWFyaXR5IGFqIHBvIHByZXZlZGVuw60gcHJlbWVubsO9Y2ggbmEgcGVyY2VudHXDoWxuZSB6bWVueS4gVsWhZXRreSB2eXN2ZXTEvnVqw7pjZSBwcmVtZW5uw6kgc8O6IG5hdnrDoWpvbSBuZXrDoXZpc2zDqSB2IHRha29tIHJvenNhaHUsIMW+ZSBpY2ggc3BvbG/EjW7DqSB6YWhybnV0aWUgZG8gcmVncmVzbsOpaG8gbW9kZWx1IG5lcHJlZHN0YXZ1amUgxb5pYWRueSBwcm9ibMOpbS4KCiMjIyBDb25kaXRpb24gbnVtYmVyCgpgYGB7cn0KClggPC0gbW9kZWwubWF0cml4KG1vZGVsX3BjdClbLCAtMV0KWHRYIDwtIHQoWCkgJSolIFgKZWlnIDwtIGVpZ2VuKFh0WCkKY29uZGl0aW9uX251bWJlciA8LSBzcXJ0KG1heChlaWckdmFsdWVzKSAvIG1pbihlaWckdmFsdWVzKSkKY29uZGl0aW9uX251bWJlcgoKYGBgCgpWeXBvxI3DrXRhbsOhIGhvZG5vdGEgY29uZGl0aW9uIG51bWJlciBqZSBwcmlibGnFvm5lIDEuNzUsIMSNbyBqZSB2ZcS+bWkgbsOtemthIGhvZG5vdGEgYSB6b2Rwb3ZlZMOhIGRvYnJlIHBvZG1pZW5lbsOpbXUgcmVncmVzbsOpbXUgbW9kZWx1LiBUbyB6bmFtZW7DoSwgxb5lIG51bWVyaWNrw6Egc3RhYmlsaXRhIG1vZGVsdSB6b3N0w6F2YSB6YWNob3ZhbsOhIGEgxb5lIGFuaSBwbyB6bWVuZSBqZWRub3RpZWsgbmVkb2Now6FkemEgayB6dsO9xaFlbml1IGNpdGxpdm9zdGkgbW9kZWx1IG5hIG1hbMOpIHptZW55IHZvIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2guCgoK