knitr::opts_chunk$set(
    echo = TRUE,
    message = FALSE,
    warning = FALSE
)
library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())

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.

summary(ret_df)
    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é.

vif(model)
 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
vif(model_centered)
   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
NA

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