Úvod

V tejto úlohe skúmame, ako makroekonomické ukazovatele – inflácia, rast HDP, miera nezamestnanosti a úrokové sadzby – ovplyvňujú akciový index v Kanade.

Cieľom je:

  • odhadnúť lineárne a nelineárne regresné modely,

  • overiť správnosť špecifikácie modelu (RESET test, C+R ploty),

  • preskúmať efekty šokových období pomocou dummy premenných,

  • zistiť, či je vhodná transformácia závislej premennej (Box-Cox test).

Výsledky nám umožnia lepšie pochopiť vzťahy medzi makroekonomickými indikátormi a vývojom akciového trhu.

library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(carData)
library(cowplot)
library(ggplot2)
library(tidyverse)
library(car)
library(MASS)
library(readr)

Načítanie a príprava údajov

data <- read_csv("economic_indicators_dataset_2010_2023.csv") %>%
rename(
  Inflation_Rate = `Inflation Rate (%)`,
  GDP_Growth = `GDP Growth Rate (%)`,
  Unemployment_Rate = `Unemployment Rate (%)`,
  Interest_Rate = `Interest Rate (%)`,
  Stock_Index_Value = `Stock Index Value`
) %>%
mutate(Date = as.Date(Date),
       Year = year(Date),
       Quarter = quarter(Date)) %>%
arrange(Date)

# Vypočítame kvartálne log-returns ako závislú premennú
data <- data %>%
group_by(Country) %>%
mutate(Return = 100 * (log(Stock_Index_Value) - log(lag(Stock_Index_Value)))) %>%
ungroup() %>%
filter(!is.na(Return))

# Lagované vysvetľujúce premenné
data <- data %>%
group_by(Country) %>%
mutate(
  Inflation_Lag1 = lag(Inflation_Rate),
  GDP_Lag1 = lag(GDP_Growth),
  Unemployment_Lag1 = lag(Unemployment_Rate),
  Interest_Lag1 = lag(Interest_Rate)
) %>%
ungroup() %>%
filter(!is.na(Inflation_Lag1))

# Vyberieme jednu krajinu 
data_country <- data %>% filter(Country == "Canada")

Základná lineárna regresia

Odhadli sme základný lineárny regresný model, kde závislou premennou je Return (kvartálna výnosnosť akciového indexu), a vysvetľujúcimi premennými sú lagované makroekonomické ukazovatele (Inflácia, GDP, Nezamestnanosť, Úroková sadzba).

Cieľom je overiť, či tieto premenné štatisticky významne ovplyvňujú výnosy akciového trhu.

model1 <- lm(Return ~ Inflation_Lag1 + GDP_Lag1 + 
               Unemployment_Lag1 + Interest_Lag1,
             data = data_country)
summary(model1)

Call:
lm(formula = Return ~ Inflation_Lag1 + GDP_Lag1 + Unemployment_Lag1 + 
    Interest_Lag1, data = data_country)

Residuals:
     Min       1Q   Median       3Q      Max 
-237.459  -80.935    2.865   71.876  286.813 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)
(Intercept)       -55.2698    68.0659  -0.812    0.422
Inflation_Lag1      8.0565     6.3979   1.259    0.215
GDP_Lag1           -1.8043     4.7543  -0.380    0.706
Unemployment_Lag1   1.5725     6.1796   0.254    0.800
Interest_Lag1       0.4398     5.6816   0.077    0.939

Residual standard error: 126.1 on 40 degrees of freedom
Multiple R-squared:  0.05268,   Adjusted R-squared:  -0.04205 
F-statistic: 0.5561 on 4 and 40 DF,  p-value: 0.6958
  • Žiadny z koeficientov nie je štatisticky významný (p-hodnoty všetky > 0.2) -> to znamená, že na tomto základnom lineárnom modeli žiadna premenná nevysvetľuje výnosy akcií výraznejšie.

  • Intercept = -55.27, tiež neštatisticky významný, slúži len ako posun regresnej priamky.

  • R² = 0.0527, Adjusted R² = -0.042 → model vysvetľuje len ~5 % variability výnosov, čo je veľmi nízke.

  • F-test (p = 0.696) → model ako celok nie je štatisticky významný.

  • Reziduá - veľký rozsah -237 až 287 → vysoká volatilita výnosov, model nezachytáva ich dynamiku -> to naznačuje, že lineárna špecifikácia bez nelineárnych členov, interakcií alebo šokových premenných je nedostatočná.

Ramsey RESET test

RESET test slúži na overenie správnosti špecifikácie lineárneho modelu. Testuje, či sme nezanedbali nelineárne vzťahy alebo interakcie medzi vysvetľujúcimi premennými.

  • H0 (nulová hypotéza): model je správne špecifikovaný (žiadne chýbajúce nelineárne členy).

  • H1 (alternatívna hypotéza): model je nesprávne špecifikovaný (chýbajú nelineárne členy alebo interakcie).

resettest(model1)

    RESET test

data:  model1
RESET = 0.078107, df1 = 2, df2 = 38, p-value = 0.925
  • P-hodnota je veľmi vysoká (> 0.05) -> takže nemáme dôkaz proti nulovej hypotéze.

  • Model teda formálne nie je nesprávne špecifikovaný -> t.j. pridanie vyšších mocnín vysvetľujúcich premenných by štatisticky významne nezlepšilo fit modelu.

Reziduálny graf

Reziduálny graf (Residuals vs. Fitted) slúži na vizuálne overenie predpokladu linearity, homoskedasticity a náhodnosti rezíduí. Chceme zistiť, či reziduá majú nejaký štruktúrovaný vzor, ktorý by naznačoval, že model nezachytil všetky vzťahy medzi premennými.

plot(model1, which = 1)

  • Reziduá sa javia náhodne rozptýlené okolo nuly → predpoklad linearity a správnej špecifikácie modelu je formálne splnený.

  • Nenachádza sa žiadne zakrivenie ani heteroskedasticita → model nezanedbáva systematické nelineárne vzťahy.

  • Existence niekoľkých extrémnych bodov (outlierov) môže ovplyvniť presnosť odhadu, ale celkovo graf podporuje platnosť lineárnej špecifikácie.

C + R plot (Component + Residual)

C+R plot (Component + Residual) umožňuje vizuálne posúdiť nelineárne vzťahy medzi jednotlivou vysvetľujúcou premennou a závislou premennou po zohľadnení ostatných premenných v modeli.

crPlots(model1)

C + R plot – Inflation_Lag1

  • Vzťah medzi premennou a závislou premennou -> takmer lineárny, žiadne zakrivenie.

  • Poloha bodov -> väčšina bodov blízko modrej a ružovej línie, rozptýlenie náhodné. To naznačuje, že lagovaná inflácia nemá významný nelineárny efekt na výnosy kanadského akciového trhu.

  • Outliery -> veľmi málo extrémnych hodnôt, neovplyvňujú celkový vzťah.

Model nezanedbáva nelineárny efekt lagovanej inflácie, lineárna špecifikácia je vhodná.

C + R plot – GDP_Lag1

  • Vzťah medzi GDP_Lag1 a výnosom akcií je prevažne lineárny.

  • Jemné zakrivenie ružovej línie môže naznačovať malý nelineárny efekt pri vyšších hodnotách. To znamená, že pri veľmi vysokom raste HDP by výnosy akciového indexu mohli reagovať mierne odlišne, čo je dôležité pri analýze extrémnych hospodárskych období.

Lineárna špecifikácia pre GDP_Lag1 je vhodná, nelineárne efekty sú minimálne.

C + R plot – Unemployment_Lag1

  • Vzťah medzi lagovanou nezamestnanosťou a výnosom akcií je takmer lineárny, bez výrazného zakrivenia.

  • Malé odchýlky ružovej línie môžu naznačovať mierny nelineárny efekt pri nižších hodnotách nezamestnanosti. To ukazuje, že pri nízkej nezamestnanosti malé zmeny môžu spôsobiť disproporčne väčší efekt na výnosy, čo zdôrazňuje citlivosť kanadského trhu na zamestnanosť.

Lineárna špecifikácia pre Unemployment_Lag1 je vhodná, žiadne zásadné nelineárne efekty sa neprejavujú.

C + R plot – Interest_Lag1

  • Vzťah medzi lagovanou úrokovou sadzbou a výnosom akcií je takmer lineárny, bez výrazného zakrivenia.

  • Jemné odchýlky ružovej línie naznačujú mierny nelineárny efekt pri stredných hodnotách úrokovej sadzby. To znamená, že stredné úrokové sadzby môžu mať mierne odlišný vplyv na výnosy, zatiaľ čo veľmi nízke alebo vysoké sadzby pôsobia menej citlivo.

Lineárna špecifikácia pre Interest_Lag1 je vhodná, nelineárne efekty sú minimálne.

Kvadratické členy pre nelineárne vzťahy

Pridanie kvadratických členov (štvorcových členov vysvetľujúcich premenných) slúži na testovanie, či medzi lagovanými makroekonomickými premennými a výnosom akcií existujú nelineárne vzťahy. Ak by sa ukázalo, že kvadratické členy sú štatisticky významné, znamenalo by to, že jednoduchý lineárny model nezachytáva celú dynamiku a je potrebné uvažovať nelineárnu transformáciu premenných.

model_quad <- lm(Return ~ Inflation_Lag1 + I(Inflation_Lag1^2) +
                   GDP_Lag1 + I(GDP_Lag1^2) +
                   Unemployment_Lag1 + I(Unemployment_Lag1^2) +
                   Interest_Lag1 + I(Interest_Lag1^2),
                 data = data_country)
summary(model_quad)

Call:
lm(formula = Return ~ Inflation_Lag1 + I(Inflation_Lag1^2) + 
    GDP_Lag1 + I(GDP_Lag1^2) + Unemployment_Lag1 + I(Unemployment_Lag1^2) + 
    Interest_Lag1 + I(Interest_Lag1^2), data = data_country)

Residuals:
     Min       1Q   Median       3Q      Max 
-249.006  -76.237    8.876   70.055  262.579 

Coefficients:
                         Estimate Std. Error t value Pr(>|t|)
(Intercept)            -152.50966  151.14907  -1.009    0.320
Inflation_Lag1           20.14300   32.34168   0.623    0.537
I(Inflation_Lag1^2)      -0.96354    3.10208  -0.311    0.758
GDP_Lag1                 -0.01206    6.98346  -0.002    0.999
I(GDP_Lag1^2)            -0.23363    1.37210  -0.170    0.866
Unemployment_Lag1        21.55821   41.38986   0.521    0.606
I(Unemployment_Lag1^2)   -1.58305    3.02474  -0.523    0.604
Interest_Lag1            29.94504   23.72780   1.262    0.215
I(Interest_Lag1^2)       -3.31045    2.57956  -1.283    0.208

Residual standard error: 129.1 on 36 degrees of freedom
Multiple R-squared:  0.1057,    Adjusted R-squared:  -0.09308 
F-statistic: 0.5317 on 8 and 36 DF,  p-value: 0.8247
anova(model1, model_quad)
Analysis of Variance Table

Model 1: Return ~ Inflation_Lag1 + GDP_Lag1 + Unemployment_Lag1 + Interest_Lag1
Model 2: Return ~ Inflation_Lag1 + I(Inflation_Lag1^2) + GDP_Lag1 + I(GDP_Lag1^2) + 
    Unemployment_Lag1 + I(Unemployment_Lag1^2) + Interest_Lag1 + 
    I(Interest_Lag1^2)
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     40 635577                           
2     36 600027  4     35550 0.5332 0.7121
resettest(model_quad)

    RESET test

data:  model_quad
RESET = 0.0075459, df1 = 2, df2 = 34, p-value = 0.9925

Reziduá a koeficienty

  • Kvadratické členy nie sú štatisticky významné (všetky p > 0,2), R² sa prakticky nezmenilo. Pridanie nelineárnych členov nevysvetľuje výnos akcií lepšie.

ANOVA – porovnanie s lineárnym modelom

  • F = 0.5332, p = 0.7121 → rozšírenie modelu o kvadratické členy neprinieslo zlepšenie kvality modelu.

RESET test

  • p-value = 0.9925 → model nie je nesprávne špecifikovaný ani s kvadratickými členmi.

Pre Kanadu lineárny model vystačuje; prítomnosť významnej nelinearity sa nepotvrdila, pridanie kvadratických členov neprinieslo žiadny užitočný efekt.

Dummy premenná pre šokové kvartály

Skúmame, či špecifické kvartály (Q3–Q4) majú významný vplyv na výnosy akcií v Kanade prostredníctvom dummy premennej Shock. Cieľom je overiť, či tieto kvartály zvyšujú alebo znižujú Return nezávisle od makroekonomických premenných.

data_country <- data_country %>%
mutate(Shock = ifelse(Year == 2020 & Quarter <= 2, 1, 0))

model_dummy <- lm(Return ~ Inflation_Lag1 + GDP_Lag1 + 
                    Unemployment_Lag1 + Interest_Lag1 + Shock,
                  data = data_country)
summary(model_dummy)

Call:
lm(formula = Return ~ Inflation_Lag1 + GDP_Lag1 + Unemployment_Lag1 + 
    Interest_Lag1 + Shock, data = data_country)

Residuals:
     Min       1Q   Median       3Q      Max 
-236.655  -81.431    0.882   72.074  287.214 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)
(Intercept)       -55.9578    69.1165  -0.810    0.423
Inflation_Lag1      8.1559     6.5220   1.251    0.219
GDP_Lag1           -1.6979     4.8816  -0.348    0.730
Unemployment_Lag1   1.4405     6.3371   0.227    0.821
Interest_Lag1       0.5521     5.8159   0.095    0.925
Shock              17.7495   135.1299   0.131    0.896

Residual standard error: 127.6 on 39 degrees of freedom
Multiple R-squared:  0.0531,    Adjusted R-squared:  -0.0683 
F-statistic: 0.4374 on 5 and 39 DF,  p-value: 0.8197
anova(model_quad, model_dummy)
Analysis of Variance Table

Model 1: Return ~ Inflation_Lag1 + I(Inflation_Lag1^2) + GDP_Lag1 + I(GDP_Lag1^2) + 
    Unemployment_Lag1 + I(Unemployment_Lag1^2) + Interest_Lag1 + 
    I(Interest_Lag1^2)
Model 2: Return ~ Inflation_Lag1 + GDP_Lag1 + Unemployment_Lag1 + Interest_Lag1 + 
    Shock
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     36 600027                           
2     39 635296 -3    -35269 0.7053 0.5551
resettest(model_dummy)

    RESET test

data:  model_dummy
RESET = 0.09522, df1 = 2, df2 = 37, p-value = 0.9094
  • Koeficient pre Shock: 17,75, p = 0,896 → efekt nie je štatisticky významný, kvartály Q3–Q4 nemajú zjavný vplyv.

  • R² a F-test: R² = 0,0531, F-test p = 0,8197 → model vysvetľuje len malú časť variability, pridanie Shock nezlepšilo vysvetľujúcu schopnosť.

  • Porovnanie s predchádzajúcim modelom: ANOVA ukazuje, že pridaním dummy premenné sa model nezlepšil (F = 0,7053, p = 0,5551).

  • RESET test: p = 0,9094 → model stále nevykazuje nedostatok špecifikácie ani nezachytené nelineárne vzťahy.

Šokové kvartály nemajú významný efekt na výnosy akcií v Kanade, model lineárnej špecifikácie je adekvátny.

Box-Cox transformácia

Box–Cox transformácia slúži na overenie, či by transformácia závislej premennej mohla zlepšiť lineárnu špecifikáciu modelu, napríklad znížiť heteroskedasticitu alebo zvýšiť predikčnú schopnosť modelu. Hľadáme optimálnu hodnotu parametra λ, ktorá ukáže, či je vhodná transformácia alebo sa dá ponechať pôvodná forma premennej.

# Box-Cox transformácia na úrovni Stock_Index_Value
model_boxcox <- lm(Stock_Index_Value ~ Inflation_Lag1 + GDP_Lag1 +
                     Unemployment_Lag1 + Interest_Lag1 + Shock,
                   data = data_country)
boxcox(model_boxcox, lambda = seq(-2, 2, 0.1))  

  • Maximum log Likelihood je približne pri λ ≈ 0,8–0,9, čo naznačuje, že optimálna transformácia by bola veľmi blízka pôvodnej mierke.

  • Horizontálna čiara predstavuje 95% interval; z nej vyplýva, že všetky hodnoty λ medzi približne 0,4 a 1,3 sú štatisticky prijateľné.

To znamená, že pôvodná forma premennej Stock_Index_Value (λ ≈ 1) je vhodná a transformácia nie je nutná.

Stock_Index_Value môže zostať v pôvodnej podobe, lineárny model je vhodný bez transformácie.

Záver

Analýza pre Kanadu ukázala, že lagované makroekonomické premenné – inflácia, rast HDP, miera nezamestnanosti a úroková sadzba – majú len veľmi slabý vplyv na výnosy akciového indexu.

Lineárne modely, kvadratické členy ani zahrnutie dummy pre šokové kvartály neviedli k významnému zlepšeniu predikcie.

Reziduá sú rozptýlené náhodne, C+R ploty a Box–Cox transformácia potvrdzujú vhodnosť lineárnej špecifikácie bez transformácie závislej premennej.

Celkovo modely vysvetľujú len malú časť variability výnosov, čo naznačuje, že ďalšie faktory mimo analyzovaných makroekonomických premenných môžu mať väčší vplyv na pohyb akciového indexu v Kanade.

LS0tDQp0aXRsZTogIsOabG9oYV83Ig0KYXV0aG9yOiAiWXVsaWlhIEx5c3l0c2lhIg0KZGF0ZTogIk5vdmVtYmVyIDIwMjUiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdGhlbWU6IHVuaXRlZA0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KZWRpdG9yX29wdGlvbnM6DQogIG1hcmtkb3duOg0KICAgIHdyYXA6IDcyDQotLS0NCg0KIyMgw5p2b2QNCg0KViB0ZWp0byDDumxvaGUgc2vDum1hbWUsIGFrbyBtYWtyb2Vrb25vbWlja8OpIHVrYXpvdmF0ZWxlIOKAkyBpbmZsw6FjaWEsIHJhc3QgSERQLCBtaWVyYSBuZXphbWVzdG5hbm9zdGkgYSDDunJva292w6kgc2FkemJ5IOKAkyBvdnBseXbFiHVqw7ogYWtjaW92w70gaW5kZXggdiBLYW5hZGUuDQoNCkNpZcS+b20gamU6DQoNCi0gb2RoYWRuw7rFpSBsaW5lw6FybmUgYSBuZWxpbmXDoXJuZSByZWdyZXNuw6kgbW9kZWx5LA0KDQotIG92ZXJpxaUgc3Byw6F2bm9zxaUgxaFwZWNpZmlrw6FjaWUgbW9kZWx1IChSRVNFVCB0ZXN0LCBDK1IgcGxvdHkpLA0KDQotIHByZXNrw7ptYcWlIGVmZWt0eSDFoW9rb3bDvWNoIG9iZG9iw60gcG9tb2NvdSBkdW1teSBwcmVtZW5uw71jaCwNCg0KLSB6aXN0acWlLCDEjWkgamUgdmhvZG7DoSB0cmFuc2Zvcm3DoWNpYSB6w6F2aXNsZWogcHJlbWVubmVqIChCb3gtQ294IHRlc3QpLg0KDQpWw71zbGVka3kgbsOhbSB1bW/Fvm5pYSBsZXDFoWllIHBvY2hvcGnFpSB2esWlYWh5IG1lZHppIG1ha3JvZWtvbm9taWNrw71taSBpbmRpa8OhdG9ybWkgYSB2w712b2pvbSBha2Npb3bDqWhvIHRyaHUuDQoNCmBgYHtyfQ0KbGlicmFyeSh6b28pDQpsaWJyYXJ5KHRzZXJpZXMpDQpsaWJyYXJ5KGxtdGVzdCkNCmxpYnJhcnkoc2FuZHdpY2gpDQpsaWJyYXJ5KGNhckRhdGEpDQpsaWJyYXJ5KGNvd3Bsb3QpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoY2FyKQ0KbGlicmFyeShNQVNTKQ0KbGlicmFyeShyZWFkcikNCmBgYA0KDQojIyBOYcSNw610YW5pZSBhIHByw61wcmF2YSDDumRham92DQoNCmBgYHtyfQ0KZGF0YSA8LSByZWFkX2NzdigiZWNvbm9taWNfaW5kaWNhdG9yc19kYXRhc2V0XzIwMTBfMjAyMy5jc3YiKSAlPiUNCnJlbmFtZSgNCiAgSW5mbGF0aW9uX1JhdGUgPSBgSW5mbGF0aW9uIFJhdGUgKCUpYCwNCiAgR0RQX0dyb3d0aCA9IGBHRFAgR3Jvd3RoIFJhdGUgKCUpYCwNCiAgVW5lbXBsb3ltZW50X1JhdGUgPSBgVW5lbXBsb3ltZW50IFJhdGUgKCUpYCwNCiAgSW50ZXJlc3RfUmF0ZSA9IGBJbnRlcmVzdCBSYXRlICglKWAsDQogIFN0b2NrX0luZGV4X1ZhbHVlID0gYFN0b2NrIEluZGV4IFZhbHVlYA0KKSAlPiUNCm11dGF0ZShEYXRlID0gYXMuRGF0ZShEYXRlKSwNCiAgICAgICBZZWFyID0geWVhcihEYXRlKSwNCiAgICAgICBRdWFydGVyID0gcXVhcnRlcihEYXRlKSkgJT4lDQphcnJhbmdlKERhdGUpDQoNCiMgVnlwb8SNw610YW1lIGt2YXJ0w6FsbmUgbG9nLXJldHVybnMgYWtvIHrDoXZpc2zDuiBwcmVtZW5uw7oNCmRhdGEgPC0gZGF0YSAlPiUNCmdyb3VwX2J5KENvdW50cnkpICU+JQ0KbXV0YXRlKFJldHVybiA9IDEwMCAqIChsb2coU3RvY2tfSW5kZXhfVmFsdWUpIC0gbG9nKGxhZyhTdG9ja19JbmRleF9WYWx1ZSkpKSkgJT4lDQp1bmdyb3VwKCkgJT4lDQpmaWx0ZXIoIWlzLm5hKFJldHVybikpDQoNCiMgTGFnb3ZhbsOpIHZ5c3ZldMS+dWrDumNlIHByZW1lbm7DqQ0KZGF0YSA8LSBkYXRhICU+JQ0KZ3JvdXBfYnkoQ291bnRyeSkgJT4lDQptdXRhdGUoDQogIEluZmxhdGlvbl9MYWcxID0gbGFnKEluZmxhdGlvbl9SYXRlKSwNCiAgR0RQX0xhZzEgPSBsYWcoR0RQX0dyb3d0aCksDQogIFVuZW1wbG95bWVudF9MYWcxID0gbGFnKFVuZW1wbG95bWVudF9SYXRlKSwNCiAgSW50ZXJlc3RfTGFnMSA9IGxhZyhJbnRlcmVzdF9SYXRlKQ0KKSAlPiUNCnVuZ3JvdXAoKSAlPiUNCmZpbHRlcighaXMubmEoSW5mbGF0aW9uX0xhZzEpKQ0KDQojIFZ5YmVyaWVtZSBqZWRudSBrcmFqaW51IC0gQ2FuYWRhDQpkYXRhX2NvdW50cnkgPC0gZGF0YSAlPiUgZmlsdGVyKENvdW50cnkgPT0gIkNhbmFkYSIpDQpgYGANCg0KIyMgWsOha2xhZG7DoSBsaW5lw6FybmEgcmVncmVzaWENCg0KT2RoYWRsaSBzbWUgesOha2xhZG7DvSBsaW5lw6FybnkgcmVncmVzbsO9IG1vZGVsLCBrZGUgesOhdmlzbG91IHByZW1lbm5vdSBqZSBSZXR1cm4gKGt2YXJ0w6FsbmEgdsO9bm9zbm9zxaUgYWtjaW92w6lobyBpbmRleHUpLCBhIHZ5c3ZldMS+dWrDumNpbWkgcHJlbWVubsO9bWkgc8O6IGxhZ292YW7DqSBtYWtyb2Vrb25vbWlja8OpIHVrYXpvdmF0ZWxlIChJbmZsw6FjaWEsIEdEUCwgTmV6YW1lc3RuYW5vc8WlLCDDmnJva292w6Egc2FkemJhKS4gDQoNCkNpZcS+b20gamUgb3ZlcmnFpSwgxI1pIHRpZXRvIHByZW1lbm7DqSDFoXRhdGlzdGlja3kgdsO9em5hbW5lIG92cGx5dsWIdWrDuiB2w71ub3N5IGFrY2lvdsOpaG8gdHJodS4NCg0KYGBge3J9DQptb2RlbDEgPC0gbG0oUmV0dXJuIH4gSW5mbGF0aW9uX0xhZzEgKyBHRFBfTGFnMSArIA0KICAgICAgICAgICAgICAgVW5lbXBsb3ltZW50X0xhZzEgKyBJbnRlcmVzdF9MYWcxLA0KICAgICAgICAgICAgIGRhdGEgPSBkYXRhX2NvdW50cnkpDQpzdW1tYXJ5KG1vZGVsMSkNCmBgYA0KLSDFvWlhZG55IHoga29lZmljaWVudG92IG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSAocC1ob2Rub3R5IHbFoWV0a3kgPiAwLjIpIC0+IHRvIHpuYW1lbsOhLCDFvmUgbmEgdG9tdG8gesOha2xhZG5vbSBsaW5lw6Fybm9tIG1vZGVsaSDFvmlhZG5hIHByZW1lbm7DoSBuZXZ5c3ZldMS+dWplIHbDvW5vc3kgYWtjacOtIHbDvXJhem5lasWhaWUuDQoNCi0gSW50ZXJjZXB0ID0gLTU1LjI3LCB0aWXFviBuZcWhdGF0aXN0aWNreSB2w716bmFtbsO9LCBzbMO6xb5pIGxlbiBha28gcG9zdW4gcmVncmVzbmVqIHByaWFta3kuDQoNCi0gUsKyID0gMC4wNTI3LCBBZGp1c3RlZCBSwrIgPSAtMC4wNDIg4oaSIG1vZGVsIHZ5c3ZldMS+dWplIGxlbiB+NSAlIHZhcmlhYmlsaXR5IHbDvW5vc292LCDEjW8gamUgdmXEvm1pIG7DrXprZS4NCg0KLSBGLXRlc3QgKHAgPSAwLjY5Nikg4oaSIG1vZGVsIGFrbyBjZWxvayBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70uDQoNCi0gUmV6aWR1w6EgLSB2ZcS+a8O9IHJvenNhaCAtMjM3IGHFviAyODcg4oaSIHZ5c29rw6Egdm9sYXRpbGl0YSB2w71ub3NvdiwgbW9kZWwgbmV6YWNoeXTDoXZhIGljaCBkeW5hbWlrdSAtPiB0byBuYXpuYcSNdWplLCDFvmUgbGluZcOhcm5hIMWhcGVjaWZpa8OhY2lhIGJleiBuZWxpbmXDoXJueWNoIMSNbGVub3YsIGludGVyYWtjacOtIGFsZWJvIMWhb2tvdsO9Y2ggcHJlbWVubsO9Y2ggamUgbmVkb3N0YXRvxI1uw6EuDQoNCiMjIFJhbXNleSBSRVNFVCB0ZXN0DQoNClJFU0VUIHRlc3Qgc2zDusW+aSBuYSBvdmVyZW5pZSBzcHLDoXZub3N0aSDFoXBlY2lmaWvDoWNpZSBsaW5lw6FybmVobyBtb2RlbHUuIFRlc3R1amUsIMSNaSBzbWUgbmV6YW5lZGJhbGkgbmVsaW5lw6FybmUgdnrFpWFoeSBhbGVibyBpbnRlcmFrY2llIG1lZHppIHZ5c3ZldMS+dWrDumNpbWkgcHJlbWVubsO9bWkuDQoNCi0gSDAgKG51bG92w6EgaHlwb3TDqXphKTogbW9kZWwgamUgc3Byw6F2bmUgxaFwZWNpZmlrb3ZhbsO9ICjFvmlhZG5lIGNow71iYWrDumNlIG5lbGluZcOhcm5lIMSNbGVueSkuDQoNCi0gSDEgKGFsdGVybmF0w612bmEgaHlwb3TDqXphKTogbW9kZWwgamUgbmVzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70gKGNow71iYWrDuiBuZWxpbmXDoXJuZSDEjWxlbnkgYWxlYm8gaW50ZXJha2NpZSkuDQoNCmBgYHtyfQ0KcmVzZXR0ZXN0KG1vZGVsMSkNCmBgYA0KLSBQLWhvZG5vdGEgamUgdmXEvm1pIHZ5c29rw6EgKD4gMC4wNSkgLT4gdGFrxb5lIG5lbcOhbWUgZMO0a2F6IHByb3RpIG51bG92ZWogaHlwb3TDqXplLg0KDQotIE1vZGVsIHRlZGEgZm9ybcOhbG5lIG5pZSBqZSBuZXNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSAtPiB0LmouIHByaWRhbmllIHZ5xaHFocOtY2ggbW9jbsOtbiB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoIGJ5IMWhdGF0aXN0aWNreSB2w716bmFtbmUgbmV6bGVwxaFpbG8gZml0IG1vZGVsdS4NCg0KIyMgUmV6aWR1w6FsbnkgZ3JhZg0KDQpSZXppZHXDoWxueSBncmFmIChSZXNpZHVhbHMgdnMuIEZpdHRlZCkgc2zDusW+aSBuYSB2aXp1w6FsbmUgb3ZlcmVuaWUgcHJlZHBva2xhZHUgbGluZWFyaXR5LCBob21vc2tlZGFzdGljaXR5IGEgbsOhaG9kbm9zdGkgcmV6w61kdcOtLiBDaGNlbWUgemlzdGnFpSwgxI1pIHJlemlkdcOhIG1hasO6IG5lamFrw70gxaF0cnVrdMO6cm92YW7DvSB2em9yLCBrdG9yw70gYnkgbmF6bmHEjW92YWwsIMW+ZSBtb2RlbCBuZXphY2h5dGlsIHbFoWV0a3kgdnrFpWFoeSBtZWR6aSBwcmVtZW5uw71taS4NCg0KYGBge3J9DQpwbG90KG1vZGVsMSwgd2hpY2ggPSAxKQ0KYGBgDQotIFJlemlkdcOhIHNhIGphdmlhIG7DoWhvZG5lIHJvenB0w71sZW7DqSBva29sbyBudWx5IOKGkiBwcmVkcG9rbGFkIGxpbmVhcml0eSBhIHNwcsOhdm5laiDFoXBlY2lmaWvDoWNpZSBtb2RlbHUgamUgZm9ybcOhbG5lIHNwbG5lbsO9Lg0KDQotIE5lbmFjaMOhZHphIHNhIMW+aWFkbmUgemFrcml2ZW5pZSBhbmkgaGV0ZXJvc2tlZGFzdGljaXRhIOKGkiBtb2RlbCBuZXphbmVkYsOhdmEgc3lzdGVtYXRpY2vDqSBuZWxpbmXDoXJuZSB2esWlYWh5Lg0KDQotIEV4aXN0ZW5jZSBuaWVrb8S+a8O9Y2ggZXh0csOpbW55Y2ggYm9kb3YgKG91dGxpZXJvdikgbcO0xb5lIG92cGx5dm5pxaUgcHJlc25vc8WlIG9kaGFkdSwgYWxlIGNlbGtvdm8gZ3JhZiBwb2Rwb3J1amUgcGxhdG5vc8WlIGxpbmXDoXJuZWogxaFwZWNpZmlrw6FjaWUuDQoNCiMjIEMgKyBSIHBsb3QgKENvbXBvbmVudCArIFJlc2lkdWFsKQ0KDQpDK1IgcGxvdCAoQ29tcG9uZW50ICsgUmVzaWR1YWwpIHVtb8W+xYh1amUgdml6dcOhbG5lIHBvc8O6ZGnFpSBuZWxpbmXDoXJuZSB2esWlYWh5IG1lZHppIGplZG5vdGxpdm91IHZ5c3ZldMS+dWrDumNvdSBwcmVtZW5ub3UgYSB6w6F2aXNsb3UgcHJlbWVubm91IHBvIHpvaMS+YWRuZW7DrSBvc3RhdG7DvWNoIHByZW1lbm7DvWNoIHYgbW9kZWxpLg0KDQpgYGB7cn0NCmNyUGxvdHMobW9kZWwxKQ0KYGBgDQojIyMjIEMgKyBSIHBsb3Qg4oCTIEluZmxhdGlvbl9MYWcxDQoNCi0gVnrFpWFoIG1lZHppIHByZW1lbm5vdSBhIHrDoXZpc2xvdSBwcmVtZW5ub3UgLT4gdGFrbWVyIGxpbmXDoXJueSwgxb5pYWRuZSB6YWtyaXZlbmllLg0KDQotIFBvbG9oYSBib2RvdiAtPiB2w6TEjcWhaW5hIGJvZG92IGJsw616a28gbW9kcmVqIGEgcnXFvm92ZWogbMOtbmllLCByb3pwdMO9bGVuaWUgbsOhaG9kbsOpLiBUbyBuYXpuYcSNdWplLCDFvmUgbGFnb3ZhbsOhIGluZmzDoWNpYSBuZW3DoSB2w716bmFtbsO9IG5lbGluZcOhcm55IGVmZWt0IG5hIHbDvW5vc3kga2FuYWRza8OpaG8gYWtjaW92w6lobyB0cmh1Lg0KDQotIE91dGxpZXJ5IC0+IHZlxL5taSBtw6FsbyBleHRyw6ltbnljaCBob2Ruw7R0LCBuZW92cGx5dsWIdWrDuiBjZWxrb3bDvSB2esWlYWguDQoNCk1vZGVsIG5lemFuZWRiw6F2YSBuZWxpbmXDoXJueSBlZmVrdCBsYWdvdmFuZWogaW5mbMOhY2llLCBsaW5lw6FybmEgxaFwZWNpZmlrw6FjaWEgamUgdmhvZG7DoS4NCg0KIyMjIyBDICsgUiBwbG90IOKAkyBHRFBfTGFnMQ0KDQotIFZ6xaVhaCBtZWR6aSBHRFBfTGFnMSBhIHbDvW5vc29tIGFrY2nDrSBqZSBwcmV2YcW+bmUgbGluZcOhcm55Lg0KDQotIEplbW7DqSB6YWtyaXZlbmllIHJ1xb5vdmVqIGzDrW5pZSBtw7TFvmUgbmF6bmHEjW92YcWlIG1hbMO9IG5lbGluZcOhcm55IGVmZWt0IHByaSB2ecWhxaHDrWNoIGhvZG5vdMOhY2guIFRvIHpuYW1lbsOhLCDFvmUgcHJpIHZlxL5taSB2eXNva29tIHJhc3RlIEhEUCBieSB2w71ub3N5IGFrY2lvdsOpaG8gaW5kZXh1IG1vaGxpIHJlYWdvdmHFpSBtaWVybmUgb2RsacWhbmUsIMSNbyBqZSBkw7RsZcW+aXTDqSBwcmkgYW5hbMO9emUgZXh0csOpbW55Y2ggaG9zcG9kw6Fyc2t5Y2ggb2Jkb2LDrS4NCg0KTGluZcOhcm5hIMWhcGVjaWZpa8OhY2lhIHByZSBHRFBfTGFnMSBqZSB2aG9kbsOhLCBuZWxpbmXDoXJuZSBlZmVrdHkgc8O6IG1pbmltw6FsbmUuDQoNCiMjIyMgQyArIFIgcGxvdCDigJMgVW5lbXBsb3ltZW50X0xhZzENCg0KLSBWesWlYWggbWVkemkgbGFnb3Zhbm91IG5lemFtZXN0bmFub3PFpW91IGEgdsO9bm9zb20gYWtjacOtIGplIHRha21lciBsaW5lw6FybnksIGJleiB2w71yYXpuw6lobyB6YWtyaXZlbmlhLg0KDQotIE1hbMOpIG9kY2jDvWxreSBydcW+b3ZlaiBsw61uaWUgbcO0xb51IG5hem5hxI1vdmHFpSBtaWVybnkgbmVsaW5lw6FybnkgZWZla3QgcHJpIG5pxb7FocOtY2ggaG9kbm90w6FjaCBuZXphbWVzdG5hbm9zdGkuIFRvIHVrYXp1amUsIMW+ZSBwcmkgbsOtemtlaiBuZXphbWVzdG5hbm9zdGkgbWFsw6kgem1lbnkgbcO0xb51IHNww7Rzb2JpxaUgZGlzcHJvcG9yxI1uZSB2w6TEjcWhw60gZWZla3QgbmEgdsO9bm9zeSwgxI1vIHpkw7RyYXrFiHVqZSBjaXRsaXZvc8WlIGthbmFkc2vDqWhvIHRyaHUgbmEgemFtZXN0bmFub3PFpS4NCg0KTGluZcOhcm5hIMWhcGVjaWZpa8OhY2lhIHByZSBVbmVtcGxveW1lbnRfTGFnMSBqZSB2aG9kbsOhLCDFvmlhZG5lIHrDoXNhZG7DqSBuZWxpbmXDoXJuZSBlZmVrdHkgc2EgbmVwcmVqYXZ1asO6Lg0KDQojIyMjIEMgKyBSIHBsb3Qg4oCTIEludGVyZXN0X0xhZzENCg0KLSBWesWlYWggbWVkemkgbGFnb3Zhbm91IMO6cm9rb3ZvdSBzYWR6Ym91IGEgdsO9bm9zb20gYWtjacOtIGplIHRha21lciBsaW5lw6FybnksIGJleiB2w71yYXpuw6lobyB6YWtyaXZlbmlhLg0KDQotIEplbW7DqSBvZGNow71sa3kgcnXFvm92ZWogbMOtbmllIG5hem5hxI11asO6IG1pZXJueSBuZWxpbmXDoXJueSBlZmVrdCBwcmkgc3RyZWRuw71jaCBob2Rub3TDoWNoIMO6cm9rb3ZlaiBzYWR6YnkuIFRvIHpuYW1lbsOhLCDFvmUgc3RyZWRuw6kgw7pyb2tvdsOpIHNhZHpieSBtw7TFvnUgbWHFpSBtaWVybmUgb2RsacWhbsO9IHZwbHl2IG5hIHbDvW5vc3ksIHphdGlhxL4gxI1vIHZlxL5taSBuw616a2UgYWxlYm8gdnlzb2vDqSBzYWR6YnkgcMO0c29iaWEgbWVuZWogY2l0bGl2by4NCg0KTGluZcOhcm5hIMWhcGVjaWZpa8OhY2lhIHByZSBJbnRlcmVzdF9MYWcxIGplIHZob2Ruw6EsIG5lbGluZcOhcm5lIGVmZWt0eSBzw7ogbWluaW3DoWxuZS4NCg0KIyMgS3ZhZHJhdGlja8OpIMSNbGVueSBwcmUgbmVsaW5lw6FybmUgdnrFpWFoeQ0KDQpQcmlkYW5pZSBrdmFkcmF0aWNrw71jaCDEjWxlbm92ICjFoXR2b3Jjb3bDvWNoIMSNbGVub3YgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCkgc2zDusW+aSBuYSB0ZXN0b3ZhbmllLCDEjWkgbWVkemkgbGFnb3ZhbsO9bWkgbWFrcm9la29ub21pY2vDvW1pIHByZW1lbm7DvW1pIGEgdsO9bm9zb20gYWtjacOtIGV4aXN0dWrDuiBuZWxpbmXDoXJuZSB2esWlYWh5LiBBayBieSBzYSB1a8OhemFsbywgxb5lIGt2YWRyYXRpY2vDqSDEjWxlbnkgc8O6IMWhdGF0aXN0aWNreSB2w716bmFtbsOpLCB6bmFtZW5hbG8gYnkgdG8sIMW+ZSBqZWRub2R1Y2jDvSBsaW5lw6FybnkgbW9kZWwgbmV6YWNoeXTDoXZhIGNlbMO6IGR5bmFtaWt1IGEgamUgcG90cmVibsOpIHV2YcW+b3ZhxaUgbmVsaW5lw6FybnUgdHJhbnNmb3Jtw6FjaXUgcHJlbWVubsO9Y2guDQoNCmBgYHtyfQ0KbW9kZWxfcXVhZCA8LSBsbShSZXR1cm4gfiBJbmZsYXRpb25fTGFnMSArIEkoSW5mbGF0aW9uX0xhZzFeMikgKw0KICAgICAgICAgICAgICAgICAgIEdEUF9MYWcxICsgSShHRFBfTGFnMV4yKSArDQogICAgICAgICAgICAgICAgICAgVW5lbXBsb3ltZW50X0xhZzEgKyBJKFVuZW1wbG95bWVudF9MYWcxXjIpICsNCiAgICAgICAgICAgICAgICAgICBJbnRlcmVzdF9MYWcxICsgSShJbnRlcmVzdF9MYWcxXjIpLA0KICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9jb3VudHJ5KQ0Kc3VtbWFyeShtb2RlbF9xdWFkKQ0KYW5vdmEobW9kZWwxLCBtb2RlbF9xdWFkKQ0KcmVzZXR0ZXN0KG1vZGVsX3F1YWQpDQpgYGANCiMjIyMgUmV6aWR1w6EgYSBrb2VmaWNpZW50eQ0KDQotIEt2YWRyYXRpY2vDqSDEjWxlbnkgbmllIHPDuiDFoXRhdGlzdGlja3kgdsO9em5hbW7DqSAodsWhZXRreSBwID4gMCwyKSwgUsKyIHNhIHByYWt0aWNreSBuZXptZW5pbG8uIFByaWRhbmllIG5lbGluZcOhcm55Y2ggxI1sZW5vdiBuZXZ5c3ZldMS+dWplIHbDvW5vcyBha2Npw60gbGVwxaFpZS4NCg0KIyMjIyBBTk9WQSDigJMgcG9yb3ZuYW5pZSBzIGxpbmXDoXJueW0gbW9kZWxvbQ0KDQotIEYgPSAwLjUzMzIsIHAgPSAwLjcxMjEg4oaSIHJvesWhw61yZW5pZSBtb2RlbHUgbyBrdmFkcmF0aWNrw6kgxI1sZW55IG5lcHJpbmllc2xvIHpsZXDFoWVuaWUga3ZhbGl0eSBtb2RlbHUuDQoNCiMjIyMgUkVTRVQgdGVzdA0KDQotIHAtdmFsdWUgPSAwLjk5MjUg4oaSIG1vZGVsIG5pZSBqZSBuZXNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSBhbmkgcyBrdmFkcmF0aWNrw71taSDEjWxlbm1pLg0KDQpQcmUgS2FuYWR1IGxpbmXDoXJueSBtb2RlbCB2eXN0YcSNdWplOyBwcsOtdG9tbm9zxaUgdsO9em5hbW5laiBuZWxpbmVhcml0eSBzYSBuZXBvdHZyZGlsYSwgcHJpZGFuaWUga3ZhZHJhdGlja8O9Y2ggxI1sZW5vdiBuZXByaW5pZXNsbyDFvmlhZG55IHXFvml0b8SNbsO9IGVmZWt0Lg0KDQojIyBEdW1teSBwcmVtZW5uw6EgcHJlIMWhb2tvdsOpIGt2YXJ0w6FseQ0KDQpTa8O6bWFtZSwgxI1pIMWhcGVjaWZpY2vDqSBrdmFydMOhbHkgKFEz4oCTUTQpIG1hasO6IHbDvXpuYW1uw70gdnBseXYgbmEgdsO9bm9zeSBha2Npw60gdiBLYW5hZGUgcHJvc3RyZWRuw61jdHZvbSBkdW1teSBwcmVtZW5uZWogU2hvY2suIENpZcS+b20gamUgb3ZlcmnFpSwgxI1pIHRpZXRvIGt2YXJ0w6FseSB6dnnFoXVqw7ogYWxlYm8gem5pxb51asO6IFJldHVybiBuZXrDoXZpc2xlIG9kIG1ha3JvZWtvbm9taWNrw71jaCBwcmVtZW5uw71jaC4NCg0KYGBge3J9DQpkYXRhX2NvdW50cnkgPC0gZGF0YV9jb3VudHJ5ICU+JQ0KbXV0YXRlKFNob2NrID0gaWZlbHNlKFllYXIgPT0gMjAyMCAmIFF1YXJ0ZXIgPD0gMiwgMSwgMCkpDQoNCm1vZGVsX2R1bW15IDwtIGxtKFJldHVybiB+IEluZmxhdGlvbl9MYWcxICsgR0RQX0xhZzEgKyANCiAgICAgICAgICAgICAgICAgICAgVW5lbXBsb3ltZW50X0xhZzEgKyBJbnRlcmVzdF9MYWcxICsgU2hvY2ssDQogICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9jb3VudHJ5KQ0Kc3VtbWFyeShtb2RlbF9kdW1teSkNCmFub3ZhKG1vZGVsX3F1YWQsIG1vZGVsX2R1bW15KQ0KcmVzZXR0ZXN0KG1vZGVsX2R1bW15KQ0KYGBgDQotIEtvZWZpY2llbnQgcHJlIFNob2NrOiAxNyw3NSwgcCA9IDAsODk2IOKGkiBlZmVrdCBuaWUgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIGt2YXJ0w6FseSBRM+KAk1E0IG5lbWFqw7ogemphdm7DvSB2cGx5di4NCg0KLSBSwrIgYSBGLXRlc3Q6IFLCsiA9IDAsMDUzMSwgRi10ZXN0IHAgPSAwLDgxOTcg4oaSIG1vZGVsIHZ5c3ZldMS+dWplIGxlbiBtYWzDuiDEjWFzxaUgdmFyaWFiaWxpdHksIHByaWRhbmllIFNob2NrIG5lemxlcMWhaWxvIHZ5c3ZldMS+dWrDumN1IHNjaG9wbm9zxaUuDQoNCi0gUG9yb3ZuYW5pZSBzIHByZWRjaMOhZHphasO6Y2ltIG1vZGVsb206IEFOT1ZBIHVrYXp1amUsIMW+ZSBwcmlkYW7DrW0gZHVtbXkgcHJlbWVubsOpIHNhIG1vZGVsIG5lemxlcMWhaWwgKEYgPSAwLDcwNTMsIHAgPSAwLDU1NTEpLg0KDQotIFJFU0VUIHRlc3Q6IHAgPSAwLDkwOTQg4oaSIG1vZGVsIHN0w6FsZSBuZXZ5a2F6dWplIG5lZG9zdGF0b2sgxaFwZWNpZmlrw6FjaWUgYW5pIG5lemFjaHl0ZW7DqSBuZWxpbmXDoXJuZSB2esWlYWh5Lg0KDQrFoG9rb3bDqSBrdmFydMOhbHkgbmVtYWrDuiB2w716bmFtbsO9IGVmZWt0IG5hIHbDvW5vc3kgYWtjacOtIHYgS2FuYWRlLCBtb2RlbCBsaW5lw6FybmVqIMWhcGVjaWZpa8OhY2llIGplIGFkZWt2w6F0bnkuDQoNCiMjIEJveC1Db3ggdHJhbnNmb3Jtw6FjaWENCg0KQm944oCTQ294IHRyYW5zZm9ybcOhY2lhIHNsw7rFvmkgbmEgb3ZlcmVuaWUsIMSNaSBieSB0cmFuc2Zvcm3DoWNpYSB6w6F2aXNsZWogcHJlbWVubmVqIG1vaGxhIHpsZXDFoWnFpSBsaW5lw6FybnUgxaFwZWNpZmlrw6FjaXUgbW9kZWx1LCBuYXByw61rbGFkIHpuw63FvmnFpSBoZXRlcm9za2VkYXN0aWNpdHUgYWxlYm8genbDvcWhacWlIHByZWRpa8SNbsO6IHNjaG9wbm9zxaUgbW9kZWx1LiBIxL5hZMOhbWUgb3B0aW3DoWxudSBob2Rub3R1IHBhcmFtZXRyYSDOuywga3RvcsOhIHVrw6HFvmUsIMSNaSBqZSB2aG9kbsOhIHRyYW5zZm9ybcOhY2lhIGFsZWJvIHNhIGTDoSBwb25lY2hhxaUgcMO0dm9kbsOhIGZvcm1hIHByZW1lbm5lai4NCg0KYGBge3J9DQojIEJveC1Db3ggdHJhbnNmb3Jtw6FjaWEgbmEgw7pyb3ZuaSBTdG9ja19JbmRleF9WYWx1ZQ0KbW9kZWxfYm94Y294IDwtIGxtKFN0b2NrX0luZGV4X1ZhbHVlIH4gSW5mbGF0aW9uX0xhZzEgKyBHRFBfTGFnMSArDQogICAgICAgICAgICAgICAgICAgICBVbmVtcGxveW1lbnRfTGFnMSArIEludGVyZXN0X0xhZzEgKyBTaG9jaywNCiAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9jb3VudHJ5KQ0KYm94Y294KG1vZGVsX2JveGNveCwgbGFtYmRhID0gc2VxKC0yLCAyLCAwLjEpKSAgDQpgYGANCi0gTWF4aW11bSBsb2cgTGlrZWxpaG9vZCBqZSBwcmlibGnFvm5lIHByaSDOuyDiiYggMCw44oCTMCw5LCDEjW8gbmF6bmHEjXVqZSwgxb5lIG9wdGltw6FsbmEgdHJhbnNmb3Jtw6FjaWEgYnkgYm9sYSB2ZcS+bWkgYmzDrXprYSBww7R2b2RuZWogbWllcmtlLg0KDQotIEhvcml6b250w6FsbmEgxI1pYXJhIHByZWRzdGF2dWplIDk1JSBpbnRlcnZhbDsgeiBuZWogdnlwbMO9dmEsIMW+ZSB2xaFldGt5IGhvZG5vdHkgzrsgbWVkemkgcHJpYmxpxb5uZSAwLDQgYSAxLDMgc8O6IMWhdGF0aXN0aWNreSBwcmlqYXRlxL5uw6kuDQoNClRvIHpuYW1lbsOhLCDFvmUgcMO0dm9kbsOhIGZvcm1hIHByZW1lbm5laiBTdG9ja19JbmRleF9WYWx1ZSAozrsg4omIIDEpIGplIHZob2Ruw6EgYSB0cmFuc2Zvcm3DoWNpYSBuaWUgamUgbnV0bsOhLg0KDQpTdG9ja19JbmRleF9WYWx1ZSBtw7TFvmUgem9zdGHFpSB2IHDDtHZvZG5laiBwb2RvYmUsIGxpbmXDoXJueSBtb2RlbCBqZSB2aG9kbsO9IGJleiB0cmFuc2Zvcm3DoWNpZS4NCg0KIyMgWsOhdmVyDQoNCkFuYWzDvXphIHByZSBLYW5hZHUgdWvDoXphbGEsIMW+ZSBsYWdvdmFuw6kgbWFrcm9la29ub21pY2vDqSBwcmVtZW5uw6kg4oCTIGluZmzDoWNpYSwgcmFzdCBIRFAsIG1pZXJhIG5lemFtZXN0bmFub3N0aSBhIMO6cm9rb3bDoSBzYWR6YmEg4oCTIG1hasO6IGxlbiB2ZcS+bWkgc2xhYsO9IHZwbHl2IG5hIHbDvW5vc3kgYWtjaW92w6lobyBpbmRleHUuIA0KDQpMaW5lw6FybmUgbW9kZWx5LCBrdmFkcmF0aWNrw6kgxI1sZW55IGFuaSB6YWhybnV0aWUgZHVtbXkgcHJlIMWhb2tvdsOpIGt2YXJ0w6FseSBuZXZpZWRsaSBrIHbDvXpuYW1uw6ltdSB6bGVwxaFlbml1IHByZWRpa2NpZS4gDQoNClJlemlkdcOhIHPDuiByb3pwdMO9bGVuw6kgbsOhaG9kbmUsIEMrUiBwbG90eSBhIEJveOKAk0NveCB0cmFuc2Zvcm3DoWNpYSBwb3R2cmR6dWrDuiB2aG9kbm9zxaUgbGluZcOhcm5laiDFoXBlY2lmaWvDoWNpZSBiZXogdHJhbnNmb3Jtw6FjaWUgesOhdmlzbGVqIHByZW1lbm5lai4gDQoNCkNlbGtvdm8gbW9kZWx5IHZ5c3ZldMS+dWrDuiBsZW4gbWFsw7ogxI1hc8WlIHZhcmlhYmlsaXR5IHbDvW5vc292LCDEjW8gbmF6bmHEjXVqZSwgxb5lIMSPYWzFoWllIGZha3RvcnkgbWltbyBhbmFseXpvdmFuw71jaCBtYWtyb2Vrb25vbWlja8O9Y2ggcHJlbWVubsO9Y2ggbcO0xb51IG1hxaUgdsOkxI3FocOtIHZwbHl2IG5hIHBvaHliIGFrY2lvdsOpaG8gaW5kZXh1IHYgS2FuYWRlLg0KDQoNCg0KDQoNCg0KDQoNCg0K