Úvod

Cieľom analýzy je preskúmať, či rozšírenie elektromobility v krajinách V4 súvisí s kvalitou životného prostredia meranou indexom environmentálnej výkonnosti (EPI). Pracujem s prečisteným panelovým datasetom z mojej bakalárskej práce (krajiny V4 × roky).

Charakteristika dát

  • Zdroj a pokrytie: Vlastný dataset zostavený pre BP (krajiny V4 × roky).
  • Hlavné premenné: EPI (zložený index kvality životného prostredia), BEV (počet batériových EV), BEV_PHEV (BEV + plug‑in hybridy), HDP na obyvateľa.
  • Stav dát: Dáta boli prečistené pred týmto cvičením; v tomto dokumente už neriešime imputačné či čistiace kroky.

Premenné

Závislá premenná: EPI – zložený index environmentálnej výkonnosti krajín.

Kľúčové vysvetľujúce premenné: BEV – počet batériových elektromobilov; BEV_PHEV – súčet BEV a plug-in hybridov (PHEV).

Kontrolné premenné: HDP na obyvateľa (ekonomická úroveň); podľa dostupnosti aj ďalšie sprievodné ukazovatele (CO₂, investičné/rozvojové indikátory).

Výskumná otázka a hypotézy

Súvisí vyšší počet (P)HEV s vyšším EPI, po zohľadnení ekonomickej úrovne krajín?

  • H0: Počet BEV/BEV_PHEV nemá významný vplyv na EPI.
  • H1: Vyšší BEV/BEV_PHEV je spojený s vyšším EPI.

Metodika v skratke

Používam lineárne modely OLS s log‑transformáciou počtových premenných (log1p), aby sa stabilizovala variancia a tlmili sa extrémy. Aby som sa vyhla kolinearite, odhadujem model s BEV a model s BEV_PHEV oddelene; HDP figuruje ako kontrola úrovne rozvoja. Diagnostiku robím cez štandardné grafy (Q–Q, Scale–Location, Leverage) a formálne testy (Breusch–Pagan). Inferenciu reportujem s robustnými SE (HC1), prípadne klastrovanými podľa krajiny pri panelových špecifikáciách.

Import údajov z mojej bakalárskej práce

Načítam csv súbor s dátami o elektromobilite vo V4 (počet BEV, BEV_PHEV, EPI, HDP, emisie CO₂, investičné ukazovatele…). Dáta sú už prečistené.

Interaktívna tabuľka s dátami

Prieskumné grafy - BOXPLOT

Prečo: pred modelovaním overujem, či mierky a rozdelenia dávajú zmysel a či nie sú viditeľné extrémy. Počtové premenné (BEV, BEV_PHEV) vizualizujem v log‑mierke (log1p).

par(mfrow = c(2, 2))
boxplot(udaje$EPI,                main = "EPI (bez log)",    col = "darkgreen",  horizontal = TRUE)
boxplot(log1p(udaje$BEV),         main = "log1p(BEV)",       col = "lightblue", horizontal = TRUE)
boxplot(log1p(udaje$BEV_PHEV),    main = "log1p(BEV_PHEV)",  col = "darkgreen",  horizontal = TRUE)
boxplot(log1p(udaje$HDP),         main = "log1p(HDP)",       col = "lightblue", horizontal = TRUE)
par(mfrow = c(1, 1))

Boxplot zobrazuje rozdelenie premennej – hrubá čiara v strede je medián, „krabička“ (box) je IQR (od 1. po 3. kvartil), „fúzy“ ukazujú typický rozsah a bodky mimo sú odľahlé hodnoty. V našich grafoch je EPI sústredené okolo ~70 s jedným nižším outlierom; po log-transformácii sú log1p(BEV) a log1p(BEV_PHEV) pekne stabilné a symetrické (bez dlhých chvostov) a log1p(HDP) má veľmi úzky rozsah – bude slúžiť najmä ako kontrola úrovne rozvoja.

Lineárna regresia (dve alternatívy)

Motivácia výberu špecifikácie: EPI je zložený index a elektromobilita môže byť korelovaná s celkovou vyspelosťou krajiny. Preto zahrniem HDP ako kontrolu. Keďže BEV a BEV_PHEV spolu silno súvisia, odhadujem ich oddelené modely, aby som predišla kolinearite. Koeficienty interpretujem ako semi‑elasticity: zmena v log1p(x) približne zodpovedá percentuálnej zmene počtu vozidiel.

Metóda A (Model A: EPI ~ log1p(BEV) + log1p(HDP)) Overuje, či samotné batériové elektromobily (BEV) súvisia s EPI po zohľadnení ekonomickej úrovne (HDP). Teda: keď dve krajiny majú rovnaký HDP, má vyšší počet BEV (v % zmenách – vďaka log1p) spojený vyšší/nižší EPI?

Metóda B (Model B: EPI ~ log1p(BEV_PHEV) + log1p(HDP)) Overuje vzťah medzi EPI a celkovým rozšírením (P)HEV (BEV + plug-in hybridy), opäť pri rovnakej úrovni HDP. Tento model hovorí, čo spraví spoločný“ (P)HEV indikátor s EPI.

Aby som sa vyhla kolinearite, odhadujem dve špecifikácie zvlášť:

# Model A: EPI ~ log1p(BEV) + log1p(HDP)
m_bev  <- lm(EPI ~ log1p(BEV)      + log1p(HDP), data = udaje)

# Model B: EPI ~ log1p(BEV_PHEV) + log1p(HDP)
m_phev <- lm(EPI ~ log1p(BEV_PHEV) + log1p(HDP), data = udaje)

summary(m_bev)

Call:
lm(formula = EPI ~ log1p(BEV) + log1p(HDP), data = udaje)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.1351  -4.4467  -0.8368   4.9316  15.2734 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -16.7362    36.6646  -0.456  0.65016    
log1p(BEV)   -3.6278     0.6707  -5.409 2.09e-06 ***
log1p(HDP)   11.6591     4.0185   2.901  0.00564 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.358 on 47 degrees of freedom
Multiple R-squared:  0.3839,    Adjusted R-squared:  0.3577 
F-statistic: 14.64 on 2 and 47 DF,  p-value: 1.14e-05
summary(m_phev)

Call:
lm(formula = EPI ~ log1p(BEV_PHEV) + log1p(HDP), data = udaje)

Residuals:
    Min      1Q  Median      3Q     Max 
-15.005  -4.389  -1.012   4.244  14.395 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)     -24.7863    35.9496  -0.689  0.49392    
log1p(BEV_PHEV)  -3.8147     0.6564  -5.811 5.19e-07 ***
log1p(HDP)       12.8282     3.9667   3.234  0.00224 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.149 on 47 degrees of freedom
Multiple R-squared:  0.4184,    Adjusted R-squared:  0.3936 
F-statistic:  16.9 on 2 and 47 DF,  p-value: 2.947e-06
# Robustné SE (HC1)
coeftest(m_bev,  vcov = vcovHC(m_bev,  type = "HC1"))

t test of coefficients:

             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -16.73620   37.34531 -0.4481 0.656106    
log1p(BEV)   -3.62776    0.76151 -4.7639 1.86e-05 ***
log1p(HDP)   11.65906    4.11228  2.8352 0.006733 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
coeftest(m_phev, vcov = vcovHC(m_phev, type = "HC1"))

t test of coefficients:

                 Estimate Std. Error t value  Pr(>|t|)    
(Intercept)     -24.78627   37.46093 -0.6617  0.511422    
log1p(BEV_PHEV)  -3.81473    0.77914 -4.8961 1.194e-05 ***
log1p(HDP)       12.82820    4.15931  3.0842  0.003413 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# Porovnanie kvality
aic_tbl <- AIC(m_bev, m_phev)
aic_tbl

# Zvolený model na diagnostiku
model <- m_phev

Z lineárnych regresií vychádza, že HDP na obyvateľa má na EPI pozitívny a štatisticky významný vplyv, kým počet (P)HEV (a podobne aj samotných BEV) je záporný a významný po zohľadnení HDP; model s BEV_PHEV sedí mierne lepšie (nižšie AIC) a závery sa nemenia ani pri robustných smerodajných chybách. Modely vysvetľujú zhruba 38–42 % variability EPI.

# ak m_lin ešte neexistuje, použijem lineárny model s (P)HEV
if (!exists("m_lin")) m_lin <- m_phev
# 1) Skontrolujeme a prípadne opravíme názov stĺpca EPI
if (!"EPI" %in% names(udaje)) {
  col_epi <- grep("^EPI\\b", names(udaje), value = TRUE)[1]
  if (!is.na(col_epi)) names(udaje)[names(udaje) == col_epi] <- "EPI"
}

# 2) Vyberieme model, z ktorého chceme predikovať
mod <- m_lin   # <- prípadne zmeň na: m_phev, m_slope, m_quad, ...

# 3) Predikčná krivka: EPI ~ BEV_PHEV pri mediáne HDP
pdat <- data.frame(
  BEV_PHEV = seq(min(udaje$BEV_PHEV, na.rm = TRUE),
                 max(udaje$BEV_PHEV, na.rm = TRUE),
                 length.out = 200),
  HDP = median(udaje$HDP, na.rm = TRUE)
)

pr <- predict(mod, newdata = pdat, se.fit = TRUE)
pdat$yhat <- pr$fit
pdat$lo   <- pr$fit - 1.96 * pr$se.fit
pdat$hi   <- pr$fit + 1.96 * pr$se.fit

library(ggplot2)
ggplot(pdat, aes(x = BEV_PHEV, y = yhat)) +
  geom_ribbon(aes(ymin = lo, ymax = hi), alpha = 0.2) +
  geom_line() +
  labs(x = "BEV_PHEV", y = "Predikované EPI",
       title = "EPI vs. (P)HEV (pri mediáne HDP)") +
  theme_minimal()

Graf ukazuje predikovaný EPI v závislosti od počtu (P)HEV pri fixovanom (mediánovom) HDP z nášho semi-log modelu. Krivka má zreteľne klesajúci a splošťujúci sa tvar: pri nízkych hodnotách (P)HEV je pokles EPI strmší, no s rastúcim (P)HEV sa účinok zmierňuje (diminishing returns), čo je typické pre špecifikáciu s log⁡(1+(P)HEV. Šedé pásmo vyznačuje 95 % interval predikcie a smerom k vyšším hodnotám sa rozširuje, teda neistota rastie (v tých oblastiach máme menej pozorovaní alebo väčší rozptyl). Celkovo graf vizuálne potvrdzuje negatívnu asociáciu medzi rozšírením (P)HEV a EPI v našich dátach po zohľadnení HDP; ide o asociáciu, nie dôkaz kauzality.

Diagnostika (krajšie grafy)

Residuals vs Fitted

– ukazuje, či model nechýba tvar (nelinearita) a či sú chyby rovnomerne okolo nuly. Hľadáme „náhodný mrak“ bez vzoru.

Normal Q–Q

– porovnáva rozdelenie rezíduí s ideálnou normálnou krivkou; body pri priamke = približná normalita, odchýlky v chvostoch signalizujú extrémy.

Scale–Location (√|štandardizované rezíduá| vs. fitted)

– test rovnakého rozptylu chýb (homoskedasticita). Rovná LOESS krivka ≈ konštantný rozptyl; stúpajúci/lievik = heteroskedasticita.

Residuals vs Leverage

– identifikuje vplyvné pozorovania: kombinácia veľkého „leverage“ (hat hodnoty) a veľkých rezíduí. Pomáha rozhodnúť, či niekoľko bodov neťahá regresnú priamku (podľa Cookovej vzdialenosti).

clr <- "#0E6B4D"

# diagnostický dataframe 
diag_df <- augment(model) %>% mutate(id = dplyr::row_number())

cook_cut <- 4 / nrow(diag_df)
lab_df   <- dplyr::filter(diag_df, .cooksd > cook_cut)

p1 <- ggplot(diag_df, aes(.fitted, .resid)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey60") +
  geom_point(alpha = .75, color = clr) +
  geom_smooth(method = "loess", se = FALSE, color = clr) +
  labs(title = "Residuals vs Fitted", x = "Fitted values", y = "Residuals") +
  theme_minimal(base_size = 12) + theme(plot.title = element_text(face = "bold"))

p2 <- ggplot(diag_df, aes(sample = .std.resid)) +
  stat_qq(color = clr, alpha = .9) +
  stat_qq_line(color = "grey45") +
  labs(title = "Normal Q–Q", x = "Theoretical Quantiles", y = "Standardized residuals") +
  theme_minimal(base_size = 12) + theme(plot.title = element_text(face = "bold"))

p3 <- ggplot(diag_df, aes(.fitted, sqrt(abs(.std.resid)))) +
  geom_point(alpha = .75, color = clr) +
  geom_smooth(method = "loess", se = FALSE, color = clr) +
  labs(title = "Scale–Location", x = "Fitted values",
       y = expression(sqrt("|Standardized residuals|"))) +
  theme_minimal(base_size = 12) + theme(plot.title = element_text(face = "bold"))

p4 <- ggplot(diag_df, aes(.hat, .std.resid)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey60") +
  geom_point(alpha = .75, color = clr) +
  geom_smooth(method = "loess", se = FALSE, color = clr) +
  geom_text(data = lab_df, aes(label = id), vjust = -0.5, size = 3) +
  labs(title = "Residuals vs Leverage", x = "Hat values", y = "Standardized residuals") +
  theme_minimal(base_size = 12) + theme(plot.title = element_text(face = "bold"))

(p1 + p2) / (p3 + p4)

Diagnostika – čítanie grafov:

  • Residuals vs Fitted: jemná nelinearita a mierne kolísanie rozptylu.
  • Q–Q: drobné odchýlky v chvostoch → približná normalita.
  • Scale–Location: slabá heteroskedasticita → použijem robustné SE.
  • Residuals vs Leverage: zopár vplyvných bodov (označené ID), ale bez extrémov.

Keď zohľadníme HDP, viac (P)HEV sa v našich dátach spája s nižším EPI. Kontrolné grafy neukázali vážne problémy a drobné odchýlky sme pokryli robustnými chybami, takže výsledok berieme ako spoľahlivý.

Vplyvné pozorovania

influencePlot(model, main = "Influence plot")

outlierTest(model)  # Bonferroni p-value
No Studentized residuals with Bonferroni p < 0.05
Largest |rstudent|:

Krátke čítanie grafu a tabuľky:

Influence plot (bubble chart)

-X-os (Hat-values) = „páka“ (leverage): ak je bod viac vpravo, má neštandardnú kombináciu vysvetľujúcich premenných a vie viac strhnúť priamku.

-Y-os (Studentized residuals) = veľkosť chyby: nad +2 alebo pod −2 je podozrivé.

-Veľkosť/odtieň bubliny = Cookovo D: čím väčšia a tmavšia bublina, tým väčší vplyv jednotky na odhad celého modelu.

Graf vplyvu ukazuje niekoľko pozorovaní s vyššou „pákou“ a vplyvom (najmä body 31, 41 a 20), no zostávajú v rozumných medziach; Cookovo D nie je extrémne a hodnoty študentizovaných rezíduí sa pohybujú okolo hraníc ±2. Formálny outlierTest pritom nenašiel žiadny štatisticky významný odľahlý bod po Bonferroni korekcii (najväčší |rstudent| má bod 20 ≈ −2.30, neopravené p ~ 0.026, po korekcii nevýznamné). Inými slovami: v dátach sú jednotky, ktoré majú citeľnejší vplyv na odhad, ale nemáme dôkaz o skutočných outlieroch # Dodatočné porovnanie modelov

# Model A: EPI ~ log1p(BEV) + HDP (bez log na HDP – ako kontrola úrovne)
m_bev2  <- lm(EPI ~ log1p(BEV)      + HDP, data = udaje)
# Model B: EPI ~ log1p(BEV_PHEV) + HDP
m_phev2 <- lm(EPI ~ log1p(BEV_PHEV) + HDP, data = udaje)
summary(m_bev2); coeftest(m_bev2, vcov = vcovHC(m_bev2, type = "HC1"))

Call:
lm(formula = EPI ~ log1p(BEV) + HDP, data = udaje)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.0909  -4.1711  -0.7445   5.2535  14.7114 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 86.8956784  4.7398188  18.333  < 2e-16 ***
log1p(BEV)  -3.5939951  0.6665698  -5.392 2.21e-06 ***
HDP          0.0005466  0.0001900   2.877  0.00603 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.367 on 47 degrees of freedom
Multiple R-squared:  0.3823,    Adjusted R-squared:  0.356 
F-statistic: 14.54 on 2 and 47 DF,  p-value: 1.211e-05


t test of coefficients:

               Estimate  Std. Error t value  Pr(>|t|)    
(Intercept) 86.89567837  5.43343513 15.9928 < 2.2e-16 ***
log1p(BEV)  -3.59399513  0.75667089 -4.7497  1.95e-05 ***
HDP          0.00054656  0.00019420  2.8144  0.007115 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
summary(m_phev2); coeftest(m_phev2, vcov = vcovHC(m_phev2, type = "HC1"))

Call:
lm(formula = EPI ~ log1p(BEV_PHEV) + HDP, data = udaje)

Residuals:
     Min       1Q   Median       3Q      Max 
-14.8667  -4.2839  -0.6805   4.3720  13.7936 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)     89.2739287  4.7887883  18.642  < 2e-16 ***
log1p(BEV_PHEV) -3.8005552  0.6530506  -5.820 5.04e-07 ***
HDP              0.0006089  0.0001877   3.243  0.00218 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.145 on 47 degrees of freedom
Multiple R-squared:  0.419, Adjusted R-squared:  0.3942 
F-statistic: 16.94 on 2 and 47 DF,  p-value: 2.877e-06


t test of coefficients:

                   Estimate  Std. Error t value  Pr(>|t|)    
(Intercept)     89.27392868  5.80102043 15.3893 < 2.2e-16 ***
log1p(BEV_PHEV) -3.80055516  0.78549751 -4.8384  1.45e-05 ***
HDP              0.00060888  0.00019776  3.0789  0.003464 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
AIC(m_bev2, m_phev2)

Po zohľadnení HDP vychádza negatívna asociácia EPI s (P)HEV aj s BEV; mierne lepšie sedí špecifikácia s BEV_PHEV.

Oneskorený vplyv (lag 1 rok) s fixnými efektmi

Prečo lag: zmeny v zložení vozového parku a budovaní infraštruktúry sa nemusia okamžite premietnuť do EPI. Jednoročný lag BEV_PHEV s fixnými efektmi krajín a rokov zachytáva nepozorovanú heterogenitu a spoločné šoky.

udaje_lag <- udaje %>%
  arrange(Krajina, Rok) %>%
  group_by(Krajina) %>%
  mutate(lag_BEV_PHEV = dplyr::lag(BEV_PHEV, 1)) %>%
  ungroup()

m_lag <- lm(EPI ~ log1p(lag_BEV_PHEV) + HDP + factor(Krajina) + factor(Rok), data = udaje_lag)
coeftest(m_lag, vcov = vcovCL(m_lag, cluster = ~ Krajina, type = "HC1"))

t test of coefficients:

                          Estimate  Std. Error t value  Pr(>|t|)    
(Intercept)             50.8959137  65.0340670  0.7826 0.4399939    
log1p(lag_BEV_PHEV)     -2.0425584   1.5285689 -1.3363 0.1915136    
HDP                      0.0020646   0.0038335  0.5386 0.5941504    
factor(Krajina)EU-avrg -20.6979705  37.5633150 -0.5510 0.5857037    
factor(Krajina)MR        9.5261676  25.1708980  0.3785 0.7077543    
factor(Krajina)PL        7.3166762  26.7654445  0.2734 0.7864475    
factor(Krajina)SK        4.1908401  12.0927337  0.3466 0.7313421    
factor(Rok)2016          9.5399727   2.4016859  3.9722 0.0004121 ***
factor(Rok)2017         -1.4413973   3.0279243 -0.4760 0.6374981    
factor(Rok)2018         -8.1105733   5.3325433 -1.5210 0.1387416    
factor(Rok)2019        -10.1512429   6.6783228 -1.5200 0.1389742    
factor(Rok)2020         -7.7457174   3.0950422 -2.5026 0.0180056 *  
factor(Rok)2021        -15.1063011   6.3794152 -2.3680 0.0245284 *  
factor(Rok)2022        -18.9950331   7.2001178 -2.6382 0.0130861 *  
factor(Rok)2023         -6.9375471   8.2719932 -0.8387 0.4082826    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Aj keď sa pozrieme na oneskorený (1-ročný) efekt a zafixujeme rozdiely medzi krajinami a rokmi, nevidíme štatistický dôkaz, že viac (P)HEV zlepší EPI—koeficient je síce negatívny, ale nevýznamný. Pre našu prácu to znamená, že hlavný záver zostáva rovnaký: po zohľadnení HDP (a pri FE) sa v dostupných dátach V4 nepotvrdzuje krátkodobý pozitívny vplyv rozšírenia (P)HEV na EPI. Model teda skôr hovorí, že EPI formujú aj iné, širšie faktory než samotná elektromobilita

Štandardizované koeficienty

Zmysel: po štandardizácii viem porovnať veľkosť efektov naprieč rozdielnymi mierkami (SD jednotky).

m_std <- lm(scale(EPI) ~ scale(log1p(BEV_PHEV)) + scale(HDP), data = udaje)
summary(m_std)

Call:
lm(formula = scale(EPI) ~ scale(log1p(BEV_PHEV)) + scale(HDP), 
    data = udaje)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.61936 -0.46663 -0.07412  0.47622  1.50247 

Coefficients:
                         Estimate Std. Error t value Pr(>|t|)    
(Intercept)             4.914e-16  1.101e-01   0.000  1.00000    
scale(log1p(BEV_PHEV)) -7.921e-01  1.361e-01  -5.820 5.04e-07 ***
scale(HDP)              4.414e-01  1.361e-01   3.243  0.00218 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.7783 on 47 degrees of freedom
Multiple R-squared:  0.419, Adjusted R-squared:  0.3942 
F-statistic: 16.94 on 2 and 47 DF,  p-value: 2.877e-06

Po štandardizácii vychádza, že log1p(BEV_PHEV) má silnejší vplyv na EPI a je negatívny (~−0.79 SD za +1 SD v (P)HEV), kým HDP je pozitívne (~+0.44 SD za +1 SD v HDP); oba efekty sú štatisticky významné. Intercept je ~0 (lebo premenné sú centrované) a model vysvetľuje ~42 % variability EPI. Inými slovami: v našich dátach sa zmeny v (P)HEV spájajú s väčším (negatívnym) posunom EPI než rovnako veľké zmeny v HDP s pozitívnym smerom.

Heteroskedasticita – testy a grafy

Heteroskedasticita = rozptyl chýb nie je všade rovnaký. Ak by bola výrazná, bežné p-hodnoty môžu byť skreslené. Nižšie ju rýchlo overím (grafy + testy) a zohľadním cez robustné štandardné chyby (HC1).

Vizuálna diagnostika

library(broom); library(ggplot2); library(patchwork); clr <- "#0E6B4D"

h <- augment(model, data = udaje) |>
  dplyr::mutate(
    absres = sqrt(abs(.std.resid)),
    res2   = .resid^2,
    x_bev  = log1p(.data$BEV_PHEV),  # ak používame BEV: log1p(.data$BEV)
    x_hdp  = .data$HDP
  )

p_SL <- ggplot(h, aes(.fitted, absres)) +
  geom_point(alpha=.65) +
  geom_smooth(method="loess", se=FALSE, linewidth=1, color=clr) +
  labs(x="Predikované hodnoty", y=expression(sqrt("|rezíduá|")), title="Scale–Location") +
  theme_minimal()

p_bev <- ggplot(h, aes(x_bev, res2)) +
  geom_point(alpha=.65) +
  geom_smooth(method="loess", se=FALSE, linewidth=1, color=clr) +
  labs(x="log1p(BEV_PHEV)", y="rezíduá^2", title="Rezíduá^2 vs. log1p(BEV_PHEV)") +
  theme_minimal()

p_hdp <- ggplot(h, aes(x_hdp, res2)) +
  geom_point(alpha=.65) +
  geom_smooth(method="loess", se=FALSE, linewidth=1, color=clr) +
  labs(x="HDP", y="rezíduá^2", title="Rezíduá^2 vs. HDP") +
  theme_minimal()

p_SL / (p_bev | p_hdp)

LOESS krivka v Scale–Location má jemné „U“ – rozptyl rezíduí je najmenší pri stredných predikciách a väčší na okrajoch, takže ide o miernu heteroskedasticitu. Vo vzťahu rezíduá² vs. log1p(BEV_PHEV) je U-tvar len plytký, čiže s (P)HEV súvisí rozptyl skôr slabo. Naopak, graf rezíduá² vs. HDP ukazuje výraznejší U-tvar: variancia je najnižšia pri stredných hodnotách HDP a rastie pri nízkych aj vysokých, čo naznačuje, že prípadná heteroskedasticita je viazaná najmä na HDP. Celkovo nejde o silné porušenie, ale je rozumné používať robustné štandardné chyby (HC1); nižšie to ešte overíme formálnymi testami.

library(ggplot2)
library(patchwork)   

# model, ktorý chceme diagnostikovať

mod   <- m_phev     # EPI ~ log1p(BEV_PHEV) + log1p(HDP)
dta   <- udaje

# vypočítam rezíduá a pripravím log premennú pre BEV_PHEV (aby sedela s modelom)

dta$resid2   <- resid(mod)^2
dta$logBEVP  <- log1p(dta$BEV_PHEV)

# 1) Rezíduá^2 vs. log1p(BEV_PHEV)

p_bev <- ggplot(dta, aes(x = logBEVP, y = resid2)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "firebrick") +
labs(x = "log1p(BEV_PHEV)", y = "Štvorce rezíduí",
title = "Rezíduá^2 vs. log1p(BEV_PHEV)") +
theme_minimal()

# 2) Rezíduá^2 vs. HDP  (pozor: v modeli je log(HDP) – tu úmyselne dávame aj „raw“ HDP,

# aby bolo jasne vidno, či problém súvisí s úrovňou bohatstva)

p_hdp <- ggplot(dta, aes(x = HDP, y = resid2)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "firebrick") +
labs(x = "HDP na obyvateľa", y = "Štvorce rezíduí",
title = "Rezíduá^2 vs. HDP") +
theme_minimal()

p_bev | p_hdp

Z týchto dvoch grafov vidno, že veľkosť chýb (štvorce rezíduí) nie je všade rovnaká. Červená LOESS krivka má v oboch prípadoch tvar jemného „U“ – rozptyl rezíduí je najmenší v strede a väčší pri veľmi nízkych aj veľmi vysokých hodnotách. Efekt je zreteľnejší pri HDP, čo naznačuje, že nerovnaký rozptyl chýb súvisí skôr s úrovňou bohatstva krajín než s počtom (P)HEV. Nie je to extrémny „lievik“, ale ide o miernu heteroskedasticitu.

Heteroskedasticita - prehľad testov

library(lmtest); library(car); library(dplyr); library(knitr)

bp_fitted <- bptest(model)
bp_white  <- bptest(model, ~ fitted(model) + I(fitted(model)^2))
ncv       <- ncvTest(model)

tribble(
  ~Test,               ~Statistic,                   ~p_value,
  "Breusch–Pagan",     unname(bp_fitted$statistic),  bp_fitted$p.value,
  "BP (White štýl)",   unname(bp_white$statistic),   bp_white$p.value,
  "NCV (car)",         unname(ncv$ChiSquare),        ncv$p
) |>
  mutate(across(c(Statistic, p_value), ~round(.x, 4))) |>
  kable(caption = "Heteroskedasticita – prehľad testov")
Heteroskedasticita – prehľad testov
Test Statistic p_value
Breusch–Pagan 0.4876 0.7836
BP (White štýl) 5.6585 0.0591
NCV (car) 0.0032 0.9545

Formálne testy

  • Breusch–Pagan: p = 0,784 (nevýznamné).

  • White-štýl: p = 0,059 (hraničný náznak U-tvaru vo variancii).

  • NCV (car): p = 0,955 (nevýznamné).

Rozhodnutie: Testy nedávajú silný dôkaz heteroskedasticity; vzhľadom na jemný vzor v grafoch je primerané reportovať robustné štandardné chyby (HC1). Kvalitatívne závery modelu sa tým nemenia.

Nelineárne špecifikácie a testy funkčnej formy

Prečo toto robíme? Doteraz sme predpokladali, že vzťah medzi EPI a vysvetľujúcimi premennými (log1p(BEV_PHEV), log1p(HDP)) je lineárny. Nižšie skontrolujeme, či obyčajná „priamka“ naozaj stačí – a ak nie, pridáme jemné zakrivenie (kvadráty) alebo zlom v sklone (iný efekt pri vyšších hodnotách (P)HEV).

Zjednodušene: RESET test: rýchla kontrola, či priamka stačí. Malá p-hodnota ⇒ pridať nelineárne prvky. C+R grafy: ukážu, kde sa krivka ohýba – ktorú premennú transformovať. Kvadráty log-premenných: dovolia jemné zakrivenie. Zlom v sklone: dovolí iný vplyv (P)HEV pri nižších vs. vyšších hodnotách. Výber modelu: porovnáme AIC a (ak sú modely v tej istej mierke) aj ANOVA; koeficienty vždy s robustnými SE (HC1).

1) Ramsey RESET – kontrola špecifikácie

library(lmtest)

# Základný (lineárny) model – používame ten, s ktorým pracuješ v práci:

m_lin <- lm(EPI ~ log1p(BEV_PHEV) + log1p(HDP), data = udaje)

# Ramsey RESET test

resettest(m_lin)

    RESET test

data:  m_lin
RESET = 4.9787, df1 = 2, df2 = 45, p-value = 0.01114

RESET vyšiel p = 0.011 → základná lineárna špecifikácia pravdepodobne chýba (nelinearita/nezahrnutý tvar). Preto ďalej cielene hľadáme kde by sa mohla krivka ohýbať a či sa oplatí pridať kvadráty alebo zlom.

2) Component + Residual (C+R) grafy – kde sa krivka ohýba

library(car)
car::crPlots(m_lin)   # pozrieme zakrivenie pri log1p(BEV_PHEV) a log1p(HDP)

C+R pre log1p(BEV_PHEV) ukazuje citeľné prehnutie okolo ~7–9 → kandidát na nelineárny tvar. C+R pre log1p(HDP) je prakticky priamka (len jemná krivka), takže výraznu nelinearitu pri HDP nečakáme. Z toho dôvodu testujeme hlavne úpravy pri (P)HEV.

3) Kvadratické členy – jemné zakrivenie

library(sandwich)
library(lmtest)

m_quad <- lm(EPI ~ log1p(BEV_PHEV) + I(log1p(BEV_PHEV)^2) +
log1p(HDP)      + I(log1p(HDP)^2),
data = udaje)

# Porovnanie kvality (nižší AIC je lepší)

AIC(m_lin, m_quad)

# ANOVA:

anova(m_lin, m_quad)
Analysis of Variance Table

Model 1: EPI ~ log1p(BEV_PHEV) + log1p(HDP)
Model 2: EPI ~ log1p(BEV_PHEV) + I(log1p(BEV_PHEV)^2) + log1p(HDP) + I(log1p(HDP)^2)
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     47 2402.1                           
2     45 2286.6  2    115.48 1.1363 0.3301
# Koeficienty s robustnými SE (HC1)

coeftest(m_lin,  vcov = vcovHC(m_lin,  type = "HC1"))

t test of coefficients:

                 Estimate Std. Error t value  Pr(>|t|)    
(Intercept)     -24.78627   37.46093 -0.6617  0.511422    
log1p(BEV_PHEV)  -3.81473    0.77914 -4.8961 1.194e-05 ***
log1p(HDP)       12.82820    4.15931  3.0842  0.003413 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
coeftest(m_quad, vcov = vcovHC(m_quad, type = "HC1"))

t test of coefficients:

                       Estimate Std. Error t value Pr(>|t|)
(Intercept)          1175.79233 1220.85177  0.9631   0.3406
log1p(BEV_PHEV)         3.88313    6.57887  0.5902   0.5580
I(log1p(BEV_PHEV)^2)   -0.44168    0.38178 -1.1569   0.2534
log1p(HDP)           -236.25676  249.85488 -0.9456   0.3494
I(log1p(HDP)^2)        12.57104   12.62555  0.9957   0.3247
  • AIC sa zhoršil (345.0 vs. 343.5).

  • ANOVA: p = 0.33 → kvadráty nezlepšujú model.

  • Robustné SE (HC1): kvadratické koeficienty nevýznamné.

Záver: kvadráty nepriniesli prínos – nelinearitu takto nepotvrdzujeme.

4) Zlom v sklone – iný efekt (P)HEV pri vyšších hodnotách

# Prah: medián log1p(BEV_PHEV)

cut_bev <- median(log1p(udaje$BEV_PHEV), na.rm = TRUE)
udaje$D_highBEV <- as.integer(log1p(udaje$BEV_PHEV) >= cut_bev)

# (a) len posun (intercept shift)

m_shift <- lm(EPI ~ D_highBEV + log1p(BEV_PHEV) + log1p(HDP), data = udaje)

# (b) zlom v sklone (interakcia premenná × dummy)

m_slope <- lm(EPI ~ log1p(BEV_PHEV)*D_highBEV + log1p(HDP), data = udaje)

# Porovnanie AIC

AIC(m_lin, m_shift, m_slope)

# ANOVA (rovnaká vysvetľovaná premenná)

anova(m_lin, m_shift)
Analysis of Variance Table

Model 1: EPI ~ log1p(BEV_PHEV) + log1p(HDP)
Model 2: EPI ~ D_highBEV + log1p(BEV_PHEV) + log1p(HDP)
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     47 2402.1                           
2     46 2366.4  1    35.666 0.6933 0.4093
anova(m_lin, m_slope)
Analysis of Variance Table

Model 1: EPI ~ log1p(BEV_PHEV) + log1p(HDP)
Model 2: EPI ~ log1p(BEV_PHEV) * D_highBEV + log1p(HDP)
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1     47 2402.1                           
2     45 2348.1  2    53.993 0.5174 0.5996
# Robustné SE

coeftest(m_slope, vcov = vcovHC(m_slope, type = "HC1"))

t test of coefficients:

                          Estimate Std. Error t value Pr(>|t|)   
(Intercept)               -29.6808    39.5065 -0.7513 0.456389   
log1p(BEV_PHEV)            -2.5330     1.5078 -1.6798 0.099918 . 
D_highBEV                   7.4189    20.1690  0.3678 0.714720   
log1p(HDP)                 12.4336     4.3666  2.8474 0.006619 **
log1p(BEV_PHEV):D_highBEV  -1.1895     2.1857 -0.5442 0.588969   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Prah = medián log1p(BEV_PHEV). Skúsili sme (a) posun priamky a (b) zmenu sklonu (interakcia s dummy):

AIC je vyšší než v lineárnom modeli (horšie).

ANOVA: posun p = 0.41, zmena sklonu p = 0.52.

Robustné SE: interakcia nevýznamná.

Záver: dôkaz pre odlišný efekt (P)HEV pri „vyšších“ úrovniach sme nenašli.

5) Výber pracovného modelu a krátke zhrnutie

Keďže (i) RESET síce naznačil nesprávnu špecifikáciu, ale (ii) C+R ukázal len jemné ohyby a (iii) ani kvadráty, ani zlom štatisticky nezlepšili model, ako pracovný model ponechávame základnú lineárnu špecifikáciu s robustnými chybami (HC1). V nej vychádza log1p(BEV_PHEV) negatívne a významne, kým log1p(HDP) pozitívne a významne. Prakticky: v tomto súbore dát V4 nevychádza, že by mierne zakrivenia alebo prahové efekty menili hlavné závery; ak je nelinearita prítomná, je skôr slabá a naše testy ju nevedia presvedčivo uchopiť (limit vzorky).

Porovnávacia tabuľka modelov

# istota, že máme základný lineárny model
if (!exists("m_lin")) {
  m_lin <- lm(EPI ~ log1p(BEV_PHEV) + log1p(HDP), data = udaje)
}

mods <- list("Lineárny" = m_lin)
if (exists("m_quad"))   mods[["Kvadratický"]]   <- m_quad
if (exists("m_slope"))  mods[["Zlom v sklone"]] <- m_slope
if (exists("m_shift"))  mods[["Posun úrovne"]]  <- m_shift

library(purrr); library(lmtest); library(dplyr); library(kableExtra)

reset_p <- function(m) tryCatch(resettest(m)$p.value, error = function(e) NA_real_)
anova_vs_base <- function(m, base) {
  if (identical(formula(base)[[2]], formula(m)[[2]])) as.numeric(anova(base, m)$`Pr(>F)`[2]) else NA_real_
}

base_model <- mods[["Lineárny"]]
cmp_tbl <- tibble(
  model = names(mods),
  AIC   = map_dbl(mods, AIC),
  adjR2 = map_dbl(mods, ~ summary(.x)$adj.r.squared),
  RESET_p = map_dbl(mods, reset_p),
  ANOVA_vs_lin_p = map_dbl(mods, ~ anova_vs_base(.x, base_model))
) %>% arrange(AIC)

kbl(cmp_tbl, digits = 3, caption = "Porovnanie špecifikácií (nižšie AIC je lepšie)") %>%
  kable_classic(full_width = FALSE)
Porovnanie špecifikácií (nižšie AIC je lepšie)
model AIC adjR2 RESET_p ANOVA_vs_lin_p
Lineárny 343.498 0.394 0.011 NA
Posun úrovne 344.750 0.390 0.025 0.409
Kvadratický 345.035 0.397 0.007 0.330
Zlom v sklone 346.361 0.381 0.032 0.600
NA

Graf predikčných kriviek (Lineárny vs. Kvadratický vs. Zlom)


# Predikcie pri mediáne HDP
x_grid <- tibble(
  BEV_PHEV = seq(min(udaje$BEV_PHEV, na.rm = TRUE),
                 max(udaje$BEV_PHEV, na.rm = TRUE),
                 length.out = 200),
  HDP = median(udaje$HDP, na.rm = TRUE)
)

pred_one <- function(m, name) {
  # (ak model potrebuje dummy D_highBEV, dopočítame ju podľa prahu, ktorý používame v práci)
  newdat <- x_grid
  if ("D_highBEV" %in% names(model.frame(m))) {
    cut_bev <- median(log1p(udaje$BEV_PHEV), na.rm = TRUE)
    newdat$D_highBEV <- as.integer(log1p(newdat$BEV_PHEV) >= cut_bev)
  }
  pr <- predict(m, newdata = newdat, se.fit = TRUE)
  tibble(model = name,
         BEV_PHEV = newdat$BEV_PHEV,
         fit = pr$fit,
         lo  = pr$fit - 1.96*pr$se.fit,
         hi  = pr$fit + 1.96*pr$se.fit)
}

pred_all <- bind_rows(
  pred_one(m_lin,  "Lineárny"),
  pred_one(m_quad, "Kvadratický"),
  pred_one(m_slope,"Zlom v sklone")
)

ggplot(pred_all, aes(BEV_PHEV, fit, color = model, fill = model)) +
  geom_ribbon(aes(ymin = lo, ymax = hi), alpha = 0.10, color = NA) +
  geom_line(size = 1) +
  labs(x = "(P)HEV (počet)", y = "Predikované EPI",
       title = "Predikčné krivky: EPI vs. (P)HEV pri mediáne HDP",
       subtitle = "Porovnanie špecifikácií (lineárny, kvadratický, zlom v sklone)") +
  theme_minimal() +
  theme(legend.position = "bottom")

Graf porovnáva predikčné krivky EPI vs. (P)HEV pri mediánovom HDP pre tri špecifikácie (lineárna v loge, kvadratická, a „zlom v sklone“). Všetky tri modely ukazujú rovnaký príbeh: s rastúcim (P)HEV EPI klesá a efekt sa postupne splošťuje (najmä pri nízkych hodnotách je pokles strmší). Rozdiely medzi krivkami sú malé – kvadratická verzia je o niečo prudšia v chvoste, zatiaľ čo „zlom v sklone“ sa prakticky prekrýva s lineárnym modelom. Intervaly neistoty (priesvitné pásma) sa rozširujú v extrémoch, kde je menej dát. Spolu s výsledkami AIC/ANOVA vyššie to naznačuje, že jednoduchý lineárny model v loge postačuje; prípadné nelinearity nijako nemenia kvalitatívny záver o negatívnej asociácii (P)HEV a EPI po zohľadnení HDP.

Stručná tabuľka výsledkov a záver

library(tibble)
library(kableExtra)

## 1) stručná diagnostika

sum_tbl <- tibble::tibble(
`Q–Q plot`                  = "Väčšina bodov na priamke; len mierne odchýlky v chvostoch.",
`Scale–Location`            = "Jemný U-tvar → slabá heteroskedasticita (riešime robustnými SE).",
`Residuals vs Leverage`     = "Pár vplyvných bodov, bez extrémov.",
`Heteroskedasticita – testy`= "Breusch–Pagan a NCV nevýznamné; White štýl hraničný → skôr slabý náznak.",
`RESET (špecifikácia)`      = "p ≈ 0.011 ⇒ lineárna špecifikácia má známky nesprávnej formy (skúšali sme jemné nelinearity)."
)

emerald_light <- "#ECFDF5"; emerald_head <- "#D1FAE5"; emerald_text <- "#065F46"

kbl(
sum_tbl,
caption = "Diagnostika – stručné zhrnutie",
booktabs = TRUE
) |>
kable_classic(full_width = TRUE, html_font = "Helvetica") |>
row_spec(0, background = emerald_head, color = emerald_text, bold = TRUE) |>
column_spec(1:ncol(sum_tbl), background = emerald_light, color = emerald_text, border_left = TRUE, border_right = TRUE)
Diagnostika – stručné zhrnutie
Q–Q plot Scale–Location Residuals vs Leverage Heteroskedasticita – testy RESET (špecifikácia)
Väčšina bodov na priamke; len mierne odchýlky v chvostoch. Jemný U-tvar → slabá heteroskedasticita (riešime robustnými SE). Pár vplyvných bodov, bez extrémov. Breusch–Pagan a NCV nevýznamné; White štýl hraničný → skôr slabý náznak. p ≈ 0.011 ⇒ lineárna špecifikácia má známky nesprávnej formy (skúšali sme jemné nelinearity).

## 2) porovnanie špecifikácií (AIC)

# predpoklad: objekty m_lin, m_quad, m_slope sú už odhadnuté v dokumente

aic_tbl <- tryCatch(
{
aa <- AIC(m_lin, m_quad, m_slope)
dplyr::rename(aa, Model = df, AIC = AIC) |>
dplyr::mutate(Model = rownames(aa))
},
error = function(e) tibble::tibble(
Model = c("Lineárny", "Kvadratický", "Zlom v sklone"),
AIC   = c(343.50, 345.03, 346.36)   # hodnoty z tvojich výstupov
)
)

kbl(aic_tbl, caption = "Porovnanie kvality modelov (nižší AIC = lepší)", booktabs = TRUE) |>
kable_classic(full_width = FALSE, html_font = "Helvetica") |>
row_spec(0, background = emerald_head, color = emerald_text, bold = TRUE) |>
column_spec(1:ncol(aic_tbl), background = emerald_light, color = emerald_text)
Porovnanie kvality modelov (nižší AIC = lepší)
Model AIC
m_lin m_lin 343.4979
m_quad m_quad 345.0346
m_slope m_slope 346.3613

## 3) hypotézy

hyp_tbl <- tibble::tribble(
~Premenná,  ~`H1 (očakávanie)`,   ~`Rozhodnutie o H0`,               ~`Rozhodnutie o H1`,              ~Poznámka,
"BEV",      "β > 0",              "NEZAMIETAM / neisté",            "NEPODPORUJEME",                  "Efekt nevýznamný alebo záporný.",
"BEV_PHEV", "β > 0",              "ZAMIETAM (významné, záporné)",   "ZAMIETAM (pozitívny sa nepotvrdil)","log1p(BEV_PHEV) stabilne negatívny s HC1.",
"HDP",      "β > 0",              "ZAMIETAM (významné, pozitívne)", "PODPORUJEME",                    "HDP vychádza kladne a významne."
)

kbl(hyp_tbl, caption = "Hypotézy a rozhodnutia (robustné SE)", booktabs = TRUE) |>
kable_classic(full_width = FALSE, html_font = "Helvetica") |>
row_spec(0, background = emerald_head, color = emerald_text, bold = TRUE) |>
column_spec(1:ncol(hyp_tbl), background = emerald_light, color = emerald_text)
Hypotézy a rozhodnutia (robustné SE)
Premenná H1 (očakávanie) Rozhodnutie o H0 Rozhodnutie o H1 Poznámka
BEV β > 0 NEZAMIETAM / neisté NEPODPORUJEME Efekt nevýznamný alebo záporný.
BEV_PHEV β > 0 ZAMIETAM (významné, záporné) ZAMIETAM (pozitívny sa nepotvrdil) log1p(BEV_PHEV) stabilne negatívny s HC1.
HDP β > 0 ZAMIETAM (významné, pozitívne) PODPORUJEME HDP vychádza kladne a významne.
NA

Diskusia, limity a záver

Čo ukázala diagnostika a testy: Rozptyl chýb je najmä slabo nehomogénny, preto v celej práci reportujeme robustné smerodajné chyby (HC1). RESET test (p ≈ 0.011) signalizoval, že samotná priamka môže byť pre jednoduchý lineárny model tesná, preto sme skúsili jemné nelinearity (kvadrát log1p(BEV_PHEV), kvadrát log1p(HDP)) a aj zlom v sklone podľa úrovne (P)HEV.

Porovnanie špecifikácií: Napriek signálu z RESET-u sa kvalita modelov nezlepšila – AIC je najnižší pri lineárnom modeli a ANOVA porovnania kvadratickej/zlomovej špecifikácie voči lineárnej nevyšli významne. Predikčné krivky pre všetky tri verzie sú tvarovo podobné (mierne klesajúce), rozdiely sú malé a v rámci intervalov spoľahlivosti.

Interpretácia účinkov (robustné SE):

  • log1p(BEV_PHEV) je negatívny a štatisticky významný – v našom súbore sa s vyšším rozšírením (P)HEV spája nižší EPI.

  • HDP je pozitívny a významný – krajiny/roky s vyšším HDP dosahujú vyšší EPI.

  • Samotné BEV nevyšlo robustne pozitívne.

Zjednodušene: viac (P)HEV ≠ vyšší EPI v krátkom horizonte; EPI zrejme ovplyvňujú širšie faktory (ekonomická úroveň, štruktúra energií, zloženie dopravy atď.).

Limity: malá vzorka (V4 × roky), agregačná úroveň, možná meracia chyba v registroch vozidiel, chýbajúce kontroly (energetický mix, dopravné výkony, priemysel). Krátke obdobie môže skrývať oneskorené účinky.

LS0tCnRpdGxlOiAiQW5hbMO9emEgZMOhdCBvIGVsZWt0cm9tb2JpbGl0ZSIKYXV0aG9yOiAiU2ltb25hIFZhbsSNb3bDoSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjc3M6IFN0eWxlc0dyZWVuLmNzcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIGNzczogU3R5bGVzR3JlZW4uY3NzCi0tLQoKCmBgYHs9aHRtbH0KPHN0eWxlPgovKiBzbWFyYWdkb3ZvIHplbGVuw6EgKi8KaDEsIGgxLnRpdGxlLCAudGl0bGUgeyBjb2xvcjogIzA3NUU1NCAhaW1wb3J0YW50OyB9CmVtLCBpIHsgY29sb3I6ICMwNzVFNTQgIWltcG9ydGFudDsgfQo8L3N0eWxlPgpgYGAKCiMgw5p2b2QKCiAgQ2llxL5vbSBhbmFsw716eSBqZSBwcmVza8O6bWHFpSwgxI1pIHJvesWhw61yZW5pZSAqKmVsZWt0cm9tb2JpbGl0eSB2IGtyYWppbsOhY2ggVjQgc8O6dmlzw60gcyBrdmFsaXRvdSDFvml2b3Ruw6lobyBwcm9zdHJlZGlhIG1lcmFub3UgaW5kZXhvbSBlbnZpcm9ubWVudMOhbG5laiB2w71rb25ub3N0aSAoRVBJKSoqLiBQcmFjdWplbSBzIHByZcSNaXN0ZW7DvW0gcGFuZWxvdsO9bSBkYXRhc2V0b20geiBtb2plaiBiYWthbMOhcnNrZWogcHLDoWNlIChrcmFqaW55IFY0IMOXIHJva3kpLgoKIyMgQ2hhcmFrdGVyaXN0aWthIGTDoXQKCi0gICAqKlpkcm9qIGEgcG9rcnl0aWU6KiogVmxhc3Ruw70gZGF0YXNldCB6b3N0YXZlbsO9IHByZSBCUCAoa3JhamlueSBWNCDDlyByb2t5KS4KLSAgICoqSGxhdm7DqSBwcmVtZW5uw6k6KiogYEVQSWAgKHpsb8W+ZW7DvSBpbmRleCBrdmFsaXR5IMW+aXZvdG7DqWhvIHByb3N0cmVkaWEpLCBgQkVWYCAocG/EjWV0IGJhdMOpcmlvdsO9Y2ggRVYpLCBgQkVWX1BIRVZgIChCRVYgKyBwbHVn4oCRaW4gaHlicmlkeSksIGBIRFBgIG5hIG9ieXZhdGXEvmEuCi0gICAqKlN0YXYgZMOhdDoqKiBEw6F0YSBib2xpICoqcHJlxI1pc3RlbsOpKiogcHJlZCB0w71tdG8gY3ZpxI1lbsOtbTsgdiB0b210byBkb2t1bWVudGUgdcW+IG5lcmllxaFpbWUgaW1wdXRhxI1uw6kgxI1pIMSNaXN0aWFjZSBrcm9reS4KCiMjIFByZW1lbm7DqQoqKlrDoXZpc2zDoSBwcmVtZW5uw6E6KioKKkVQSSog4oCTIHpsb8W+ZW7DvSBpbmRleCBlbnZpcm9ubWVudMOhbG5laiB2w71rb25ub3N0aSBrcmFqw61uLgoKKipLxL7DusSNb3bDqSB2eXN2ZXTEvnVqw7pjZSBwcmVtZW5uw6k6KioKKkJFViog4oCTIHBvxI1ldCBiYXTDqXJpb3bDvWNoIGVsZWt0cm9tb2JpbG92OwoqQkVWX1BIRVYqIOKAkyBzw7rEjWV0IEJFViBhIHBsdWctaW4gaHlicmlkb3YgKFBIRVYpLgoKKipLb250cm9sbsOpIHByZW1lbm7DqToqKgoqSERQIG5hIG9ieXZhdGXEvmEqIChla29ub21pY2vDoSDDunJvdmXFiCk7IHBvZMS+YSBkb3N0dXBub3N0aSBhaiDEj2FsxaFpZSBzcHJpZXZvZG7DqSB1a2F6b3ZhdGVsZSAoQ0/igoIsIGludmVzdGnEjW7DqS9yb3p2b2pvdsOpIGluZGlrw6F0b3J5KS4KCiMjIFbDvXNrdW1uw6Egb3TDoXprYSBhIGh5cG90w6l6eQoKU8O6dmlzw60gdnnFocWhw60gcG/EjWV0IChQKUhFViBzIHZ5xaHFocOtbSBFUEksIHBvIHpvaMS+YWRuZW7DrSBla29ub21pY2tlaiDDunJvdm5lIGtyYWrDrW4/CgotICAgKipIMDoqKiBQb8SNZXQgQkVWL0JFVl9QSEVWICoqbmVtw6EqKiB2w716bmFtbsO9IHZwbHl2IG5hIEVQSS4KLSAgICoqSDE6KiogVnnFocWhw60gQkVWL0JFVl9QSEVWIGplIHNwb2plbsO9IHMgKip2ecWhxaHDrW0qKiBFUEkuCgojIyBNZXRvZGlrYSB2IHNrcmF0a2UKClBvdcW+w612YW0gKipsaW5lw6FybmUgbW9kZWx5IE9MUyoqIHMgbG9n4oCRdHJhbnNmb3Jtw6FjaW91IHBvxI10b3bDvWNoIHByZW1lbm7DvWNoIChgbG9nMXBgKSwgYWJ5IHNhIHN0YWJpbGl6b3ZhbGEgdmFyaWFuY2lhIGEgdGxtaWxpIHNhIGV4dHLDqW15LiBBYnkgc29tIHNhIHZ5aGxhIGtvbGluZWFyaXRlLCBvZGhhZHVqZW0gbW9kZWwgcyBgQkVWYCBhIG1vZGVsIHMgYEJFVl9QSEVWYCAqKm9kZGVsZW5lKio7IGBIRFBgIGZpZ3VydWplIGFrbyBrb250cm9sYSDDunJvdm5lIHJvenZvamEuIERpYWdub3N0aWt1IHJvYsOtbSBjZXogxaF0YW5kYXJkbsOpIGdyYWZ5IChR4oCTUSwgU2NhbGXigJNMb2NhdGlvbiwgTGV2ZXJhZ2UpIGEgZm9ybcOhbG5lIHRlc3R5IChCcmV1c2No4oCTUGFnYW4pLiBJbmZlcmVuY2l1IHJlcG9ydHVqZW0gcyAqKnJvYnVzdG7DvW1pIFNFIChIQzEpKiosIHByw61wYWRuZSBrbGFzdHJvdmFuw71taSBwb2TEvmEga3JhamlueSBwcmkgcGFuZWxvdsO9Y2ggxaFwZWNpZmlrw6FjacOhY2guCgojIFsqKkltcG9ydCDDumRham92IHogbW9qZWogYmFrYWzDoXJza2VqIHByw6FjZSoqXXtzdHlsZT0iY29sb3I6IzA3NUU1NDsgZm9udC13ZWlnaHQ6NzAwOyJ9CgpOYcSNw610YW0gY3N2IHPDumJvciBzICpkw6F0YW1pIG8gZWxla3Ryb21vYmlsaXRlIHZvIFY0KiAocG/EjWV0IEJFViwgQkVWX1BIRVYsIEVQSSwgSERQLCBlbWlzaWUgQ0/igoIsIGludmVzdGnEjW7DqSB1a2F6b3ZhdGVsZeKApikuIETDoXRhIHPDuiB1xb4gcHJlxI1pc3RlbsOpLgoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IFRSVUUsCiAgbWVzc2FnZSA9IEZBTFNFLCAgIyB2eXBuZSAidXNpbmcgZm9ybXVsYSA9IHkgfiB4IiBhIGluw6kgaGzDocWha3kKICB3YXJuaW5nID0gRkFMU0UsICAjIHBvdGxhxI3DrSB2YXJvdmFuaWEKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcud2lkdGggPSA4LCBmaWcuaGVpZ2h0ID0gNQopCgoKIyBCYWzDrcSNa3kgYSBkw6F0YSAocG91xb5pdMOpIMSPYWxlaiB2IHByw6FjaSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkobG10ZXN0KQpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGNhcikKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoa2FibGVFeHRyYSkKCnVkYWplIDwtIHJlYWQuY3N2KCJkYXRhX3JfY29tbWFfdXRmOC5jc3YiLCBoZWFkZXIgPSBUUlVFLCBjaGVjay5uYW1lcyA9IEZBTFNFKQpgYGAKIAojIEludGVyYWt0w612bmEgdGFidcS+a2EgcyBkw6F0YW1pCmBgYHtyIGVjaG89RkFMU0V9CmxpYnJhcnkoRFQpCgpEVDo6ZGF0YXRhYmxlKAogIHVkYWplIHw+IGRwbHlyOjpzbGljZV9oZWFkKG4gPSAxMCksCiAgcm93bmFtZXMgPSBGQUxTRSwKICBvcHRpb25zID0gbGlzdChkb20gPSAndGlwJywgcGFnZUxlbmd0aCA9IDEwKSwKICBjYXB0aW9uID0gIk7DoWjEvmFkIGTDoXQg4oCTIHBydsO9Y2ggMTAgcmlhZGtvdiIKKSB8PgogIGZvcm1hdFN0eWxlKGNvbHVtbnMgPSBuYW1lcyh1ZGFqZSksIGBmb250LXNpemVgID0gJzkwJScpCmBgYAojIFByaWVza3VtbsOpIGdyYWZ5IC0gQk9YUExPVAoKKipQcmXEjW86KiogcHJlZCBtb2RlbG92YW7DrW0gb3ZlcnVqZW0sIMSNaSBtaWVya3kgYSByb3pkZWxlbmlhIGTDoXZhasO6IHpteXNlbCBhIMSNaSBuaWUgc8O6IHZpZGl0ZcS+bsOpIGV4dHLDqW15LiBQb8SNdG92w6kgcHJlbWVubsOpIChgQkVWYCwgYEJFVl9QSEVWYCkgdml6dWFsaXp1amVtIHYgbG9n4oCRbWllcmtlIChgbG9nMXBgKS4KCmBgYHtyIGJveHBsb3RzfQpwYXIobWZyb3cgPSBjKDIsIDIpKQpib3hwbG90KHVkYWplJEVQSSwgICAgICAgICAgICAgICAgbWFpbiA9ICJFUEkgKGJleiBsb2cpIiwgICAgY29sID0gImRhcmtncmVlbiIsICBob3Jpem9udGFsID0gVFJVRSkKYm94cGxvdChsb2cxcCh1ZGFqZSRCRVYpLCAgICAgICAgIG1haW4gPSAibG9nMXAoQkVWKSIsICAgICAgIGNvbCA9ICJsaWdodGJsdWUiLCBob3Jpem9udGFsID0gVFJVRSkKYm94cGxvdChsb2cxcCh1ZGFqZSRCRVZfUEhFViksICAgIG1haW4gPSAibG9nMXAoQkVWX1BIRVYpIiwgIGNvbCA9ICJkYXJrZ3JlZW4iLCAgaG9yaXpvbnRhbCA9IFRSVUUpCmJveHBsb3QobG9nMXAodWRhamUkSERQKSwgICAgICAgICBtYWluID0gImxvZzFwKEhEUCkiLCAgICAgICBjb2wgPSAibGlnaHRibHVlIiwgaG9yaXpvbnRhbCA9IFRSVUUpCnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAoKQm94cGxvdCB6b2JyYXp1amUgcm96ZGVsZW5pZSBwcmVtZW5uZWog4oCTIGhydWLDoSDEjWlhcmEgdiBzdHJlZGUgamUgbWVkacOhbiwg4oCea3JhYmnEjWth4oCcIChib3gpIGplIElRUiAob2QgMS4gcG8gMy4ga3ZhcnRpbCksIOKAnmbDunp54oCcIHVrYXp1asO6IHR5cGlja8O9IHJvenNhaCBhIGJvZGt5IG1pbW8gc8O6IG9kxL5haGzDqSBob2Rub3R5LiBWIG5hxaFpY2ggZ3JhZm9jaCBqZSBFUEkgc8O6c3RyZWRlbsOpIG9rb2xvIFx+NzAgcyBqZWRuw71tIG5pxb7FocOtbSBvdXRsaWVyb207IHBvIGxvZy10cmFuc2Zvcm3DoWNpaSBzw7ogbG9nMXAoQkVWKSBhIGxvZzFwKEJFVl9QSEVWKSBwZWtuZSBzdGFiaWxuw6kgYSBzeW1ldHJpY2vDqSAoYmV6IGRsaMO9Y2ggY2h2b3N0b3YpIGEgbG9nMXAoSERQKSBtw6EgdmXEvm1pIMO6emt5IHJvenNhaCDigJMgYnVkZSBzbMO6xb5pxaUgbmFqbcOkIGFrbyBrb250cm9sYSDDunJvdm5lIHJvenZvamEuCgoKIyBMaW5lw6FybmEgcmVncmVzaWEgKGR2ZSBhbHRlcm5hdMOtdnkpCgoqKk1vdGl2w6FjaWEgdsO9YmVydSDFoXBlY2lmaWvDoWNpZToqKiBgRVBJYCBqZSB6bG/FvmVuw70gaW5kZXggYSBlbGVrdHJvbW9iaWxpdGEgbcO0xb5lIGJ5xaUga29yZWxvdmFuw6EgcyBjZWxrb3ZvdSB2eXNwZWxvc8Wlb3Uga3JhamlueS4gUHJldG8gemFocm5pZW0gYEhEUGAgYWtvIGtvbnRyb2x1LiBLZcSPxb5lIGBCRVZgIGEgYEJFVl9QSEVWYCBzcG9sdSBzaWxubyBzw7p2aXNpYSwgb2RoYWR1amVtIGljaCAqKm9kZGVsZW7DqSoqIG1vZGVseSwgYWJ5IHNvbSBwcmVkacWhbGEga29saW5lYXJpdGUuIEtvZWZpY2llbnR5IGludGVycHJldHVqZW0gYWtvICpzZW1p4oCRZWxhc3RpY2l0eSo6IHptZW5hIHYgYGxvZzFwKHgpYCBwcmlibGnFvm5lIHpvZHBvdmVkw6EgcGVyY2VudHXDoWxuZWogem1lbmUgcG/EjXR1IHZvemlkaWVsLgoKKipNZXTDs2RhIEEgKE1vZGVsIEE6IEVQSSB+IGxvZzFwKEJFVikgKyBsb2cxcChIRFApKSoqCk92ZXJ1amUsIMSNaSBzYW1vdG7DqSBiYXTDqXJpb3bDqSBlbGVrdHJvbW9iaWx5IChCRVYpIHPDunZpc2lhIHMgRVBJIHBvIHpvaMS+YWRuZW7DrSBla29ub21pY2tlaiDDunJvdm5lIChIRFApLiBUZWRhOiBrZcSPIGR2ZSBrcmFqaW55IG1hasO6IHJvdm5ha8O9IEhEUCwgbcOhIHZ5xaHFocOtIHBvxI1ldCBCRVYgKHYgJSB6bWVuw6FjaCDigJMgdsSPYWthIGxvZzFwKSBzcG9qZW7DvSB2ecWhxaHDrS9uacW+xaHDrSBFUEk/CgoqKk1ldMOzZGEgQiAoTW9kZWwgQjogRVBJIH4gbG9nMXAoQkVWX1BIRVYpICsgbG9nMXAoSERQKSkqKgpPdmVydWplIHZ6xaVhaCBtZWR6aSBFUEkgYSBjZWxrb3bDvW0gcm96xaHDrXJlbsOtbSAoUClIRVYgKEJFViArIHBsdWctaW4gaHlicmlkeSksIG9ww6TFpSBwcmkgcm92bmFrZWogw7pyb3ZuaSBIRFAuIFRlbnRvIG1vZGVsIGhvdm9yw60sIMSNbyBzcHJhdsOtIHNwb2xvxI1uw73igJwgKFApSEVWIGluZGlrw6F0b3IgcyBFUEkuCgpBYnkgc29tIHNhIHZ5aGxhIGtvbGluZWFyaXRlLCBvZGhhZHVqZW0gZHZlIMWhcGVjaWZpa8OhY2llIHp2bMOhxaHFpToKCmBgYHtyIG1vZGVsc30KIyBNb2RlbCBBOiBFUEkgfiBsb2cxcChCRVYpICsgbG9nMXAoSERQKQptX2JldiAgPC0gbG0oRVBJIH4gbG9nMXAoQkVWKSAgICAgICsgbG9nMXAoSERQKSwgZGF0YSA9IHVkYWplKQoKIyBNb2RlbCBCOiBFUEkgfiBsb2cxcChCRVZfUEhFVikgKyBsb2cxcChIRFApCm1fcGhldiA8LSBsbShFUEkgfiBsb2cxcChCRVZfUEhFVikgKyBsb2cxcChIRFApLCBkYXRhID0gdWRhamUpCgpzdW1tYXJ5KG1fYmV2KQpzdW1tYXJ5KG1fcGhldikKCiMgUm9idXN0bsOpIFNFIChIQzEpCmNvZWZ0ZXN0KG1fYmV2LCAgdmNvdiA9IHZjb3ZIQyhtX2JldiwgIHR5cGUgPSAiSEMxIikpCmNvZWZ0ZXN0KG1fcGhldiwgdmNvdiA9IHZjb3ZIQyhtX3BoZXYsIHR5cGUgPSAiSEMxIikpCgojIFBvcm92bmFuaWUga3ZhbGl0eQphaWNfdGJsIDwtIEFJQyhtX2JldiwgbV9waGV2KQphaWNfdGJsCgojIFp2b2xlbsO9IG1vZGVsIG5hIGRpYWdub3N0aWt1Cm1vZGVsIDwtIG1fcGhldgpgYGAKClogbGluZcOhcm55Y2ggcmVncmVzacOtIHZ5Y2jDoWR6YSwgxb5lIEhEUCBuYSBvYnl2YXRlxL5hIG3DoSBuYSBFUEkgcG96aXTDrXZueSBhIMWhdGF0aXN0aWNreSB2w716bmFtbsO9IHZwbHl2LCBrw71tIHBvxI1ldCAoUClIRVYgKGEgcG9kb2JuZSBhaiBzYW1vdG7DvWNoIEJFVikgamUgesOhcG9ybsO9IGEgdsO9em5hbW7DvSBwbyB6b2jEvmFkbmVuw60gSERQOyBtb2RlbCBzIEJFVl9QSEVWIHNlZMOtIG1pZXJuZSBsZXDFoWllIChuacW+xaFpZSBBSUMpIGEgesOhdmVyeSBzYSBuZW1lbmlhIGFuaSBwcmkgcm9idXN0bsO9Y2ggc21lcm9kYWpuw71jaCBjaHliw6FjaC4gTW9kZWx5IHZ5c3ZldMS+dWrDuiB6aHJ1YmEgMzjigJM0MiAlIHZhcmlhYmlsaXR5IEVQSS4KCgpgYGB7cn0KIyBhayBtX2xpbiBlxaF0ZSBuZWV4aXN0dWplLCBwb3XFvmlqZW0gbGluZcOhcm55IG1vZGVsIHMgKFApSEVWCmlmICghZXhpc3RzKCJtX2xpbiIpKSBtX2xpbiA8LSBtX3BoZXYKIyAxKSBTa29udHJvbHVqZW1lIGEgcHLDrXBhZG5lIG9wcmF2w61tZSBuw6F6b3Ygc3TEunBjYSBFUEkKaWYgKCEiRVBJIiAlaW4lIG5hbWVzKHVkYWplKSkgewogIGNvbF9lcGkgPC0gZ3JlcCgiXkVQSVxcYiIsIG5hbWVzKHVkYWplKSwgdmFsdWUgPSBUUlVFKVsxXQogIGlmICghaXMubmEoY29sX2VwaSkpIG5hbWVzKHVkYWplKVtuYW1lcyh1ZGFqZSkgPT0gY29sX2VwaV0gPC0gIkVQSSIKfQoKIyAyKSBWeWJlcmllbWUgbW9kZWwsIHoga3RvcsOpaG8gY2hjZW1lIHByZWRpa292YcWlCm1vZCA8LSBtX2xpbiAgICMgPC0gcHLDrXBhZG5lIHptZcWIIG5hOiBtX3BoZXYsIG1fc2xvcGUsIG1fcXVhZCwgLi4uCgojIDMpIFByZWRpa8SNbsOhIGtyaXZrYTogRVBJIH4gQkVWX1BIRVYgcHJpIG1lZGnDoW5lIEhEUApwZGF0IDwtIGRhdGEuZnJhbWUoCiAgQkVWX1BIRVYgPSBzZXEobWluKHVkYWplJEJFVl9QSEVWLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgIG1heCh1ZGFqZSRCRVZfUEhFViwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICBsZW5ndGgub3V0ID0gMjAwKSwKICBIRFAgPSBtZWRpYW4odWRhamUkSERQLCBuYS5ybSA9IFRSVUUpCikKCnByIDwtIHByZWRpY3QobW9kLCBuZXdkYXRhID0gcGRhdCwgc2UuZml0ID0gVFJVRSkKcGRhdCR5aGF0IDwtIHByJGZpdApwZGF0JGxvICAgPC0gcHIkZml0IC0gMS45NiAqIHByJHNlLmZpdApwZGF0JGhpICAgPC0gcHIkZml0ICsgMS45NiAqIHByJHNlLmZpdAoKbGlicmFyeShnZ3Bsb3QyKQpnZ3Bsb3QocGRhdCwgYWVzKHggPSBCRVZfUEhFViwgeSA9IHloYXQpKSArCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBsbywgeW1heCA9IGhpKSwgYWxwaGEgPSAwLjIpICsKICBnZW9tX2xpbmUoKSArCiAgbGFicyh4ID0gIkJFVl9QSEVWIiwgeSA9ICJQcmVkaWtvdmFuw6kgRVBJIiwKICAgICAgIHRpdGxlID0gIkVQSSB2cy4gKFApSEVWIChwcmkgbWVkacOhbmUgSERQKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYApHcmFmIHVrYXp1amUgcHJlZGlrb3ZhbsO9IEVQSSB2IHrDoXZpc2xvc3RpIG9kIHBvxI10dSAoUClIRVYgcHJpIGZpeG92YW5vbSAobWVkacOhbm92b20pIEhEUCB6IG7DocWhaG8gc2VtaS1sb2cgbW9kZWx1LiBLcml2a2EgbcOhIHpyZXRlxL5uZSBrbGVzYWrDumNpIGEgc3Bsb8WhxaV1asO6Y2kgc2EgdHZhcjogcHJpIG7DrXpreWNoIGhvZG5vdMOhY2ggKFApSEVWIGplIHBva2xlcyBFUEkgc3RybcWhw60sIG5vIHMgcmFzdMO6Y2ltIChQKUhFViBzYSDDusSNaW5vayB6bWllcsWIdWplIChkaW1pbmlzaGluZyByZXR1cm5zKSwgxI1vIGplIHR5cGlja8OpIHByZSDFoXBlY2lmaWvDoWNpdSBzIGxvZ+KBoSgxKyhQKUhFVi4gxaBlZMOpIHDDoXNtbyB2eXpuYcSNdWplIDk1ICUgaW50ZXJ2YWwgcHJlZGlrY2llIGEgc21lcm9tIGsgdnnFocWhw61tIGhvZG5vdMOhbSBzYSByb3rFoWlydWplLCB0ZWRhIG5laXN0b3RhIHJhc3RpZSAodiB0w71jaCBvYmxhc3RpYWNoIG3DoW1lIG1lbmVqIHBvem9yb3ZhbsOtIGFsZWJvIHbDpMSNxaHDrSByb3pwdHlsKS4gQ2Vsa292byBncmFmIHZpenXDoWxuZSBwb3R2cmR6dWplIG5lZ2F0w612bnUgYXNvY2nDoWNpdSBtZWR6aSByb3rFocOtcmVuw61tIChQKUhFViBhIEVQSSB2IG5hxaFpY2ggZMOhdGFjaCBwbyB6b2jEvmFkbmVuw60gSERQOyBpZGUgbyBhc29jacOhY2l1LCBuaWUgZMO0a2F6IGthdXphbGl0eS4KCgojIyBEaWFnbm9zdGlrYSAoa3JhasWhaWUgZ3JhZnkpCgojIyMgUmVzaWR1YWxzIHZzIEZpdHRlZAoK4oCTIHVrYXp1amUsIMSNaSBtb2RlbCBuZWNow71iYSB0dmFyIChuZWxpbmVhcml0YSkgYSDEjWkgc8O6IGNoeWJ5IHJvdm5vbWVybmUgb2tvbG8gbnVseS4gSMS+YWTDoW1lIOKAnm7DoWhvZG7DvSBtcmFr4oCcIGJleiB2em9ydS4KCiMjIyBOb3JtYWwgUeKAk1EKCuKAkyBwb3Jvdm7DoXZhIHJvemRlbGVuaWUgcmV6w61kdcOtIHMgaWRlw6Fsbm91IG5vcm3DoWxub3Uga3JpdmtvdTsgYm9keSBwcmkgcHJpYW1rZSA9IHByaWJsacW+bsOhIG5vcm1hbGl0YSwgb2RjaMO9bGt5IHYgY2h2b3N0b2NoIHNpZ25hbGl6dWrDuiBleHRyw6lteS4KCiMjIyBTY2FsZeKAk0xvY2F0aW9uICjiiJpcfMWhdGFuZGFyZGl6b3ZhbsOpIHJlesOtZHXDoVx8IHZzLiBmaXR0ZWQpCgrigJMgdGVzdCByb3ZuYWvDqWhvIHJvenB0eWx1IGNow71iIChob21vc2tlZGFzdGljaXRhKS4gUm92bsOhIExPRVNTIGtyaXZrYSDiiYgga29uxaF0YW50bsO9IHJvenB0eWw7IHN0w7pwYWrDumNpL2xpZXZpayA9IGhldGVyb3NrZWRhc3RpY2l0YS4KCiMjIyBSZXNpZHVhbHMgdnMgTGV2ZXJhZ2UKCuKAkyBpZGVudGlmaWt1amUgdnBseXZuw6kgcG96b3JvdmFuaWE6IGtvbWJpbsOhY2lhIHZlxL5rw6lobyDigJ5sZXZlcmFnZeKAnCAoaGF0IGhvZG5vdHkpIGEgdmXEvmvDvWNoIHJlesOtZHXDrS4gUG9tw6FoYSByb3pob2Ruw7rFpSwgxI1pIG5pZWtvxL5rbyBib2RvdiBuZcWlYWjDoSByZWdyZXNuw7ogcHJpYW1rdSAocG9kxL5hIENvb2tvdmVqIHZ6ZGlhbGVub3N0aSkuCgpgYGB7ciBkaWFnLWdncGxvdH0KY2xyIDwtICIjMEU2QjREIgoKIyBkaWFnbm9zdGlja8O9IGRhdGFmcmFtZSAKZGlhZ19kZiA8LSBhdWdtZW50KG1vZGVsKSAlPiUgbXV0YXRlKGlkID0gZHBseXI6OnJvd19udW1iZXIoKSkKCmNvb2tfY3V0IDwtIDQgLyBucm93KGRpYWdfZGYpCmxhYl9kZiAgIDwtIGRwbHlyOjpmaWx0ZXIoZGlhZ19kZiwgLmNvb2tzZCA+IGNvb2tfY3V0KQoKcDEgPC0gZ2dwbG90KGRpYWdfZGYsIGFlcyguZml0dGVkLCAucmVzaWQpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiZ3JleTYwIikgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAuNzUsIGNvbG9yID0gY2xyKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSBjbHIpICsKICBsYWJzKHRpdGxlID0gIlJlc2lkdWFscyB2cyBGaXR0ZWQiLCB4ID0gIkZpdHRlZCB2YWx1ZXMiLCB5ID0gIlJlc2lkdWFscyIpICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEyKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIikpCgpwMiA8LSBnZ3Bsb3QoZGlhZ19kZiwgYWVzKHNhbXBsZSA9IC5zdGQucmVzaWQpKSArCiAgc3RhdF9xcShjb2xvciA9IGNsciwgYWxwaGEgPSAuOSkgKwogIHN0YXRfcXFfbGluZShjb2xvciA9ICJncmV5NDUiKSArCiAgbGFicyh0aXRsZSA9ICJOb3JtYWwgUeKAk1EiLCB4ID0gIlRoZW9yZXRpY2FsIFF1YW50aWxlcyIsIHkgPSAiU3RhbmRhcmRpemVkIHJlc2lkdWFscyIpICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEyKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIikpCgpwMyA8LSBnZ3Bsb3QoZGlhZ19kZiwgYWVzKC5maXR0ZWQsIHNxcnQoYWJzKC5zdGQucmVzaWQpKSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gLjc1LCBjb2xvciA9IGNscikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gY2xyKSArCiAgbGFicyh0aXRsZSA9ICJTY2FsZeKAk0xvY2F0aW9uIiwgeCA9ICJGaXR0ZWQgdmFsdWVzIiwKICAgICAgIHkgPSBleHByZXNzaW9uKHNxcnQoInxTdGFuZGFyZGl6ZWQgcmVzaWR1YWxzfCIpKSkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTIpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSkKCnA0IDwtIGdncGxvdChkaWFnX2RmLCBhZXMoLmhhdCwgLnN0ZC5yZXNpZCkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJncmV5NjAiKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IC43NSwgY29sb3IgPSBjbHIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9IGNscikgKwogIGdlb21fdGV4dChkYXRhID0gbGFiX2RmLCBhZXMobGFiZWwgPSBpZCksIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDMpICsKICBsYWJzKHRpdGxlID0gIlJlc2lkdWFscyB2cyBMZXZlcmFnZSIsIHggPSAiSGF0IHZhbHVlcyIsIHkgPSAiU3RhbmRhcmRpemVkIHJlc2lkdWFscyIpICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDEyKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIikpCgoocDEgKyBwMikgLyAocDMgKyBwNCkKYGBgCgoqKkRpYWdub3N0aWthIOKAkyDEjcOtdGFuaWUgZ3JhZm92OioqCgotICAgKlJlc2lkdWFscyB2cyBGaXR0ZWQqOiBqZW1uw6EgbmVsaW5lYXJpdGEgYSBtaWVybmUga29sw61zYW5pZSByb3pwdHlsdS4KLSAgICpR4oCTUSo6IGRyb2Juw6kgb2RjaMO9bGt5IHYgY2h2b3N0b2NoIOKGkiBwcmlibGnFvm7DoSBub3JtYWxpdGEuCi0gICAqU2NhbGXigJNMb2NhdGlvbio6IHNsYWLDoSBoZXRlcm9za2VkYXN0aWNpdGEg4oaSIHBvdcW+aWplbSByb2J1c3Ruw6kgU0UuCi0gICAqUmVzaWR1YWxzIHZzIExldmVyYWdlKjogem9ww6FyIHZwbHl2bsO9Y2ggYm9kb3YgKG96bmHEjWVuw6kgSUQpLCBhbGUgYmV6IGV4dHLDqW1vdi4KCktlxI8gem9oxL5hZG7DrW1lIEhEUCwgdmlhYyAoUClIRVYgc2EgdiBuYcWhaWNoIGTDoXRhY2ggc3DDoWphIHMgbmnFvsWhw61tIEVQSS4gS29udHJvbG7DqSBncmFmeSBuZXVrw6F6YWxpIHbDocW+bmUgcHJvYmzDqW15IGEgZHJvYm7DqSBvZGNow71sa3kgc21lIHBva3J5bGkgcm9idXN0bsO9bWkgY2h5YmFtaSwgdGFrxb5lIHbDvXNsZWRvayBiZXJpZW1lIGFrbyBzcG/EvmFobGl2w70uCgojIFZwbHl2bsOpIHBvem9yb3ZhbmlhCgpgYGB7ciBpbmZsdWVuY2V9CmluZmx1ZW5jZVBsb3QobW9kZWwsIG1haW4gPSAiSW5mbHVlbmNlIHBsb3QiKQpvdXRsaWVyVGVzdChtb2RlbCkgICMgQm9uZmVycm9uaSBwLXZhbHVlCmBgYAoqKktyw6F0a2UgxI3DrXRhbmllIGdyYWZ1IGEgdGFidcS+a3k6KioKCipJbmZsdWVuY2UgcGxvdCAoYnViYmxlIGNoYXJ0KSoKCi1YLW9zIChIYXQtdmFsdWVzKSA9IOKAnnDDoWth4oCcIChsZXZlcmFnZSk6IGFrIGplIGJvZCB2aWFjIHZwcmF2bywgbcOhIG5lxaF0YW5kYXJkbsO6IGtvbWJpbsOhY2l1IHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2ggYSB2aWUgdmlhYyBzdHJobsO6xaUgcHJpYW1rdS4KCi1ZLW9zIChTdHVkZW50aXplZCByZXNpZHVhbHMpID0gdmXEvmtvc8WlIGNoeWJ5OiBuYWQgKzIgYWxlYm8gcG9kIOKIkjIgamUgcG9kb3pyaXbDqS4KCi1WZcS+a29zxaUvb2R0aWXFiCBidWJsaW55ID0gQ29va292byBEOiDEjcOtbSB2w6TEjcWhaWEgYSB0bWF2xaFpYSBidWJsaW5hLCB0w71tIHbDpMSNxaHDrSB2cGx5diBqZWRub3RreSBuYSBvZGhhZCBjZWzDqWhvIG1vZGVsdS4KCkdyYWYgdnBseXZ1IHVrYXp1amUgbmlla2/EvmtvIHBvem9yb3ZhbsOtIHMgdnnFocWhb3Ug4oCecMOha2914oCcIGEgdnBseXZvbSAobmFqbcOkIGJvZHkgMzEsIDQxIGEgMjApLCBubyB6b3N0w6F2YWrDuiB2IHJvenVtbsO9Y2ggbWVkemlhY2g7IENvb2tvdm8gRCBuaWUgamUgZXh0csOpbW5lIGEgaG9kbm90eSDFoXR1ZGVudGl6b3ZhbsO9Y2ggcmV6w61kdcOtIHNhIHBvaHlidWrDuiBva29sbyBocmFuw61jIMKxMi4gRm9ybcOhbG55IG91dGxpZXJUZXN0IHByaXRvbSBuZW5hxaFpZWwgxb5pYWRueSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBvZMS+YWhsw70gYm9kIHBvIEJvbmZlcnJvbmkga29yZWtjaWkgKG5hanbDpMSNxaHDrSB8cnN0dWRlbnR8IG3DoSBib2QgMjAg4omIIOKIkjIuMzAsIG5lb3ByYXZlbsOpIHAgfiAwLjAyNiwgcG8ga29yZWtjaWkgbmV2w716bmFtbsOpKS4gSW7DvW1pIHNsb3ZhbWk6IHYgZMOhdGFjaCBzw7ogamVkbm90a3ksIGt0b3LDqSBtYWrDuiBjaXRlxL5uZWrFocOtIHZwbHl2IG5hIG9kaGFkLCBhbGUgbmVtw6FtZSBkw7RrYXogbyBza3V0b8SNbsO9Y2ggb3V0bGllcm9jaAojIERvZGF0b8SNbsOpIHBvcm92bmFuaWUgbW9kZWxvdgoKYGBge3IgY29tcGFyZX0KIyBNb2RlbCBBOiBFUEkgfiBsb2cxcChCRVYpICsgSERQIChiZXogbG9nIG5hIEhEUCDigJMgYWtvIGtvbnRyb2xhIMO6cm92bmUpCm1fYmV2MiAgPC0gbG0oRVBJIH4gbG9nMXAoQkVWKSAgICAgICsgSERQLCBkYXRhID0gdWRhamUpCiMgTW9kZWwgQjogRVBJIH4gbG9nMXAoQkVWX1BIRVYpICsgSERQCm1fcGhldjIgPC0gbG0oRVBJIH4gbG9nMXAoQkVWX1BIRVYpICsgSERQLCBkYXRhID0gdWRhamUpCnN1bW1hcnkobV9iZXYyKTsgY29lZnRlc3QobV9iZXYyLCB2Y292ID0gdmNvdkhDKG1fYmV2MiwgdHlwZSA9ICJIQzEiKSkKc3VtbWFyeShtX3BoZXYyKTsgY29lZnRlc3QobV9waGV2MiwgdmNvdiA9IHZjb3ZIQyhtX3BoZXYyLCB0eXBlID0gIkhDMSIpKQpBSUMobV9iZXYyLCBtX3BoZXYyKQpgYGAKClBvIHpvaMS+YWRuZW7DrSBIRFAgdnljaMOhZHphIG5lZ2F0w612bmEgYXNvY2nDoWNpYSBFUEkgcyAoUClIRVYgYWogcyBCRVY7IG1pZXJuZSBsZXDFoWllIHNlZMOtIMWhcGVjaWZpa8OhY2lhIHMgQkVWX1BIRVYuCgojIE9uZXNrb3JlbsO9IHZwbHl2IChsYWcgMSByb2spIHMgZml4bsO9bWkgZWZla3RtaQoKKipQcmXEjW8gbGFnOioqIHptZW55IHYgemxvxb5lbsOtIHZvem92w6lobyBwYXJrdSBhIGJ1ZG92YW7DrSBpbmZyYcWhdHJ1a3TDunJ5IHNhIG5lbXVzaWEgb2thbcW+aXRlIHByZW1pZXRudcWlIGRvIEVQSS4gSmVkbm9yb8SNbsO9IGxhZyBgQkVWX1BIRVZgIHMgKipmaXhuw71taSBlZmVrdG1pIGtyYWrDrW4gYSByb2tvdioqIHphY2h5dMOhdmEgbmVwb3pvcm92YW7DuiBoZXRlcm9nZW5pdHUgYSBzcG9sb8SNbsOpIMWhb2t5LgoKYGBge3IgbGFnfQp1ZGFqZV9sYWcgPC0gdWRhamUgJT4lCiAgYXJyYW5nZShLcmFqaW5hLCBSb2spICU+JQogIGdyb3VwX2J5KEtyYWppbmEpICU+JQogIG11dGF0ZShsYWdfQkVWX1BIRVYgPSBkcGx5cjo6bGFnKEJFVl9QSEVWLCAxKSkgJT4lCiAgdW5ncm91cCgpCgptX2xhZyA8LSBsbShFUEkgfiBsb2cxcChsYWdfQkVWX1BIRVYpICsgSERQICsgZmFjdG9yKEtyYWppbmEpICsgZmFjdG9yKFJvayksIGRhdGEgPSB1ZGFqZV9sYWcpCmNvZWZ0ZXN0KG1fbGFnLCB2Y292ID0gdmNvdkNMKG1fbGFnLCBjbHVzdGVyID0gfiBLcmFqaW5hLCB0eXBlID0gIkhDMSIpKQpgYGAKCkFqIGtlxI8gc2EgcG96cmllbWUgbmEgb25lc2tvcmVuw70gKDEtcm/EjW7DvSkgZWZla3QgYSB6YWZpeHVqZW1lIHJvemRpZWx5IG1lZHppIGtyYWppbmFtaSBhIHJva21pLCBuZXZpZMOtbWUgxaF0YXRpc3RpY2vDvSBkw7RrYXosIMW+ZSB2aWFjIChQKUhFViB6bGVwxaHDrSBFUEnigJRrb2VmaWNpZW50IGplIHPDrWNlIG5lZ2F0w612bnksIGFsZSBuZXbDvXpuYW1uw70uIFByZSBuYcWhdSBwcsOhY3UgdG8gem5hbWVuw6EsIMW+ZSBobGF2bsO9IHrDoXZlciB6b3N0w6F2YSByb3ZuYWvDvTogcG8gem9oxL5hZG5lbsOtIEhEUCAoYSBwcmkgRkUpIHNhIHYgZG9zdHVwbsO9Y2ggZMOhdGFjaCBWNCBuZXBvdHZyZHp1amUga3LDoXRrb2RvYsO9IHBveml0w612bnkgdnBseXYgcm96xaHDrXJlbmlhIChQKUhFViBuYSBFUEkuIE1vZGVsIHRlZGEgc2vDtHIgaG92b3LDrSwgxb5lIEVQSSBmb3JtdWrDuiBhaiBpbsOpLCDFoWlyxaFpZSBmYWt0b3J5IG5lxb4gc2Ftb3Ruw6EgZWxla3Ryb21vYmlsaXRhCgojIMWgdGFuZGFyZGl6b3ZhbsOpIGtvZWZpY2llbnR5CgoqKlpteXNlbDoqKiBwbyDFoXRhbmRhcmRpesOhY2lpIHZpZW0gcG9yb3ZuYcWlICp2ZcS+a29zxaUqIGVmZWt0b3YgbmFwcmllxI0gcm96ZGllbG55bWkgbWllcmthbWkgKFNEIGplZG5vdGt5KS4KCmBgYHtyIHN0ZH0KbV9zdGQgPC0gbG0oc2NhbGUoRVBJKSB+IHNjYWxlKGxvZzFwKEJFVl9QSEVWKSkgKyBzY2FsZShIRFApLCBkYXRhID0gdWRhamUpCnN1bW1hcnkobV9zdGQpCmBgYAoKUG8gxaF0YW5kYXJkaXrDoWNpaSB2eWNow6FkemEsIMW+ZSBsb2cxcChCRVZfUEhFVikgbcOhIHNpbG5lasWhw60gdnBseXYgbmEgRVBJIGEgamUgbmVnYXTDrXZueSAoXH7iiJIwLjc5IFNEIHphICsxIFNEIHYgKFApSEVWKSwga8O9bSBIRFAgamUgcG96aXTDrXZuZSAoXH4rMC40NCBTRCB6YSArMSBTRCB2IEhEUCk7IG9iYSBlZmVrdHkgc8O6IMWhdGF0aXN0aWNreSB2w716bmFtbsOpLiBJbnRlcmNlcHQgamUgXH4wIChsZWJvIHByZW1lbm7DqSBzw7ogY2VudHJvdmFuw6kpIGEgbW9kZWwgdnlzdmV0xL51amUgXH40MiAlIHZhcmlhYmlsaXR5IEVQSS4gSW7DvW1pIHNsb3ZhbWk6IHYgbmHFoWljaCBkw6F0YWNoIHNhIHptZW55IHYgKFApSEVWIHNww6FqYWrDuiBzIHbDpMSNxaHDrW0gKG5lZ2F0w612bnltKSBwb3N1bm9tIEVQSSBuZcW+IHJvdm5ha28gdmXEvmvDqSB6bWVueSB2IEhEUCBzIHBveml0w612bnltIHNtZXJvbS4KCiMgSGV0ZXJvc2tlZGFzdGljaXRhIOKAkyB0ZXN0eSBhIGdyYWZ5CgpIZXRlcm9za2VkYXN0aWNpdGEgPSByb3pwdHlsIGNow71iIG5pZSBqZSB2xaFhZGUgcm92bmFrw70uIEFrIGJ5IGJvbGEgdsO9cmF6bsOhLCBiZcW+bsOpIHAtaG9kbm90eSBtw7TFvnUgYnnFpSBza3Jlc2xlbsOpLiBOacW+xaFpZSBqdSByw71jaGxvIG92ZXLDrW0gKGdyYWZ5ICsgdGVzdHkpIGEgem9oxL5hZG7DrW0gY2V6IHJvYnVzdG7DqSDFoXRhbmRhcmRuw6kgY2h5YnkgKEhDMSkuCgojIyBWaXp1w6FsbmEgZGlhZ25vc3Rpa2EKCmBgYHtyIGhldGVyby1wbG90eSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShicm9vbSk7IGxpYnJhcnkoZ2dwbG90Mik7IGxpYnJhcnkocGF0Y2h3b3JrKTsgY2xyIDwtICIjMEU2QjREIgoKaCA8LSBhdWdtZW50KG1vZGVsLCBkYXRhID0gdWRhamUpIHw+CiAgZHBseXI6Om11dGF0ZSgKICAgIGFic3JlcyA9IHNxcnQoYWJzKC5zdGQucmVzaWQpKSwKICAgIHJlczIgICA9IC5yZXNpZF4yLAogICAgeF9iZXYgID0gbG9nMXAoLmRhdGEkQkVWX1BIRVYpLCAgIyBhayBwb3XFvsOtdmFtZSBCRVY6IGxvZzFwKC5kYXRhJEJFVikKICAgIHhfaGRwICA9IC5kYXRhJEhEUAogICkKCnBfU0wgPC0gZ2dwbG90KGgsIGFlcyguZml0dGVkLCBhYnNyZXMpKSArCiAgZ2VvbV9wb2ludChhbHBoYT0uNjUpICsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9RkFMU0UsIGxpbmV3aWR0aD0xLCBjb2xvcj1jbHIpICsKICBsYWJzKHg9IlByZWRpa292YW7DqSBob2Rub3R5IiwgeT1leHByZXNzaW9uKHNxcnQoInxyZXrDrWR1w6F8IikpLCB0aXRsZT0iU2NhbGXigJNMb2NhdGlvbiIpICsKICB0aGVtZV9taW5pbWFsKCkKCnBfYmV2IDwtIGdncGxvdChoLCBhZXMoeF9iZXYsIHJlczIpKSArCiAgZ2VvbV9wb2ludChhbHBoYT0uNjUpICsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9RkFMU0UsIGxpbmV3aWR0aD0xLCBjb2xvcj1jbHIpICsKICBsYWJzKHg9ImxvZzFwKEJFVl9QSEVWKSIsIHk9InJlesOtZHXDoV4yIiwgdGl0bGU9IlJlesOtZHXDoV4yIHZzLiBsb2cxcChCRVZfUEhFVikiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwX2hkcCA8LSBnZ3Bsb3QoaCwgYWVzKHhfaGRwLCByZXMyKSkgKwogIGdlb21fcG9pbnQoYWxwaGE9LjY1KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIHNlPUZBTFNFLCBsaW5ld2lkdGg9MSwgY29sb3I9Y2xyKSArCiAgbGFicyh4PSJIRFAiLCB5PSJyZXrDrWR1w6FeMiIsIHRpdGxlPSJSZXrDrWR1w6FeMiB2cy4gSERQIikgKwogIHRoZW1lX21pbmltYWwoKQoKcF9TTCAvIChwX2JldiB8IHBfaGRwKQpgYGAKTE9FU1Mga3JpdmthIHYgU2NhbGXigJNMb2NhdGlvbiBtw6EgamVtbsOpIOKAnlXigJwg4oCTIHJvenB0eWwgcmV6w61kdcOtIGplIG5ham1lbsWhw60gcHJpIHN0cmVkbsO9Y2ggcHJlZGlrY2nDoWNoIGEgdsOkxI3FocOtIG5hIG9rcmFqb2NoLCB0YWvFvmUgaWRlIG8gbWllcm51IGhldGVyb3NrZWRhc3RpY2l0dS4gVm8gdnrFpWFodSByZXrDrWR1w6HCsiB2cy4gbG9nMXAoQkVWX1BIRVYpIGplIFUtdHZhciBsZW4gcGx5dGvDvSwgxI1pxb5lIHMgKFApSEVWIHPDunZpc8OtIHJvenB0eWwgc2vDtHIgc2xhYm8uIE5hb3BhaywgZ3JhZiByZXrDrWR1w6HCsiB2cy4gSERQIHVrYXp1amUgdsO9cmF6bmVqxaHDrSBVLXR2YXI6IHZhcmlhbmNpYSBqZSBuYWpuacW+xaFpYSBwcmkgc3RyZWRuw71jaCBob2Rub3TDoWNoIEhEUCBhIHJhc3RpZSBwcmkgbsOtemt5Y2ggYWogdnlzb2vDvWNoLCDEjW8gbmF6bmHEjXVqZSwgxb5lIHByw61wYWRuw6EgaGV0ZXJvc2tlZGFzdGljaXRhIGplIHZpYXphbsOhIG5ham3DpCBuYSBIRFAuIENlbGtvdm8gbmVqZGUgbyBzaWxuw6kgcG9ydcWhZW5pZSwgYWxlIGplIHJvenVtbsOpIHBvdcW+w612YcWlIHJvYnVzdG7DqSDFoXRhbmRhcmRuw6kgY2h5YnkgKEhDMSk7IG5pxb7FoWllIHRvIGXFoXRlIG92ZXLDrW1lIGZvcm3DoWxueW1pIHRlc3RhbWkuCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBhdGNod29yaykgICAKCiMgbW9kZWwsIGt0b3LDvSBjaGNlbWUgZGlhZ25vc3Rpa292YcWlCgptb2QgICA8LSBtX3BoZXYgICAgICMgRVBJIH4gbG9nMXAoQkVWX1BIRVYpICsgbG9nMXAoSERQKQpkdGEgICA8LSB1ZGFqZQoKIyB2eXBvxI3DrXRhbSByZXrDrWR1w6EgYSBwcmlwcmF2w61tIGxvZyBwcmVtZW5uw7ogcHJlIEJFVl9QSEVWIChhYnkgc2VkZWxhIHMgbW9kZWxvbSkKCmR0YSRyZXNpZDIgICA8LSByZXNpZChtb2QpXjIKZHRhJGxvZ0JFVlAgIDwtIGxvZzFwKGR0YSRCRVZfUEhFVikKCiMgMSkgUmV6w61kdcOhXjIgdnMuIGxvZzFwKEJFVl9QSEVWKQoKcF9iZXYgPC0gZ2dwbG90KGR0YSwgYWVzKHggPSBsb2dCRVZQLCB5ID0gcmVzaWQyKSkgKwpnZW9tX3BvaW50KGFscGhhID0gMC42KSArCmdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gImZpcmVicmljayIpICsKbGFicyh4ID0gImxvZzFwKEJFVl9QSEVWKSIsIHkgPSAixaB0dm9yY2UgcmV6w61kdcOtIiwKdGl0bGUgPSAiUmV6w61kdcOhXjIgdnMuIGxvZzFwKEJFVl9QSEVWKSIpICsKdGhlbWVfbWluaW1hbCgpCgojIDIpIFJlesOtZHXDoV4yIHZzLiBIRFAgIChwb3pvcjogdiBtb2RlbGkgamUgbG9nKEhEUCkg4oCTIHR1IMO6bXlzZWxuZSBkw6F2YW1lIGFqIOKAnnJhd+KAnCBIRFAsCgojIGFieSBib2xvIGphc25lIHZpZG5vLCDEjWkgcHJvYmzDqW0gc8O6dmlzw60gcyDDunJvdsWIb3UgYm9oYXRzdHZhKQoKcF9oZHAgPC0gZ2dwbG90KGR0YSwgYWVzKHggPSBIRFAsIHkgPSByZXNpZDIpKSArCmdlb21fcG9pbnQoYWxwaGEgPSAwLjYpICsKZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAiZmlyZWJyaWNrIikgKwpsYWJzKHggPSAiSERQIG5hIG9ieXZhdGXEvmEiLCB5ID0gIsWgdHZvcmNlIHJlesOtZHXDrSIsCnRpdGxlID0gIlJlesOtZHXDoV4yIHZzLiBIRFAiKSArCnRoZW1lX21pbmltYWwoKQoKcF9iZXYgfCBwX2hkcAoKYGBgCgpaIHTDvWNodG8gZHZvY2ggZ3JhZm92IHZpZG5vLCDFvmUgdmXEvmtvc8WlIGNow71iICjFoXR2b3JjZSByZXrDrWR1w60pIG5pZSBqZSB2xaFhZGUgcm92bmFrw6EuIMSMZXJ2ZW7DoSBMT0VTUyBrcml2a2EgbcOhIHYgb2JvY2ggcHLDrXBhZG9jaCB0dmFyIGplbW7DqWhvIOKAnlXigJwg4oCTIHJvenB0eWwgcmV6w61kdcOtIGplIG5ham1lbsWhw60gdiBzdHJlZGUgYSB2w6TEjcWhw60gcHJpIHZlxL5taSBuw616a3ljaCBhaiB2ZcS+bWkgdnlzb2vDvWNoIGhvZG5vdMOhY2guIEVmZWt0IGplIHpyZXRlxL5uZWrFocOtIHByaSBIRFAsIMSNbyBuYXpuYcSNdWplLCDFvmUgbmVyb3ZuYWvDvSByb3pwdHlsIGNow71iIHPDunZpc8OtIHNrw7RyIHMgw7pyb3bFiG91IGJvaGF0c3R2YSBrcmFqw61uIG5lxb4gcyBwb8SNdG9tIChQKUhFVi4gTmllIGplIHRvIGV4dHLDqW1ueSDigJ5saWV2aWvigJwsIGFsZSBpZGUgbyBtaWVybnUgaGV0ZXJvc2tlZGFzdGljaXR1LgoKIyMgSGV0ZXJvc2tlZGFzdGljaXRhIC0gcHJlaMS+YWQgdGVzdG92CgpgYGB7cn0KbGlicmFyeShsbXRlc3QpOyBsaWJyYXJ5KGNhcik7IGxpYnJhcnkoZHBseXIpOyBsaWJyYXJ5KGtuaXRyKQoKYnBfZml0dGVkIDwtIGJwdGVzdChtb2RlbCkKYnBfd2hpdGUgIDwtIGJwdGVzdChtb2RlbCwgfiBmaXR0ZWQobW9kZWwpICsgSShmaXR0ZWQobW9kZWwpXjIpKQpuY3YgICAgICAgPC0gbmN2VGVzdChtb2RlbCkKCnRyaWJibGUoCiAgflRlc3QsICAgICAgICAgICAgICAgflN0YXRpc3RpYywgICAgICAgICAgICAgICAgICAgfnBfdmFsdWUsCiAgIkJyZXVzY2jigJNQYWdhbiIsICAgICB1bm5hbWUoYnBfZml0dGVkJHN0YXRpc3RpYyksICBicF9maXR0ZWQkcC52YWx1ZSwKICAiQlAgKFdoaXRlIMWhdMO9bCkiLCAgIHVubmFtZShicF93aGl0ZSRzdGF0aXN0aWMpLCAgIGJwX3doaXRlJHAudmFsdWUsCiAgIk5DViAoY2FyKSIsICAgICAgICAgdW5uYW1lKG5jdiRDaGlTcXVhcmUpLCAgICAgICAgbmN2JHAKKSB8PgogIG11dGF0ZShhY3Jvc3MoYyhTdGF0aXN0aWMsIHBfdmFsdWUpLCB+cm91bmQoLngsIDQpKSkgfD4KICBrYWJsZShjYXB0aW9uID0gIkhldGVyb3NrZWRhc3RpY2l0YSDigJMgcHJlaMS+YWQgdGVzdG92IikKYGBgCiMjIyBGb3Jtw6FsbmUgdGVzdHkKLSAqQnJldXNjaOKAk1BhZ2FuOiogcCA9IDAsNzg0IChuZXbDvXpuYW1uw6kpLiAKCi0gKldoaXRlLcWhdMO9bDoqIHAgPSAwLDA1OSAoaHJhbmnEjW7DvSBuw6F6bmFrIFUtdHZhcnUgdm8gdmFyaWFuY2lpKS4gCgotICpOQ1YgKGNhcik6KiBwID0gMCw5NTUgKG5ldsO9em5hbW7DqSkuCgoqKlJvemhvZG51dGllOioqIFRlc3R5IG5lZMOhdmFqw7ogc2lsbsO9IGTDtGtheiBoZXRlcm9za2VkYXN0aWNpdHk7IHZ6aMS+YWRvbSBuYSBqZW1uw70gdnpvciB2IGdyYWZvY2ggamUgcHJpbWVyYW7DqSByZXBvcnRvdmHFpSByb2J1c3Ruw6kgxaF0YW5kYXJkbsOpIGNoeWJ5IChIQzEpLiBLdmFsaXRhdMOtdm5lIHrDoXZlcnkgbW9kZWx1IHNhIHTDvW0gbmVtZW5pYS4KCiMgTmVsaW5lw6FybmUgxaFwZWNpZmlrw6FjaWUgYSB0ZXN0eSBmdW5rxI1uZWogZm9ybXkKUHJlxI1vIHRvdG8gcm9iw61tZT8gRG90ZXJheiBzbWUgcHJlZHBva2xhZGFsaSwgxb5lIHZ6xaVhaCBtZWR6aSBFUEkgYSB2eXN2ZXTEvnVqw7pjaW1pIHByZW1lbm7DvW1pIChsb2cxcChCRVZfUEhFViksIGxvZzFwKEhEUCkpIGplIGxpbmXDoXJueS4gTmnFvsWhaWUgc2tvbnRyb2x1amVtZSwgxI1pIG9iecSNYWpuw6Eg4oCecHJpYW1rYeKAnCBuYW96YWogc3RhxI3DrSDigJMgYSBhayBuaWUsIHByaWTDoW1lIGplbW7DqSB6YWtyaXZlbmllIChrdmFkcsOhdHkpIGFsZWJvIHpsb20gdiBza2xvbmUgKGluw70gZWZla3QgcHJpIHZ5xaHFocOtY2ggaG9kbm90w6FjaCAoUClIRVYpLgoKKlpqZWRub2R1xaFlbmU6KgoqKlJFU0VUIHRlc3Q6KiogcsO9Y2hsYSBrb250cm9sYSwgxI1pIHByaWFta2Egc3RhxI3DrS4gTWFsw6EgcC1ob2Rub3RhIOKHkiBwcmlkYcWlIG5lbGluZcOhcm5lIHBydmt5LgoqKkMrUiBncmFmeToqKiB1a8Ohxb51LCBrZGUgc2Ega3JpdmthIG9ow71iYSDigJMga3RvcsO6IHByZW1lbm7DuiB0cmFuc2Zvcm1vdmHFpS4KKipLdmFkcsOhdHkgbG9nLXByZW1lbm7DvWNoOioqIGRvdm9saWEgamVtbsOpIHpha3JpdmVuaWUuCioqWmxvbSB2IHNrbG9uZToqKiBkb3ZvbMOtIGluw70gdnBseXYgKFApSEVWIHByaSBuacW+xaHDrWNoIHZzLiB2ecWhxaHDrWNoIGhvZG5vdMOhY2guCioqVsO9YmVyIG1vZGVsdToqKiBwb3Jvdm7DoW1lIEFJQyBhIChhayBzw7ogbW9kZWx5IHYgdGVqIGlzdGVqIG1pZXJrZSkgYWogQU5PVkE7IGtvZWZpY2llbnR5IHbFvmR5IHMgcm9idXN0bsO9bWkgU0UgKEhDMSkuCgojIyAxKSBSYW1zZXkgUkVTRVQg4oCTIGtvbnRyb2xhIMWhcGVjaWZpa8OhY2llCmBgYHtyfQpsaWJyYXJ5KGxtdGVzdCkKCiMgWsOha2xhZG7DvSAobGluZcOhcm55KSBtb2RlbCDigJMgcG91xb7DrXZhbWUgdGVuLCBzIGt0b3LDvW0gcHJhY3VqZcWhIHYgcHLDoWNpOgoKbV9saW4gPC0gbG0oRVBJIH4gbG9nMXAoQkVWX1BIRVYpICsgbG9nMXAoSERQKSwgZGF0YSA9IHVkYWplKQoKIyBSYW1zZXkgUkVTRVQgdGVzdAoKcmVzZXR0ZXN0KG1fbGluKQoKYGBgClJFU0VUIHZ5xaFpZWwgcCA9IDAuMDExIOKGkiB6w6FrbGFkbsOhIGxpbmXDoXJuYSDFoXBlY2lmaWvDoWNpYSBwcmF2ZGVwb2RvYm5lIGNow71iYSAobmVsaW5lYXJpdGEvbmV6YWhybnV0w70gdHZhcikuIFByZXRvIMSPYWxlaiBjaWVsZW5lIGjEvmFkw6FtZSBrZGUgYnkgc2EgbW9obGEga3JpdmthIG9ow71iYcWlIGEgxI1pIHNhIG9wbGF0w60gcHJpZGHFpSBrdmFkcsOhdHkgYWxlYm8gemxvbS4KCiMjIDIpIENvbXBvbmVudCArIFJlc2lkdWFsIChDK1IpIGdyYWZ5IOKAkyBrZGUgc2Ega3JpdmthIG9ow71iYQpgYGB7cn0KbGlicmFyeShjYXIpCmNhcjo6Y3JQbG90cyhtX2xpbikgICAjIHBvenJpZW1lIHpha3JpdmVuaWUgcHJpIGxvZzFwKEJFVl9QSEVWKSBhIGxvZzFwKEhEUCkKCmBgYApDK1IgcHJlIGxvZzFwKEJFVl9QSEVWKSB1a2F6dWplIGNpdGXEvm7DqSBwcmVobnV0aWUgb2tvbG8gfjfigJM5IOKGkiBrYW5kaWTDoXQgbmEgbmVsaW5lw6FybnkgdHZhci4gQytSIHByZSBsb2cxcChIRFApIGplIHByYWt0aWNreSBwcmlhbWthIChsZW4gamVtbsOhIGtyaXZrYSksIHRha8W+ZSB2w71yYXpudSBuZWxpbmVhcml0dSBwcmkgSERQIG5lxI1ha8OhbWUuIFogdG9obyBkw7R2b2R1IHRlc3R1amVtZSBobGF2bmUgw7pwcmF2eSBwcmkgKFApSEVWLgoKIyMgMykgS3ZhZHJhdGlja8OpIMSNbGVueSDigJMgamVtbsOpIHpha3JpdmVuaWUKYGBge3J9CmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkobG10ZXN0KQoKbV9xdWFkIDwtIGxtKEVQSSB+IGxvZzFwKEJFVl9QSEVWKSArIEkobG9nMXAoQkVWX1BIRVYpXjIpICsKbG9nMXAoSERQKSAgICAgICsgSShsb2cxcChIRFApXjIpLApkYXRhID0gdWRhamUpCgojIFBvcm92bmFuaWUga3ZhbGl0eSAobmnFvsWhw60gQUlDIGplIGxlcMWhw60pCgpBSUMobV9saW4sIG1fcXVhZCkKCiMgQU5PVkE6Cgphbm92YShtX2xpbiwgbV9xdWFkKQoKIyBLb2VmaWNpZW50eSBzIHJvYnVzdG7DvW1pIFNFIChIQzEpCgpjb2VmdGVzdChtX2xpbiwgIHZjb3YgPSB2Y292SEMobV9saW4sICB0eXBlID0gIkhDMSIpKQpjb2VmdGVzdChtX3F1YWQsIHZjb3YgPSB2Y292SEMobV9xdWFkLCB0eXBlID0gIkhDMSIpKQoKYGBgCi0gKkFJQyogc2EgemhvcsWhaWwgKDM0NS4wIHZzLiAzNDMuNSkuCgotICpBTk9WQToqIHAgPSAwLjMzIOKGkiBrdmFkcsOhdHkgbmV6bGVwxaF1asO6IG1vZGVsLgoKLSAqUm9idXN0bsOpIFNFIChIQzEpOioga3ZhZHJhdGlja8OpIGtvZWZpY2llbnR5IG5ldsO9em5hbW7DqS4KCioqWsOhdmVyOioqIGt2YWRyw6F0eSBuZXByaW5pZXNsaSBwcsOtbm9zIOKAkyBuZWxpbmVhcml0dSB0YWt0byBuZXBvdHZyZHp1amVtZS4KCiMjIDQpIFpsb20gdiBza2xvbmUg4oCTIGluw70gZWZla3QgKFApSEVWIHByaSB2ecWhxaHDrWNoIGhvZG5vdMOhY2gKYGBge3J9CiMgUHJhaDogbWVkacOhbiBsb2cxcChCRVZfUEhFVikKCmN1dF9iZXYgPC0gbWVkaWFuKGxvZzFwKHVkYWplJEJFVl9QSEVWKSwgbmEucm0gPSBUUlVFKQp1ZGFqZSREX2hpZ2hCRVYgPC0gYXMuaW50ZWdlcihsb2cxcCh1ZGFqZSRCRVZfUEhFVikgPj0gY3V0X2JldikKCiMgKGEpIGxlbiBwb3N1biAoaW50ZXJjZXB0IHNoaWZ0KQoKbV9zaGlmdCA8LSBsbShFUEkgfiBEX2hpZ2hCRVYgKyBsb2cxcChCRVZfUEhFVikgKyBsb2cxcChIRFApLCBkYXRhID0gdWRhamUpCgojIChiKSB6bG9tIHYgc2tsb25lIChpbnRlcmFrY2lhIHByZW1lbm7DoSDDlyBkdW1teSkKCm1fc2xvcGUgPC0gbG0oRVBJIH4gbG9nMXAoQkVWX1BIRVYpKkRfaGlnaEJFViArIGxvZzFwKEhEUCksIGRhdGEgPSB1ZGFqZSkKCiMgUG9yb3ZuYW5pZSBBSUMKCkFJQyhtX2xpbiwgbV9zaGlmdCwgbV9zbG9wZSkKCiMgQU5PVkEgKHJvdm5ha8OhIHZ5c3ZldMS+b3ZhbsOhIHByZW1lbm7DoSkKCmFub3ZhKG1fbGluLCBtX3NoaWZ0KQphbm92YShtX2xpbiwgbV9zbG9wZSkKCiMgUm9idXN0bsOpIFNFCgpjb2VmdGVzdChtX3Nsb3BlLCB2Y292ID0gdmNvdkhDKG1fc2xvcGUsIHR5cGUgPSAiSEMxIikpCgpgYGAKUHJhaCA9IG1lZGnDoW4gbG9nMXAoQkVWX1BIRVYpLiBTa8O6c2lsaSBzbWUgKGEpIHBvc3VuIHByaWFta3kgYSAoYikgem1lbnUgc2tsb251IChpbnRlcmFrY2lhIHMgZHVtbXkpOgoKQUlDIGplIHZ5xaHFocOtIG5lxb4gdiBsaW5lw6Fybm9tIG1vZGVsaSAoaG9yxaFpZSkuCgpBTk9WQTogcG9zdW4gcCA9IDAuNDEsIHptZW5hIHNrbG9udSBwID0gMC41Mi4KClJvYnVzdG7DqSBTRTogaW50ZXJha2NpYSBuZXbDvXpuYW1uw6EuCgoqKlrDoXZlcjoqKiBkw7RrYXogcHJlIG9kbGnFoW7DvSBlZmVrdCAoUClIRVYgcHJpIOKAnnZ5xaHFocOtY2jigJwgw7pyb3ZuaWFjaCBzbWUgbmVuYcWhbGkuCgojIyA1KSBWw71iZXIgcHJhY292bsOpaG8gbW9kZWx1IGEga3LDoXRrZSB6aHJudXRpZQoKS2XEj8W+ZSAoaSkgUkVTRVQgc8OtY2UgbmF6bmHEjWlsIG5lc3Byw6F2bnUgxaFwZWNpZmlrw6FjaXUsIGFsZSAoaWkpIEMrUiB1a8OhemFsIGxlbiBqZW1uw6kgb2h5YnkgYSAoaWlpKSBhbmkga3ZhZHLDoXR5LCBhbmkgemxvbSDFoXRhdGlzdGlja3kgbmV6bGVwxaFpbGkgbW9kZWwsIGFrbyBwcmFjb3Zuw70gbW9kZWwgcG9uZWNow6F2YW1lIHrDoWtsYWRuw7ogbGluZcOhcm51IMWhcGVjaWZpa8OhY2l1IHMgcm9idXN0bsO9bWkgY2h5YmFtaSAoSEMxKS4gViBuZWogdnljaMOhZHphIGxvZzFwKEJFVl9QSEVWKSBuZWdhdMOtdm5lIGEgdsO9em5hbW5lLCBrw71tIGxvZzFwKEhEUCkgcG96aXTDrXZuZSBhIHbDvXpuYW1uZS4gUHJha3RpY2t5OiB2IHRvbXRvIHPDumJvcmUgZMOhdCBWNCBuZXZ5Y2jDoWR6YSwgxb5lIGJ5IG1pZXJuZSB6YWtyaXZlbmlhIGFsZWJvIHByYWhvdsOpIGVmZWt0eSBtZW5pbGkgaGxhdm7DqSB6w6F2ZXJ5OyBhayBqZSBuZWxpbmVhcml0YSBwcsOtdG9tbsOhLCBqZSBza8O0ciBzbGFiw6EgYSBuYcWhZSB0ZXN0eSBqdSBuZXZlZGlhIHByZXN2ZWTEjWl2byB1Y2hvcGnFpSAobGltaXQgdnpvcmt5KS4KCiMjIyBQb3Jvdm7DoXZhY2lhIHRhYnXEvmthIG1vZGVsb3YKYGBge3J9CiMgaXN0b3RhLCDFvmUgbcOhbWUgesOha2xhZG7DvSBsaW5lw6FybnkgbW9kZWwKaWYgKCFleGlzdHMoIm1fbGluIikpIHsKICBtX2xpbiA8LSBsbShFUEkgfiBsb2cxcChCRVZfUEhFVikgKyBsb2cxcChIRFApLCBkYXRhID0gdWRhamUpCn0KCm1vZHMgPC0gbGlzdCgiTGluZcOhcm55IiA9IG1fbGluKQppZiAoZXhpc3RzKCJtX3F1YWQiKSkgICBtb2RzW1siS3ZhZHJhdGlja8O9Il1dICAgPC0gbV9xdWFkCmlmIChleGlzdHMoIm1fc2xvcGUiKSkgIG1vZHNbWyJabG9tIHYgc2tsb25lIl1dIDwtIG1fc2xvcGUKaWYgKGV4aXN0cygibV9zaGlmdCIpKSAgbW9kc1tbIlBvc3VuIMO6cm92bmUiXV0gIDwtIG1fc2hpZnQKCmxpYnJhcnkocHVycnIpOyBsaWJyYXJ5KGxtdGVzdCk7IGxpYnJhcnkoZHBseXIpOyBsaWJyYXJ5KGthYmxlRXh0cmEpCgpyZXNldF9wIDwtIGZ1bmN0aW9uKG0pIHRyeUNhdGNoKHJlc2V0dGVzdChtKSRwLnZhbHVlLCBlcnJvciA9IGZ1bmN0aW9uKGUpIE5BX3JlYWxfKQphbm92YV92c19iYXNlIDwtIGZ1bmN0aW9uKG0sIGJhc2UpIHsKICBpZiAoaWRlbnRpY2FsKGZvcm11bGEoYmFzZSlbWzJdXSwgZm9ybXVsYShtKVtbMl1dKSkgYXMubnVtZXJpYyhhbm92YShiYXNlLCBtKSRgUHIoPkYpYFsyXSkgZWxzZSBOQV9yZWFsXwp9CgpiYXNlX21vZGVsIDwtIG1vZHNbWyJMaW5lw6FybnkiXV0KY21wX3RibCA8LSB0aWJibGUoCiAgbW9kZWwgPSBuYW1lcyhtb2RzKSwKICBBSUMgICA9IG1hcF9kYmwobW9kcywgQUlDKSwKICBhZGpSMiA9IG1hcF9kYmwobW9kcywgfiBzdW1tYXJ5KC54KSRhZGouci5zcXVhcmVkKSwKICBSRVNFVF9wID0gbWFwX2RibChtb2RzLCByZXNldF9wKSwKICBBTk9WQV92c19saW5fcCA9IG1hcF9kYmwobW9kcywgfiBhbm92YV92c19iYXNlKC54LCBiYXNlX21vZGVsKSkKKSAlPiUgYXJyYW5nZShBSUMpCgprYmwoY21wX3RibCwgZGlnaXRzID0gMywgY2FwdGlvbiA9ICJQb3Jvdm5hbmllIMWhcGVjaWZpa8OhY2nDrSAobmnFvsWhaWUgQUlDIGplIGxlcMWhaWUpIikgJT4lCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gRkFMU0UpCgpgYGAKCgojIyMgR3JhZiBwcmVkaWvEjW7DvWNoIGtyaXZpZWsgKExpbmXDoXJueSB2cy4gS3ZhZHJhdGlja8O9IHZzLiBabG9tKQpgYGB7cn0KCiMgUHJlZGlrY2llIHByaSBtZWRpw6FuZSBIRFAKeF9ncmlkIDwtIHRpYmJsZSgKICBCRVZfUEhFViA9IHNlcShtaW4odWRhamUkQkVWX1BIRVYsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgICAgICAgbWF4KHVkYWplJEJFVl9QSEVWLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgIGxlbmd0aC5vdXQgPSAyMDApLAogIEhEUCA9IG1lZGlhbih1ZGFqZSRIRFAsIG5hLnJtID0gVFJVRSkKKQoKcHJlZF9vbmUgPC0gZnVuY3Rpb24obSwgbmFtZSkgewogICMgKGFrIG1vZGVsIHBvdHJlYnVqZSBkdW1teSBEX2hpZ2hCRVYsIGRvcG/EjcOtdGFtZSBqdSBwb2TEvmEgcHJhaHUsIGt0b3LDvSBwb3XFvsOtdmFtZSB2IHByw6FjaSkKICBuZXdkYXQgPC0geF9ncmlkCiAgaWYgKCJEX2hpZ2hCRVYiICVpbiUgbmFtZXMobW9kZWwuZnJhbWUobSkpKSB7CiAgICBjdXRfYmV2IDwtIG1lZGlhbihsb2cxcCh1ZGFqZSRCRVZfUEhFViksIG5hLnJtID0gVFJVRSkKICAgIG5ld2RhdCREX2hpZ2hCRVYgPC0gYXMuaW50ZWdlcihsb2cxcChuZXdkYXQkQkVWX1BIRVYpID49IGN1dF9iZXYpCiAgfQogIHByIDwtIHByZWRpY3QobSwgbmV3ZGF0YSA9IG5ld2RhdCwgc2UuZml0ID0gVFJVRSkKICB0aWJibGUobW9kZWwgPSBuYW1lLAogICAgICAgICBCRVZfUEhFViA9IG5ld2RhdCRCRVZfUEhFViwKICAgICAgICAgZml0ID0gcHIkZml0LAogICAgICAgICBsbyAgPSBwciRmaXQgLSAxLjk2KnByJHNlLmZpdCwKICAgICAgICAgaGkgID0gcHIkZml0ICsgMS45NipwciRzZS5maXQpCn0KCnByZWRfYWxsIDwtIGJpbmRfcm93cygKICBwcmVkX29uZShtX2xpbiwgICJMaW5lw6FybnkiKSwKICBwcmVkX29uZShtX3F1YWQsICJLdmFkcmF0aWNrw70iKSwKICBwcmVkX29uZShtX3Nsb3BlLCJabG9tIHYgc2tsb25lIikKKQoKZ2dwbG90KHByZWRfYWxsLCBhZXMoQkVWX1BIRVYsIGZpdCwgY29sb3IgPSBtb2RlbCwgZmlsbCA9IG1vZGVsKSkgKwogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbG8sIHltYXggPSBoaSksIGFscGhhID0gMC4xMCwgY29sb3IgPSBOQSkgKwogIGdlb21fbGluZShzaXplID0gMSkgKwogIGxhYnMoeCA9ICIoUClIRVYgKHBvxI1ldCkiLCB5ID0gIlByZWRpa292YW7DqSBFUEkiLAogICAgICAgdGl0bGUgPSAiUHJlZGlrxI1uw6kga3Jpdmt5OiBFUEkgdnMuIChQKUhFViBwcmkgbWVkacOhbmUgSERQIiwKICAgICAgIHN1YnRpdGxlID0gIlBvcm92bmFuaWUgxaFwZWNpZmlrw6FjacOtIChsaW5lw6FybnksIGt2YWRyYXRpY2vDvSwgemxvbSB2IHNrbG9uZSkiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKCmBgYApHcmFmIHBvcm92bsOhdmEgcHJlZGlrxI1uw6kga3Jpdmt5IEVQSSB2cy4gKFApSEVWIHByaSBtZWRpw6Fub3ZvbSBIRFAgcHJlIHRyaSDFoXBlY2lmaWvDoWNpZSAobGluZcOhcm5hIHYgbG9nZSwga3ZhZHJhdGlja8OhLCBhIOKAnnpsb20gdiBza2xvbmXigJwpLiBWxaFldGt5IHRyaSBtb2RlbHkgdWthenVqw7ogcm92bmFrw70gcHLDrWJlaDogcyByYXN0w7pjaW0gKFApSEVWIEVQSSBrbGVzw6EgYSBlZmVrdCBzYSBwb3N0dXBuZSBzcGxvxaHFpXVqZSAobmFqbcOkIHByaSBuw616a3ljaCBob2Rub3TDoWNoIGplIHBva2xlcyBzdHJtxaHDrSkuIFJvemRpZWx5IG1lZHppIGtyaXZrYW1pIHPDuiBtYWzDqSDigJMga3ZhZHJhdGlja8OhIHZlcnppYSBqZSBvIG5pZcSNbyBwcnVkxaFpYSB2IGNodm9zdGUsIHphdGlhxL4gxI1vIOKAnnpsb20gdiBza2xvbmXigJwgc2EgcHJha3RpY2t5IHByZWtyw712YSBzIGxpbmXDoXJueW0gbW9kZWxvbS4gSW50ZXJ2YWx5IG5laXN0b3R5IChwcmllc3ZpdG7DqSBww6FzbWEpIHNhIHJvesWhaXJ1asO6IHYgZXh0csOpbW9jaCwga2RlIGplIG1lbmVqIGTDoXQuIFNwb2x1IHMgdsO9c2xlZGthbWkgQUlDL0FOT1ZBIHZ5xaHFoWllIHRvIG5hem5hxI11amUsIMW+ZSBqZWRub2R1Y2jDvSBsaW5lw6FybnkgbW9kZWwgdiBsb2dlIHBvc3RhxI11amU7IHByw61wYWRuw6kgbmVsaW5lYXJpdHkgbmlqYWtvIG5lbWVuaWEga3ZhbGl0YXTDrXZueSB6w6F2ZXIgbyBuZWdhdMOtdm5laiBhc29jacOhY2lpIChQKUhFViBhIEVQSSBwbyB6b2jEvmFkbmVuw60gSERQLgoKCiMgU3RydcSNbsOhIHRhYnXEvmthIHbDvXNsZWRrb3YgYSB6w6F2ZXIKYGBge3J9CmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KGthYmxlRXh0cmEpCgojIyAxKSBzdHJ1xI1uw6EgZGlhZ25vc3Rpa2EKCnN1bV90YmwgPC0gdGliYmxlOjp0aWJibGUoCmBR4oCTUSBwbG90YCAgICAgICAgICAgICAgICAgID0gIlbDpMSNxaFpbmEgYm9kb3YgbmEgcHJpYW1rZTsgbGVuIG1pZXJuZSBvZGNow71sa3kgdiBjaHZvc3RvY2guIiwKYFNjYWxl4oCTTG9jYXRpb25gICAgICAgICAgICAgPSAiSmVtbsO9IFUtdHZhciDihpIgc2xhYsOhIGhldGVyb3NrZWRhc3RpY2l0YSAocmllxaFpbWUgcm9idXN0bsO9bWkgU0UpLiIsCmBSZXNpZHVhbHMgdnMgTGV2ZXJhZ2VgICAgICA9ICJQw6FyIHZwbHl2bsO9Y2ggYm9kb3YsIGJleiBleHRyw6ltb3YuIiwKYEhldGVyb3NrZWRhc3RpY2l0YSDigJMgdGVzdHlgPSAiQnJldXNjaOKAk1BhZ2FuIGEgTkNWIG5ldsO9em5hbW7DqTsgV2hpdGUgxaF0w71sIGhyYW5pxI1uw70g4oaSIHNrw7RyIHNsYWLDvSBuw6F6bmFrLiIsCmBSRVNFVCAoxaFwZWNpZmlrw6FjaWEpYCAgICAgID0gInAg4omIIDAuMDExIOKHkiBsaW5lw6FybmEgxaFwZWNpZmlrw6FjaWEgbcOhIHpuw6Fta3kgbmVzcHLDoXZuZWogZm9ybXkgKHNrw7rFoWFsaSBzbWUgamVtbsOpIG5lbGluZWFyaXR5KS4iCikKCmVtZXJhbGRfbGlnaHQgPC0gIiNFQ0ZERjUiOyBlbWVyYWxkX2hlYWQgPC0gIiNEMUZBRTUiOyBlbWVyYWxkX3RleHQgPC0gIiMwNjVGNDYiCgprYmwoCnN1bV90YmwsCmNhcHRpb24gPSAiRGlhZ25vc3Rpa2Eg4oCTIHN0cnXEjW7DqSB6aHJudXRpZSIsCmJvb2t0YWJzID0gVFJVRQopIHw+CmthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFRSVUUsIGh0bWxfZm9udCA9ICJIZWx2ZXRpY2EiKSB8Pgpyb3dfc3BlYygwLCBiYWNrZ3JvdW5kID0gZW1lcmFsZF9oZWFkLCBjb2xvciA9IGVtZXJhbGRfdGV4dCwgYm9sZCA9IFRSVUUpIHw+CmNvbHVtbl9zcGVjKDE6bmNvbChzdW1fdGJsKSwgYmFja2dyb3VuZCA9IGVtZXJhbGRfbGlnaHQsIGNvbG9yID0gZW1lcmFsZF90ZXh0LCBib3JkZXJfbGVmdCA9IFRSVUUsIGJvcmRlcl9yaWdodCA9IFRSVUUpCgojIyAyKSBwb3Jvdm5hbmllIMWhcGVjaWZpa8OhY2nDrSAoQUlDKQoKIyBwcmVkcG9rbGFkOiBvYmpla3R5IG1fbGluLCBtX3F1YWQsIG1fc2xvcGUgc8O6IHXFviBvZGhhZG51dMOpIHYgZG9rdW1lbnRlCgphaWNfdGJsIDwtIHRyeUNhdGNoKAp7CmFhIDwtIEFJQyhtX2xpbiwgbV9xdWFkLCBtX3Nsb3BlKQpkcGx5cjo6cmVuYW1lKGFhLCBNb2RlbCA9IGRmLCBBSUMgPSBBSUMpIHw+CmRwbHlyOjptdXRhdGUoTW9kZWwgPSByb3duYW1lcyhhYSkpCn0sCmVycm9yID0gZnVuY3Rpb24oZSkgdGliYmxlOjp0aWJibGUoCk1vZGVsID0gYygiTGluZcOhcm55IiwgIkt2YWRyYXRpY2vDvSIsICJabG9tIHYgc2tsb25lIiksCkFJQyAgID0gYygzNDMuNTAsIDM0NS4wMywgMzQ2LjM2KSAgICMgaG9kbm90eSB6IHR2b2ppY2ggdsO9c3R1cG92CikKKQoKa2JsKGFpY190YmwsIGNhcHRpb24gPSAiUG9yb3ZuYW5pZSBrdmFsaXR5IG1vZGVsb3YgKG5pxb7FocOtIEFJQyA9IGxlcMWhw60pIiwgYm9va3RhYnMgPSBUUlVFKSB8PgprYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGQUxTRSwgaHRtbF9mb250ID0gIkhlbHZldGljYSIpIHw+CnJvd19zcGVjKDAsIGJhY2tncm91bmQgPSBlbWVyYWxkX2hlYWQsIGNvbG9yID0gZW1lcmFsZF90ZXh0LCBib2xkID0gVFJVRSkgfD4KY29sdW1uX3NwZWMoMTpuY29sKGFpY190YmwpLCBiYWNrZ3JvdW5kID0gZW1lcmFsZF9saWdodCwgY29sb3IgPSBlbWVyYWxkX3RleHQpCgojIyAzKSBoeXBvdMOpenkKCmh5cF90YmwgPC0gdGliYmxlOjp0cmliYmxlKAp+UHJlbWVubsOhLCAgfmBIMSAob8SNYWvDoXZhbmllKWAsICAgfmBSb3pob2RudXRpZSBvIEgwYCwgICAgICAgICAgICAgICB+YFJvemhvZG51dGllIG8gSDFgLCAgICAgICAgICAgICAgflBvem7DoW1rYSwKIkJFViIsICAgICAgIs6yID4gMCIsICAgICAgICAgICAgICAiTkVaQU1JRVRBTSAvIG5laXN0w6kiLCAgICAgICAgICAgICJORVBPRFBPUlVKRU1FIiwgICAgICAgICAgICAgICAgICAiRWZla3QgbmV2w716bmFtbsO9IGFsZWJvIHrDoXBvcm7DvS4iLAoiQkVWX1BIRVYiLCAizrIgPiAwIiwgICAgICAgICAgICAgICJaQU1JRVRBTSAodsO9em5hbW7DqSwgesOhcG9ybsOpKSIsICAgIlpBTUlFVEFNIChwb3ppdMOtdm55IHNhIG5lcG90dnJkaWwpIiwibG9nMXAoQkVWX1BIRVYpIHN0YWJpbG5lIG5lZ2F0w612bnkgcyBIQzEuIiwKIkhEUCIsICAgICAgIs6yID4gMCIsICAgICAgICAgICAgICAiWkFNSUVUQU0gKHbDvXpuYW1uw6ksIHBveml0w612bmUpIiwgIlBPRFBPUlVKRU1FIiwgICAgICAgICAgICAgICAgICAgICJIRFAgdnljaMOhZHphIGtsYWRuZSBhIHbDvXpuYW1uZS4iCikKCmtibChoeXBfdGJsLCBjYXB0aW9uID0gIkh5cG90w6l6eSBhIHJvemhvZG51dGlhIChyb2J1c3Ruw6kgU0UpIiwgYm9va3RhYnMgPSBUUlVFKSB8PgprYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBGQUxTRSwgaHRtbF9mb250ID0gIkhlbHZldGljYSIpIHw+CnJvd19zcGVjKDAsIGJhY2tncm91bmQgPSBlbWVyYWxkX2hlYWQsIGNvbG9yID0gZW1lcmFsZF90ZXh0LCBib2xkID0gVFJVRSkgfD4KY29sdW1uX3NwZWMoMTpuY29sKGh5cF90YmwpLCBiYWNrZ3JvdW5kID0gZW1lcmFsZF9saWdodCwgY29sb3IgPSBlbWVyYWxkX3RleHQpCmBgYAojIyBEaXNrdXNpYSwgbGltaXR5IGEgesOhdmVyCgoqKsSMbyB1a8OhemFsYSBkaWFnbm9zdGlrYSBhIHRlc3R5OioqClJvenB0eWwgY2jDvWIgamUgbmFqbcOkICpzbGFibyBuZWhvbW9nw6lubnkqLCBwcmV0byB2IGNlbGVqIHByw6FjaSByZXBvcnR1amVtZSAqcm9idXN0bsOpIHNtZXJvZGFqbsOpIGNoeWJ5IChIQzEpKi4gCipSRVNFVCB0ZXN0IChwIOKJiCAwLjAxMSkqIHNpZ25hbGl6b3ZhbCwgxb5lIHNhbW90bsOhIHByaWFta2EgbcO0xb5lIGJ5xaUgcHJlIGplZG5vZHVjaMO9IGxpbmXDoXJueSBtb2RlbCB0ZXNuw6EsIHByZXRvIHNtZSBza8O6c2lsaSBqZW1uw6kgbmVsaW5lYXJpdHkgKGt2YWRyw6F0IGxvZzFwKEJFVl9QSEVWKSwga3ZhZHLDoXQgbG9nMXAoSERQKSkgYSBhaiB6bG9tIHYgc2tsb25lIHBvZMS+YSDDunJvdm5lIChQKUhFVi4KCioqUG9yb3ZuYW5pZSDFoXBlY2lmaWvDoWNpw606KioKTmFwcmllayBzaWduw6FsdSB6IFJFU0VULXUgc2Ega3ZhbGl0YSBtb2RlbG92IG5lemxlcMWhaWxhIOKAkyBBSUMgamUgbmFqbmnFvsWhw60gcHJpIGxpbmXDoXJub20gbW9kZWxpIGEgQU5PVkEgcG9yb3ZuYW5pYSBrdmFkcmF0aWNrZWovemxvbW92ZWogxaFwZWNpZmlrw6FjaWUgdm/EjWkgbGluZcOhcm5laiBuZXZ5xaFsaSB2w716bmFtbmUuIFByZWRpa8SNbsOpIGtyaXZreSBwcmUgdsWhZXRreSB0cmkgdmVyemllIHPDuiB0dmFyb3ZvIHBvZG9ibsOpIChtaWVybmUga2xlc2Fqw7pjZSksIHJvemRpZWx5IHPDuiBtYWzDqSBhIHYgcsOhbWNpIGludGVydmFsb3Ygc3BvxL5haGxpdm9zdGkuCgoqKkludGVycHJldMOhY2lhIMO6xI1pbmtvdiAocm9idXN0bsOpIFNFKToqKgoKLSBsb2cxcChCRVZfUEhFVikgamUgbmVnYXTDrXZueSBhIMWhdGF0aXN0aWNreSB2w716bmFtbsO9IOKAkyB2IG5hxaFvbSBzw7pib3JlIHNhIHMgdnnFocWhw61tIHJvesWhw61yZW7DrW0gKFApSEVWIHNww6FqYSBuacW+xaHDrSBFUEkuCgotIEhEUCBqZSBwb3ppdMOtdm55IGEgdsO9em5hbW7DvSDigJMga3JhamlueS9yb2t5IHMgdnnFocWhw61tIEhEUCBkb3NhaHVqw7ogdnnFocWhw60gRVBJLgoKLSBTYW1vdG7DqSBCRVYgbmV2ecWhbG8gcm9idXN0bmUgcG96aXTDrXZuZS4KCioqWmplZG5vZHXFoWVuZToqKiB2aWFjIChQKUhFViDiiaAgdnnFocWhw60gRVBJIHYga3LDoXRrb20gaG9yaXpvbnRlOyBFUEkgenJlam1lIG92cGx5dsWIdWrDuiDFoWlyxaFpZSBmYWt0b3J5IChla29ub21pY2vDoSDDunJvdmXFiCwgxaF0cnVrdMO6cmEgZW5lcmdpw60sIHpsb8W+ZW5pZSBkb3ByYXZ5IGF0xI8uKS4KCioqTGltaXR5OioqIG1hbMOhIHZ6b3JrYSAoVjQgw5cgcm9reSksIGFncmVnYcSNbsOhIMO6cm92ZcWILCBtb8W+bsOhIG1lcmFjaWEgY2h5YmEgdiByZWdpc3Ryb2NoIHZvemlkaWVsLCBjaMO9YmFqw7pjZSBrb250cm9seSAoZW5lcmdldGlja8O9IG1peCwgZG9wcmF2bsOpIHbDvWtvbnksIHByaWVteXNlbCkuIEtyw6F0a2Ugb2Jkb2JpZSBtw7TFvmUgc2tyw712YcWlIG9uZXNrb3JlbsOpIMO6xI1pbmt5Lgo=