Úvod a popis databázy

V tejto časti sa testujú štatistické hypotézy pomocou údajov z databázy, ktorá obsahuje ekonomické ukazovatele krajín v rokoch 1991 – 2022. Použité premenné zahŕňajú hrubý domáci produkt (HDP) v USD, mieru nezamestnanosti (%) a štruktúru zamestnanosti v troch sektoroch – poľnohospodárstve, priemysle a službách.

install.packages("stargazer")
install.packages("zoo")
install.packages("tseries")
install.packages("lmtest")
install.packages("sandwich")
install.packages("car")
library(zoo)
library(tseries) 
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())
install.packages("knitr")
install.packages("dplyr")
install.packages("ggplot2")
# Import vlastného CSV súboru

udaje <- read.csv("Employment_Unemployment_GDP_data.csv",
header = TRUE,
sep = ",",
dec = ".",
stringsAsFactors = FALSE)

# Zobrazenie prvých riadkov a názvov stĺpcov

head(udaje)
colnames(udaje)
[1] "Country.Name"                   "Year"                          
[3] "Employment.Sector..Agriculture" "Employment.Sector..Industry"   
[5] "Employment.Sector..Services"    "Unemployment.Rate"             
[7] "GDP..in.USD."                  

Regresia

V tejto analýze sa zameriavame na to, do akej miery je miera nezamestnanosti ovplyvnená štruktúrou zamestnanosti podľa sektorov (poľnohospodárstvo, priemysel, služby) a úrovňou hrubého domáceho produktu na obyvateľa (GDP).

Pracujeme s údajmi za rok 2003.

Cieľom je zistiť, ktoré z dostupných ekonomických ukazovateľov najviac vysvetľujú rozdiely v miere nezamestnanosti medzi krajinami.

#######################################################################
# PRIPRAVA UDAJOV
#######################################################################
udaje <- read.csv("Employment_Unemployment_GDP_data.csv",dec=".",sep=",",header = TRUE)
# select just the record from 2003
udaje.2003 <- udaje[udaje$Year==2003,c("Unemployment.Rate","Employment.Sector..Agriculture","GDP..in.USD.", "Employment.Sector..Industry","Employment.Sector..Services" )]

# data imputation

# Compute column medians
#column_medians <- sapply(udaje.2003, median, na.rm = TRUE)

# Impute missing values with column medians
# Compute column medians
column_medians <- sapply(udaje.2003, median, na.rm = TRUE)

# Impute missing values with column medians
udaje_imputed <- udaje.2003
for (col in names(udaje.2003)) {
  udaje_imputed[[col]][is.na(udaje_imputed[[col]])] <- column_medians[col]
}

udaje.2003 <- udaje_imputed
udaje <- udaje.2003

################################################################################
# ZAKLADNA REGRESIA
################################################################################
attach(udaje)
model <- lm(Unemployment.Rate ~ 
              Employment.Sector..Agriculture +
              Employment.Sector..Industry +
              Employment.Sector..Services +
              GDP..in.USD.,
            data = udaje)
summary(model)

Call:
lm(formula = Unemployment.Rate ~ Employment.Sector..Agriculture + 
    Employment.Sector..Industry + Employment.Sector..Services + 
    GDP..in.USD., data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-11.426  -4.399  -1.240   2.583  25.949 

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)  
(Intercept)                     8.812e+04  1.580e+05   0.558   0.5777  
Employment.Sector..Agriculture -8.812e+02  1.580e+03  -0.558   0.5777  
Employment.Sector..Industry    -8.811e+02  1.580e+03  -0.558   0.5778  
Employment.Sector..Services    -8.812e+02  1.580e+03  -0.558   0.5777  
GDP..in.USD.                   -8.262e-13  4.844e-13  -1.706   0.0898 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6.16 on 177 degrees of freedom
Multiple R-squared:  0.09631,   Adjusted R-squared:  0.07589 
F-statistic: 4.716 on 4 and 177 DF,  p-value: 0.00122

Testujeme, či je náš regresný model vhodne špecifikovaný, či lineárna funkčná forma postačuje, alebo či by sme mali uvažovať o transformáciách premenných (napr. logaritmy, mocniny).

1. Ramsey RESET test

Myšlienka testu je jednoduchá:
Ak je pôvodný model správne špecifikovaný, pridanie mocnín predikovaných hodnôt (\(\hat{y}^2\), \(\hat{y}^3\)) by model nemalo významne zlepšiť.

Testované hypotézy:

\[ H_0: \text{Model je správne špecifikovaný} \]

\[ H_1: \text{Model je nesprávne špecifikovaný}\]

Ak p-hodnota < 0.05 → model je pravdepodobne zle špecifikovaný.

Výpočet RESET testu :

# Suppose your model is:
model <- lm(Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + Employment.Sector..Services + GDP..in.USD., data = udaje)

# RESET test from 'lmtest' package:
library(lmtest)
resettest(model)

    RESET test

data:  model
RESET = 6.0494, df1 = 2, df2 = 175, p-value = 0.002882

Interpretácia

Keďže p-hodnota je nižšia ako 0.05, zamietame nulovú hypotézu o správnej funkčnej forme.
To znamená, že náš model je nesprávne špecifikovaný. Model pravdepodobne potrebuje nelineárnu transformáciu premenných (napr. log GDP, kvadratické členy), alebo mu chýbajú niektoré vysvetľujúce premenné, ktoré by lepšie vysvetlili mieru nezamestnanosti.

Výsledok RESET testu teda naznačuje, že jednoduchá lineárna špecifikácia nemusí byť pre tieto dáta postačujúca.

2. Grafická analýza funkčnej formy

Graf Residuals vs. Fitted

Prvým krokom je vizuálna kontrola lineárnej špecifikácie pomocou grafu rezíduí voči vyrovnaným hodnotám. Tento graf nám pomáha odhaliť nelineárne vzťahy alebo iné problémy s modelom.

car::crPlots(model)

Interpretácia C+R grafov

Component + Residual grafy ukazujú, či má každá vysvetľujúca premenná lineárny vzťah so závislou premennou (Unemployment.Rate).

  • Employment.Sector..Agriculture – krivka kopíruje priamku,čiže vzťah je približne lineárny.
  • Employment.Sector..Industry – situácia je rovnaká, žiadne výrazné zakrivenie, takže lineárna špecifikácia je pravdepodobne postačujúca.
  • Employment.Sector..Services – taktiež prakticky lineárny vzťah bez odchýlok.

Najväčší problém – GDP..in.USD.

  • Pri premennej GDP..in.USD. je vidieť silné zakrivenie.
  • Body sú extrémne zhustené pri veľmi nízkych hodnotách GDP a rozťahané pri vyšších hodnotách.
  • To znamená, že vzťah medzi GDP a nezamestnanosťou NIE JE lineárny, a lineárny model to nevie správne zachytiť. Mali by sme práve túto premennú transformovať .

Toto je v súlade aj s RESET testom, ktorý ukázal, že lineárna špecifikácia modelu je chybná.

3. Porovnanie základného a modifikovaného modelu

Budeme porovnávať:

  • Základný lineárny model
  • Model doplnený o kvadratický člen premennej GDP:
    \[ I(GDP^2)\]

Cieľom je zistiť, či pridaním kvadratického člena:

  • stúpne upravený koeficient determinácie \(R^2_{adj}\),
  • model bude štatisticky lepší podľa ANOVA testu,
  • RESET test prestane signalizovať chybnú špecifikáciu.
# základný model
model_linear <- lm(Unemployment.Rate ~ 
                     Employment.Sector..Agriculture +
                     Employment.Sector..Industry +
                     Employment.Sector..Services +
                     GDP..in.USD.,
                   data = udaje)

# model s kvadrátom GDP
model_gdp_quad <- lm(Unemployment.Rate ~ 
                       Employment.Sector..Agriculture +
                       Employment.Sector..Industry +
                       Employment.Sector..Services +
                       GDP..in.USD. +
                       I(GDP..in.USD.^2),
                     data = udaje)

summary(model_gdp_quad)

Call:
lm(formula = Unemployment.Rate ~ Employment.Sector..Agriculture + 
    Employment.Sector..Industry + Employment.Sector..Services + 
    GDP..in.USD. + I(GDP..in.USD.^2), data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-12.075  -4.493  -1.018   2.560  25.411 

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)  
(Intercept)                     9.048e+04  1.569e+05   0.577   0.5649  
Employment.Sector..Agriculture -9.047e+02  1.569e+03  -0.577   0.5649  
Employment.Sector..Industry    -9.046e+02  1.569e+03  -0.577   0.5650  
Employment.Sector..Services    -9.047e+02  1.569e+03  -0.577   0.5649  
GDP..in.USD.                   -3.187e-12  1.356e-12  -2.351   0.0199 *
I(GDP..in.USD.^2)               2.442e-25  1.311e-25   1.862   0.0642 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6.118 on 176 degrees of freedom
Multiple R-squared:  0.1138,    Adjusted R-squared:  0.0886 
F-statistic: 4.519 on 5 and 176 DF,  p-value: 0.0006697
# porovnanie modelov
anova(model_linear, model_gdp_quad)
Analysis of Variance Table

Model 1: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + GDP..in.USD.
Model 2: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + GDP..in.USD. + I(GDP..in.USD.^2)
  Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
1    177 6717.3                              
2    176 6587.4  1    129.82 3.4684 0.06422 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# RESET test na modifikovaný model
resettest(model_gdp_quad)

    RESET test

data:  model_gdp_quad
RESET = 3.0094, df1 = 2, df2 = 174, p-value = 0.05189

Výsledky modifikovaného modelu s kvadrátom GDP

Po pridaní kvadratického člena premennej GDP..in.USD. dostávame nasledovné výsledky:

  • Koeficient pri premenej GDP je štatisticky významný (p = 0.0199).
  • Koeficient pri I(GDP²) je na hranici významnosti (p = 0.0642), čo naznačuje možný nelineárny vzťah.
  • Upravený koeficient determinácie vzrástol z 0.0759 na 0.0886, teda model sa mierne zlepšil.

ANOVA test

Porovnanie pôvodného a kvadratického modelu:

  • p-hodnota = 0.06422, teda na úrovni 10 % je zlepšenie modelu štatisticky významné.
  • To podporuje myšlienku, že pridanie nelineárneho prvku (GDP²) má zmysel.

RESET test pre modifikovaný model

  • p-hodnota = 0.05189

  • Toto je tesne nad hranicou 0.05 → už nezamietame hypotézu o správnej špecifikácii.

  • Model teraz lepšie zachytáva nelineárny vzťah medzi GDP a nezamestnanosťou.

4. Rozšírený RESET test a úplný kvadratický model

model_rozsireny <- lm(Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + Employment.Sector..Services + GDP..in.USD. + I(Employment.Sector..Agriculture^2) + I(Employment.Sector..Industry^2) + I(Employment.Sector..Services^2) + I(GDP..in.USD.^2), data = udaje)

summary(model_rozsireny)

Call:
lm(formula = Unemployment.Rate ~ Employment.Sector..Agriculture + 
    Employment.Sector..Industry + Employment.Sector..Services + 
    GDP..in.USD. + I(Employment.Sector..Agriculture^2) + I(Employment.Sector..Industry^2) + 
    I(Employment.Sector..Services^2) + I(GDP..in.USD.^2), data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-12.518  -4.344  -0.772   2.600  22.914 

Coefficients:
                                      Estimate Std. Error t value Pr(>|t|)   
(Intercept)                          6.746e+04  1.554e+05   0.434  0.66466   
Employment.Sector..Agriculture      -6.740e+02  1.554e+03  -0.434  0.66494   
Employment.Sector..Industry         -6.749e+02  1.554e+03  -0.434  0.66453   
Employment.Sector..Services         -6.750e+02  1.554e+03  -0.434  0.66451   
GDP..in.USD.                        -2.183e-12  1.362e-12  -1.603  0.11074   
I(Employment.Sector..Agriculture^2) -6.131e-03  2.080e-03  -2.948  0.00364 **
I(Employment.Sector..Industry^2)     1.494e-02  7.199e-03   2.075  0.03945 * 
I(Employment.Sector..Services^2)     5.661e-03  3.043e-03   1.860  0.06459 . 
I(GDP..in.USD.^2)                    1.691e-25  1.303e-25   1.298  0.19612   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.984 on 173 degrees of freedom
Multiple R-squared:  0.1665,    Adjusted R-squared:  0.1279 
F-statistic: 4.319 on 8 and 173 DF,  p-value: 9.177e-05
anova(model,model_rozsireny)
Analysis of Variance Table

Model 1: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + GDP..in.USD.
Model 2: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + GDP..in.USD. + I(Employment.Sector..Agriculture^2) + 
    I(Employment.Sector..Industry^2) + I(Employment.Sector..Services^2) + 
    I(GDP..in.USD.^2)
  Res.Df    RSS Df Sum of Sq      F   Pr(>F)   
1    177 6717.3                                
2    173 6195.8  4     521.5 3.6404 0.007102 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
resettest(model_rozsireny)

    RESET test

data:  model_rozsireny
RESET = 8.9371, df1 = 2, df2 = 171, p-value = 0.0002034

ANOVA porovnanie základného a plne kvadratického modelu

ANOVA test porovnáva pôvodný lineárny model s rozšíreným modelom obsahujúcim všetky kvadratické členy. Výsledky sú:

  • p-hodnota = 0.007102
  • F = 3.6404

Keďže p-hodnota je výrazne nižšia ako 0.05, rozšírený kvadratický model je štatisticky lepší ako pôvodný lineárny model.
Pridanie kvadratických členov teda výrazne zlepšilo vysvetľovaciu schopnosť modelu.

RESET test pre rozšírený model

Výsledok:

  • p-hodnota = 0.0002034
  • RESET = 8.9371

Tento výsledok je veľmi dôležitý:

  • p-hodnota < 0.001 → model je stále nesprávne špecifikovaný
  • ani pridanie všetkých kvadratických členov neodstránilo špecifikačnú chybu Čiže aj keď ANOVA ukazuje, že kvadratické členy priniesli štatistické zlepšenie, RESET test odhaľuje, že ani rozšírená nelineárna špecifikácia nevyriešila problém špecifikácie modelu. Takže je v modeli, buď stále chýba dôležitá premenná,
    alebo treba použiť inú transformáciu, alebo vzťahy medzi premennými sú zložitejšie než kvadratické.

5. Transformácia pomocou dummy premennej a lineárnej lomenej funkcie

Z predchádzajúcich grafov vidíme, že premenná GDP sa nespráva úplne lineárne. Preto skúsime dáta rozdeliť na dve skupiny – krajiny s nižším GDP a krajiny s vyšším GDP – a pozrieme sa, či sa správanie modelu medzi nimi líši.

Na to vytvoríme jednoduchú dummy premennú (DUM), ktorá je:

  • 0 = krajiny s nižším GDP
  • 1 = krajiny s vyšším GDP

Cieľom je zistiť, či sa pre tieto dve skupiny krajín mení: - buď celková úroveň nezamestnanosti (posun modelu), - alebo samotný vzťah medzi GDP a nezamestnanosťou (teda sklon).

Najskôr vytvoríme túto DUM premennú:

Takto rozdelíme krajiny na dve skupiny: - krajiny s nižším GDP,
- krajiny s vyšším GDP.

V ďalšom kroku odhadneme: 1. model so zlomom v autonómnom člene, 2. model so zlomom v sklone.

Najprv vytvoríme dummy premennú DUM:

# dummy podľa mediánu GDP
threshold <- median(udaje$GDP..in.USD.)
udaje$DUM <- ifelse(udaje$GDP..in.USD. < threshold, 0, 1)

table(udaje$DUM)

 0  1 
91 91 

5.1 Model so zlomom v autonómnom člene

Teraz otestujeme, či sa model „posúva“ nahor alebo nadol pre krajiny s vyšším GDP.
Teda či krajiny s vysokým GDP majú v priemere inú úroveň nezamestnanosti ako krajiny s nízkym GDP.

Odhadneme model, kde pridáme dummy premennú DUM ako samostatný vysvetľujúci faktor:

modelD_auto <- lm(Unemployment.Rate ~ DUM +
                    Employment.Sector..Agriculture +
                    Employment.Sector..Industry +
                    Employment.Sector..Services +
                    GDP..in.USD.,
                  data = udaje)

summary(modelD_auto)

Call:
lm(formula = Unemployment.Rate ~ DUM + Employment.Sector..Agriculture + 
    Employment.Sector..Industry + Employment.Sector..Services + 
    GDP..in.USD., data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-13.431  -4.110  -1.260   3.037  23.049 

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)                     9.949e+04  1.527e+05   0.652 0.515422    
DUM                            -3.783e+00  1.024e+00  -3.696 0.000293 ***
Employment.Sector..Agriculture -9.949e+02  1.527e+03  -0.652 0.515435    
Employment.Sector..Industry    -9.946e+02  1.527e+03  -0.652 0.515530    
Employment.Sector..Services    -9.948e+02  1.527e+03  -0.652 0.515463    
GDP..in.USD.                   -5.574e-13  4.736e-13  -1.177 0.240785    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.951 on 176 degrees of freedom
Multiple R-squared:  0.1614,    Adjusted R-squared:  0.1376 
F-statistic: 6.774 on 5 and 176 DF,  p-value: 8.412e-06

Výsledok modelu so zlomom v autonómnom člene

Do modelu sme pridali dumm premennú DUM, ktorá rozdeľuje krajiny na tie s nižším a vyšším GDP. Cieľom bolo zistiť, či sa model pri krajinách s vyšším GDP „posúva“ nahor alebo nadol.

Výsledky ukazujú, že koeficient pri DUM je významný (p < 0.001).
To znamená, že krajiny s vyšším GDP majú v priemere inú úroveň nezamestnanosti ako krajiny s nižším GDP.

Konkrétne: - koeficient DUM = –3.78
→ krajiny s vyšším GDP majú približne o 3.8 percentuálneho bodu nižšiu nezamestnanosť.

Ostatné premenné sa takmer nezmenili a nie sú významné.

Zavedenie DUMM spôsobí iba posun modelu, ale nemení tvar vzťahu medzi premennými. Tento krok síce zlepšil model, ale problém lineárnej špecifikácie stále pretrváva.

6.2 Model so zlomom v sklone

V predchádzajúcom kroku sme zistili, že krajiny s vyšším GDP majú iný „posun“ v modeli.
Teraz otestujeme, či sa pri týchto krajinách mení aj sklon, teda samotný vzťah medzi GDP a nezamestnanosťou.

Na to použijeme interakčný člen:
\[DUM * GDP\]

Tým vlastne hovoríme: „vzťah medzi GDP a nezamestnanosťou môže byť iný pre obe skupiny krajín.“

modelD_sklon <- lm(Unemployment.Rate ~ 
                     Employment.Sector..Agriculture +
                     Employment.Sector..Industry +
                     Employment.Sector..Services +
                     GDP..in.USD. +
                     I(DUM * GDP..in.USD.),
                   data = udaje)

summary(modelD_sklon)

Call:
lm(formula = Unemployment.Rate ~ Employment.Sector..Agriculture + 
    Employment.Sector..Industry + Employment.Sector..Services + 
    GDP..in.USD. + I(DUM * GDP..in.USD.), data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-12.370  -4.197  -1.252   2.702  25.340 

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)
(Intercept)                     1.011e+05  1.580e+05   0.640    0.523
Employment.Sector..Agriculture -1.011e+03  1.580e+03  -0.640    0.523
Employment.Sector..Industry    -1.011e+03  1.580e+03  -0.640    0.523
Employment.Sector..Services    -1.011e+03  1.580e+03  -0.640    0.523
GDP..in.USD.                    1.931e-10  1.506e-10   1.283    0.201
I(DUM * GDP..in.USD.)          -1.939e-10  1.505e-10  -1.288    0.199

Residual standard error: 6.149 on 176 degrees of freedom
Multiple R-squared:  0.1048,    Adjusted R-squared:  0.07932 
F-statistic: 4.119 on 5 and 176 DF,  p-value: 0.00146

Výsledok modelu so zlomom v sklone

V tomto modeli sme skúšali, či sa vzťah medzi GDP a nezamestnanosťou mení pre krajiny s vyšším a nižším GDP. To zisťujeme pomocou interakcie DUM * GDP.

Z výsledkov vidíme, že:

  • koeficient pri premennej GDP nie je významný (p = 0.201)
  • koeficient pri DUM * GDP tiež nie je významný (p = 0.199)

To znamená, že sklon sa nemení.
Inými slovami: nezamestnanosť reaguje na GDP veľmi podobne v oboch skupinách krajín (teda v krajinách s nižším aj vyšším GDP).

Tento model teda nepriniesol zlepšenie a nezachytil žiadny zlom v sklone.

anova(model_linear, modelD_sklon)
Analysis of Variance Table

Model 1: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + GDP..in.USD.
Model 2: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + GDP..in.USD. + I(DUM * GDP..in.USD.)
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1    177 6717.3                           
2    176 6654.5  1    62.748 1.6596 0.1994
resettest(modelD_sklon)

    RESET test

data:  modelD_sklon
RESET = 3.2494, df1 = 2, df2 = 174, p-value = 0.04116

Porovnanie modelu so zlomom v sklone (ANOVA)

ANOVA porovnáva pôvodný model s modelom, kde sme pridali interakciu DUM * GDP.

Výsledok:

  • p-hodnota = 0.1994
  • F = 1.6596

Keďže p-hodnota je väčšia ako 0.05, nový model nie je štatisticky lepší ako pôvodný.
To znamená, že pridanie interakcie (teda zlom v sklone) model nijako nezlepšilo.


RESET test pre model so zlomom v sklone

  • p-hodnota = 0.04116

Keďže p-hodnota je nižšia ako 0.05, RESET test nám hovorí, že model stále nie je správne špecifikovaný (má chybu vo funkčnej forme).

  • Zlom v sklone neexistuje (interakcia nie je významná, model sa nezlepšil).
  • Model so zlomom v sklone nevyriešil problém špecifikácie (RESET je stále významný).
  • Tento model teda nie je vhodný a nebudeme ho ďalej používať.

Logaritmická transformácia

Keďže sa náš model stále javí ako nesprávne špecifikovaný (RESET test to potvrdil), skúšame najbežnejšiu a najjednoduchšiu transformáciu – logaritmus.
Logaritmus pomáha hlavne vtedy, keď je vzťah medzi premennými zakrivený alebo rýchlo rastie, čo bol náš prípad pri GDP.

Preto nahradíme premennú GDP logaritmom z GDP.

udaje$logGDP <- log(udaje$GDP..in.USD.)

model_log <- lm(Unemployment.Rate ~ 
                  Employment.Sector..Agriculture +
                  Employment.Sector..Industry +
                  Employment.Sector..Services +
                  logGDP,
                data = udaje)

summary(model_log)

Call:
lm(formula = Unemployment.Rate ~ Employment.Sector..Agriculture + 
    Employment.Sector..Industry + Employment.Sector..Services + 
    logGDP, data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-12.879  -4.017  -1.164   2.169  23.702 

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)                     3.661e+04  1.521e+05   0.241     0.81    
Employment.Sector..Agriculture -3.659e+02  1.521e+03  -0.241     0.81    
Employment.Sector..Industry    -3.657e+02  1.521e+03  -0.240     0.81    
Employment.Sector..Services    -3.658e+02  1.521e+03  -0.241     0.81    
logGDP                         -9.873e-01  2.318e-01  -4.260 3.32e-05 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 5.915 on 177 degrees of freedom
Multiple R-squared:  0.1669,    Adjusted R-squared:  0.148 
F-statistic: 8.862 on 4 and 177 DF,  p-value: 1.518e-06
# RESET test pre logaritmický model
resettest(model_log)

    RESET test

data:  model_log
RESET = 0.59418, df1 = 2, df2 = 175, p-value = 0.5531
anova(model_linear, model_log)
Analysis of Variance Table

Model 1: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + GDP..in.USD.
Model 2: Unemployment.Rate ~ Employment.Sector..Agriculture + Employment.Sector..Industry + 
    Employment.Sector..Services + logGDP
  Res.Df    RSS Df Sum of Sq F Pr(>F)
1    177 6717.3                      
2    177 6192.8  0    524.42         
resettest(model_log)

    RESET test

data:  model_log
RESET = 0.59418, df1 = 2, df2 = 175, p-value = 0.5531

Logaritmická transformácia (logGDP)

Keď sme vymenili premennú GDP za jej logaritmus (logGDP), model sa citeľne zlepšil.

ANOVA test

ANOVA porovnáva pôvodný lineárny model s modelom, ktorý používa logGDP.

Výsledok: - reziduálny súčet štvorcov (RSS) sa znížil z 6717.3 na 6192.8 - rozdiel je 524.42, čo znamená, že logaritmický model opisuje dáta lepšie

Aj keď ANOVA neukazuje klasickú p-hodnotu (lebo model má rovnaký počet stupňov voľnosti), zníženie RSS je jasné zlepšenie.

RESET test

  • p-hodnota = 0.5531
  • to znamená, že model je správne špecifikovaný
    (žiadna chyba funkčnej formy)

Takže model s logGDP je doteraz najlepší: - má najnižší RSS, - má najvyšší upravený R², - všetko je štatisticky v poriadku, - a ako jediný prešiel RESET testom bez problémov.

V ďalšej analýze budeme pracovať s logaritmickým modelom.

7. Box-Coxov transformačný test (len doplnkové)

Pre istotu sa pozrieme aj na Box–Cox test, ktorý ukazuje, či by sme mali transformovať samotnú závislú premennú (Unemployment.Rate). Test hľadá takú hodnotu λ, ktorá dá modelu najlepší tvar.

Význam λ: - λ ≈ 1 → netreba transformovať, - λ ≈ 0 → logaritmus, - λ ≈ 0.5 → odmocnina, - λ ≈ -1 → 1/Y, atď.

library(MASS)
boxcox(model_log)   # používame model s logGDP, pretože to je náš najlepší model

Box-Coxov graf nám ukazuje, aká transformácia by bola najlepšia pre závislú premennú (Unemployment.Rate).

V našom grafe vidíme, že maximum krivky je pri hodnote λ približne okolo 0.
To znamená, že najvhodnejšia transformácia by bola logaritmus, teda log(Y).

To je ale dôležité:
my už logaritmus používame – ale nie na Y, ale na GDP, čo nám ako jediné opravilo chybnú špecifikáciu.

Preto Box-Cox potvrdzuje, že nejaká logaritmická úprava v modeli je potrebná, ale nemusíme transformovať samotnú nezamestnanosť (to by zhoršilo interpretáciu).

LogGDP model je už teraz: - správne špecifikovaný, - najlepší podľa všetkých testov, - a dáva zmysel aj ekonomicky.

Preto Box-Cox berieme len ako doplnkovú kontrolu a ďalšiu transformáciu už robiť netreba.

LS0tCnRpdGxlOiAiUHLDoWNhIHMgZGF0YWLDoXpvdSAtIGltcG9ydCDDumRham92LCBncmFmeSwgxaF0YXRpc3Rpa3kiCmF1dGhvcjogIkzDrXZpYSBNZWxpY2hvdsOhIgpkYXRlOiAiTm92ZW1iZXIgMjAyNSIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KZWRpdG9yX29wdGlvbnM6IAogIG1hcmtkb3duOiAKICAgIHdyYXA6IDcyCi0tLQoKIyMgw5p2b2QgYSBwb3BpcyBkYXRhYsOhenkKClYgdGVqdG8gxI1hc3RpIHNhIHRlc3R1asO6IMWhdGF0aXN0aWNrw6kgaHlwb3TDqXp5IHBvbW9jb3Ugw7pkYWpvdiB6IGRhdGFiw6F6eSwKa3RvcsOhIG9ic2FodWplIGVrb25vbWlja8OpIHVrYXpvdmF0ZWxlIGtyYWrDrW4gdiByb2tvY2ggMTk5MSDigJMgMjAyMi4KUG91xb5pdMOpIHByZW1lbm7DqSB6YWjFlcWIYWrDuiBocnViw70gZG9tw6FjaSBwcm9kdWt0IChIRFApIHYgVVNELCBtaWVydQpuZXphbWVzdG5hbm9zdGkgKCUpIGEgxaF0cnVrdMO6cnUgemFtZXN0bmFub3N0aSB2IHRyb2NoIHNla3Rvcm9jaCDigJMKcG/Evm5vaG9zcG9kw6Fyc3R2ZSwgcHJpZW15c2xlIGEgc2x1xb5iw6FjaC4KCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCJzdGFyZ2F6ZXIiKQoKYGBgCgoKYGBge3J9Cmluc3RhbGwucGFja2FnZXMoInpvbyIpCmluc3RhbGwucGFja2FnZXMoInRzZXJpZXMiKQppbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQppbnN0YWxsLnBhY2thZ2VzKCJzYW5kd2ljaCIpCmluc3RhbGwucGFja2FnZXMoImNhciIpCmxpYnJhcnkoem9vKQpsaWJyYXJ5KHRzZXJpZXMpIApsaWJyYXJ5KGxtdGVzdCkKbGlicmFyeShzYW5kd2ljaCkKbGlicmFyeShjYXIpCnJtKGxpc3Q9bHMoKSkKYGBgCgpgYGB7cn0KaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQppbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpCmluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQpgYGAKCmBgYHtyfQojIEltcG9ydCB2bGFzdG7DqWhvIENTViBzw7pib3J1Cgp1ZGFqZSA8LSByZWFkLmNzdigiRW1wbG95bWVudF9VbmVtcGxveW1lbnRfR0RQX2RhdGEuY3N2IiwKaGVhZGVyID0gVFJVRSwKc2VwID0gIiwiLApkZWMgPSAiLiIsCnN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKCiMgWm9icmF6ZW5pZSBwcnbDvWNoIHJpYWRrb3YgYSBuw6F6dm92IHN0xLpwY292CgpoZWFkKHVkYWplKQpjb2xuYW1lcyh1ZGFqZSkKCmBgYAoKIyMgUmVncmVzaWEKCiBWIHRlanRvIGFuYWzDvXplIHNhIHphbWVyaWF2YW1lIG5hIHRvLCBkbyBha2VqIG1pZXJ5IGplIG1pZXJhIG5lemFtZXN0bmFub3N0aSBvdnBseXZuZW7DoSDFoXRydWt0w7pyb3UgemFtZXN0bmFub3N0aSBwb2TEvmEgc2VrdG9yb3YgKHBvxL5ub2hvc3BvZMOhcnN0dm8sIHByaWVteXNlbCwgc2x1xb5ieSkgYSDDunJvdsWIb3UgaHJ1YsOpaG8gZG9tw6FjZWhvIHByb2R1a3R1IG5hIG9ieXZhdGXEvmEgKEdEUCkuCgpQcmFjdWplbWUgcyDDumRham1pIHphIHJvayAqKjIwMDMqKi4gCgpDaWXEvm9tIGplIHppc3RpxaUsIGt0b3LDqSB6IGRvc3R1cG7DvWNoIGVrb25vbWlja8O9Y2ggdWthem92YXRlxL5vdiBuYWp2aWFjIHZ5c3ZldMS+dWrDuiByb3pkaWVseSB2IG1pZXJlIG5lemFtZXN0bmFub3N0aSBtZWR6aSBrcmFqaW5hbWkuCgpgYGB7cn0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBQUklQUkFWQSBVREFKT1YKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKdWRhamUgPC0gcmVhZC5jc3YoIkVtcGxveW1lbnRfVW5lbXBsb3ltZW50X0dEUF9kYXRhLmNzdiIsZGVjPSIuIixzZXA9IiwiLGhlYWRlciA9IFRSVUUpCiMgc2VsZWN0IGp1c3QgdGhlIHJlY29yZCBmcm9tIDIwMDMKdWRhamUuMjAwMyA8LSB1ZGFqZVt1ZGFqZSRZZWFyPT0yMDAzLGMoIlVuZW1wbG95bWVudC5SYXRlIiwiRW1wbG95bWVudC5TZWN0b3IuLkFncmljdWx0dXJlIiwiR0RQLi5pbi5VU0QuIiwgIkVtcGxveW1lbnQuU2VjdG9yLi5JbmR1c3RyeSIsIkVtcGxveW1lbnQuU2VjdG9yLi5TZXJ2aWNlcyIgKV0KCiMgZGF0YSBpbXB1dGF0aW9uCgojIENvbXB1dGUgY29sdW1uIG1lZGlhbnMKI2NvbHVtbl9tZWRpYW5zIDwtIHNhcHBseSh1ZGFqZS4yMDAzLCBtZWRpYW4sIG5hLnJtID0gVFJVRSkKCiMgSW1wdXRlIG1pc3NpbmcgdmFsdWVzIHdpdGggY29sdW1uIG1lZGlhbnMKIyBDb21wdXRlIGNvbHVtbiBtZWRpYW5zCmNvbHVtbl9tZWRpYW5zIDwtIHNhcHBseSh1ZGFqZS4yMDAzLCBtZWRpYW4sIG5hLnJtID0gVFJVRSkKCiMgSW1wdXRlIG1pc3NpbmcgdmFsdWVzIHdpdGggY29sdW1uIG1lZGlhbnMKdWRhamVfaW1wdXRlZCA8LSB1ZGFqZS4yMDAzCmZvciAoY29sIGluIG5hbWVzKHVkYWplLjIwMDMpKSB7CiAgdWRhamVfaW1wdXRlZFtbY29sXV1baXMubmEodWRhamVfaW1wdXRlZFtbY29sXV0pXSA8LSBjb2x1bW5fbWVkaWFuc1tjb2xdCn0KCnVkYWplLjIwMDMgPC0gdWRhamVfaW1wdXRlZAp1ZGFqZSA8LSB1ZGFqZS4yMDAzCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFpBS0xBRE5BIFJFR1JFU0lBCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCmF0dGFjaCh1ZGFqZSkKbW9kZWwgPC0gbG0oVW5lbXBsb3ltZW50LlJhdGUgfiAKICAgICAgICAgICAgICBFbXBsb3ltZW50LlNlY3Rvci4uQWdyaWN1bHR1cmUgKwogICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5JbmR1c3RyeSArCiAgICAgICAgICAgICAgRW1wbG95bWVudC5TZWN0b3IuLlNlcnZpY2VzICsKICAgICAgICAgICAgICBHRFAuLmluLlVTRC4sCiAgICAgICAgICAgIGRhdGEgPSB1ZGFqZSkKc3VtbWFyeShtb2RlbCkKYGBgCgoKVGVzdHVqZW1lLCDEjWkgamUgbsOhxaEgcmVncmVzbsO9IG1vZGVsIHZob2RuZSDFoXBlY2lmaWtvdmFuw70sIMSNaSBsaW5lw6FybmEgZnVua8SNbsOhIGZvcm1hIHBvc3RhxI11amUsIGFsZWJvIMSNaSBieSBzbWUgbWFsaSB1dmHFvm92YcWlIG8gdHJhbnNmb3Jtw6FjacOhY2ggcHJlbWVubsO9Y2ggKG5hcHIuIGxvZ2FyaXRteSwgbW9jbmlueSkuIAoKIyMjIDEuIFJhbXNleSBSRVNFVCB0ZXN0CgpNecWhbGllbmthIHRlc3R1IGplIGplZG5vZHVjaMOhOiAgCkFrIGplIHDDtHZvZG7DvSBtb2RlbCBzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70sIHByaWRhbmllIG1vY27DrW4gcHJlZGlrb3ZhbsO9Y2ggaG9kbsO0dCAoXChcaGF0e3l9XjJcKSwgXChcaGF0e3l9XjNcKSkgYnkgbW9kZWwgKipuZW1hbG8qKiB2w716bmFtbmUgemxlcMWhacWlLgoKVGVzdG92YW7DqSBoeXBvdMOpenk6CgpcWyBIXzA6IFx0ZXh0e01vZGVsIGplIHNwcsOhdm5lIMWhcGVjaWZpa292YW7DvX0gXF0KClxbIEhfMTogXHRleHR7TW9kZWwgamUgbmVzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw719XF0KCkFrIHAtaG9kbm90YSA8IDAuMDUg4oaSIG1vZGVsIGplIHByYXZkZXBvZG9ibmUgemxlIMWhcGVjaWZpa292YW7DvS4KCiMjIyBWw71wb8SNZXQgUkVTRVQgdGVzdHUgOgpgYGB7cn0KIyBTdXBwb3NlIHlvdXIgbW9kZWwgaXM6Cm1vZGVsIDwtIGxtKFVuZW1wbG95bWVudC5SYXRlIH4gRW1wbG95bWVudC5TZWN0b3IuLkFncmljdWx0dXJlICsgRW1wbG95bWVudC5TZWN0b3IuLkluZHVzdHJ5ICsgRW1wbG95bWVudC5TZWN0b3IuLlNlcnZpY2VzICsgR0RQLi5pbi5VU0QuLCBkYXRhID0gdWRhamUpCgojIFJFU0VUIHRlc3QgZnJvbSAnbG10ZXN0JyBwYWNrYWdlOgpsaWJyYXJ5KGxtdGVzdCkKcmVzZXR0ZXN0KG1vZGVsKQpgYGAKCgojIyMgSW50ZXJwcmV0w6FjaWEKCktlxI/FvmUgcC1ob2Rub3RhIGplICoqbmnFvsWhaWEgYWtvIDAuMDUqKiwgemFtaWV0YW1lIG51bG92w7ogaHlwb3TDqXp1IG8gc3Byw6F2bmVqIGZ1bmvEjW5laiBmb3JtZS4gIApUbyB6bmFtZW7DoSwgxb5lICoqbsOhxaEgbW9kZWwgamUgbmVzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70qKi4gCk1vZGVsIHByYXZkZXBvZG9ibmUgcG90cmVidWplIG5lbGluZcOhcm51IHRyYW5zZm9ybcOhY2l1IHByZW1lbm7DvWNoIChuYXByLiBsb2cgR0RQLCBrdmFkcmF0aWNrw6kgxI1sZW55KSwgKiphbGVibyoqIG11IGNow71iYWrDuiBuaWVrdG9yw6kgdnlzdmV0xL51asO6Y2UgcHJlbWVubsOpLCBrdG9yw6kgYnkgbGVwxaFpZSB2eXN2ZXRsaWxpIG1pZXJ1IG5lemFtZXN0bmFub3N0aS4KClbDvXNsZWRvayBSRVNFVCB0ZXN0dSB0ZWRhIG5hem5hxI11amUsIMW+ZSBqZWRub2R1Y2jDoSBsaW5lw6FybmEgxaFwZWNpZmlrw6FjaWEgbmVtdXPDrSBiecWlIHByZSB0aWV0byBkw6F0YSBwb3N0YcSNdWrDumNhLgoKCiMjIyAyLiBHcmFmaWNrw6EgYW5hbMO9emEgZnVua8SNbmVqIGZvcm15CgojIyMjIEdyYWYgKlJlc2lkdWFscyB2cy4gRml0dGVkKgoKUHJ2w71tIGtyb2tvbSBqZSB2aXp1w6FsbmEga29udHJvbGEgbGluZcOhcm5laiDFoXBlY2lmaWvDoWNpZSBwb21vY291IGdyYWZ1IHJlesOtZHXDrSB2b8SNaSB2eXJvdm5hbsO9bSBob2Rub3TDoW0uIFRlbnRvIGdyYWYgbsOhbSBwb23DoWhhIG9kaGFsacWlIG5lbGluZcOhcm5lIHZ6xaVhaHkgYWxlYm8gaW7DqSBwcm9ibMOpbXkgcyBtb2RlbG9tLgoKYGBge3J9CmNhcjo6Y3JQbG90cyhtb2RlbCkKCmBgYAoKIyMjIEludGVycHJldMOhY2lhIEMrUiBncmFmb3YKCkNvbXBvbmVudCArIFJlc2lkdWFsIGdyYWZ5IHVrYXp1asO6LCDEjWkgbcOhIGthxb5kw6EgdnlzdmV0xL51asO6Y2EgcHJlbWVubsOhIGxpbmXDoXJueSB2esWlYWggc28gesOhdmlzbG91IHByZW1lbm5vdSAoVW5lbXBsb3ltZW50LlJhdGUpLgoKLSAqKkVtcGxveW1lbnQuU2VjdG9yLi5BZ3JpY3VsdHVyZSoqIOKAkyBrcml2a2Ega29ww61ydWplIHByaWFta3UsxI1pxb5lIHZ6xaVhaCBqZSBwcmlibGnFvm5lIGxpbmXDoXJueS4gIAotICoqRW1wbG95bWVudC5TZWN0b3IuLkluZHVzdHJ5Kiog4oCTIHNpdHXDoWNpYSBqZSByb3ZuYWvDoSwgxb5pYWRuZSB2w71yYXpuw6kgemFrcml2ZW5pZSwgdGFrxb5lIGxpbmXDoXJuYSDFoXBlY2lmaWvDoWNpYSBqZSBwcmF2ZGVwb2RvYm5lIHBvc3RhxI11asO6Y2EuICAKLSAqKkVtcGxveW1lbnQuU2VjdG9yLi5TZXJ2aWNlcyoqIOKAkyB0YWt0aWXFviBwcmFrdGlja3kgbGluZcOhcm55IHZ6xaVhaCBiZXogb2RjaMO9bG9rLiAgCgojIyMjICBOYWp2w6TEjcWhw60gcHJvYmzDqW0g4oCTICoqR0RQLi5pbi5VU0QuKioKCi0gUHJpIHByZW1lbm5laiAqKkdEUC4uaW4uVVNELioqIGplIHZpZGllxaUgKipzaWxuw6kgemFrcml2ZW5pZSoqLgotIEJvZHkgc8O6IGV4dHLDqW1uZSB6aHVzdGVuw6kgcHJpIHZlxL5taSBuw616a3ljaCBob2Rub3TDoWNoIEdEUCBhIHJvesWlYWhhbsOpIHByaSB2ecWhxaHDrWNoIGhvZG5vdMOhY2guICAKLSBUbyB6bmFtZW7DoSwgxb5lICoqdnrFpWFoIG1lZHppIEdEUCBhIG5lemFtZXN0bmFub3PFpW91IE5JRSBKRSBsaW5lw6FybnkqKiwgYSBsaW5lw6FybnkgbW9kZWwgdG8gbmV2aWUgc3Byw6F2bmUgemFjaHl0acWlLgpNYWxpIGJ5IHNtZSBwcsOhdmUgdMO6dG8gcHJlbWVubsO6ICAqKnRyYW5zZm9ybW92YcWlKiogLgoKVG90byBqZSB2IHPDumxhZGUgYWogcyBSRVNFVCB0ZXN0b20sIGt0b3LDvSB1a8OhemFsLCDFvmUgbGluZcOhcm5hIMWhcGVjaWZpa8OhY2lhIG1vZGVsdSBqZSBjaHlibsOhLgoKIyMgMy4gUG9yb3ZuYW5pZSB6w6FrbGFkbsOpaG8gYSBtb2RpZmlrb3ZhbsOpaG8gbW9kZWx1CgpCdWRlbWUgcG9yb3Zuw6F2YcWlOgoKLSAqKlrDoWtsYWRuw70gbGluZcOhcm55IG1vZGVsKioKLSAqKk1vZGVsIGRvcGxuZW7DvSBvIGt2YWRyYXRpY2vDvSDEjWxlbiBwcmVtZW5uZWogR0RQKio6ICAKICBcWyBJKEdEUF4yKVxdCgpDaWXEvm9tIGplIHppc3RpxaUsIMSNaSBwcmlkYW7DrW0ga3ZhZHJhdGlja8OpaG8gxI1sZW5hOgoKLSBzdMO6cG5lIHVwcmF2ZW7DvSBrb2VmaWNpZW50IGRldGVybWluw6FjaWUgXChSXjJfe2Fkan1cKSwKLSBtb2RlbCBidWRlIMWhdGF0aXN0aWNreSBsZXDFocOtIHBvZMS+YSBBTk9WQSB0ZXN0dSwKLSBSRVNFVCB0ZXN0IHByZXN0YW5lIHNpZ25hbGl6b3ZhxaUgY2h5Ym7DuiDFoXBlY2lmaWvDoWNpdS4KCmBgYHtyfQojIHrDoWtsYWRuw70gbW9kZWwKbW9kZWxfbGluZWFyIDwtIGxtKFVuZW1wbG95bWVudC5SYXRlIH4gCiAgICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5BZ3JpY3VsdHVyZSArCiAgICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5JbmR1c3RyeSArCiAgICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5TZXJ2aWNlcyArCiAgICAgICAgICAgICAgICAgICAgIEdEUC4uaW4uVVNELiwKICAgICAgICAgICAgICAgICAgIGRhdGEgPSB1ZGFqZSkKCiMgbW9kZWwgcyBrdmFkcsOhdG9tIEdEUAptb2RlbF9nZHBfcXVhZCA8LSBsbShVbmVtcGxveW1lbnQuUmF0ZSB+IAogICAgICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5BZ3JpY3VsdHVyZSArCiAgICAgICAgICAgICAgICAgICAgICAgRW1wbG95bWVudC5TZWN0b3IuLkluZHVzdHJ5ICsKICAgICAgICAgICAgICAgICAgICAgICBFbXBsb3ltZW50LlNlY3Rvci4uU2VydmljZXMgKwogICAgICAgICAgICAgICAgICAgICAgIEdEUC4uaW4uVVNELiArCiAgICAgICAgICAgICAgICAgICAgICAgSShHRFAuLmluLlVTRC5eMiksCiAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWxfZ2RwX3F1YWQpCgojIHBvcm92bmFuaWUgbW9kZWxvdgphbm92YShtb2RlbF9saW5lYXIsIG1vZGVsX2dkcF9xdWFkKQoKIyBSRVNFVCB0ZXN0IG5hIG1vZGlmaWtvdmFuw70gbW9kZWwKcmVzZXR0ZXN0KG1vZGVsX2dkcF9xdWFkKQoKYGBgCgojIyMgVsO9c2xlZGt5IG1vZGlmaWtvdmFuw6lobyBtb2RlbHUgcyBrdmFkcsOhdG9tIEdEUAoKUG8gcHJpZGFuw60ga3ZhZHJhdGlja8OpaG8gxI1sZW5hIHByZW1lbm5laiAqKkdEUC4uaW4uVVNELioqIGRvc3TDoXZhbWUgbmFzbGVkb3Zuw6kgdsO9c2xlZGt5OgoKLSBLb2VmaWNpZW50IHByaSBwcmVtZW5laiAqKkdEUCoqIGplIMWhdGF0aXN0aWNreSB2w716bmFtbsO9IChwID0gMC4wMTk5KS4KLSBLb2VmaWNpZW50IHByaSAqKkkoR0RQwrIpKiogamUgbmEgaHJhbmljaSB2w716bmFtbm9zdGkgKHAgPSAwLjA2NDIpLCDEjW8gbmF6bmHEjXVqZSBtb8W+bsO9IG5lbGluZcOhcm55IHZ6xaVhaC4KLSBVcHJhdmVuw70ga29lZmljaWVudCBkZXRlcm1pbsOhY2llIHZ6csOhc3RvbCB6ICoqMC4wNzU5KiogbmEgKiowLjA4ODYqKiwgdGVkYSBtb2RlbCBzYSBtaWVybmUgemxlcMWhaWwuCgojIyMgQU5PVkEgdGVzdAoKUG9yb3ZuYW5pZSBww7R2b2Ruw6lobyBhIGt2YWRyYXRpY2vDqWhvIG1vZGVsdToKCi0gcC1ob2Rub3RhID0gKiowLjA2NDIyKiosIHRlZGEgbmEgw7pyb3ZuaSAxMCAlIGplIHpsZXDFoWVuaWUgbW9kZWx1IMWhdGF0aXN0aWNreSB2w716bmFtbsOpLgotIFRvIHBvZHBvcnVqZSBtecWhbGllbmt1LCDFvmUgcHJpZGFuaWUgbmVsaW5lw6FybmVobyBwcnZrdSAoR0RQwrIpIG3DoSB6bXlzZWwuCgojIyMgUkVTRVQgdGVzdCBwcmUgbW9kaWZpa292YW7DvSBtb2RlbAoKLSBwLWhvZG5vdGEgPSAqKjAuMDUxODkqKgotIFRvdG8gamUgdGVzbmUgbmFkIGhyYW5pY291IDAuMDUg4oaSICoqdcW+IG5lemFtaWV0YW1lIGh5cG90w6l6dSBvIHNwcsOhdm5laiDFoXBlY2lmaWvDoWNpaSoqLgoKLSBNb2RlbCB0ZXJheiBsZXDFoWllIHphY2h5dMOhdmEgbmVsaW5lw6FybnkgdnrFpWFoIG1lZHppIEdEUCBhIG5lemFtZXN0bmFub3PFpW91LgoKCiMjIDQuIFJvesWhw61yZW7DvSBSRVNFVCB0ZXN0IGEgw7pwbG7DvSBrdmFkcmF0aWNrw70gbW9kZWwKCmBgYHtyfQptb2RlbF9yb3pzaXJlbnkgPC0gbG0oVW5lbXBsb3ltZW50LlJhdGUgfiBFbXBsb3ltZW50LlNlY3Rvci4uQWdyaWN1bHR1cmUgKyBFbXBsb3ltZW50LlNlY3Rvci4uSW5kdXN0cnkgKyBFbXBsb3ltZW50LlNlY3Rvci4uU2VydmljZXMgKyBHRFAuLmluLlVTRC4gKyBJKEVtcGxveW1lbnQuU2VjdG9yLi5BZ3JpY3VsdHVyZV4yKSArIEkoRW1wbG95bWVudC5TZWN0b3IuLkluZHVzdHJ5XjIpICsgSShFbXBsb3ltZW50LlNlY3Rvci4uU2VydmljZXNeMikgKyBJKEdEUC4uaW4uVVNELl4yKSwgZGF0YSA9IHVkYWplKQoKc3VtbWFyeShtb2RlbF9yb3pzaXJlbnkpCgpgYGAKYGBge3J9CmFub3ZhKG1vZGVsLG1vZGVsX3JvenNpcmVueSkKcmVzZXR0ZXN0KG1vZGVsX3JvenNpcmVueSkKYGBgCgojIyMgQU5PVkEgcG9yb3ZuYW5pZSB6w6FrbGFkbsOpaG8gYSBwbG5lIGt2YWRyYXRpY2vDqWhvIG1vZGVsdQoKQU5PVkEgdGVzdCBwb3Jvdm7DoXZhIHDDtHZvZG7DvSBsaW5lw6FybnkgbW9kZWwgcyByb3rFocOtcmVuw71tIG1vZGVsb20gb2JzYWh1asO6Y2ltIHbFoWV0a3kga3ZhZHJhdGlja8OpIMSNbGVueS4gVsO9c2xlZGt5IHPDujoKCi0gcC1ob2Rub3RhID0gKiowLjAwNzEwMioqICAKLSBGID0gKiozLjY0MDQqKgoKS2XEj8W+ZSBwLWhvZG5vdGEgamUgKip2w71yYXpuZSBuacW+xaFpYSBha28gMC4wNSoqLCByb3rFocOtcmVuw70ga3ZhZHJhdGlja8O9IG1vZGVsIGplICoqxaF0YXRpc3RpY2t5IGxlcMWhw60qKiBha28gcMO0dm9kbsO9IGxpbmXDoXJueSBtb2RlbC4gIApQcmlkYW5pZSBrdmFkcmF0aWNrw71jaCDEjWxlbm92IHRlZGEgdsO9cmF6bmUgemxlcMWhaWxvIHZ5c3ZldMS+b3ZhY2l1IHNjaG9wbm9zxaUgbW9kZWx1LgoKIyMjIFJFU0VUIHRlc3QgcHJlIHJvesWhw61yZW7DvSBtb2RlbAoKVsO9c2xlZG9rOgoKLSBwLWhvZG5vdGEgPSAqKjAuMDAwMjAzNCoqCi0gUkVTRVQgPSAqKjguOTM3MSoqCgpUZW50byB2w71zbGVkb2sgamUgdmXEvm1pIGTDtGxlxb5pdMO9OgoKLSBwLWhvZG5vdGEgPCAwLjAwMSDihpIgKiptb2RlbCBqZSBzdMOhbGUgbmVzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70qKgotIGFuaSBwcmlkYW5pZSB2xaFldGvDvWNoIGt2YWRyYXRpY2vDvWNoIMSNbGVub3YgKipuZW9kc3Ryw6FuaWxvIMWhcGVjaWZpa2HEjW7DuiBjaHlidSoqCsSMacW+ZSBhaiBrZcSPIEFOT1ZBIHVrYXp1amUsIMW+ZSBrdmFkcmF0aWNrw6kgxI1sZW55IHByaW5pZXNsaSDFoXRhdGlzdGlja8OpIHpsZXDFoWVuaWUsIFJFU0VUIHRlc3Qgb2RoYcS+dWplLCDFvmUgYW5pIHJvesWhw61yZW7DoSBuZWxpbmXDoXJuYSDFoXBlY2lmaWvDoWNpYSAqKm5ldnlyaWXFoWlsYSBwcm9ibMOpbSDFoXBlY2lmaWvDoWNpZSBtb2RlbHUqKi4gVGFrxb5lIGplIHYgbW9kZWxpLCBidcSPICBzdMOhbGUgY2jDvWJhIGTDtGxlxb5pdMOhIHByZW1lbm7DoSwgIAogIGFsZWJvIHRyZWJhIHBvdcW+acWlIGluw7ogdHJhbnNmb3Jtw6FjaXUsIGFsZWJvIHZ6xaVhaHkgbWVkemkgcHJlbWVubsO9bWkgc8O6IHpsb8W+aXRlasWhaWUgbmXFviBrdmFkcmF0aWNrw6kuCgojIyA1LiBUcmFuc2Zvcm3DoWNpYSBwb21vY291IGR1bW15IHByZW1lbm5laiBhIGxpbmXDoXJuZWogbG9tZW5laiBmdW5rY2llCgoKWiBwcmVkY2jDoWR6YWrDumNpY2ggZ3JhZm92IHZpZMOtbWUsIMW+ZSBwcmVtZW5uw6EgR0RQIHNhIG5lc3Byw6F2YSDDunBsbmUgbGluZcOhcm5lLiBQcmV0byBza8O6c2ltZSBkw6F0YSByb3pkZWxpxaUgbmEgZHZlIHNrdXBpbnkg4oCTIGtyYWppbnkgcyBuacW+xaHDrW0gR0RQIGEga3JhamlueSBzIHZ5xaHFocOtbSBHRFAg4oCTIGEgcG96cmllbWUgc2EsIMSNaSBzYSBzcHLDoXZhbmllIG1vZGVsdSBtZWR6aSBuaW1pIGzDrcWhaS4KCk5hIHRvIHZ5dHZvcsOtbWUgamVkbm9kdWNow7ogKipkdW1teSBwcmVtZW5uw7ogKERVTSkqKiwga3RvcsOhIGplOgoKLSAwID0ga3JhamlueSBzIG5pxb7FocOtbSBHRFAgIAotIDEgPSBrcmFqaW55IHMgdnnFocWhw61tIEdEUCAgCgpDaWXEvm9tIGplIHppc3RpxaUsIMSNaSBzYSBwcmUgdGlldG8gZHZlIHNrdXBpbnkga3JhasOtbiBtZW7DrToKLSBidcSPIGNlbGtvdsOhIMO6cm92ZcWIIG5lemFtZXN0bmFub3N0aSAocG9zdW4gbW9kZWx1KSwKLSBhbGVibyBzYW1vdG7DvSB2esWlYWggbWVkemkgR0RQIGEgbmV6YW1lc3RuYW5vc8Wlb3UgKHRlZGEgc2tsb24pLgoKTmFqc2vDtHIgdnl0dm9yw61tZSB0w7p0byBEVU0gcHJlbWVubsO6OgoKVGFrdG8gcm96ZGVsw61tZSBrcmFqaW55IG5hIGR2ZSBza3VwaW55OgotICoqa3JhamlueSBzIG5pxb7FocOtbSBHRFAqKiwgIAotICoqa3JhamlueSBzIHZ5xaHFocOtbSBHRFAqKi4KClYgxI9hbMWhb20ga3Jva3Ugb2RoYWRuZW1lOgoxLiBtb2RlbCBzbyB6bG9tb20gdiBhdXRvbsOzbW5vbSDEjWxlbmUsCjIuIG1vZGVsIHNvIHpsb21vbSB2IHNrbG9uZS4KCk5hanBydiB2eXR2b3LDrW1lIGR1bW15IHByZW1lbm7DuiBEVU06CgpgYGB7cn0KIyBkdW1teSBwb2TEvmEgbWVkacOhbnUgR0RQCnRocmVzaG9sZCA8LSBtZWRpYW4odWRhamUkR0RQLi5pbi5VU0QuKQp1ZGFqZSREVU0gPC0gaWZlbHNlKHVkYWplJEdEUC4uaW4uVVNELiA8IHRocmVzaG9sZCwgMCwgMSkKCnRhYmxlKHVkYWplJERVTSkKCmBgYAoKIyMjIDUuMSBNb2RlbCBzbyB6bG9tb20gdiBhdXRvbsOzbW5vbSDEjWxlbmUKClRlcmF6IG90ZXN0dWplbWUsIMSNaSBzYSBtb2RlbCDigJ5wb3PDunZh4oCcIG5haG9yIGFsZWJvIG5hZG9sIHByZSBrcmFqaW55IHMgdnnFocWhw61tIEdEUC4gIApUZWRhIMSNaSBrcmFqaW55IHMgdnlzb2vDvW0gR0RQIG1hasO6IHYgcHJpZW1lcmUgaW7DuiDDunJvdmXFiCBuZXphbWVzdG5hbm9zdGkgYWtvIGtyYWppbnkgcyBuw616a3ltIEdEUC4KCk9kaGFkbmVtZSBtb2RlbCwga2RlIHByaWTDoW1lIGR1bW15IHByZW1lbm7DuiBEVU0gYWtvIHNhbW9zdGF0bsO9IHZ5c3ZldMS+dWrDumNpIGZha3RvcjoKCmBgYHtyfQptb2RlbERfYXV0byA8LSBsbShVbmVtcGxveW1lbnQuUmF0ZSB+IERVTSArCiAgICAgICAgICAgICAgICAgICAgRW1wbG95bWVudC5TZWN0b3IuLkFncmljdWx0dXJlICsKICAgICAgICAgICAgICAgICAgICBFbXBsb3ltZW50LlNlY3Rvci4uSW5kdXN0cnkgKwogICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5TZXJ2aWNlcyArCiAgICAgICAgICAgICAgICAgICAgR0RQLi5pbi5VU0QuLAogICAgICAgICAgICAgICAgICBkYXRhID0gdWRhamUpCgpzdW1tYXJ5KG1vZGVsRF9hdXRvKQoKYGBgCgojIyMgVsO9c2xlZG9rIG1vZGVsdSBzbyB6bG9tb20gdiBhdXRvbsOzbW5vbSDEjWxlbmUKCkRvIG1vZGVsdSBzbWUgcHJpZGFsaSBkdW1tIHByZW1lbm7DuiBEVU0sIGt0b3LDoSByb3pkZcS+dWplIGtyYWppbnkgbmEgdGllIHMgbmnFvsWhw61tIGEgdnnFocWhw61tIEdEUC4gQ2llxL5vbSBib2xvIHppc3RpxaUsIMSNaSBzYSBtb2RlbCBwcmkga3Jhamluw6FjaCBzIHZ5xaHFocOtbSBHRFAg4oCecG9zw7p2YeKAnCBuYWhvciBhbGVibyBuYWRvbC4KClbDvXNsZWRreSB1a2F6dWrDuiwgxb5lIGtvZWZpY2llbnQgcHJpIERVTSBqZSAqKnbDvXpuYW1uw70qKiAocCA8IDAuMDAxKS4gIApUbyB6bmFtZW7DoSwgxb5lIGtyYWppbnkgcyB2ecWhxaHDrW0gR0RQIG1hasO6ICoqdiBwcmllbWVyZSBpbsO6IMO6cm92ZcWIIG5lemFtZXN0bmFub3N0aSoqIGFrbyBrcmFqaW55IHMgbmnFvsWhw61tIEdEUC4KCktvbmtyw6l0bmU6Ci0ga29lZmljaWVudCBEVU0gPSDigJMzLjc4ICAK4oaSIGtyYWppbnkgcyB2ecWhxaHDrW0gR0RQIG1hasO6IHByaWJsacW+bmUgKipvIDMuOCBwZXJjZW50dcOhbG5laG8gYm9kdSBuacW+xaFpdSBuZXphbWVzdG5hbm9zxaUqKi4KCk9zdGF0bsOpIHByZW1lbm7DqSBzYSB0YWttZXIgbmV6bWVuaWxpIGEgbmllIHPDuiB2w716bmFtbsOpLgoKWmF2ZWRlbmllIERVTU0gc3DDtHNvYsOtIGliYSBwb3N1biBtb2RlbHUsIGFsZSBuZW1lbsOtIHR2YXIgdnrFpWFodSBtZWR6aSBwcmVtZW5uw71taS4gVGVudG8ga3JvayBzw61jZSB6bGVwxaFpbCBtb2RlbCwgYWxlIHByb2Jsw6ltIGxpbmXDoXJuZWogxaFwZWNpZmlrw6FjaWUgc3TDoWxlIHByZXRydsOhdmEuCgoKIyMjIDYuMiBNb2RlbCBzbyB6bG9tb20gdiBza2xvbmUKClYgcHJlZGNow6FkemFqw7pjb20ga3Jva3Ugc21lIHppc3RpbGksIMW+ZSBrcmFqaW55IHMgdnnFocWhw61tIEdEUCBtYWrDuiBpbsO9IOKAnnBvc3Vu4oCcIHYgbW9kZWxpLiAgClRlcmF6IG90ZXN0dWplbWUsIMSNaSBzYSBwcmkgdMO9Y2h0byBrcmFqaW7DoWNoIG1lbsOtIGFqICoqc2tsb24qKiwgdGVkYSBzYW1vdG7DvSB2esWlYWggbWVkemkgR0RQIGEgbmV6YW1lc3RuYW5vc8Wlb3UuCgpOYSB0byBwb3XFvmlqZW1lIGludGVyYWvEjW7DvSDEjWxlbjogIApcW0RVTSAqIEdEUFxdCgpUw71tIHZsYXN0bmUgaG92b3LDrW1lOiDigJ52esWlYWggbWVkemkgR0RQIGEgbmV6YW1lc3RuYW5vc8Wlb3UgbcO0xb5lIGJ5xaUgaW7DvSBwcmUgb2JlIHNrdXBpbnkga3JhasOtbi7igJwKCgpgYGB7cn0KbW9kZWxEX3NrbG9uIDwtIGxtKFVuZW1wbG95bWVudC5SYXRlIH4gCiAgICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5BZ3JpY3VsdHVyZSArCiAgICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5JbmR1c3RyeSArCiAgICAgICAgICAgICAgICAgICAgIEVtcGxveW1lbnQuU2VjdG9yLi5TZXJ2aWNlcyArCiAgICAgICAgICAgICAgICAgICAgIEdEUC4uaW4uVVNELiArCiAgICAgICAgICAgICAgICAgICAgIEkoRFVNICogR0RQLi5pbi5VU0QuKSwKICAgICAgICAgICAgICAgICAgIGRhdGEgPSB1ZGFqZSkKCnN1bW1hcnkobW9kZWxEX3NrbG9uKQoKYGBgCiMjIyBWw71zbGVkb2sgbW9kZWx1IHNvIHpsb21vbSB2IHNrbG9uZQoKViB0b210byBtb2RlbGkgc21lIHNrw7rFoWFsaSwgxI1pIHNhIHZ6xaVhaCBtZWR6aSBHRFAgYSBuZXphbWVzdG5hbm9zxaVvdSBtZW7DrSBwcmUga3JhamlueSBzIHZ5xaHFocOtbSBhIG5pxb7FocOtbSBHRFAuIFRvIHppc8WldWplbWUgcG9tb2NvdSBpbnRlcmFrY2llIGBEVU0gKiBHRFBgLgoKWiB2w71zbGVka292IHZpZMOtbWUsIMW+ZToKCi0ga29lZmljaWVudCBwcmkgcHJlbWVubmVqICoqR0RQKiogbmllIGplIHbDvXpuYW1uw70gKHAgPSAwLjIwMSkKLSBrb2VmaWNpZW50IHByaSAqKkRVTSAqIEdEUCoqIHRpZcW+IG5pZSBqZSB2w716bmFtbsO9IChwID0gMC4xOTkpCgpUbyB6bmFtZW7DoSwgxb5lICoqc2tsb24gc2EgbmVtZW7DrSoqLiAgCkluw71taSBzbG92YW1pOiBuZXphbWVzdG5hbm9zxaUgcmVhZ3VqZSBuYSBHRFAgdmXEvm1pIHBvZG9ibmUgdiBvYm9jaCBza3VwaW7DoWNoIGtyYWrDrW4gKHRlZGEgdiBrcmFqaW7DoWNoIHMgbmnFvsWhw61tIGFqIHZ5xaHFocOtbSBHRFApLgoKVGVudG8gbW9kZWwgdGVkYSBuZXByaW5pZXNvbCB6bGVwxaFlbmllIGEgbmV6YWNoeXRpbCDFvmlhZG55IHpsb20gdiBza2xvbmUuCgpgYGB7cn0KYW5vdmEobW9kZWxfbGluZWFyLCBtb2RlbERfc2tsb24pCnJlc2V0dGVzdChtb2RlbERfc2tsb24pCgpgYGAKIyMjIFBvcm92bmFuaWUgbW9kZWx1IHNvIHpsb21vbSB2IHNrbG9uZSAoQU5PVkEpCgpBTk9WQSBwb3Jvdm7DoXZhIHDDtHZvZG7DvSBtb2RlbCBzIG1vZGVsb20sIGtkZSBzbWUgcHJpZGFsaSBpbnRlcmFrY2l1IGBEVU0gKiBHRFBgLgoKVsO9c2xlZG9rOgoKLSBwLWhvZG5vdGEgPSAqKjAuMTk5NCoqICAKLSBGID0gKioxLjY1OTYqKgoKS2XEj8W+ZSBwLWhvZG5vdGEgamUgKip2w6TEjcWhaWEgYWtvIDAuMDUqKiwgbm92w70gbW9kZWwgKipuaWUgamUgxaF0YXRpc3RpY2t5IGxlcMWhw60qKiBha28gcMO0dm9kbsO9LiAgClRvIHpuYW1lbsOhLCDFvmUgcHJpZGFuaWUgaW50ZXJha2NpZSAodGVkYSB6bG9tIHYgc2tsb25lKSBtb2RlbCBuaWpha28gbmV6bGVwxaFpbG8uCgotLS0KCiMjIyBSRVNFVCB0ZXN0IHByZSBtb2RlbCBzbyB6bG9tb20gdiBza2xvbmUKCi0gcC1ob2Rub3RhID0gKiowLjA0MTE2KioKCktlxI/FvmUgcC1ob2Rub3RhIGplICoqbmnFvsWhaWEgYWtvIDAuMDUqKiwgUkVTRVQgdGVzdCBuw6FtIGhvdm9yw60sIMW+ZSBtb2RlbCAqKnN0w6FsZSBuaWUgamUgc3Byw6F2bmUgxaFwZWNpZmlrb3ZhbsO9KiogKG3DoSBjaHlidSB2byBmdW5rxI1uZWogZm9ybWUpLgoKCi0gWmxvbSB2IHNrbG9uZSAqKm5lZXhpc3R1amUqKiAoaW50ZXJha2NpYSBuaWUgamUgdsO9em5hbW7DoSwgbW9kZWwgc2EgbmV6bGVwxaFpbCkuICAKLSBNb2RlbCBzbyB6bG9tb20gdiBza2xvbmUgKipuZXZ5cmllxaFpbCBwcm9ibMOpbSDFoXBlY2lmaWvDoWNpZSoqIChSRVNFVCBqZSBzdMOhbGUgdsO9em5hbW7DvSkuICAKLSBUZW50byBtb2RlbCB0ZWRhICoqbmllIGplIHZob2Ruw70qKiBhIG5lYnVkZW1lIGhvIMSPYWxlaiBwb3XFvsOtdmHFpS4KCgojIyBMb2dhcml0bWlja8OhIHRyYW5zZm9ybcOhY2lhCgpLZcSPxb5lIHNhIG7DocWhIG1vZGVsIHN0w6FsZSBqYXbDrSBha28gbmVzcHLDoXZuZSDFoXBlY2lmaWtvdmFuw70gKFJFU0VUIHRlc3QgdG8gcG90dnJkaWwpLCBza8O6xaFhbWUgbmFqYmXFvm5lasWhaXUgYSBuYWpqZWRub2R1Y2jFoWl1IHRyYW5zZm9ybcOhY2l1IOKAkyBsb2dhcml0bXVzLiAgCkxvZ2FyaXRtdXMgcG9tw6FoYSBobGF2bmUgdnRlZHksIGtlxI8gamUgdnrFpWFoIG1lZHppIHByZW1lbm7DvW1pIHpha3JpdmVuw70gYWxlYm8gcsO9Y2hsbyByYXN0aWUsIMSNbyBib2wgbsOhxaEgcHLDrXBhZCBwcmkgR0RQLgoKUHJldG8gbmFocmFkw61tZSBwcmVtZW5uw7ogR0RQIGxvZ2FyaXRtb20geiBHRFAuCgpgYGB7cn0KdWRhamUkbG9nR0RQIDwtIGxvZyh1ZGFqZSRHRFAuLmluLlVTRC4pCgptb2RlbF9sb2cgPC0gbG0oVW5lbXBsb3ltZW50LlJhdGUgfiAKICAgICAgICAgICAgICAgICAgRW1wbG95bWVudC5TZWN0b3IuLkFncmljdWx0dXJlICsKICAgICAgICAgICAgICAgICAgRW1wbG95bWVudC5TZWN0b3IuLkluZHVzdHJ5ICsKICAgICAgICAgICAgICAgICAgRW1wbG95bWVudC5TZWN0b3IuLlNlcnZpY2VzICsKICAgICAgICAgICAgICAgICAgbG9nR0RQLAogICAgICAgICAgICAgICAgZGF0YSA9IHVkYWplKQoKc3VtbWFyeShtb2RlbF9sb2cpCgojIFJFU0VUIHRlc3QgcHJlIGxvZ2FyaXRtaWNrw70gbW9kZWwKcmVzZXR0ZXN0KG1vZGVsX2xvZykKCmBgYAoKYGBge3J9CmFub3ZhKG1vZGVsX2xpbmVhciwgbW9kZWxfbG9nKQpyZXNldHRlc3QobW9kZWxfbG9nKQoKYGBgCgojIyBMb2dhcml0bWlja8OhIHRyYW5zZm9ybcOhY2lhIChsb2dHRFApCgpLZcSPIHNtZSB2eW1lbmlsaSBwcmVtZW5uw7ogR0RQIHphIGplaiBsb2dhcml0bXVzIChsb2dHRFApLCBtb2RlbCBzYSBjaXRlxL5uZSB6bGVwxaFpbC4KCiMjIyBBTk9WQSB0ZXN0CkFOT1ZBIHBvcm92bsOhdmEgcMO0dm9kbsO9IGxpbmXDoXJueSBtb2RlbCBzIG1vZGVsb20sIGt0b3LDvSBwb3XFvsOtdmEgbG9nR0RQLgoKVsO9c2xlZG9rOgotIHJlemlkdcOhbG55IHPDusSNZXQgxaF0dm9yY292IChSU1MpIHNhIHpuw63FvmlsIHogKio2NzE3LjMqKiBuYSAqKjYxOTIuOCoqCi0gcm96ZGllbCBqZSAqKjUyNC40MioqLCDEjW8gem5hbWVuw6EsIMW+ZSBsb2dhcml0bWlja8O9IG1vZGVsIG9waXN1amUgZMOhdGEgbGVwxaFpZQoKQWoga2XEjyBBTk9WQSBuZXVrYXp1amUga2xhc2lja8O6IHAtaG9kbm90dSAobGVibyBtb2RlbCBtw6Egcm92bmFrw70gcG/EjWV0IHN0dXDFiG92IHZvxL5ub3N0aSksIHpuw63FvmVuaWUgUlNTIGplIGphc27DqSB6bGVwxaFlbmllLgoKIyMjIFJFU0VUIHRlc3QKLSBwLWhvZG5vdGEgPSAqKjAuNTUzMSoqCi0gdG8gem5hbWVuw6EsIMW+ZSAqKm1vZGVsIGplIHNwcsOhdm5lIMWhcGVjaWZpa292YW7DvSoqICAKICAoxb5pYWRuYSBjaHliYSBmdW5rxI1uZWogZm9ybXkpCiAgClRha8W+ZSBtb2RlbCBzIGxvZ0dEUCBqZSBkb3RlcmF6IG5hamxlcMWhw606Ci0gbcOhIG5ham5pxb7FocOtIFJTUywKLSBtw6EgbmFqdnnFocWhw60gdXByYXZlbsO9IFLCsiwKLSB2xaFldGtvIGplIMWhdGF0aXN0aWNreSB2IHBvcmlhZGt1LAotIGEgYWtvIGplZGluw70gcHJlxaFpZWwgUkVTRVQgdGVzdG9tIGJleiBwcm9ibMOpbW92LgoKViDEj2FsxaFlaiBhbmFsw716ZSBidWRlbWUgcHJhY292YcWlIHMgKipsb2dhcml0bWlja8O9bSBtb2RlbG9tKiouCgoKCiMjIDcuIEJveC1Db3hvdiB0cmFuc2Zvcm1hxI1uw70gdGVzdCAobGVuIGRvcGxua292w6kpCgpQcmUgaXN0b3R1IHNhIHBvenJpZW1lIGFqIG5hIEJveOKAk0NveCB0ZXN0LCBrdG9yw70gdWthenVqZSwgxI1pIGJ5IHNtZSBtYWxpIHRyYW5zZm9ybW92YcWlIHNhbW90bsO6IHrDoXZpc2zDuiBwcmVtZW5uw7ogKFVuZW1wbG95bWVudC5SYXRlKS4gVGVzdCBoxL5hZMOhIHRha8O6IGhvZG5vdHUgzrssIGt0b3LDoSBkw6EgbW9kZWx1IG5hamxlcMWhw60gdHZhci4KClbDvXpuYW0gzrs6Ci0gzrsg4omIIDEg4oaSIG5ldHJlYmEgdHJhbnNmb3Jtb3ZhxaUsCi0gzrsg4omIIDAg4oaSIGxvZ2FyaXRtdXMsCi0gzrsg4omIIDAuNSDihpIgb2Rtb2NuaW5hLAotIM67IOKJiCAtMSDihpIgMS9ZLCBhdMSPLgoKYGBge3J9CmxpYnJhcnkoTUFTUykKYm94Y294KG1vZGVsX2xvZykgICAjIHBvdcW+w612YW1lIG1vZGVsIHMgbG9nR0RQLCBwcmV0b8W+ZSB0byBqZSBuw6HFoSBuYWpsZXDFocOtIG1vZGVsCgpgYGAKCgpCb3gtQ294b3YgZ3JhZiBuw6FtIHVrYXp1amUsIGFrw6EgdHJhbnNmb3Jtw6FjaWEgYnkgYm9sYSBuYWpsZXDFoWlhIHByZSB6w6F2aXNsw7ogcHJlbWVubsO6IChVbmVtcGxveW1lbnQuUmF0ZSkuCgpWIG5hxaFvbSBncmFmZSB2aWTDrW1lLCDFvmUgbWF4aW11bSBrcml2a3kgamUgcHJpIGhvZG5vdGUgKirOuyBwcmlibGnFvm5lIG9rb2xvIDAqKi4gIApUbyB6bmFtZW7DoSwgxb5lIG5hanZob2RuZWrFoWlhIHRyYW5zZm9ybcOhY2lhIGJ5IGJvbGEgKipsb2dhcml0bXVzKiosIHRlZGEgbG9nKFkpLgoKVG8gamUgYWxlIGTDtGxlxb5pdMOpOiAgCm15IHXFviBsb2dhcml0bXVzIHBvdcW+w612YW1lIOKAkyBhbGUgbmllIG5hIFksIGFsZSBuYSBHRFAsIMSNbyBuw6FtIGFrbyBqZWRpbsOpIG9wcmF2aWxvIGNoeWJuw7ogxaFwZWNpZmlrw6FjaXUuCgpQcmV0byBCb3gtQ294IHBvdHZyZHp1amUsIMW+ZSAqKm5lamFrw6EgbG9nYXJpdG1pY2vDoSDDunByYXZhIHYgbW9kZWxpIGplIHBvdHJlYm7DoSoqLCBhbGUgbmVtdXPDrW1lIHRyYW5zZm9ybW92YcWlIHNhbW90bsO6IG5lemFtZXN0bmFub3PFpSAodG8gYnkgemhvcsWhaWxvIGludGVycHJldMOhY2l1KS4KCkxvZ0dEUCBtb2RlbCBqZSB1xb4gdGVyYXo6Ci0gc3Byw6F2bmUgxaFwZWNpZmlrb3ZhbsO9LAotIG5hamxlcMWhw60gcG9kxL5hIHbFoWV0a8O9Y2ggdGVzdG92LAotIGEgZMOhdmEgem15c2VsIGFqIGVrb25vbWlja3kuCgpQcmV0byBCb3gtQ294IGJlcmllbWUgbGVuIGFrbyBkb3BsbmtvdsO6IGtvbnRyb2x1IGEgKirEj2FsxaFpdSB0cmFuc2Zvcm3DoWNpdSB1xb4gcm9iacWlIG5ldHJlYmEqKi4KCgoKCgoKCg==