S využitím databázy WHO Life Expactancy Data database.

Pri ďalšej práci budeme používať knižnice

library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())

1. Úvod a údaje

Údaje o očakávanej dĺžke života sú usporiadané v súbore csv, stĺpce sú oddelené znakom “,” a používajú desatinnú čiarku. V pracovnom priečinku som vytvoril podpriečinok s názvom udaje, aby som oddelil údaje od zvyšku projektu. Môj priečinok sa tiež nazýva udaje.

Nie všetky údaje budú použité, preto som vybral len niektoré stĺpce pre neskoršie použitie.

1.1 Úvod do problému, stanovenie hypotéz

Rozhodol som sa modelovať strednú dĺžku života Life.expectancy v závislosti od troch vysvetľujúcich premenných a to BMI, HDP na obyvateľa GDP a stredný počet rokov štúdia Schooling.

Naša pracovná hypotéza hovorí o štatisticky významnom vplyve všetkých troch vysvetľujúcich premenných, pričom u premenných GDP a Schooling by malo ísť o pozitívny vplyv (očakávame kladné znamienko odhadovaného regresného koeficienta) a v prípade BMI by malo ísť of negatívny vplyv (so záporným znamienkom)

1.2 Príprava databázy, úprava údajov

Tuto uvádzam len kódy, diskusia je urobená na predchádzajúcich cvičeniach.

udaje <- read.csv("udaje/Life_Expectancy_Data.csv",dec=".",sep=",",header = TRUE)
# select just the record from 2015
udajeAustria <- udaje[udaje$Country=="Austria",c("Life.expectancy","BMI","GDP","Schooling","Year")]
rownames(udajeAustria)<-udajeAustria$Year
udajeAustria <- udajeAustria[order(udajeAustria$Year), ]


udajeAustria
NA

2. Lineárna regresia v základnom tvare

Ide o odhad rovnice

\[Life.expectancy_t = \beta_0 + \beta_1 BMI_t + \beta_2 GDP_t + \beta_3Schooling_t + e_t\]

library(ggplot2)

# your regression model
model <- lm(Life.expectancy ~ BMI + GDP + Schooling, data = udajeAustria)
summary(model)

Call:
lm(formula = Life.expectancy ~ BMI + GDP + Schooling, data = udajeAustria)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.6260 -1.0164 -0.3103  0.5488  4.7682 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept) 51.2975638 25.8395778   1.985   0.0705 .
BMI         -0.0709884  0.7207499  -0.098   0.9232  
GDP          0.0002143  0.0001517   1.413   0.1831  
Schooling    1.6279409  1.9582731   0.831   0.4220  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2.425 on 12 degrees of freedom
Multiple R-squared:  0.5132,    Adjusted R-squared:  0.3915 
F-statistic: 4.217 on 3 and 12 DF,  p-value: 0.02976

3 Autokorelácia rezíduí

V tejto časti sa pozrieme na ďalší dôležitý predpoklad klasického lineárneho regresného modelu – nezávislosť rezíduí. V časových radoch sa často stáva, že chyba v čase \(t\) je systematicky spätá s chybou v čase \(t-1\), čo nazývame autokoreláciou rezíduí.

3.1 Čo je autokorelácia rezíduí?

Autokorelácia rezíduí je situácia, keď platí:

\[ \operatorname{Corr}(e_t, e_{t-k}) \neq 0 \quad \text{pre niektoré } k \neq 0. \]

Najčastejšie sa skúma autokorelácia prvého rádu:

\[ e_t = \rho e_{t-1} + \nu_t,\quad |\rho| < 1. \]

3.2 Dôsledky autokorelácie rezíduí

  • odhady koeficientov \(\hat{\beta}\) sú nestranné,
  • ale neefektívne,
  • štandardné chyby sú podhodnotené teda p hodnoty sa javia menšie, než by mali byť - dochádza k falošnému zdaniu o štatistickej významnosti.
  • teda t- a F-testy sú skreslené.

3.3 Detekcia autokorelácie

Grafická informácia

library(ggplot2)

# add fitted values to the dataframe
udajeAustria$fitted <- fitted(model)

# scatterplot + regression line + spline smoother
ggplot(udajeAustria, aes(x = Year, y = Life.expectancy)) +
  geom_point(color = "steelblue", size = 2) +
  
  # regression fitted line
  geom_line(aes(y = fitted), color = "red", size = 1) +
  

  labs(
    title = "Life Expectancy in Austria: Empirical Data (blue) vs. Fitted Data (Red)",
    x = "Year",
    y = "Life Expectancy"
  ) +
  theme_minimal()

Analýzou obrázka vidíme že empirické hodnoty sa počas niekoľkých susedných kompaktných období stále nachádzajú pod vyrovnanou hodnotou ako najmä v rokoch 2005 až 2007 respektíve 2013 až 2015. Vždy, ak sa dajú identifikovaťkompaktné úseky v čase, keď rezíduá majú rovnaké znamienko, signalizuje to možnú prítomnosť autokorelácie náhodných zložiek.

# ulosime si rezidua z povodneho modelu - nazvaneho model
res <- residuals(model)

ACF graf (Autocorrelation Function)

Táto funkcia priradzuje odhad korelácie, ktorá je medzi jednotlivými rezíduami v aktuálnom období a období posunutom (Lag) o \(k\) období späť.

acf(res, lag.max = 4,main = "Autokorelačná funkcia rezíduí")

Na tomto grafe je modrou prerušovanou čiarou vujadrený aj 95 % interval spoľahlivosti pre hodnotu autokorelačného koeficientu s príslušným posunom. Podľa výsledkov sa zdá že žiaden koeficient autokorelácie nie je 3tatistický významný, keďže pre posun väčší alebo rovný 1 je odhadnutý autokorelačný koeficient stále v hraniciach konfidenčného intervalu (intervalu spoľahlivosti).


Durbin–Watsonov test

Durbin Watsonov koeficient (DW) je vypočítaný z rezíduí podľa vzorca

\[ DW = \frac{\sum_{t=2}^{n} (e_t - e_{t-1})^{2}}{\sum_{t=1}^{n} e_t^{2}} \] kde \(n\) je počet pozorovaní. Medzi koeficientom autokorelácie dvoch susedných rezíduí a DW platí približný vzťah \[ \hat{\rho} \approx 1 - \frac{DW}{2} \]

Durbin Watsonov koeficient nie je v pôvodnej forme tabelovaný. My ho ale v našich výstupoch tabelovaný máme a poskytuje teda aj p-hodnotu. Tento koeficient nadobúda hodnoty od nula po 4. Hodnoty blízke nule signalizujú významnú pozitívnu autokoreláciu ktorá je typická v mnohých časových radoch a hodnoty nad 2 vyjadrujú negatívnu autokoreláciu. V praxi poväčšine používame intuitívne pravidlo a to, či Durbin-Watsonov koeficient sa nachádza niekde v intervale 1,8 až 2,2. Problém autokoreácie potom nemusíme riešiť. V našom prípade je ten koeficient veľmi nízky a teda nám to signalizuje prítomnosť významnej autokorelácie pozitívnej autokorelácie rezíduí prvého rádu.

library(lmtest)
dwtest(model)

    Durbin-Watson test

data:  model
DW = 1.3837, p-value = 0.01916
alternative hypothesis: true autocorrelation is greater than 0

DW test má svoje obmedzenie použitia - regresory nesmú byť časovo posunuté a nesmú obsahovať časovo oneskorené pozorovania vysvetľovanej veličiny ako regresory. Tieto ohraničenia neplatia pre Breush-Godfreyov test.


Breusch–Godfreyov test (BG test)

Čo test testuje

BG test je formálnym testom autokorelácie (sériovej korelácie) rezíduí regresného modelu:

\[ u_t = \rho_1 u_{t-1} + \rho_2 u_{t-2} + \cdots + \rho_p u_{t-p} + \varepsilon_t \]

Testuje, či rezíduá sú koelované v čase a to aj pre \(p\) posunov (lagov), čo je typické pre časové rady (nie pre prierezové údaje!).

Na rozdiel od DW testu, BG test testuje:

  • autokorelácie s vyšším posunom (lag 1, 2, 3, …),
  • pracuje aj s modelmi, ktoré obsahujú časovo posunuté vysvetľované premenné ako regresory. (BG test),
  • pracuje s nekonštantnými regresormi.

Hypotézy

Pre test autokorelácie až do rádu \(p\):

Nulová hypotéza \(H_0\): žiadna sériová korelácia

\[ \rho_1 = \rho_2 = \cdots = \rho_p = 0 \]

Alternatívna hypotéza \(H_1\): sériová korelácia prítomná

Aspoň jedna z \(\rho_j\) je odlišná od nuly.


Ako funguje Breuschov–Godfreyho test
  1. Odhadnite regresiu pomocou OLS a získajte rezíduá \(e_t\).

  2. Spustite pomocnú regresiu:

\[ e_t = \alpha_0 + \alpha_1 x_{1t} + \cdots + \alpha_k x_{kt} + \rho_1 e_{t-1} + \cdots + \rho_p e_{t-p} + v_t \]

Regresory z pôvodného modelu musia byť zahrnuté.

  1. Vypočítajte testovú štatistiku:

\[ \text{BG} = (n - p) R^2_{\text{aux}} \]

  1. Pod nulovou hypotézou:

\[ \text{BG} \sim \chi^2_p \]


Interpretácia
  • Veľká štatistika BG (malá hodnota p) → zamietnuť \(H_0\)zistená autokorelácia.
  • Malá štatistika BG (veľká hodnota p) → nezamietnuť \(H_0\)žiadny dôkaz autokorelácie.

Intuícia

Ak sú rezíduá korelované v čase, oneskorené rezíduá \(e_{t-1}, e_{t-2}, \ldots\) pomôžu vysvetliť variabilitu v \(e_t\).


Praktický výpočet v R
bgtest(model, order = 1)

    Breusch-Godfrey test for serial correlation of order up to 1

data:  model
LM test = 1.674, df = 1, p-value = 0.1957

V našich údajoch sme identifikovali týmto testom nízku úroveň autokorelácie s posunom o 1, teda závery DW testu a BG testu sú rozporuplné. Preto aspoň z demonštratívneho dôvodu pristúpime ku odstraňovaniu dôsledkov autokorelácie.

Ako riešiť autokoreláciu

Koyckova transformácia a Koyckova rovnica

V predchádzajúcej časti sme sa venovali autokorelácii rezíduí. Teraz rozšírime model o dynamickú štruktúru založenú na tzv. geometricky klesajúcom rozložení oneskorených efektov. Takýto model sa nazýva Koyckov model a jeho ústredným prvkom je Koyckova transformácia.


Východiskový model s distribuovaným oneskorením

Uvažujme model:

\[ y_t = \alpha + \beta_0 x_t + \beta_1 x_{t-1} + \beta_2 x_{t-2} + \cdots + u_t. \]

Takýto model obsahuje veľký počet parametrov \(\beta_k\). Problémy:

  • vysoká multikolinearita medzi \(x_t, x_{t-1}, x_{t-2}, \dots\)
  • veľká variancia odhadov
  • nestabilita parametrov pri malých výberoch

Koyckova štruktúra koeficientov

Koyck navrhol, že oneskorené efekty majú geometricky klesajúcu podobu:

\[ \beta_k = \lambda^k \beta_0, \qquad 0 < \lambda < 1. \]

Tým sa distribučné oneskorenie zjednoduší tak, že namiesto nekonečného počtu parametrov odhadujeme len:

  • \(\beta_0\) – okamžitý efekt,
  • \(\lambda\) – rýchlosť tlmenia efektov oneskorenia.

Koyckova transformácia

Začnime pôvodným modelom:

\[ y_t = \alpha + \beta_0 x_t + \lambda \beta_0 x_{t-1} + \lambda^2 \beta_0 x_{t-2} + \cdots + u_t. \]

Vynásobme celý model konštantou \(\lambda\) a posuňme časový indexdozadu o 1:

\[ \lambda y_{t-1} = \lambda\alpha + \beta_0 x_{t-1} + \lambda \beta_0 x_{t-2} + \cdots + \lambda u_{t-1}. \]

Teraz odčítame oba výrazy:

\[ y_t - \lambda y_{t-1} = \alpha(1-\lambda) + \beta_0 (x_t - \lambda x_{t-1}) + (u_t - \lambda u_{t-1}). \]

Toto je Koyckova transformácia.


Koyckova rovnica (autoregresívny model)

Po algebraickej úprave získame:

\[ y_t = \alpha(1-\lambda) + \beta_0 x_t + \lambda y_{t-1} + v_t, \]

kde:

\[ v_t = u_t - \lambda u_{t-1}. \]

Toto je Koyckova rovnica – dynamický autoregresívny model so závislosťou na minulosti.

Interpretácia:

  • \(\lambda\) – rýchlosť prispôsobenia (čím bližšie 1, tým pomalšia reakcia)
  • \(\beta_0\) – okamžitý efekt \(x_t\)
  • dlhodobý efekt:

\[ \frac{\beta_0}{1-\lambda} \]


Odstraňovanie problému autokorelácie rezíduí

Odhad Koyckovho modelu v R

Najjednoduchšia implementácia:


library(dplyr)

udajeAustria <- udajeAustria %>%
  arrange(Year) %>%
  mutate(
    Life.expectancy_lag1 = lag(Life.expectancy)
  )

model_koyck <- lm(Life.expectancy ~ GDP + BMI + Schooling +  Life.expectancy_lag1, 
                  data = udajeAustria)

summary(model_koyck)

Call:
lm(formula = Life.expectancy ~ GDP + BMI + Schooling + Life.expectancy_lag1, 
    data = udajeAustria)

Residuals:
    Min      1Q  Median      3Q     Max 
-4.9183 -0.7982 -0.2828  0.9154  4.1247 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)
(Intercept)          35.6572901 28.7114197   1.242    0.243
GDP                   0.0001254  0.0001675   0.749    0.471
BMI                  -0.1107985  0.7403988  -0.150    0.884
Schooling             0.7848417  2.1058277   0.373    0.717
Life.expectancy_lag1  0.4245017  0.3200273   1.326    0.214

Residual standard error: 2.449 on 10 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.548, Adjusted R-squared:  0.3672 
F-statistic: 3.031 on 4 and 10 DF,  p-value: 0.07057
dwtest(model_koyck)

    Durbin-Watson test

data:  model_koyck
DW = 1.7426, p-value = 0.07015
alternative hypothesis: true autocorrelation is greater than 0

Dynamizovaný model nám neidentifikuje žiaden regresor ako štatisicky významný. Koeficient pri y_lag1, čo je očakávaná dĺžka dožitia v minulom období, je kladný a menší ako 1. Hodnota 0.42 nám hovorí o zotrvačnom vplyve vysvetľovanej premennej z minulosti (niečo ako 42 percent očakávanej dĺžky života sa prenesie z minulého obdobia - čo je interpretáucia v tomto konkrétnom prípade dosť kostrbatá).

Pri hodnotení kvality nového modelu porovnajme len Adjusted R-squared. Z neho vyplýva, že pôvodný model nám poskytuje lepšie výsledky.

Newey–West robustné štandardné chyby

library(sandwich)
library(lmtest)

coeftest(model, vcov = NeweyWest(model))

t test of coefficients:

               Estimate  Std. Error t value Pr(>|t|)   
(Intercept)  5.1298e+01  1.4030e+01  3.6563 0.003288 **
BMI         -7.0988e-02  1.7758e-01 -0.3998 0.696364   
GDP          2.1430e-04  5.2481e-05  4.0834 0.001517 **
Schooling    1.6279e+00  7.9867e-01  2.0383 0.064182 . 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

4. Záver

Autokorelácia rezíduí a z nej vyplývajúca potreba dynamizácie modelov má ekonómometrii veľmi veľký význam. My sme tu uviedli len najzákladnejšie problémy. K trochu zložitejším patrí Almonovej model riešenia dynamizácie alebo metóda Cochran-Orcutt. Samostatnou metodológiou je ale metodika arima modelov ktorá je dnes populárna a pri dlhých časových radoch sa používa najčastejšie.

LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIgLSBjdmnEjWVuaWUgOSIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogVi4gR2F6ZGEgYSBDaGF0R1BUCi0tLQoKUyB2eXXFvml0w61tIGRhdGFiw6F6eSBbV0hPIExpZmUgRXhwYWN0YW5jeSBEYXRhXShodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2t1bWFyYWphcnNoaS9saWZlLWV4cGVjdGFuY3ktd2hvKSBkYXRhYmFzZS4KClByaSDEj2FsxaFlaiBwcsOhY2kgYnVkZW1lIHBvdcW+w612YcWlIGtuacW+bmljZQoKYGBge3J9CmxpYnJhcnkoem9vKQpsaWJyYXJ5KHRzZXJpZXMpCmxpYnJhcnkobG10ZXN0KQpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGNhcikKcm0obGlzdD1scygpKQpgYGAKCiMjIDEuIMOadm9kIGEgw7pkYWplCgrDmmRhamUgbyBvxI1ha8OhdmFuZWogZMS6xb5rZSDFvml2b3RhIHPDuiB1c3BvcmlhZGFuw6kgdiBzw7pib3JlICpjc3YqLCBzdMS6cGNlIHPDuiBvZGRlbGVuw6kgem5ha29tICIsIiBhIHBvdcW+w612YWrDuiBkZXNhdGlubsO6IMSNaWFya3UuIFYgcHJhY292bm9tIHByaWXEjWlua3Ugc29tIHZ5dHZvcmlsIHBvZHByaWXEjWlub2sgcyBuw6F6dm9tICp1ZGFqZSosIGFieSBzb20gb2RkZWxpbCDDumRhamUgb2QgenZ5xaFrdSBwcm9qZWt0dS4gTcO0aiBwcmllxI1pbm9rIHNhIHRpZcW+IG5hesO9dmEgKnVkYWplKi4gCgpOaWUgdsWhZXRreSDDumRhamUgYnVkw7ogcG91xb5pdMOpLCBwcmV0byBzb20gdnlicmFsIGxlbiBuaWVrdG9yw6kgc3TEunBjZSBwcmUgbmVza29yxaFpZSBwb3XFvml0aWUuCgojIyMgMS4xIMOadm9kIGRvIHByb2Jsw6ltdSwgc3Rhbm92ZW5pZSBoeXBvdMOpeiAKClJvemhvZG9sIHNvbSBzYSBtb2RlbG92YcWlIHN0cmVkbsO6IGTEusW+a3Ugxb5pdm90YSAqTGlmZS5leHBlY3RhbmN5KiB2IHrDoXZpc2xvc3RpIG9kIHRyb2NoIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2ggYSB0byAqQk1JKiwgSERQIG5hIG9ieXZhdGXEvmEgKkdEUCogYSBzdHJlZG7DvSBwb8SNZXQgcm9rb3YgxaF0w7pkaWEgICpTY2hvb2xpbmcqLgoKTmHFoWEgcHJhY292bsOhIGh5cG90w6l6YSBob3ZvcsOtIG8gxaF0YXRpc3RpY2t5IHbDvXpuYW1ub20gdnBseXZlIHbFoWV0a8O9Y2ggdHJvY2ggdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCwgcHJpxI1vbSB1IHByZW1lbm7DvWNoICpHRFAqIGEgKlNjaG9vbGluZyogYnkgbWFsbyDDrXPFpSBvIHBveml0w612bnkgdnBseXYgKG/EjWFrw6F2YW1lIGtsYWRuw6kgem5hbWllbmtvIG9kaGFkb3ZhbsOpaG8gcmVncmVzbsOpaG8ga29lZmljaWVudGEpIGEgdiBwcsOtcGFkZSBCTUkgYnkgbWFsbyDDrXPFpSBvZiBuZWdhdMOtdm55IHZwbHl2IChzbyB6w6Fwb3Juw71tIHpuYW1pZW5rb20pCgoKCgojIyMgMS4yIFByw61wcmF2YSBkYXRhYsOhenksIMO6cHJhdmEgw7pkYWpvdgoKVHV0byB1dsOhZHphbSBsZW4ga8OzZHksIGRpc2t1c2lhIGplIHVyb2JlbsOhIG5hIHByZWRjaMOhZHphasO6Y2ljaCBjdmnEjWVuaWFjaC4KCgpgYGB7cn0KdWRhamUgPC0gcmVhZC5jc3YoInVkYWplL0xpZmVfRXhwZWN0YW5jeV9EYXRhLmNzdiIsZGVjPSIuIixzZXA9IiwiLGhlYWRlciA9IFRSVUUpCiMgc2VsZWN0IGp1c3QgdGhlIHJlY29yZCBmcm9tIDIwMTUKdWRhamVBdXN0cmlhIDwtIHVkYWplW3VkYWplJENvdW50cnk9PSJBdXN0cmlhIixjKCJMaWZlLmV4cGVjdGFuY3kiLCJCTUkiLCJHRFAiLCJTY2hvb2xpbmciLCJZZWFyIildCnJvd25hbWVzKHVkYWplQXVzdHJpYSk8LXVkYWplQXVzdHJpYSRZZWFyCnVkYWplQXVzdHJpYSA8LSB1ZGFqZUF1c3RyaWFbb3JkZXIodWRhamVBdXN0cmlhJFllYXIpLCBdCgoKdWRhamVBdXN0cmlhCgpgYGAKCgoKIyMgMi4gTGluZcOhcm5hIHJlZ3Jlc2lhIHYgesOha2xhZG5vbSB0dmFyZQoKSWRlIG8gb2RoYWQgcm92bmljZSAKCiQkTGlmZS5leHBlY3RhbmN5X3QgPSBcYmV0YV8wICsgXGJldGFfMSBCTUlfdCArIFxiZXRhXzIgR0RQX3QgKyBcYmV0YV8zU2Nob29saW5nX3QgKyBlX3QkJAoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKCiMgeW91ciByZWdyZXNzaW9uIG1vZGVsCm1vZGVsIDwtIGxtKExpZmUuZXhwZWN0YW5jeSB+IEJNSSArIEdEUCArIFNjaG9vbGluZywgZGF0YSA9IHVkYWplQXVzdHJpYSkKc3VtbWFyeShtb2RlbCkKYGBgCgoKIyMgMyBBdXRva29yZWzDoWNpYSByZXrDrWR1w60KClYgdGVqdG8gxI1hc3RpIHNhIHBvenJpZW1lIG5hIMSPYWzFocOtIGTDtGxlxb5pdMO9IHByZWRwb2tsYWQga2xhc2lja8OpaG8gbGluZcOhcm5laG8KcmVncmVzbsOpaG8gbW9kZWx1IOKAkyAqKm5lesOhdmlzbG9zxaUgcmV6w61kdcOtKiouIFYgxI1hc292w71jaCByYWRvY2ggc2EgxI1hc3RvIHN0w6F2YSwKxb5lIGNoeWJhIHYgxI1hc2UgXCh0XCkgamUgc3lzdGVtYXRpY2t5IHNww6R0w6EgcyBjaHlib3UgdiDEjWFzZSBcKHQtMVwpLCDEjW8gbmF6w712YW1lCioqYXV0b2tvcmVsw6FjaW91IHJlesOtZHXDrSoqLgoKIyMjIDMuMSDEjG8gamUgYXV0b2tvcmVsw6FjaWEgcmV6w61kdcOtPwoKQXV0b2tvcmVsw6FjaWEgcmV6w61kdcOtIGplIHNpdHXDoWNpYSwga2XEjyBwbGF0w606CgpcWwpcb3BlcmF0b3JuYW1le0NvcnJ9KGVfdCwgZV97dC1rfSkgXG5lcSAwIFxxdWFkIFx0ZXh0e3ByZSBuaWVrdG9yw6kgfSBrIFxuZXEgMC4KXF0KCk5hasSNYXN0ZWrFoWllIHNhIHNrw7ptYSBhdXRva29yZWzDoWNpYSBwcnbDqWhvIHLDoWR1OgoKXFsKZV90ID0gXHJobyBlX3t0LTF9ICsgXG51X3QsXHF1YWQgfFxyaG98IDwgMS4KXF0KCiMjIyAzLjIgRMO0c2xlZGt5IGF1dG9rb3JlbMOhY2llIHJlesOtZHXDrQoKLSBvZGhhZHkga29lZmljaWVudG92IFwoXGhhdHtcYmV0YX1cKSBzw7ogbmVzdHJhbm7DqSwKLSBhbGUgbmVlZmVrdMOtdm5lLAotIMWhdGFuZGFyZG7DqSBjaHlieSBzw7ogcG9kaG9kbm90ZW7DqSB0ZWRhIHAgaG9kbm90eSBzYSBqYXZpYSBtZW7FoWllLCBuZcW+IGJ5IG1hbGkgYnnFpSAtIGRvY2jDoWR6YSBrIGZhbG/FoW7DqW11IHpkYW5pdSBvIMWhdGF0aXN0aWNrZWogdsO9em5hbW5vc3RpLgotIHRlZGEgdC0gYSBGLXRlc3R5IHPDuiBza3Jlc2xlbsOpLgoKLS0tLS0tLS0tLS0tLS0tCgojIyMgMy4zIERldGVrY2lhIGF1dG9rb3JlbMOhY2llIAoKIyMjIyBHcmFmaWNrw6EgaW5mb3Jtw6FjaWEKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCgojIGFkZCBmaXR0ZWQgdmFsdWVzIHRvIHRoZSBkYXRhZnJhbWUKdWRhamVBdXN0cmlhJGZpdHRlZCA8LSBmaXR0ZWQobW9kZWwpCgojIHNjYXR0ZXJwbG90ICsgcmVncmVzc2lvbiBsaW5lICsgc3BsaW5lIHNtb290aGVyCmdncGxvdCh1ZGFqZUF1c3RyaWEsIGFlcyh4ID0gWWVhciwgeSA9IExpZmUuZXhwZWN0YW5jeSkpICsKICBnZW9tX3BvaW50KGNvbG9yID0gInN0ZWVsYmx1ZSIsIHNpemUgPSAyKSArCiAgCiAgIyByZWdyZXNzaW9uIGZpdHRlZCBsaW5lCiAgZ2VvbV9saW5lKGFlcyh5ID0gZml0dGVkKSwgY29sb3IgPSAicmVkIiwgc2l6ZSA9IDEpICsKICAKCiAgbGFicygKICAgIHRpdGxlID0gIkxpZmUgRXhwZWN0YW5jeSBpbiBBdXN0cmlhOiBFbXBpcmljYWwgRGF0YSAoYmx1ZSkgdnMuIEZpdHRlZCBEYXRhIChSZWQpIiwKICAgIHggPSAiWWVhciIsCiAgICB5ID0gIkxpZmUgRXhwZWN0YW5jeSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYAoKQW5hbMO9em91IG9icsOhemthIHZpZMOtbWUgxb5lIGVtcGlyaWNrw6kgaG9kbm90eSBzYSBwb8SNYXMgbmlla2/EvmvDvWNoIHN1c2VkbsO9Y2gga29tcGFrdG7DvWNoIG9iZG9iw60gc3TDoWxlIG5hY2jDoWR6YWrDuiBwb2Qgdnlyb3ZuYW5vdSBob2Rub3RvdSBha28gbmFqbcOkIHYgcm9rb2NoIDIwMDUgYcW+IDIwMDcgcmVzcGVrdMOtdmUgMjAxMyBhxb4gMjAxNS4gVsW+ZHksIGFrIHNhIGRhasO6IGlkZW50aWZpa292YcWla29tcGFrdG7DqSDDunNla3kgdiDEjWFzZSwga2XEjyByZXrDrWR1w6EgbWFqw7ogcm92bmFrw6kgem5hbWllbmtvLCBzaWduYWxpenVqZSB0byBtb8W+bsO6IHByw610b21ub3PFpSBhdXRva29yZWzDoWNpZSBuw6Fob2Ruw71jaCB6bG/Fvmllay4KCgoKYGBge3J9CiMgdWxvc2ltZSBzaSByZXppZHVhIHogcG92b2RuZWhvIG1vZGVsdSAtIG5henZhbmVobyBtb2RlbApyZXMgPC0gcmVzaWR1YWxzKG1vZGVsKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMgQUNGIGdyYWYgKEF1dG9jb3JyZWxhdGlvbiBGdW5jdGlvbikKClTDoXRvIGZ1bmtjaWEgcHJpcmFkenVqZSBvZGhhZCBrb3JlbMOhY2llLCBrdG9yw6EgamUgbWVkemkgamVkbm90bGl2w71taSByZXrDrWR1YW1pIHYgYWt0dcOhbG5vbSBvYmRvYsOtIGEgb2Jkb2LDrSBwb3N1bnV0b20gKExhZykgbyAkayQgb2Jkb2LDrSBzcMOkxaUuCgpgYGB7cn0KYWNmKHJlcywgbGFnLm1heCA9IDQsbWFpbiA9ICJBdXRva29yZWxhxI1uw6EgZnVua2NpYSByZXrDrWR1w60iKQpgYGAKTmEgdG9tdG8gZ3JhZmUgamUgbW9kcm91IHByZXJ1xaFvdmFub3UgxI1pYXJvdSB2dWphZHJlbsO9IGFqIDk1IFwlIGludGVydmFsIHNwb8S+YWhsaXZvc3RpIHByZSBob2Rub3R1IGF1dG9rb3JlbGHEjW7DqWhvIGtvZWZpY2llbnR1IHMgcHLDrXNsdcWhbsO9bSBwb3N1bm9tLiBQb2TEvmEgdsO9c2xlZGtvdiBzYSB6ZMOhIMW+ZSDFvmlhZGVuIGtvZWZpY2llbnQgYXV0b2tvcmVsw6FjaWUgbmllIGplIDN0YXRpc3RpY2vDvSB2w716bmFtbsO9LCBrZcSPxb5lIHByZSBwb3N1biB2w6TEjcWhw60gYWxlYm8gcm92bsO9IDEgamUgb2RoYWRudXTDvSBhdXRva29yZWxhxI1uw70ga29lZmljaWVudCBzdMOhbGUgdiBocmFuaWNpYWNoIGtvbmZpZGVuxI1uw6lobyBpbnRlcnZhbHUgKGludGVydmFsdSBzcG/EvmFobGl2b3N0aSkuIAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyBEdXJiaW7igJNXYXRzb25vdiB0ZXN0CgpEdXJiaW4gV2F0c29ub3Yga29lZmljaWVudCAoRFcpIGplIHZ5cG/EjcOtdGFuw70geiByZXrDrWR1w60gcG9kxL5hIHZ6b3JjYQoKXFsKRFcgPSBcZnJhY3tcc3VtX3t0PTJ9XntufSAoZV90IC0gZV97dC0xfSleezJ9fXtcc3VtX3t0PTF9XntufSBlX3ReezJ9fQpcXQprZGUgJG4kIGplIHBvxI1ldCBwb3pvcm92YW7DrS4gTWVkemkga29lZmljaWVudG9tIGF1dG9rb3JlbMOhY2llIGR2b2NoIHN1c2VkbsO9Y2ggcmV6w61kdcOtIGEgRFcgcGxhdMOtIHByaWJsacW+bsO9IHZ6xaVhaApcWwpcaGF0e1xyaG99IFxhcHByb3ggMSAtIFxmcmFje0RXfXsyfQpcXQoKCkR1cmJpbiBXYXRzb25vdiBrb2VmaWNpZW50IG5pZSBqZSB2IHDDtHZvZG5laiBmb3JtZSB0YWJlbG92YW7DvS4gTXkgaG8gYWxlIHYgbmHFoWljaCB2w71zdHVwb2NoIHRhYmVsb3ZhbsO9IG3DoW1lIGEgcG9za3l0dWplIHRlZGEgYWogcC1ob2Rub3R1LiBUZW50byBrb2VmaWNpZW50IG5hZG9iw7pkYSBob2Rub3R5IG9kIG51bGEgcG8gNC4gSG9kbm90eSBibMOtemtlIG51bGUgc2lnbmFsaXp1asO6IHbDvXpuYW1uw7ogcG96aXTDrXZudSBhdXRva29yZWzDoWNpdSBrdG9yw6EgamUgdHlwaWNrw6EgdiBtbm9ow71jaCDEjWFzb3bDvWNoIHJhZG9jaCBhIGhvZG5vdHkgbmFkIDIgdnlqYWRydWrDuiBuZWdhdMOtdm51IGF1dG9rb3JlbMOhY2l1LiBWIHByYXhpIHBvdsOkxI3FoWluZSBwb3XFvsOtdmFtZSBpbnR1aXTDrXZuZSBwcmF2aWRsbyBhIHRvLCDEjWkgRHVyYmluLVdhdHNvbm92IGtvZWZpY2llbnQgc2EgbmFjaMOhZHphIG5pZWtkZSB2IGludGVydmFsZSAxLDggYcW+IDIsMi4gUHJvYmzDqW0gYXV0b2tvcmXDoWNpZSBwb3RvbSBuZW11c8OtbWUgcmllxaFpxaUuIFYgbmHFoW9tIHByw61wYWRlIGplIHRlbiBrb2VmaWNpZW50IHZlxL5taSBuw616a3kgYSB0ZWRhIG7DoW0gdG8gc2lnbmFsaXp1amUgcHLDrXRvbW5vc8WlIHbDvXpuYW1uZWogYXV0b2tvcmVsw6FjaWUgcG96aXTDrXZuZWogYXV0b2tvcmVsw6FjaWUgcmV6w61kdcOtIHBydsOpaG8gcsOhZHUuCgpgYGB7cn0KbGlicmFyeShsbXRlc3QpCmR3dGVzdChtb2RlbCkKYGBgCkRXIHRlc3QgbcOhIHN2b2plIG9ibWVkemVuaWUgcG91xb5pdGlhIC0gcmVncmVzb3J5IG5lc23DuiBiecWlIMSNYXNvdm8gcG9zdW51dMOpIGEgbmVzbcO6IG9ic2Fob3ZhxaUgxI1hc292byBvbmVza29yZW7DqSBwb3pvcm92YW5pYSB2eXN2ZXTEvm92YW5laiB2ZWxpxI1pbnkgYWtvIHJlZ3Jlc29yeS4gVGlldG8gb2hyYW5pxI1lbmlhIG5lcGxhdGlhIHByZSBCcmV1c2gtR29kZnJleW92IHRlc3QuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMjIEJyZXVzY2jigJNHb2RmcmV5b3YgdGVzdCAoQkcgdGVzdCkKCiMjIyMjIMSMbyB0ZXN0IHRlc3R1amUKCkJHIHRlc3QgamUgZm9ybcOhbG55bSB0ZXN0b20gICoqYXV0b2tvcmVsw6FjaWUgKHPDqXJpb3ZlaiBrb3JlbMOhY2llKSoqIHJlesOtZHXDrSByZWdyZXNuw6lobyBtb2RlbHU6CgpcWwp1X3QgPSBccmhvXzEgdV97dC0xfSArIFxyaG9fMiB1X3t0LTJ9ICsgXGNkb3RzICsgXHJob19wIHVfe3QtcH0gKyBcdmFyZXBzaWxvbl90ClxdCgpUZXN0dWplLCDEjWkgcmV6w61kdcOhIHPDuiBrb2Vsb3ZhbsOpIHYgxI1hc2UgYSB0byBhaiBwcmUgJHAkIHBvc3Vub3YgKGxhZ292KSwgxI1vIGplIHR5cGlja8OpIHByZSDEjWFzb3bDqSByYWR5IChuaWUgcHJlIHByaWVyZXpvdsOpIMO6ZGFqZSEpLgoKTmEgcm96ZGllbCBvZCBEVyB0ZXN0dSwgQkcgdGVzdCB0ZXN0dWplOgoKLSAqKmF1dG9rb3JlbMOhY2llIHMgdnnFocWhw61tIHBvc3Vub20qKiAobGFnIDEsIDIsIDMsIC4uLiksCi0gcHJhY3VqZSBhaiBzIG1vZGVsbWksIGt0b3LDqSBvYnNhaHVqw7ogKirEjWFzb3ZvIHBvc3VudXTDqSB2eXN2ZXTEvm92YW7DqSBwcmVtZW5uw6kqKiBha28gcmVncmVzb3J5LgooQkcgdGVzdCksCi0gcHJhY3VqZSBzIG5la29uxaF0YW50bsO9bWkgcmVncmVzb3JtaS4KCi0tLQoKIyMjIyMgSHlwb3TDqXp5CgpQcmUgdGVzdCBhdXRva29yZWzDoWNpZSBhxb4gZG8gcsOhZHUgXChwXCk6CgoqKk51bG92w6EgaHlwb3TDqXphIFwoSF8wXCk6IMW+aWFkbmEgc8OpcmlvdsOhIGtvcmVsw6FjaWEqKgoKXFsKXHJob18xID0gXHJob18yID0gXGNkb3RzID0gXHJob19wID0gMApcXQoKKipBbHRlcm5hdMOtdm5hIGh5cG90w6l6YSBcKEhfMVwpOiBzw6lyaW92w6Ega29yZWzDoWNpYSBwcsOtdG9tbsOhKioKCkFzcG/FiCBqZWRuYSB6IFwoXHJob19qXCkgamUgb2RsacWhbsOhIG9kIG51bHkuCgotLS0KCiMjIyMjIEFrbyBmdW5ndWplIEJyZXVzY2hvduKAk0dvZGZyZXlobyB0ZXN0CgoxLiBPZGhhZG5pdGUgcmVncmVzaXUgcG9tb2NvdSBPTFMgYSB6w61za2FqdGUgcmV6w61kdcOhIFwoZV90XCkuCgoyLiBTcHVzdGl0ZSBwb21vY27DuiByZWdyZXNpdToKClxbCmVfdAo9IFxhbHBoYV8wICsgXGFscGhhXzEgeF97MXR9ICsgXGNkb3RzICsgXGFscGhhX2sgeF97a3R9CisgXHJob18xIGVfe3QtMX0gKyBcY2RvdHMgKyBccmhvX3AgZV97dC1wfSArIHZfdApcXQoKUmVncmVzb3J5IHogcMO0dm9kbsOpaG8gbW9kZWx1ICoqbXVzaWEqKiBiecWlIHphaHJudXTDqS4KCjMuIFZ5cG/EjcOtdGFqdGUgdGVzdG92w7ogxaF0YXRpc3Rpa3U6CgpcWwpcdGV4dHtCR30gPSAobiAtIHApIFJeMl97XHRleHR7YXV4fX0KXF0KCjQuIFBvZCBudWxvdm91IGh5cG90w6l6b3U6CgpcWwpcdGV4dHtCR30gXHNpbSBcY2hpXjJfcApcXQoKLS0tCgojIyMjIyBJbnRlcnByZXTDoWNpYQoKLSAqKlZlxL5rw6EgxaF0YXRpc3Rpa2EgQkcgKG1hbMOhIGhvZG5vdGEgcCkqKiDihpIgemFtaWV0bnXFpSBcKEhfMFwpIOKGkiAqKnppc3RlbsOhIGF1dG9rb3JlbMOhY2lhKiouICAKLSAqKk1hbMOhIMWhdGF0aXN0aWthIEJHICh2ZcS+a8OhIGhvZG5vdGEgcCkqKiDihpIgbmV6YW1pZXRudcWlIFwoSF8wXCkg4oaSICoqxb5pYWRueSBkw7RrYXogYXV0b2tvcmVsw6FjaWUqKi4KCi0tLS0tLS0tLS0tLS0tLS0KCiMjIyMjIEludHXDrWNpYQoKQWsgc8O6IHJlesOtZHXDoSBrb3JlbG92YW7DqSB2IMSNYXNlLCBvbmVza29yZW7DqSByZXrDrWR1w6EgIFwoZV97dC0xfSwgZV97dC0yfSwgXGxkb3RzXCkgIHBvbcO0xb51IHZ5c3ZldGxpxaUgdmFyaWFiaWxpdHUgdiBcKGVfdFwpLgoKCi0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMjICBQcmFrdGlja8O9IHbDvXBvxI1ldCB2IFIKCmBgYHtyfQpiZ3Rlc3QobW9kZWwsIG9yZGVyID0gMSkKYGBgClYgbmHFoWljaCDDumRham9jaCBzbWUgaWRlbnRpZmlrb3ZhbGkgdMO9bXRvIHRlc3RvbSBuw616a3Ugw7pyb3ZlxYggYXV0b2tvcmVsw6FjaWUgcyBwb3N1bm9tIG8gMSwgdGVkYSB6w6F2ZXJ5IERXIHRlc3R1IGEgQkcgdGVzdHUgc8O6IHJvenBvcnVwbG7DqS4gUHJldG8gYXNwb8WIIHogZGVtb27FoXRyYXTDrXZuZWhvIGTDtHZvZHUgcHJpc3TDunBpbWUga3Ugb2RzdHJhxYhvdmFuaXUgZMO0c2xlZGtvdiBhdXRva29yZWzDoWNpZS4KCiMjIEFrbyByaWXFoWnFpSBhdXRva29yZWzDoWNpdQoKIyMjIEtveWNrb3ZhIHRyYW5zZm9ybcOhY2lhIGEgS295Y2tvdmEgcm92bmljYQoKViBwcmVkY2jDoWR6YWrDumNlaiDEjWFzdGkgc21lIHNhIHZlbm92YWxpIGF1dG9rb3JlbMOhY2lpIHJlesOtZHXDrS4gVGVyYXoKcm96xaHDrXJpbWUgbW9kZWwgbyBkeW5hbWlja8O6IMWhdHJ1a3TDunJ1IHphbG/FvmVuw7ogbmEgdHp2LiAqKmdlb21ldHJpY2t5CmtsZXNhasO6Y29tIHJvemxvxb5lbsOtIG9uZXNrb3JlbsO9Y2ggZWZla3RvdioqLiBUYWvDvXRvIG1vZGVsIHNhIG5hesO9dmEKKipLb3lja292IG1vZGVsKiogYSBqZWhvIMO6c3RyZWRuw71tIHBydmtvbSBqZSAqKktveWNrb3ZhIHRyYW5zZm9ybcOhY2lhKiouCgotLS0KCiMjIyMjIFbDvWNob2Rpc2tvdsO9IG1vZGVsIHMgZGlzdHJpYnVvdmFuw71tIG9uZXNrb3JlbsOtbQoKVXZhxb51am1lIG1vZGVsOgoKXFsKeV90ID0gXGFscGhhICsgXGJldGFfMCB4X3QgKyBcYmV0YV8xIHhfe3QtMX0gKyBcYmV0YV8yIHhfe3QtMn0gKyBcY2RvdHMgKyB1X3QuClxdCgpUYWvDvXRvIG1vZGVsIG9ic2FodWplIHZlxL5rw70gcG/EjWV0IHBhcmFtZXRyb3YgXChcYmV0YV9rXCkuIFByb2Jsw6lteToKCi0gdnlzb2vDoSBtdWx0aWtvbGluZWFyaXRhIG1lZHppIFwoeF90LCB4X3t0LTF9LCB4X3t0LTJ9LCBcZG90c1wpCi0gdmXEvmvDoSB2YXJpYW5jaWEgb2RoYWRvdgotIG5lc3RhYmlsaXRhIHBhcmFtZXRyb3YgcHJpIG1hbMO9Y2ggdsO9YmVyb2NoCgotLS0KCiMjIyMjICBLb3lja292YSDFoXRydWt0w7pyYSBrb2VmaWNpZW50b3YKCktveWNrIG5hdnJob2wsIMW+ZSBvbmVza29yZW7DqSBlZmVrdHkgbWFqw7ogKipnZW9tZXRyaWNreSBrbGVzYWrDumN1IHBvZG9idSoqOgoKXFsKXGJldGFfayA9IFxsYW1iZGFeayBcYmV0YV8wLCBccXF1YWQgMCA8IFxsYW1iZGEgPCAxLgpcXQoKVMO9bSBzYSBkaXN0cmlidcSNbsOpIG9uZXNrb3JlbmllIHpqZWRub2R1xaHDrSB0YWssIMW+ZSBuYW1pZXN0byBuZWtvbmXEjW7DqWhvCnBvxI10dSBwYXJhbWV0cm92IG9kaGFkdWplbWUgbGVuOgoKLSBcKFxiZXRhXzBcKSDigJMgb2thbcW+aXTDvSBlZmVrdCwKLSBcKFxsYW1iZGFcKSDigJMgcsO9Y2hsb3PFpSB0bG1lbmlhIGVmZWt0b3Ygb25lc2tvcmVuaWEuCgotLS0KCiMjIyMjIEtveWNrb3ZhIHRyYW5zZm9ybcOhY2lhCgpaYcSNbmltZSBww7R2b2Ruw71tIG1vZGVsb206CgpcWwp5X3QgPSBcYWxwaGEgKyBcYmV0YV8wIHhfdCArIFxsYW1iZGEgXGJldGFfMCB4X3t0LTF9CiAgICAgICsgXGxhbWJkYV4yIFxiZXRhXzAgeF97dC0yfSArIFxjZG90cyArIHVfdC4KXF0KClZ5bsOhc29ibWUgY2Vsw70gbW9kZWwga29uxaF0YW50b3UgXChcbGFtYmRhXCkgYSBwb3N1xYhtZSDEjWFzb3bDvSBpbmRleGRvemFkdSAgbyAxOgoKXFsKXGxhbWJkYSB5X3t0LTF9ID0gXGxhbWJkYVxhbHBoYSArIFxiZXRhXzAgeF97dC0xfQogICAgICArIFxsYW1iZGEgXGJldGFfMCB4X3t0LTJ9ICsgXGNkb3RzICsgXGxhbWJkYSB1X3t0LTF9LgpcXQoKVGVyYXogb2TEjcOtdGFtZSBvYmEgdsO9cmF6eToKClxbCnlfdCAtIFxsYW1iZGEgeV97dC0xfQo9IFxhbHBoYSgxLVxsYW1iZGEpICsgXGJldGFfMCAoeF90IC0gXGxhbWJkYSB4X3t0LTF9KQogICsgKHVfdCAtIFxsYW1iZGEgdV97dC0xfSkuClxdCgpUb3RvIGplICoqS295Y2tvdmEgdHJhbnNmb3Jtw6FjaWEqKi4KCi0tLQoKIyMjIyMgS295Y2tvdmEgcm92bmljYSAoYXV0b3JlZ3Jlc8Otdm55IG1vZGVsKQoKUG8gYWxnZWJyYWlja2VqIMO6cHJhdmUgesOtc2thbWU6CgpcWwp5X3QgPSBcYWxwaGEoMS1cbGFtYmRhKSArIFxiZXRhXzAgeF90ICsgXGxhbWJkYSB5X3t0LTF9ICsgdl90LApcXQoKa2RlOgoKXFsKdl90ID0gdV90IC0gXGxhbWJkYSB1X3t0LTF9LgpcXQoKVG90byBqZSAqKktveWNrb3ZhIHJvdm5pY2EqKiDigJMgZHluYW1pY2vDvSBhdXRvcmVncmVzw612bnkgbW9kZWwgc28KesOhdmlzbG9zxaVvdSBuYSBtaW51bG9zdGkuCgpJbnRlcnByZXTDoWNpYToKCi0gXChcbGFtYmRhXCkg4oCTIHLDvWNobG9zxaUgcHJpc3DDtHNvYmVuaWEgKMSNw61tIGJsacW+xaFpZSAxLCB0w71tIHBvbWFsxaFpYSByZWFrY2lhKQotIFwoXGJldGFfMFwpIOKAkyBva2Ftxb5pdMO9IGVmZWt0IFwoeF90XCkKLSBkbGhvZG9iw70gZWZla3Q6CgpcWwpcZnJhY3tcYmV0YV8wfXsxLVxsYW1iZGF9ClxdCgotLS0KCiMjIyBPZHN0cmHFiG92YW5pZSBwcm9ibMOpbXUgYXV0b2tvcmVsw6FjaWUgcmV6w61kdcOtCgojIyMjIE9kaGFkIEtveWNrb3ZobyBtb2RlbHUgdiBSCgpOYWpqZWRub2R1Y2jFoWlhIGltcGxlbWVudMOhY2lhOgoKYGBge3J9CgpsaWJyYXJ5KGRwbHlyKQoKdWRhamVBdXN0cmlhIDwtIHVkYWplQXVzdHJpYSAlPiUKICBhcnJhbmdlKFllYXIpICU+JQogIG11dGF0ZSgKICAgIExpZmUuZXhwZWN0YW5jeV9sYWcxID0gbGFnKExpZmUuZXhwZWN0YW5jeSkKICApCgptb2RlbF9rb3ljayA8LSBsbShMaWZlLmV4cGVjdGFuY3kgfiBHRFAgKyBCTUkgKyBTY2hvb2xpbmcgKyAgTGlmZS5leHBlY3RhbmN5X2xhZzEsIAogICAgICAgICAgICAgICAgICBkYXRhID0gdWRhamVBdXN0cmlhKQoKc3VtbWFyeShtb2RlbF9rb3ljaykKCmBgYApgYGB7cn0KZHd0ZXN0KG1vZGVsX2tveWNrKQpgYGAKCgpEeW5hbWl6b3ZhbsO9IG1vZGVsIG7DoW0gIG5laWRlbnRpZmlrdWplIMW+aWFkZW4gcmVncmVzb3IgYWtvIMWhdGF0aXNpY2t5IHbDvXpuYW1uw70uIEtvZWZpY2llbnQgcHJpICp5X2xhZzEqLCDEjW8gamUgb8SNYWvDoXZhbsOhIGTEusW+a2EgZG/Fvml0aWEgdiBtaW51bG9tIG9iZG9iw60sIGplIGtsYWRuw70gYSBtZW7FocOtIGFrbyAxLiBIb2Rub3RhIDAuNDIgbsOhbSBob3ZvcsOtIG8gem90cnZhxI1ub20gdnBseXZlIHZ5c3ZldMS+b3ZhbmVqIHByZW1lbm5laiB6IG1pbnVsb3N0aSAobmllxI1vIGFrbyA0MiBwZXJjZW50IG/EjWFrw6F2YW5laiBkxLrFvmt5IMW+aXZvdGEgc2EgcHJlbmVzaWUgeiBtaW51bMOpaG8gb2Jkb2JpYSAtIMSNbyBqZSBpbnRlcnByZXTDoXVjaWEgdiB0b210byBrb25rcsOpdG5vbSBwcsOtcGFkZSBkb3PFpSBrb3N0cmJhdMOhKS4KClByaSBob2Rub3RlbsOtIGt2YWxpdHkgbm92w6lobyBtb2RlbHUgcG9yb3ZuYWptZSBsZW4gKkFkanVzdGVkIFItc3F1YXJlZCouIFogbmVobyB2eXBsw712YSwgxb5lIHDDtHZvZG7DvSBtb2RlbCBuw6FtIHBvc2t5dHVqZSBsZXDFoWllIHbDvXNsZWRreS4KCgoKIyMjIyBOZXdleeKAk1dlc3Qgcm9idXN0bsOpIMWhdGFuZGFyZG7DqSBjaHlieQoKYGBge3J9CmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkobG10ZXN0KQoKY29lZnRlc3QobW9kZWwsIHZjb3YgPSBOZXdleVdlc3QobW9kZWwpKQpgYGAKIyMgNC4gWsOhdmVyCgoKQXV0b2tvcmVsw6FjaWEgcmV6w61kdcOtIGEgeiBuZWogdnlwbMO9dmFqw7pjYSBwb3RyZWJhIGR5bmFtaXrDoWNpZSBtb2RlbG92IG3DoSBla29uw7Ntb21ldHJpaSB2ZcS+bWkgdmXEvmvDvSB2w716bmFtLiBNeSBzbWUgdHUgdXZpZWRsaSBsZW4gbmFqesOha2xhZG5lasWhaWUgcHJvYmzDqW15LiBLIHRyb2NodSB6bG/Fvml0ZWrFocOtbSBwYXRyw60gQWxtb25vdmVqIG1vZGVsIHJpZcWhZW5pYSBkeW5hbWl6w6FjaWUgYWxlYm8gbWV0w7NkYSBDb2NocmFuLU9yY3V0dC4gU2Ftb3N0YXRub3UgbWV0b2RvbMOzZ2lvdSBqZSBhbGUgbWV0b2Rpa2EgYXJpbWEgbW9kZWxvdiBrdG9yw6EgamUgZG5lcyBwb3B1bMOhcm5hIGEgcHJpIGRsaMO9Y2ggxI1hc292w71jaCByYWRvY2ggc2EgcG91xb7DrXZhIG5hasSNYXN0ZWrFoWllLgoKCg==