knitr::opts_chunk$set(
    echo = TRUE,
    message = FALSE,
    warning = FALSE
)
install.packages(c(
  "tidyverse",
  "readr",
  "dplyr",
  "ggplot2",
  "knitr",
  "kableExtra",
  "broom",
  "stringr",
  "corrplot",
  "zoo",
  "tseries",
  "lmtest",
  "sandwich",
  "car",
  "corrplot",
  "patchwork"
), dependencies = TRUE)
library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())

Úvod do problému, stanovenie hypotéz

V tejto úlohe pracujeme s databázou Indian Water Data, ktorá obsahuje údaje o kvalite vody na rôznych lokalitách v Indii.
Cieľom je:

  • preskúmať štatistické vlastnosti jednotlivých ukazovateľov kvality vody,
  • analyzovať vzťahy medzi nimi,
  • a pomocou lineárnej regresie vysvetliť, ktoré faktory ovplyvňujú napríklad pH vody.

V tejto úlohe predpokladáme, že pH vody je ovplyvňované viacerými faktormi kvality vody.
Testujeme, či majú teplota, množstvo rozpusteného kyslíka, elektrická vodivosť, biologická spotreba kyslíka, obsah dusičnanov a fekálne koliformy významný vplyv na hodnotu pH.

Nulová hypotéza (H₀) tvrdí, že žiadny z týchto ukazovateľov nemá štatisticky významný vplyv na pH vody.
Alternatívna hypotéza (H₁) predpokladá, že aspoň jeden z týchto ukazovateľov má na pH štatisticky významný účinok.

library(dplyr)
library(tidyverse)
library(kableExtra)
library(corrplot)

data <- read.csv("Indian_water_data.csv")
str(data)
summary(data)

# Doplnenie chýbajúcich hodnôt mediánom
column_medians <- sapply(data, median, na.rm = TRUE)
for (col in names(data)) {
  if (is.numeric(data[[col]])) {
    data[[col]][is.na(data[[col]])] <- column_medians[col]
  }
}

# Vyber číselné premenné

data_num <- data %>% select(where(is.numeric))

# Základné štatistiky

data_num %>%
summary() %>%
kable(caption = "Základné štatistiky numerických premenných") %>%
kable_styling(full_width = FALSE)

# Vizualizácia dát

library(ggplot2)
library(tidyr)
library(dplyr)
library(scales)

# Prevedieme dáta do long formátu
data_long <- data_num %>%
  pivot_longer(cols = everything(), names_to = "Premenná", values_to = "Hodnota")

# Normalizácia každej premennej (0–1 rozsah)
data_scaled <- data_long %>%
  group_by(Premenná) %>%
  mutate(Hodnota_scaled = (Hodnota - min(Hodnota, na.rm = TRUE)) / 
                           (max(Hodnota, na.rm = TRUE) - min(Hodnota, na.rm = TRUE))) %>%
  ungroup()

# Boxplot po škálovaní
ggplot(data_scaled, aes(x = Premenná, y = Hodnota_scaled, fill = Premenná)) +
  geom_boxplot(outlier.color = "red", notch = TRUE, alpha = 0.7) +
  theme_minimal(base_size = 16) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 12),
    legend.position = "none"
  ) +
  labs(
    title = "Boxploty jednotlivých numerických premenných (štandardizované)",
    x = "",
    y = "Škálovaná hodnota (0–1)"
  )

Interpretácia boxplotov jednotlivých numerických premenných

Boxploty ukazujú rozdelenie hodnôt jednotlivých premenných po štandardizácii (v rozsahu 0–1).
Z grafu vidno niekoľko dôležitých poznatkov:

  • Premenné Conductivity...µmho.cm....Max a BOD..mg.L....Max majú veľký počet odľahlých hodnôt (červené body),
    čo naznačuje výraznú variabilitu medzi lokalitami — v niektorých oblastiach je vodivosť alebo biologická spotreba kyslíka extrémne vysoká.

  • pH...Min a pH...Max majú pomerne úzke rozpätie, čo je typické — pH vody sa zvyčajne pohybuje v úzkom intervale 6–8.

  • Temperature..C....Max a Temperature..C....Min sú rozložené rovnomerne, bez výrazných extrémov —
    to poukazuje na konzistentné klimatické podmienky meraných lokalít.

  • Total.Coliform..MPN.100ml....Max vykazuje mierne vyšší rozptyl,
    čo znamená, že bakteriologická kontaminácia vody sa výrazne líši podľa miesta merania.

  • Year a STN.code sú technické premenné (identifikátory, nie environmentálne ukazovatele),
    preto ich rozdelenie tu nemá analytický význam.

# Korelačná matica

corr <- cor(data_num, use = "complete.obs")
corrplot(corr, method = "color", type = "upper", tl.cex = 0.7)

Interpretácia korelačnej matice

Korelačná analýza naznačuje, že najvyššia korelácia s pH...Max je pozorovaná pri ukazovateľoch
rozpusteného kyslíka (Dissolved...Max) a vodivosti (Conductivity...µmho.cm....Max).
To potvrdzuje, že chemické vlastnosti vody, ako koncentrácia kyslíka a množstvo rozpustených iónov,
významne súvisia so zmenami pH.

Slabá alebo zanedbateľná korelácia je viditeľná medzi pH a biologickou spotrebou kyslíka (BOD),
čo naznačuje, že tento parameter pH ovplyvňuje len nepriamo.

Teplota vody vykazuje miernu pozitívnu koreláciu s pH,
čo môže odrážať fyzikálno-chemickú väzbu medzi teplotou a rozpúšťaním plynov vo vode.

Lineárna regresia

Predpokladajme, že maximálna hodnota pH vody je závislá premenná a ostatné chemické a biologické ukazovatele kvality vody, ako sú teplota, obsah rozpusteného kyslíka, vodivosť, biologická spotreba kyslíka, obsah dusičnanov a fekálnych koliformov, predstavujú nezávislé premenné.

# Najprv premeň prázdne bunky alebo texty ako "BDL" na NA
data$Fecal.Coliform..MPN.100ml....Max[data$Fecal.Coliform..MPN.100ml....Max %in% c("", "BDL", "NA")] <- NA

# Potom prevedieš na čísla
data$Fecal.Coliform..MPN.100ml....Max <- as.numeric(data$Fecal.Coliform..MPN.100ml....Max)

# Lineárny model – pH...Max ako závislá premenná
model <- lm(pH...Max ~ Temperature..C....Max + Dissolved...Max + Conductivity...µmho.cm....Max + 
              BOD..mg.L....Max + NitrateN..mg.L....Max + Fecal.Coliform..MPN.100ml....Max, 
            data = data)

# Výstupy modelu
cat("Odhadnuté koeficienty modelu:\n")
print(model$coefficients)

cat("Odhadnuté rezíduá (zvyšky):\n")
print(head(model$residuals, 10))  # len prvých 10 prehľadne

cat("Vyrovnané (predikované) hodnoty závislej premennej:\n")
print(head(model$fitted.values, 10))  # opäť len prvých 10

cat("Matica modelu (X):\n")
X <- model.matrix(model)
print(head(X))

cat("Projekčná matica (hat matrix):\n")
H <- X %*% solve(t(X) %*% X) %*% t(X)
print(round(H[1:5, 1:5], 4))  # len prvých 5x5 prvkov pre prehľadnosť

cat("Súhrn modelu:\n")
summary(model)

Interpretácia a diagnostika modelu

Súhrn odhadovaného modelu nám poskytuje súbor odhadnutých regresných koeficientov, ktorých znamienka a významnosť budú interpretované nižšie.
Ak hovoríme o vlastnostiach modelu ako celku, pozrime sa najskôr na diagnostické grafy.

# Nastaviť rozloženie 2 x 2
par(mfrow = c(2, 2))

# Vykresliť všetky 4 diagnostické grafy modelu
plot(model)

# Pridať spoločný nadpis
mtext("Diagnostické grafy regresného modelu – pH...Max", 
      outer = TRUE, cex = 1.2, font = 2)

# Resetovať layout
par(mfrow = c(1, 1))

Interpretácia diagnostických grafov pre model pH…Max

Residuals vs. Fitted

  • Rezíduá sa pohybujú približne okolo nulovej osi – model teda nemá systematické skreslenie v predikcii hodnôt pH.
  • Červená LOESS čiara je relatívne rovná, čo naznačuje, že vzťah medzi pH a zvolenými premennými (napr. teplota, vodivosť, BOD, dusičnany) je prevažne lineárny.
  • Vertikálny rozptyl je približne rovnomerný → predpoklad homoskedasticity (konštantného rozptylu chýb) je v zásade splnený.
  • Niekoľko bodov mimo hlavný rozptyl môže predstavovať lokality s extrémnymi hodnotami kvality vody (potenciálne odľahlé pozorovania), ktoré si overíme pomocou testov.

Q–Q plot

  • Väčšina bodov leží pozdĺž diagonály → rezíduá modelu pH…Max sú takmer normálne rozložené.
  • Na koncoch (vľavo dole a vpravo hore) možno pozorovať mierne odchýlky – to naznačuje ťažšie chvosty rozdelenia, pravdepodobne spôsobené extrémnymi hodnotami niektorých chemických ukazovateľov.
  • Stredná časť grafu je dobre zarovnaná, čo potvrdzuje, že väčšina pozorovaní sa správa normálne.

Scale–Location plot

  • Body sú rozptýlené rovnomerne po osi X bez vytvárania lievika → rozptyl rezíduí je približne konštantný.
  • Hladká LOESS čiara je takmer vodorovná, čo naznačuje, že variabilita chýb sa nemení so zmenou predikovaných hodnôt pH.
  • Tento výsledok podporuje platnosť predpokladu o homoskedasticite modelu.

Residuals vs. Leverage

  • Väčšina bodov má nízky vplyv (Cookova vzdialenosť < 0.5) → žiadne pozorovanie neovplyvňuje regresné koeficienty výrazne.
  • Jeden alebo dva body môžu mať zvýšenú pákovú hodnotu – ide pravdepodobne o lokality s extrémne odlišnými parametrami vody, ktoré však model výrazne nedeformujú.
  • Celkovo pôsobí model stabilne a bez významných odľahlých alebo vplyvných bodov.

Zhrnutie

Diagnostické grafy potvrdzujú, že model s vysvetľovanou premennou pH…Max a prediktormi
(Temperature..C….Max, Dissolved…Max, Conductivity…µmho.cm….Max,
BOD..mg.L….Max, NitrateN..mg.L….Max a Fecal.Coliform..MPN.100ml….Max)
spĺňa hlavné predpoklady lineárnej regresie.

Rezíduá sú približne normálne rozložené, rozptyl chýb je konštantný a väčšina pozorovaní nemá nadmerný vplyv na výsledok modelu.
Model teda možno považovať za štatisticky spoľahlivý na interpretáciu vzťahu medzi ukazovateľmi kvality vody a pH.

# Nový model so zlogaritmovanou Conductivity
model2 <- lm(pH...Max ~ Temperature..C....Max + Dissolved...Max +
               I(log(Conductivity...µmho.cm....Max)) +
               BOD..mg.L....Max + NitrateN..mg.L....Max, 
             data = data)
summary(model2)
par(mfrow = c(2, 2))
plot(model2)
par(mfrow = c(1, 1))

Transformácia premennej Conductivity...µmho.cm....Max pomocou logaritmu bola zvolená na zníženie vplyvu extrémnych hodnôt, ktoré sa v pôvodných údajoch výrazne líšili medzi lokalitami.
Po aplikácii logaritmickej transformácie sa model správa stabilnejšie a jeho koeficienty sú lepšie interpretovateľné.

Interpretácia diagnostických grafov pre model so zlogaritmovanou vodivosťou

Residuals vs Fitted

Rezíduá sa pohybujú rovnomerne okolo nulovej osi, čo naznačuje, že model nemá systematické skreslenie v predikcii hodnôt pH.
Červená LOESS čiara je takmer vodorovná, čo potvrdzuje, že po logaritmickej transformácii vodivosti sa odstránila pôvodná mierna nelinearita.
Vertikálny rozptyl rezíduí je konštantný – predpoklad homoskedasticity je teda splnený.
Niekoľko jednotlivých bodov s väčšou odchýlkou môže patriť extrémnym lokalitám, no neovplyvňujú model významne.


Q–Q plot

Väčšina bodov leží veľmi blízko diagonály, čo znamená, že rezíduá sú približne normálne rozložené.
Menšie odchýlky na koncoch (vľavo dole a vpravo hore) naznačujú len mierne odchýlky od normálnosti,
ktoré môžu byť spôsobené prítomnosťou niekoľkých extrémnych meraní.
Oproti pôvodnému modelu sa rozdelenie rezíduí výrazne zlepšilo – log-transformácia teda pomohla.


Scale–Location plot

Body sú rozptýlené rovnomerne pozdĺž osi X bez známok rozširujúceho sa „lievika“,
čo potvrdzuje, že variancia rezíduí je konštantná naprieč predikovanými hodnotami.
Červená hladká čiara je takmer rovná, čo naznačuje, že rozptyl chýb sa nemení so zmenou hodnôt pH.
Model teda spĺňa predpoklad homoskedasticity veľmi dobre.


Residuals vs Leverage

Väčšina pozorovaní má nízky pákový efekt (leverage < 0.1) a Cookova vzdialenosť zostáva pod 0.5.
To znamená, že žiadne pozorovanie neovplyvňuje model nadmerne.
Niekoľko bodov (napr. 191, 66) vykazuje mierne vyšší vplyv, ale nepresahuje kritické hodnoty.
Model teda neobsahuje výrazne vplyvné alebo odľahlé prípady.


Zhrnutie diagnostiky

Transformovaný model (so zlogaritmovanou vodivosťou) výrazne zlepšil štatistické vlastnosti rezíduí: - odstránil miernu nelinearitu z pôvodného modelu,
- znížil heteroskedasticitu,
- a priblížil rozdelenie rezíduí k normálnemu tvaru.

Model je teda stabilný, spoľahlivý a vhodný na interpretáciu vzťahu medzi kvalitou vody a pH.

Testy normality a identifikácia odľahlých hodnôt

V tejto časti overíme, či rezíduá pôvodného modelu spĺňajú predpoklad normality rozdelenia
a zároveň identifikujeme možné odľahlé pozorovania, ktoré by mohli ovplyvňovať výsledky.

jarque.bera.test(residuals(model))
car::outlierTest(model)

🧪 Testy normality a odľahlých hodnôt po transformácii (model2)

Po úprave modelu (logaritmácia vodivosti) overíme, či sa zlepšila normalita rozdelenia rezíduí a či sa znížil počet odľahlých hodnôt.

# Jarque–Bera test pre model2
jarque.bera.test(residuals(model2))

# Test odľahlých hodnôt pre model2
car::outlierTest(model2)

Interpretácia výsledkov:

Výsledky Jarque–Bera testu pre model2 ukazujú, že p-hodnota je vyššia než v pôvodnom modeli.
To znamená, že po logaritmickej transformácii premennej Conductivity...µmho.cm....Max sa
normalita rezíduí zlepšila, hoci pri menšom počte pozorovaní nemusí byť úplne dokonalá.

Outlier Test už neidentifikuje žiadne výrazne významné odľahlé pozorovanie,
čo potvrdzuje, že pôvodný extrémny bod (pozorovanie č. 191) už nemá podstatný vplyv na model.

Záver: Transformovaný model (model2) lepšie spĺňa predpoklady lineárnej regresie –
rezíduá sú bližšie k normálnemu rozdeleniu a model je robustnejší voči odľahlým hodnotám.

Záver

Na základe regresnej analýzy možno konštatovať, že maximálne pH vody (pH…Max)
je ovplyvnené viacerými faktormi kvality vody.
Premenné teplota vody, rozpustený kyslík a vodivosť majú prevažne pozitívny vplyv,
kým biologická spotreba kyslíka a fekálne koliformy pH znížujú.

Transformácia premennej Conductivity...µmho.cm....Max pomocou logaritmu
zlepšila štatistické vlastnosti modelu — rezíduá sú bližšie k normálnemu rozdeleniu
a rozptyl chýb je stabilnejší (homoskedasticita).
Model je teda vo všeobecnosti spoľahlivejší a lepšie spĺňa predpoklady lineárnej regresie.

Napriek tomu však testy odľahlých hodnôt ukázali, že pozorovanie č. 191
zostáva odľahlé aj po transformácii.
Ide teda o extrémne meranie, ktoré má potenciál ovplyvniť výsledky modelu —
v budúcnosti by bolo vhodné toto pozorovanie osobitne preskúmať
(napr. či nejde o chybu merania alebo špecifickú lokalitu s výrazne odlišnými podmienkami).

Celkovo možno uzavrieť, že transformovaný model lepšie vystihuje vzťahy medzi ukazovateľmi kvality vody a pH,
no prítomnosť jedného trvalého odľahlého pozorovania (č. 191)
je potrebné mať na pamäti pri interpretácii výsledkov.

Heteroskedasticita

Prítomnosť heteroskedasticity (nekonštantného rozptylu náhodnej zložky) spôsobuje chybné vyhodnocovanie t-testov významnosti jednotlivých regresných koeficientov.
Preto je nutné heteroskedasticitu:

  • detekovať (vizuálne a pomocou testov),
  • a v prípade jej prítomnosti ju odstrániť alebo kompenzovať.

Aj v našom prípade sa pokúsime o vizuálne vyhodnotenie závislosti štvorcov rezíduí od vysvetľujúcich premenných, u ktorých máme podozrenie, že môžu heteroskedasticitu spôsobovať.

Budeme posudzovať dva modely: - model – pôvodný model, - model2 – model so zlogaritmovanou vodivosťou (Conductivity...µmho.cm....Max), ktorého cieľom bolo znížiť vplyv extrémnych hodnôt.

# Heteroskedasticita – lokálne bez riadku 191 (globálne 'data' nemeníme)
library(ggplot2)
library(patchwork)

# 1) Lokálna kópia a vyhodenie 191. riadku
data_h <- data
if (nrow(data_h) >= 191) {
  data_h <- data_h[-191, , drop = FALSE]
}

# 2) Refit modelov na data_h
model_h <- lm(
  pH...Max ~ Temperature..C....Max + Dissolved...Max +
    Conductivity...µmho.cm....Max + BOD..mg.L....Max +
    NitrateN..mg.L....Max + Fecal.Coliform..MPN.100ml....Max,
  data = data_h, na.action = na.exclude
)

model2_h <- lm(
  pH...Max ~ Temperature..C....Max + Dissolved...Max +
    I(log(Conductivity...µmho.cm....Max)) +
    BOD..mg.L....Max + NitrateN..mg.L....Max,
  data = data_h, na.action = na.exclude
)

# 3) Dáta použité v modeloch (len riadky, ktoré model skutočne použil)
df_model  <- as.data.frame(model.frame(model_h))
df_model2 <- as.data.frame(model.frame(model2_h))

# --- ZAROVNANIE REZÍDUÍ PODĽA MIEN RIADKOV (kritické) ---
r1 <- residuals(model_h)
df_model$Residuals <- as.numeric(r1[match(rownames(df_model), names(r1))])

r2 <- residuals(model2_h)
df_model2$Residuals <- as.numeric(r2[match(rownames(df_model2), names(r2))])

# 4) Grafy – pôvodný model (analóg GDP/Schooling)
p1 <- ggplot(df_model, aes(x = `Conductivity...µmho.cm....Max`, y = Residuals^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Vodivosť (µmho/cm)",
       y = "Štvorce rezíduí",
       title = "Štvorce rezíduí vs Vodivosť") +
  theme_minimal()

p2 <- ggplot(df_model, aes(x = `Temperature..C....Max`, y = Residuals^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Teplota (°C)",
       y = "Štvorce rezíduí",
       title = "Štvorce rezíduí vs Teplota") +
  theme_minimal()

p1 + p2

a teraz transformovaný model

# doplň surovú vodivosť (a pre istotu aj teplotu) do df_model2 podľa rovnakých riadkov
idx2 <- as.integer(rownames(df_model2))
df_model2$Conductivity <- data_h$`Conductivity...µmho.cm....Max`[idx2]
df_model2$Temperature  <- data_h$`Temperature..C....Max`[idx2]

# 5) Grafy – transformovaný model (log vodivosti)
p3 <- ggplot(df_model2, aes(x = log(Conductivity), y = Residuals^2)) +
  geom_point(alpha = 0.6, color = "darkgreen") +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "log(Vodivosť)",
       y = "Štvorce rezíduí",
       title = "Štvorce rezíduí vs log(Vodivosť)") +
  theme_minimal()

p4 <- ggplot(df_model2, aes(x = Temperature, y = Residuals^2)) +
  geom_point(alpha = 0.6, color = "darkgreen") +
  geom_smooth(method = "loess", se = FALSE, color = "red") +
  labs(x = "Teplota (°C)",
       y = "Štvorce rezíduí",
       title = "Štvorce rezíduí vs Teplota") +
  theme_minimal()

p3 + p4

Na tomto obrázku podľa vyhladených hodnôt štvorcov rezíduí (červená krivka) môžeme konštatovať, že po logaritmickej transformácii vodivosti log(Vodivosť) (pravý panel prvého riadku) krivka nevykazuje systematický trend s vysvetľujúcou premennou a variancia chýb je približne konštantná. Podobne pri Teplote vidíme iba mierny lokálny „hrbol“ okolo 25–33 °C, ktorý však nepredstavuje výrazný rast variability.

Kvôli demonštrácii ale ukážme, že bez predchádzajúcej logaritmickej transformácie by to dopadlo inak. V pôvodnom modeli (ľavý panel prvého riadku) je červená krivka pri Vodivosti mierne klesajúca – naznačuje to slabú heteroskedasticitu (väčší rozptyl chýb pri nižšej vodivosti), ktorá sa po prechode na log(Vodivosť) vytráca a krivka sa výrazne splošťuje.

Zhrnutie: Transformácia log(Vodivosť) zjavne stabilizuje rozptyl a vizuálne nevidíme významný vývoj štvorcov rezíduí s vysvetľujúcimi premennými. Pre úplnosť je vhodné tento dojem potvrdiť formálnym testom (napr. Breusch–Pagan/Koenker–Bassett) a reportovať inferenciu s robustnými (HC1) chybami.

Testovanie prítomnosti heteroskedasticity

Najprv otestujeme prítomnosť heteroskedasticity pomocou Breusch–Pagan testu (študentizovaná verzia = Koenker–Bassett).
Následne – ak by heteroskedasticita pretrvávala – reportujeme odhady s White/HC-robustnými smerodajnými chybami (typ HC1).

m1 <- if (exists("model_h")) model_h else if (exists("model")) model else stop("Model m1 neexistuje.")
m2 <- if (exists("model2_h")) model2_h else if (exists("model2")) model2 else stop("Model m2 neexistuje.")

library(lmtest)

#Breusch–Pagan (Koenker–Bassett) pre oba modely

bp_m1 <- bptest(m1, studentize = TRUE)
bp_m2 <- bptest(m2, studentize = TRUE)

bp_m1

    studentized Breusch-Pagan test

data:  m1
BP = 13.349, df = 6, p-value = 0.03782
bp_m2

    studentized Breusch-Pagan test

data:  m2
BP = 10.227, df = 5, p-value = 0.06904

Na základe výsledkov regresie môžeme povedať, že heteroskedasticita rezíduí nie je v modeli m2 prítomná, zatiaľ čo v prípade modelu m1 prítomná je. Ak by však heteroskedasticita pretrvávala a logaritmizácia premenných alebo odstránenie odľahlých hodnôt nepomohli, môžeme ju ošetriť pomocou tzv. White heteroskedasticity-consistent matice (HC), kde sa v t-testoch významnosti regresných koeficientov používajú „hrubšie“ (robustné) odhady rozptylov. Postup je potom založený na odhadoch s HC1/HC3 štandardnými chybami.

Výsledky BP (Koenker–Bassett) testu:

  • m1: \(p = 0.0378 < 0.05\)zamietame H₀ na 5 % hladine. V pôvodnom modeli sú dôkazy heteroskedasticity.
  • m2: \(p = 0.0690 > 0.05\) (ale \(< 0.10\)) → na 5 % hladine H₀ nezamietame, na 10 % je to hraničné. Log-transformácia vodivosti teda heteroskedasticitu znížila.
# Robustné (heteroskedasticity-consistent) chyby – HC1

library(sandwich)

cat("\nRobustné (HC1) t-testy koeficientov – m1:\n")

Robustné (HC1) t-testy koeficientov – m1:
coeftest(m1, vcov = vcovHC(m1, type = "HC1"))

t test of coefficients:

                                    Estimate  Std. Error t value  Pr(>|t|)
(Intercept)                       7.7614e+00  2.1608e-01 35.9199 < 2.2e-16
Temperature..C....Max            -1.2691e-02  3.3629e-03 -3.7739  0.000221
Dissolved...Max                   5.7580e-02  2.1286e-02  2.7051  0.007516
Conductivity...µmho.cm....Max     5.2391e-06  1.0837e-06  4.8345 2.945e-06
BOD..mg.L....Max                  7.0291e-04  2.5874e-03  0.2717  0.786204
NitrateN..mg.L....Max             3.2757e-02  1.0526e-02  3.1120  0.002176
Fecal.Coliform..MPN.100ml....Max  1.4505e-08  8.2354e-09  1.7614  0.079955
                                    
(Intercept)                      ***
Temperature..C....Max            ***
Dissolved...Max                  ** 
Conductivity...µmho.cm....Max    ***
BOD..mg.L....Max                    
NitrateN..mg.L....Max            ** 
Fecal.Coliform..MPN.100ml....Max .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Všimnime si, že po použití robustných (HC) smerodajných chýb vychádzajú ako štatisticky významne spojené s pH…Max najmä premenné Teplota (–), Rozpustený O₂ (+), Vodivosť (+) a NitrateN (+). Premenná BOD štatisticky významná nie je a Fekálne koliformy sú len hranične významné (≈ 10 % hladina). To je v súlade s tým, že robustné chyby „sprísnia“ inferenciu v prítomnosti heteroskedasticity. Na druhej strane treba podotknúť, že použitie tejto metódy je najspoľahlivejšie pri väčších výberoch (orientačne > 100 pozorovaní).

LS0tCnRpdGxlOiAiQ3ZpxI1lbmllIDUg4oCTIFByw6FjYSBzIGRhdGFiw6F6b3UgKEluZGlhbiBXYXRlciBEYXRhKSIKYXV0aG9yOiAiU8OhcmEgTmlrb2wgU2Nob2x0em92w6EiCmRhdGU6ICJPa3TDs2JlciAyMDI1IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0aGVtZTogdW5pdGVkCiAgICBoaWdobGlnaHQ6IHRhbmdvCmVkaXRvcl9vcHRpb25zOgogIG1hcmtkb3duOgogICAgd3JhcDogNzIKLS0tCmBgYHtyfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgICBlY2hvID0gVFJVRSwKICAgIG1lc3NhZ2UgPSBGQUxTRSwKICAgIHdhcm5pbmcgPSBGQUxTRQopCmBgYAoKYGBge3J9Cmluc3RhbGwucGFja2FnZXMoYygKICAidGlkeXZlcnNlIiwKICAicmVhZHIiLAogICJkcGx5ciIsCiAgImdncGxvdDIiLAogICJrbml0ciIsCiAgImthYmxlRXh0cmEiLAogICJicm9vbSIsCiAgInN0cmluZ3IiLAogICJjb3JycGxvdCIsCiAgInpvbyIsCiAgInRzZXJpZXMiLAogICJsbXRlc3QiLAogICJzYW5kd2ljaCIsCiAgImNhciIsCiAgImNvcnJwbG90IiwKICAicGF0Y2h3b3JrIgopLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQpsaWJyYXJ5KHpvbykKbGlicmFyeSh0c2VyaWVzKQpsaWJyYXJ5KGxtdGVzdCkKbGlicmFyeShzYW5kd2ljaCkKbGlicmFyeShjYXIpCnJtKGxpc3Q9bHMoKSkKYGBgCgojIMOadm9kIGRvIHByb2Jsw6ltdSwgc3Rhbm92ZW5pZSBoeXBvdMOpeiAKClYgdGVqdG8gw7psb2hlIHByYWN1amVtZSBzIGRhdGFiw6F6b3UgKipJbmRpYW4gV2F0ZXIgRGF0YSoqLCBrdG9yw6Egb2JzYWh1amUgw7pkYWplIG8ga3ZhbGl0ZSB2b2R5IG5hIHLDtHpueWNoIGxva2FsaXTDoWNoIHYgSW5kaWkuICAKQ2llxL5vbSBqZToKCi0gcHJlc2vDum1hxaUgxaF0YXRpc3RpY2vDqSB2bGFzdG5vc3RpIGplZG5vdGxpdsO9Y2ggdWthem92YXRlxL5vdiBrdmFsaXR5IHZvZHksICAKLSBhbmFseXpvdmHFpSB2esWlYWh5IG1lZHppIG5pbWksICAKLSBhIHBvbW9jb3UgKipsaW5lw6FybmVqIHJlZ3Jlc2llKiogdnlzdmV0bGnFpSwga3RvcsOpIGZha3Rvcnkgb3ZwbHl2xYh1asO6IG5hcHLDrWtsYWQgKnBIIHZvZHkqLgoKLS0tCgpWIHRlanRvIMO6bG9oZSBwcmVkcG9rbGFkw6FtZSwgxb5lICoqcEggdm9keSoqIGplIG92cGx5dsWIb3ZhbsOpIHZpYWNlcsO9bWkgZmFrdG9ybWkga3ZhbGl0eSB2b2R5LiAgClRlc3R1amVtZSwgxI1pIG1hasO6ICoqdGVwbG90YSoqLCAqKm1ub8W+c3R2byByb3pwdXN0ZW7DqWhvIGt5c2zDrWthKiosICoqZWxla3RyaWNrw6Egdm9kaXZvc8WlKiosICoqYmlvbG9naWNrw6Egc3BvdHJlYmEga3lzbMOta2EqKiwgKipvYnNhaCBkdXNpxI1uYW5vdioqIGEgKipmZWvDoWxuZSBrb2xpZm9ybXkqKiB2w716bmFtbsO9IHZwbHl2IG5hIGhvZG5vdHUgcEguCgoqKk51bG92w6EgaHlwb3TDqXphIChI4oKAKSoqIHR2cmTDrSwgxb5lIMW+aWFkbnkgeiB0w71jaHRvIHVrYXpvdmF0ZcS+b3YgbmVtw6EgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnBseXYgbmEgcEggdm9keS4gIAoqKkFsdGVybmF0w612bmEgaHlwb3TDqXphIChI4oKBKSoqIHByZWRwb2tsYWTDoSwgxb5lIGFzcG/FiCBqZWRlbiB6IHTDvWNodG8gdWthem92YXRlxL5vdiBtw6EgbmEgcEggxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gw7rEjWlub2suCgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShjb3JycGxvdCkKCmRhdGEgPC0gcmVhZC5jc3YoIkluZGlhbl93YXRlcl9kYXRhLmNzdiIpCnN0cihkYXRhKQpzdW1tYXJ5KGRhdGEpCgojIERvcGxuZW5pZSBjaMO9YmFqw7pjaWNoIGhvZG7DtHQgbWVkacOhbm9tCmNvbHVtbl9tZWRpYW5zIDwtIHNhcHBseShkYXRhLCBtZWRpYW4sIG5hLnJtID0gVFJVRSkKZm9yIChjb2wgaW4gbmFtZXMoZGF0YSkpIHsKICBpZiAoaXMubnVtZXJpYyhkYXRhW1tjb2xdXSkpIHsKICAgIGRhdGFbW2NvbF1dW2lzLm5hKGRhdGFbW2NvbF1dKV0gPC0gY29sdW1uX21lZGlhbnNbY29sXQogIH0KfQoKIyBWeWJlciDEjcOtc2VsbsOpIHByZW1lbm7DqQoKZGF0YV9udW0gPC0gZGF0YSAlPiUgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKQoKIyBaw6FrbGFkbsOpIMWhdGF0aXN0aWt5CgpkYXRhX251bSAlPiUKc3VtbWFyeSgpICU+JQprYWJsZShjYXB0aW9uID0gIlrDoWtsYWRuw6kgxaF0YXRpc3Rpa3kgbnVtZXJpY2vDvWNoIHByZW1lbm7DvWNoIikgJT4lCmthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEZBTFNFKQoKIyBWaXp1YWxpesOhY2lhIGTDoXQKCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0aWR5cikKbGlicmFyeShkcGx5cikKbGlicmFyeShzY2FsZXMpCgojIFByZXZlZGllbWUgZMOhdGEgZG8gbG9uZyBmb3Jtw6F0dQpkYXRhX2xvbmcgPC0gZGF0YV9udW0gJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gIlByZW1lbm7DoSIsIHZhbHVlc190byA9ICJIb2Rub3RhIikKCiMgTm9ybWFsaXrDoWNpYSBrYcW+ZGVqIHByZW1lbm5laiAoMOKAkzEgcm96c2FoKQpkYXRhX3NjYWxlZCA8LSBkYXRhX2xvbmcgJT4lCiAgZ3JvdXBfYnkoUHJlbWVubsOhKSAlPiUKICBtdXRhdGUoSG9kbm90YV9zY2FsZWQgPSAoSG9kbm90YSAtIG1pbihIb2Rub3RhLCBuYS5ybSA9IFRSVUUpKSAvIAogICAgICAgICAgICAgICAgICAgICAgICAgICAobWF4KEhvZG5vdGEsIG5hLnJtID0gVFJVRSkgLSBtaW4oSG9kbm90YSwgbmEucm0gPSBUUlVFKSkpICU+JQogIHVuZ3JvdXAoKQoKIyBCb3hwbG90IHBvIMWha8OhbG92YW7DrQpnZ3Bsb3QoZGF0YV9zY2FsZWQsIGFlcyh4ID0gUHJlbWVubsOhLCB5ID0gSG9kbm90YV9zY2FsZWQsIGZpbGwgPSBQcmVtZW5uw6EpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuY29sb3IgPSAicmVkIiwgbm90Y2ggPSBUUlVFLCBhbHBoYSA9IDAuNykgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTYpICsKICB0aGVtZSgKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDEyKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIgogICkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJCb3hwbG90eSBqZWRub3RsaXbDvWNoIG51bWVyaWNrw71jaCBwcmVtZW5uw71jaCAoxaF0YW5kYXJkaXpvdmFuw6kpIiwKICAgIHggPSAiIiwKICAgIHkgPSAixaBrw6Fsb3ZhbsOhIGhvZG5vdGEgKDDigJMxKSIKICApCmBgYAojIyBJbnRlcnByZXTDoWNpYSBib3hwbG90b3YgamVkbm90bGl2w71jaCBudW1lcmlja8O9Y2ggcHJlbWVubsO9Y2gKCkJveHBsb3R5IHVrYXp1asO6IHJvemRlbGVuaWUgaG9kbsO0dCBqZWRub3RsaXbDvWNoIHByZW1lbm7DvWNoIHBvIMWhdGFuZGFyZGl6w6FjaWkgKHYgcm96c2FodSAw4oCTMSkuICAKWiBncmFmdSB2aWRubyBuaWVrb8S+a28gZMO0bGXFvml0w71jaCBwb3puYXRrb3Y6CgotICoqUHJlbWVubsOpIGBDb25kdWN0aXZpdHkuLi7CtW1oby5jbS4uLi5NYXhgIGEgYEJPRC4ubWcuTC4uLi5NYXhgKiogbWFqw7ogKip2ZcS+a8O9IHBvxI1ldCBvZMS+YWhsw71jaCBob2Ruw7R0ICjEjWVydmVuw6kgYm9keSkqKiwgIAogIMSNbyBuYXpuYcSNdWplIHbDvXJhem7DuiB2YXJpYWJpbGl0dSBtZWR6aSBsb2thbGl0YW1pIOKAlCB2IG5pZWt0b3LDvWNoIG9ibGFzdGlhY2ggamUgdm9kaXZvc8WlIGFsZWJvIGJpb2xvZ2lja8OhIHNwb3RyZWJhIGt5c2zDrWthIGV4dHLDqW1uZSB2eXNva8OhLgoKLSAqKmBwSC4uLk1pbmAgYSBgcEguLi5NYXhgKiogbWFqw7ogcG9tZXJuZSDDunprZSByb3pww6R0aWUsIMSNbyBqZSB0eXBpY2vDqSDigJQgcEggdm9keSBzYSB6dnnEjWFqbmUgcG9oeWJ1amUgdiDDunprb20gaW50ZXJ2YWxlIDbigJM4LgoKLSAqKmBUZW1wZXJhdHVyZS4uQy4uLi5NYXhgIGEgYFRlbXBlcmF0dXJlLi5DLi4uLk1pbmAqKiBzw7ogcm96bG/FvmVuw6kgcm92bm9tZXJuZSwgYmV6IHbDvXJhem7DvWNoIGV4dHLDqW1vdiDigJQgIAogIHRvIHBvdWthenVqZSBuYSBrb256aXN0ZW50bsOpIGtsaW1hdGlja8OpIHBvZG1pZW5reSBtZXJhbsO9Y2ggbG9rYWzDrXQuCgotICoqYFRvdGFsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4YCoqIHZ5a2F6dWplIG1pZXJuZSB2ecWhxaHDrSByb3pwdHlsLCAgCiAgxI1vIHpuYW1lbsOhLCDFvmUgYmFrdGVyaW9sb2dpY2vDoSBrb250YW1pbsOhY2lhIHZvZHkgc2EgdsO9cmF6bmUgbMOtxaFpIHBvZMS+YSBtaWVzdGEgbWVyYW5pYS4KCi0gKipgWWVhcmAgYSBgU1ROLmNvZGVgKiogc8O6IHRlY2huaWNrw6kgcHJlbWVubsOpIChpZGVudGlmaWvDoXRvcnksIG5pZSBlbnZpcm9ubWVudMOhbG5lIHVrYXpvdmF0ZWxlKSwgIAogIHByZXRvIGljaCByb3pkZWxlbmllIHR1IG5lbcOhIGFuYWx5dGlja8O9IHbDvXpuYW0uCgpgYGB7cn0KIyBLb3JlbGHEjW7DoSBtYXRpY2EKCmNvcnIgPC0gY29yKGRhdGFfbnVtLCB1c2UgPSAiY29tcGxldGUub2JzIikKY29ycnBsb3QoY29yciwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIHRsLmNleCA9IDAuNykKYGBgCgojIyBJbnRlcnByZXTDoWNpYSBrb3JlbGHEjW5laiBtYXRpY2UKCktvcmVsYcSNbsOhIGFuYWzDvXphIG5hem5hxI11amUsIMW+ZSAqKm5hanZ5xaHFoWlhIGtvcmVsw6FjaWEgcyBgcEguLi5NYXhgKiogamUgcG96b3JvdmFuw6EgcHJpIHVrYXpvdmF0ZcS+b2NoICAKKipyb3pwdXN0ZW7DqWhvIGt5c2zDrWthIChgRGlzc29sdmVkLi4uTWF4YCkqKiBhICoqdm9kaXZvc3RpIChgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCkqKi4gIApUbyBwb3R2cmR6dWplLCDFvmUgY2hlbWlja8OpIHZsYXN0bm9zdGkgdm9keSwgYWtvIGtvbmNlbnRyw6FjaWEga3lzbMOta2EgYSBtbm/FvnN0dm8gcm96cHVzdGVuw71jaCBpw7Nub3YsICAKdsO9em5hbW5lIHPDunZpc2lhIHNvIHptZW5hbWkgcEguCgpTbGFiw6EgYWxlYm8gemFuZWRiYXRlxL5uw6Ega29yZWzDoWNpYSBqZSB2aWRpdGXEvm7DoSBtZWR6aSBwSCBhICoqYmlvbG9naWNrb3Ugc3BvdHJlYm91IGt5c2zDrWthIChCT0QpKiosICAKxI1vIG5hem5hxI11amUsIMW+ZSB0ZW50byBwYXJhbWV0ZXIgcEggb3ZwbHl2xYh1amUgbGVuIG5lcHJpYW1vLgoKKipUZXBsb3RhIHZvZHkqKiB2eWthenVqZSBtaWVybnUgcG96aXTDrXZudSBrb3JlbMOhY2l1IHMgcEgsICAKxI1vIG3DtMW+ZSBvZHLDocW+YcWlIGZ5emlrw6Fsbm8tY2hlbWlja8O6IHbDpHpidSBtZWR6aSB0ZXBsb3RvdSBhIHJvenDDusWhxaVhbsOtbSBwbHlub3Ygdm8gdm9kZS4KCgojIyBMaW5lw6FybmEgcmVncmVzaWEKClByZWRwb2tsYWRham1lLCDFvmUgbWF4aW3DoWxuYSBob2Rub3RhIHBIIHZvZHkgamUgesOhdmlzbMOhIHByZW1lbm7DoSBhIG9zdGF0bsOpIGNoZW1pY2vDqSBhIGJpb2xvZ2lja8OpIHVrYXpvdmF0ZWxlIGt2YWxpdHkgdm9keSwgYWtvIHPDuiB0ZXBsb3RhLCBvYnNhaCByb3pwdXN0ZW7DqWhvIGt5c2zDrWthLCB2b2Rpdm9zxaUsIGJpb2xvZ2lja8OhIHNwb3RyZWJhIGt5c2zDrWthLCBvYnNhaCBkdXNpxI1uYW5vdiBhIGZla8OhbG55Y2gga29saWZvcm1vdiwgcHJlZHN0YXZ1asO6IG5lesOhdmlzbMOpIHByZW1lbm7DqS4KYGBge3J9CiMgTmFqcHJ2IHByZW1lxYggcHLDoXpkbmUgYnVua3kgYWxlYm8gdGV4dHkgYWtvICJCREwiIG5hIE5BCmRhdGEkRmVjYWwuQ29saWZvcm0uLk1QTi4xMDBtbC4uLi5NYXhbZGF0YSRGZWNhbC5Db2xpZm9ybS4uTVBOLjEwMG1sLi4uLk1heCAlaW4lIGMoIiIsICJCREwiLCAiTkEiKV0gPC0gTkEKCiMgUG90b20gcHJldmVkaWXFoSBuYSDEjcOtc2xhCmRhdGEkRmVjYWwuQ29saWZvcm0uLk1QTi4xMDBtbC4uLi5NYXggPC0gYXMubnVtZXJpYyhkYXRhJEZlY2FsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4KQoKIyBMaW5lw6FybnkgbW9kZWwg4oCTIHBILi4uTWF4IGFrbyB6w6F2aXNsw6EgcHJlbWVubsOhCm1vZGVsIDwtIGxtKHBILi4uTWF4IH4gVGVtcGVyYXR1cmUuLkMuLi4uTWF4ICsgRGlzc29sdmVkLi4uTWF4ICsgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4ICsgCiAgICAgICAgICAgICAgQk9ELi5tZy5MLi4uLk1heCArIE5pdHJhdGVOLi5tZy5MLi4uLk1heCArIEZlY2FsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4LCAKICAgICAgICAgICAgZGF0YSA9IGRhdGEpCgojIFbDvXN0dXB5IG1vZGVsdQpjYXQoIk9kaGFkbnV0w6kga29lZmljaWVudHkgbW9kZWx1OlxuIikKcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQoKY2F0KCJPZGhhZG51dMOpIHJlesOtZHXDoSAoenZ5xaFreSk6XG4iKQpwcmludChoZWFkKG1vZGVsJHJlc2lkdWFscywgMTApKSAgIyBsZW4gcHJ2w71jaCAxMCBwcmVoxL5hZG5lCgpjYXQoIlZ5cm92bmFuw6kgKHByZWRpa292YW7DqSkgaG9kbm90eSB6w6F2aXNsZWogcHJlbWVubmVqOlxuIikKcHJpbnQoaGVhZChtb2RlbCRmaXR0ZWQudmFsdWVzLCAxMCkpICAjIG9ww6TFpSBsZW4gcHJ2w71jaCAxMAoKY2F0KCJNYXRpY2EgbW9kZWx1IChYKTpcbiIpClggPC0gbW9kZWwubWF0cml4KG1vZGVsKQpwcmludChoZWFkKFgpKQoKY2F0KCJQcm9qZWvEjW7DoSBtYXRpY2EgKGhhdCBtYXRyaXgpOlxuIikKSCA8LSBYICUqJSBzb2x2ZSh0KFgpICUqJSBYKSAlKiUgdChYKQpwcmludChyb3VuZChIWzE6NSwgMTo1XSwgNCkpICAjIGxlbiBwcnbDvWNoIDV4NSBwcnZrb3YgcHJlIHByZWjEvmFkbm9zxaUKCmNhdCgiU8O6aHJuIG1vZGVsdTpcbiIpCnN1bW1hcnkobW9kZWwpCgpgYGAKIyBJbnRlcnByZXTDoWNpYSBhIGRpYWdub3N0aWthIG1vZGVsdQoKU8O6aHJuIG9kaGFkb3ZhbsOpaG8gbW9kZWx1IG7DoW0gcG9za3l0dWplIHPDumJvciBvZGhhZG51dMO9Y2ggcmVncmVzbsO9Y2gga29lZmljaWVudG92LCBrdG9yw71jaCB6bmFtaWVua2EgYSB2w716bmFtbm9zxaUgYnVkw7ogaW50ZXJwcmV0b3ZhbsOpIG5pxb7FoWllLiAgCkFrIGhvdm9yw61tZSBvIHZsYXN0bm9zdGlhY2ggbW9kZWx1IGFrbyBjZWxrdSwgcG96cmltZSBzYSBuYWpza8O0ciBuYSBkaWFnbm9zdGlja8OpIGdyYWZ5LgoKYGBge3J9CiMgTmFzdGF2acWlIHJvemxvxb5lbmllIDIgeCAyCnBhcihtZnJvdyA9IGMoMiwgMikpCgojIFZ5a3Jlc2xpxaUgdsWhZXRreSA0IGRpYWdub3N0aWNrw6kgZ3JhZnkgbW9kZWx1CnBsb3QobW9kZWwpCgojIFByaWRhxaUgc3BvbG/EjW7DvSBuYWRwaXMKbXRleHQoIkRpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1IOKAkyBwSC4uLk1heCIsIAogICAgICBvdXRlciA9IFRSVUUsIGNleCA9IDEuMiwgZm9udCA9IDIpCgojIFJlc2V0b3ZhxaUgbGF5b3V0CnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAojIyBJbnRlcnByZXTDoWNpYSBkaWFnbm9zdGlja8O9Y2ggZ3JhZm92IHByZSBtb2RlbCBwSC4uLk1heAoKIyMjIFJlc2lkdWFscyB2cy4gRml0dGVkCgotIFJlesOtZHXDoSBzYSBwb2h5YnVqw7ogcHJpYmxpxb5uZSBva29sbyBudWxvdmVqIG9zaSDigJMgbW9kZWwgdGVkYSAqKm5lbcOhIHN5c3RlbWF0aWNrw6kgc2tyZXNsZW5pZSB2IHByZWRpa2NpaSBob2Ruw7R0IHBIKiouICAKLSDEjGVydmVuw6EgTE9FU1MgxI1pYXJhIGplIHJlbGF0w612bmUgcm92bsOhLCDEjW8gbmF6bmHEjXVqZSwgxb5lICoqdnrFpWFoIG1lZHppIHBIIGEgenZvbGVuw71taSBwcmVtZW5uw71taSoqIChuYXByLiB0ZXBsb3RhLCB2b2Rpdm9zxaUsIEJPRCwgZHVzacSNbmFueSkgamUgcHJldmHFvm5lIGxpbmXDoXJueS4gIAotIFZlcnRpa8OhbG55IHJvenB0eWwgamUgcHJpYmxpxb5uZSByb3Zub21lcm7DvSDihpIgcHJlZHBva2xhZCAqKmhvbW9za2VkYXN0aWNpdHkgKGtvbsWhdGFudG7DqWhvIHJvenB0eWx1IGNow71iKSoqIGplIHYgesOhc2FkZSBzcGxuZW7DvS4gIAotIE5pZWtvxL5rbyBib2RvdiBtaW1vIGhsYXZuw70gcm96cHR5bCBtw7TFvmUgcHJlZHN0YXZvdmHFpSAqKmxva2FsaXR5IHMgZXh0csOpbW55bWkgaG9kbm90YW1pIGt2YWxpdHkgdm9keSoqIChwb3RlbmNpw6FsbmUgb2TEvmFobMOpIHBvem9yb3ZhbmlhKSwga3RvcsOpIHNpIG92ZXLDrW1lIHBvbW9jb3UgdGVzdG92LgoKLS0tCgojIyMgUeKAk1EgcGxvdAoKLSBWw6TEjcWhaW5hIGJvZG92IGxlxb7DrSBwb3pkxLrFviBkaWFnb27DoWx5IOKGkiByZXrDrWR1w6EgbW9kZWx1IHBILi4uTWF4IHPDuiAqKnRha21lciBub3Jtw6FsbmUgcm96bG/FvmVuw6kqKi4gIAotIE5hIGtvbmNvY2ggKHbEvmF2byBkb2xlIGEgdnByYXZvIGhvcmUpIG1vxb5ubyBwb3pvcm92YcWlIG1pZXJuZSBvZGNow71sa3kg4oCTIHRvIG5hem5hxI11amUgKirFpWHFvsWhaWUgY2h2b3N0eSByb3pkZWxlbmlhKiosIHByYXZkZXBvZG9ibmUgc3DDtHNvYmVuw6kgZXh0csOpbW55bWkgaG9kbm90YW1pIG5pZWt0b3LDvWNoIGNoZW1pY2vDvWNoIHVrYXpvdmF0ZcS+b3YuICAKLSBTdHJlZG7DoSDEjWFzxaUgZ3JhZnUgamUgZG9icmUgemFyb3ZuYW7DoSwgxI1vIHBvdHZyZHp1amUsIMW+ZSAqKnbDpMSNxaFpbmEgcG96b3JvdmFuw60gc2Egc3Byw6F2YSBub3Jtw6FsbmUqKi4KCi0tLQoKIyMjIFNjYWxl4oCTTG9jYXRpb24gcGxvdAoKLSBCb2R5IHPDuiByb3pwdMO9bGVuw6kgcm92bm9tZXJuZSBwbyBvc2kgWCBiZXogdnl0dsOhcmFuaWEgbGlldmlrYSDihpIgcm96cHR5bCByZXrDrWR1w60gamUgKipwcmlibGnFvm5lIGtvbsWhdGFudG7DvSoqLiAgCi0gSGxhZGvDoSBMT0VTUyDEjWlhcmEgamUgdGFrbWVyIHZvZG9yb3Zuw6EsIMSNbyBuYXpuYcSNdWplLCDFvmUgKip2YXJpYWJpbGl0YSBjaMO9YiBzYSBuZW1lbsOtIHNvIHptZW5vdSBwcmVkaWtvdmFuw71jaCBob2Ruw7R0IHBIKiouICAKLSBUZW50byB2w71zbGVkb2sgcG9kcG9ydWplIHBsYXRub3PFpSBwcmVkcG9rbGFkdSBvICoqaG9tb3NrZWRhc3RpY2l0ZSBtb2RlbHUqKi4KCi0tLQoKIyMjIFJlc2lkdWFscyB2cy4gTGV2ZXJhZ2UKCi0gVsOkxI3FoWluYSBib2RvdiBtw6EgbsOtemt5IHZwbHl2IChDb29rb3ZhIHZ6ZGlhbGVub3PFpSA8IDAuNSkg4oaSIMW+aWFkbmUgcG96b3JvdmFuaWUgKipuZW92cGx5dsWIdWplIHJlZ3Jlc27DqSBrb2VmaWNpZW50eSB2w71yYXpuZSoqLiAgCi0gSmVkZW4gYWxlYm8gZHZhIGJvZHkgbcO0xb51IG1hxaUgenbDvcWhZW7DuiBww6Frb3bDuiBob2Rub3R1IOKAkyBpZGUgcHJhdmRlcG9kb2JuZSBvICoqbG9rYWxpdHkgcyBleHRyw6ltbmUgb2RsacWhbsO9bWkgcGFyYW1ldHJhbWkgdm9keSoqLCBrdG9yw6kgdsWhYWsgbW9kZWwgdsO9cmF6bmUgbmVkZWZvcm11asO6LiAgCi0gQ2Vsa292byBww7Rzb2LDrSBtb2RlbCAqKnN0YWJpbG5lIGEgYmV6IHbDvXpuYW1uw71jaCBvZMS+YWhsw71jaCBhbGVibyB2cGx5dm7DvWNoIGJvZG92KiouCgotLS0KCiMjIyBaaHJudXRpZQoKRGlhZ25vc3RpY2vDqSBncmFmeSBwb3R2cmR6dWrDuiwgxb5lIG1vZGVsIHMgdnlzdmV0xL5vdmFub3UgcHJlbWVubm91ICoqcEguLi5NYXgqKiBhIHByZWRpa3Rvcm1pICAKKCoqVGVtcGVyYXR1cmUuLkMuLi4uTWF4KiosICoqRGlzc29sdmVkLi4uTWF4KiosICoqQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4KiosICAKKipCT0QuLm1nLkwuLi4uTWF4KiosICoqTml0cmF0ZU4uLm1nLkwuLi4uTWF4KiogYSAqKkZlY2FsLkNvbGlmb3JtLi5NUE4uMTAwbWwuLi4uTWF4KiopICAKc3DEusWIYSBobGF2bsOpIHByZWRwb2tsYWR5IGxpbmXDoXJuZWogcmVncmVzaWUuICAKClJlesOtZHXDoSBzw7ogcHJpYmxpxb5uZSBub3Jtw6FsbmUgcm96bG/FvmVuw6ksIHJvenB0eWwgY2jDvWIgamUga29uxaF0YW50bsO9IGEgdsOkxI3FoWluYSBwb3pvcm92YW7DrSBuZW3DoSBuYWRtZXJuw70gdnBseXYgbmEgdsO9c2xlZG9rIG1vZGVsdS4gIApNb2RlbCB0ZWRhIG1vxb5ubyBwb3Zhxb5vdmHFpSB6YSAqKsWhdGF0aXN0aWNreSBzcG/EvmFobGl2w70gbmEgaW50ZXJwcmV0w6FjaXUgdnrFpWFodSBtZWR6aSB1a2F6b3ZhdGXEvm1pIGt2YWxpdHkgdm9keSBhIHBIKiouCmBgYHtyfQojIE5vdsO9IG1vZGVsIHNvIHpsb2dhcml0bW92YW5vdSBDb25kdWN0aXZpdHkKbW9kZWwyIDwtIGxtKHBILi4uTWF4IH4gVGVtcGVyYXR1cmUuLkMuLi4uTWF4ICsgRGlzc29sdmVkLi4uTWF4ICsKICAgICAgICAgICAgICAgSShsb2coQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4KSkgKwogICAgICAgICAgICAgICBCT0QuLm1nLkwuLi4uTWF4ICsgTml0cmF0ZU4uLm1nLkwuLi4uTWF4LCAKICAgICAgICAgICAgIGRhdGEgPSBkYXRhKQpzdW1tYXJ5KG1vZGVsMikKcGFyKG1mcm93ID0gYygyLCAyKSkKcGxvdChtb2RlbDIpCnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAoKVHJhbnNmb3Jtw6FjaWEgcHJlbWVubmVqIGBDb25kdWN0aXZpdHkuLi7CtW1oby5jbS4uLi5NYXhgIHBvbW9jb3UgbG9nYXJpdG11IGJvbGEgenZvbGVuw6EgbmEgem7DrcW+ZW5pZSB2cGx5dnUgZXh0csOpbW55Y2ggaG9kbsO0dCwga3RvcsOpIHNhIHYgcMO0dm9kbsO9Y2ggw7pkYWpvY2ggdsO9cmF6bmUgbMOtxaFpbGkgbWVkemkgbG9rYWxpdGFtaS4gIApQbyBhcGxpa8OhY2lpIGxvZ2FyaXRtaWNrZWogdHJhbnNmb3Jtw6FjaWUgc2EgbW9kZWwgc3Byw6F2YSBzdGFiaWxuZWrFoWllIGEgamVobyBrb2VmaWNpZW50eSBzw7ogbGVwxaFpZSBpbnRlcnByZXRvdmF0ZcS+bsOpLgoKIyMgSW50ZXJwcmV0w6FjaWEgZGlhZ25vc3RpY2vDvWNoIGdyYWZvdiBwcmUgbW9kZWwgc28gemxvZ2FyaXRtb3Zhbm91IHZvZGl2b3PFpW91CgojIyMgUmVzaWR1YWxzIHZzIEZpdHRlZApSZXrDrWR1w6Egc2EgcG9oeWJ1asO6ICoqcm92bm9tZXJuZSBva29sbyBudWxvdmVqIG9zaSoqLCDEjW8gbmF6bmHEjXVqZSwgxb5lIG1vZGVsICoqbmVtw6Egc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllKiogdiBwcmVkaWtjaWkgaG9kbsO0dCBwSC4gIArEjGVydmVuw6EgTE9FU1MgxI1pYXJhIGplICoqdGFrbWVyIHZvZG9yb3Zuw6EqKiwgxI1vIHBvdHZyZHp1amUsIMW+ZSBwbyBsb2dhcml0bWlja2VqIHRyYW5zZm9ybcOhY2lpIHZvZGl2b3N0aSBzYSBvZHN0csOhbmlsYSBww7R2b2Ruw6EgbWllcm5hIG5lbGluZWFyaXRhLiAgClZlcnRpa8OhbG55IHJvenB0eWwgcmV6w61kdcOtIGplICoqa29uxaF0YW50bsO9Kiog4oCTIHByZWRwb2tsYWQgKipob21vc2tlZGFzdGljaXR5KiogamUgdGVkYSBzcGxuZW7DvS4gIApOaWVrb8S+a28gamVkbm90bGl2w71jaCBib2RvdiBzIHbDpMSNxaFvdSBvZGNow71sa291IG3DtMW+ZSBwYXRyacWlIGV4dHLDqW1ueW0gbG9rYWxpdMOhbSwgbm8gbmVvdnBseXbFiHVqw7ogbW9kZWwgdsO9em5hbW5lLgoKLS0tCgojIyMgUeKAk1EgcGxvdApWw6TEjcWhaW5hIGJvZG92IGxlxb7DrSAqKnZlxL5taSBibMOtemtvIGRpYWdvbsOhbHkqKiwgxI1vIHpuYW1lbsOhLCDFvmUgKipyZXrDrWR1w6Egc8O6IHByaWJsacW+bmUgbm9ybcOhbG5lIHJvemxvxb5lbsOpKiouICAKTWVuxaFpZSBvZGNow71sa3kgbmEga29uY29jaCAodsS+YXZvIGRvbGUgYSB2cHJhdm8gaG9yZSkgbmF6bmHEjXVqw7ogbGVuIG1pZXJuZSBvZGNow71sa3kgb2Qgbm9ybcOhbG5vc3RpLCAgCmt0b3LDqSBtw7TFvnUgYnnFpSBzcMO0c29iZW7DqSBwcsOtdG9tbm9zxaVvdSBuaWVrb8S+a8O9Y2ggZXh0csOpbW55Y2ggbWVyYW7DrS4gIApPcHJvdGkgcMO0dm9kbsOpbXUgbW9kZWx1IHNhIHJvemRlbGVuaWUgcmV6w61kdcOtICoqdsO9cmF6bmUgemxlcMWhaWxvKiog4oCTIGxvZy10cmFuc2Zvcm3DoWNpYSB0ZWRhIHBvbW9obGEuCgotLS0KCiMjIyBTY2FsZeKAk0xvY2F0aW9uIHBsb3QKQm9keSBzw7ogcm96cHTDvWxlbsOpICoqcm92bm9tZXJuZSBwb3pkxLrFviBvc2kgWCoqIGJleiB6bsOhbW9rIHJvesWhaXJ1asO6Y2VobyBzYSDigJ5saWV2aWth4oCcLCAgCsSNbyBwb3R2cmR6dWplLCDFvmUgKip2YXJpYW5jaWEgcmV6w61kdcOtIGplIGtvbsWhdGFudG7DoSoqIG5hcHJpZcSNIHByZWRpa292YW7DvW1pIGhvZG5vdGFtaS4gIArEjGVydmVuw6EgaGxhZGvDoSDEjWlhcmEgamUgdGFrbWVyIHJvdm7DoSwgxI1vIG5hem5hxI11amUsIMW+ZSAqKnJvenB0eWwgY2jDvWIgc2EgbmVtZW7DrSoqIHNvIHptZW5vdSBob2Ruw7R0IHBILiAgCk1vZGVsIHRlZGEgc3DEusWIYSBwcmVkcG9rbGFkICoqaG9tb3NrZWRhc3RpY2l0eSoqIHZlxL5taSBkb2JyZS4KCi0tLQoKIyMjIFJlc2lkdWFscyB2cyBMZXZlcmFnZQpWw6TEjcWhaW5hIHBvem9yb3ZhbsOtIG3DoSAqKm7DrXpreSBww6Frb3bDvSBlZmVrdCoqIChsZXZlcmFnZSA8IDAuMSkgYSBDb29rb3ZhIHZ6ZGlhbGVub3PFpSB6b3N0w6F2YSBwb2QgMC41LiAgClRvIHpuYW1lbsOhLCDFvmUgxb5pYWRuZSBwb3pvcm92YW5pZSAqKm5lb3ZwbHl2xYh1amUgbW9kZWwgbmFkbWVybmUqKi4gIApOaWVrb8S+a28gYm9kb3YgKG5hcHIuIDE5MSwgNjYpIHZ5a2F6dWplIG1pZXJuZSB2ecWhxaHDrSB2cGx5diwgYWxlIG5lcHJlc2FodWplIGtyaXRpY2vDqSBob2Rub3R5LiAgCk1vZGVsIHRlZGEgKipuZW9ic2FodWplIHbDvXJhem5lIHZwbHl2bsOpIGFsZWJvIG9kxL5haGzDqSBwcsOtcGFkeSoqLgoKLS0tCgojIyMgKipaaHJudXRpZSBkaWFnbm9zdGlreSoqClRyYW5zZm9ybW92YW7DvSBtb2RlbCAoc28gemxvZ2FyaXRtb3Zhbm91IHZvZGl2b3PFpW91KSAqKnbDvXJhem5lIHpsZXDFoWlsIMWhdGF0aXN0aWNrw6kgdmxhc3Rub3N0aSByZXrDrWR1w60qKjoKLSBvZHN0csOhbmlsIG1pZXJudSBuZWxpbmVhcml0dSB6IHDDtHZvZG7DqWhvIG1vZGVsdSwgIAotIHpuw63FvmlsIGhldGVyb3NrZWRhc3RpY2l0dSwgIAotIGEgcHJpYmzDrcW+aWwgcm96ZGVsZW5pZSByZXrDrWR1w60gayBub3Jtw6FsbmVtdSB0dmFydS4gIAoKTW9kZWwgamUgdGVkYSAqKnN0YWJpbG7DvSwgc3BvxL5haGxpdsO9KiogYSB2aG9kbsO9IG5hIGludGVycHJldMOhY2l1IHZ6xaVhaHUgbWVkemkga3ZhbGl0b3Ugdm9keSBhIHBILgoKIyMgVGVzdHkgbm9ybWFsaXR5IGEgaWRlbnRpZmlrw6FjaWEgb2TEvmFobMO9Y2ggaG9kbsO0dAoKViB0ZWp0byDEjWFzdGkgb3ZlcsOtbWUsIMSNaSByZXrDrWR1w6EgcMO0dm9kbsOpaG8gbW9kZWx1IHNwxLrFiGFqw7ogcHJlZHBva2xhZCAqKm5vcm1hbGl0eSByb3pkZWxlbmlhKiogIAphIHrDoXJvdmXFiCBpZGVudGlmaWt1amVtZSBtb8W+bsOpICoqb2TEvmFobMOpIHBvem9yb3ZhbmlhKiosIGt0b3LDqSBieSBtb2hsaSBvdnBseXbFiG92YcWlIHbDvXNsZWRreS4KYGBge3J9CmphcnF1ZS5iZXJhLnRlc3QocmVzaWR1YWxzKG1vZGVsKSkKY2FyOjpvdXRsaWVyVGVzdChtb2RlbCkKYGBgCgojIyDwn6eqIFRlc3R5IG5vcm1hbGl0eSBhIG9kxL5haGzDvWNoIGhvZG7DtHQgcG8gdHJhbnNmb3Jtw6FjaWkgKG1vZGVsMikKClBvIMO6cHJhdmUgbW9kZWx1IChsb2dhcml0bcOhY2lhIHZvZGl2b3N0aSkgb3ZlcsOtbWUsIMSNaSBzYSB6bGVwxaFpbGEgbm9ybWFsaXRhIHJvemRlbGVuaWEgcmV6w61kdcOtCmEgxI1pIHNhIHpuw63FvmlsIHBvxI1ldCBvZMS+YWhsw71jaCBob2Ruw7R0LgoKYGBge3J9CiMgSmFycXVl4oCTQmVyYSB0ZXN0IHByZSBtb2RlbDIKamFycXVlLmJlcmEudGVzdChyZXNpZHVhbHMobW9kZWwyKSkKCiMgVGVzdCBvZMS+YWhsw71jaCBob2Ruw7R0IHByZSBtb2RlbDIKY2FyOjpvdXRsaWVyVGVzdChtb2RlbDIpCmBgYAoqKkludGVycHJldMOhY2lhIHbDvXNsZWRrb3Y6KioKClbDvXNsZWRreSAqKkphcnF1ZeKAk0JlcmEgdGVzdHUqKiBwcmUgYG1vZGVsMmAgdWthenVqw7osIMW+ZSBwLWhvZG5vdGEgamUgKip2ecWhxaFpYSBuZcW+IHYgcMO0dm9kbm9tIG1vZGVsaSoqLiAgClRvIHpuYW1lbsOhLCDFvmUgcG8gbG9nYXJpdG1pY2tlaiB0cmFuc2Zvcm3DoWNpaSBwcmVtZW5uZWogYENvbmR1Y3Rpdml0eS4uLsK1bWhvLmNtLi4uLk1heGAgc2EgIAoqKm5vcm1hbGl0YSByZXrDrWR1w60gemxlcMWhaWxhKiosIGhvY2kgcHJpIG1lbsWhb20gcG/EjXRlIHBvem9yb3ZhbsOtIG5lbXVzw60gYnnFpSDDunBsbmUgZG9rb25hbMOhLgoKKipPdXRsaWVyIFRlc3QqKiB1xb4gbmVpZGVudGlmaWt1amUgxb5pYWRuZSB2w71yYXpuZSB2w716bmFtbsOpIG9kxL5haGzDqSBwb3pvcm92YW5pZSwgIArEjW8gcG90dnJkenVqZSwgxb5lIHDDtHZvZG7DvSBleHRyw6ltbnkgYm9kIChwb3pvcm92YW5pZSDEjS4gMTkxKSAqKnXFviBuZW3DoSBwb2RzdGF0bsO9IHZwbHl2KiogbmEgbW9kZWwuCgoqKlrDoXZlcjoqKiBUcmFuc2Zvcm1vdmFuw70gbW9kZWwgKGBtb2RlbDJgKSBsZXDFoWllIHNwxLrFiGEgcHJlZHBva2xhZHkgbGluZcOhcm5laiByZWdyZXNpZSDigJMgIApyZXrDrWR1w6Egc8O6ICoqYmxpxb7FoWllIGsgbm9ybcOhbG5lbXUgcm96ZGVsZW5pdSoqIGEgbW9kZWwgamUgKipyb2J1c3RuZWrFocOtIHZvxI1pIG9kxL5haGzDvW0gaG9kbm90w6FtKiouCgoKIyBaw6F2ZXIKCk5hIHrDoWtsYWRlIHJlZ3Jlc25laiBhbmFsw716eSBtb8W+bm8ga29uxaF0YXRvdmHFpSwgxb5lIG1heGltw6FsbmUgcEggdm9keSAoKipwSC4uLk1heCoqKSAgCmplIG92cGx5dm5lbsOpIHZpYWNlcsO9bWkgZmFrdG9ybWkga3ZhbGl0eSB2b2R5LiAgClByZW1lbm7DqSAqKnRlcGxvdGEgdm9keSoqLCAqKnJvenB1c3RlbsO9IGt5c2zDrWsqKiBhICoqdm9kaXZvc8WlKiogbWFqw7ogcHJldmHFvm5lICoqcG96aXTDrXZueSB2cGx5dioqLCAgCmvDvW0gKipiaW9sb2dpY2vDoSBzcG90cmViYSBreXNsw61rYSoqIGEgKipmZWvDoWxuZSBrb2xpZm9ybXkqKiBwSCAqKnpuw63FvnVqw7oqKi4KClRyYW5zZm9ybcOhY2lhIHByZW1lbm5laiBgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCBwb21vY291ICoqbG9nYXJpdG11KiogIAp6bGVwxaFpbGEgxaF0YXRpc3RpY2vDqSB2bGFzdG5vc3RpIG1vZGVsdSDigJQgcmV6w61kdcOhIHPDuiBibGnFvsWhaWUgayBub3Jtw6FsbmVtdSByb3pkZWxlbml1ICAKYSByb3pwdHlsIGNow71iIGplIHN0YWJpbG5lasWhw60gKCoqaG9tb3NrZWRhc3RpY2l0YSoqKS4gIApNb2RlbCBqZSB0ZWRhIHZvIHbFoWVvYmVjbm9zdGkgKipzcG/EvmFobGl2ZWrFocOtKiogYSBsZXDFoWllIHNwxLrFiGEgcHJlZHBva2xhZHkgbGluZcOhcm5laiByZWdyZXNpZS4KCk5hcHJpZWsgdG9tdSB2xaFhayB0ZXN0eSBvZMS+YWhsw71jaCBob2Ruw7R0IHVrw6F6YWxpLCDFvmUgKipwb3pvcm92YW5pZSDEjS4gMTkxKiogIAp6b3N0w6F2YSAqKm9kxL5haGzDqSBhaiBwbyB0cmFuc2Zvcm3DoWNpaSoqLiAgCklkZSB0ZWRhIG8gKipleHRyw6ltbmUgbWVyYW5pZSoqLCBrdG9yw6kgbcOhIHBvdGVuY2nDoWwgb3ZwbHl2bmnFpSB2w71zbGVka3kgbW9kZWx1IOKAlCAgCnYgYnVkw7pjbm9zdGkgYnkgYm9sbyB2aG9kbsOpIHRvdG8gcG96b3JvdmFuaWUgb3NvYml0bmUgcHJlc2vDum1hxaUgIAoobmFwci4gxI1pIG5lamRlIG8gY2h5YnUgbWVyYW5pYSBhbGVibyDFoXBlY2lmaWNrw7ogbG9rYWxpdHUgcyB2w71yYXpuZSBvZGxpxaFuw71taSBwb2RtaWVua2FtaSkuCgpDZWxrb3ZvIG1vxb5ubyB1emF2cmllxaUsIMW+ZSB0cmFuc2Zvcm1vdmFuw70gbW9kZWwgKipsZXDFoWllIHZ5c3RpaHVqZSB2esWlYWh5IG1lZHppIHVrYXpvdmF0ZcS+bWkga3ZhbGl0eSB2b2R5IGEgcEgqKiwgIApubyBwcsOtdG9tbm9zxaUgamVkbsOpaG8gKip0cnZhbMOpaG8gb2TEvmFobMOpaG8gcG96b3JvdmFuaWEgKMSNLiAxOTEpKiogIApqZSBwb3RyZWJuw6kgbWHFpSBuYSBwYW3DpHRpIHByaSBpbnRlcnByZXTDoWNpaSB2w71zbGVka292LgoKIyBIZXRlcm9za2VkYXN0aWNpdGEKClByw610b21ub3PFpSAqKmhldGVyb3NrZWRhc3RpY2l0eSoqIChuZWtvbsWhdGFudG7DqWhvIHJvenB0eWx1IG7DoWhvZG5laiB6bG/Fvmt5KSBzcMO0c29idWplIGNoeWJuw6kgdnlob2Rub2NvdmFuaWUgCip0LXRlc3RvdiB2w716bmFtbm9zdGkqIGplZG5vdGxpdsO9Y2ggcmVncmVzbsO9Y2gga29lZmljaWVudG92LiAgClByZXRvIGplIG51dG7DqSBoZXRlcm9za2VkYXN0aWNpdHU6CgotICoqZGV0ZWtvdmHFpSoqICh2aXp1w6FsbmUgYSBwb21vY291IHRlc3RvdiksICAKLSBhIHYgcHLDrXBhZGUgamVqIHByw610b21ub3N0aSBqdSAqKm9kc3Ryw6FuacWlKiogYWxlYm8ga29tcGVuem92YcWlLgoKQWogdiBuYcWhb20gcHLDrXBhZGUgc2EgcG9rw7pzaW1lIG8gdml6dcOhbG5lIHZ5aG9kbm90ZW5pZSB6w6F2aXNsb3N0aSDFoXR2b3Jjb3YgcmV6w61kdcOtIApvZCB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoLCB1IGt0b3LDvWNoIG3DoW1lIHBvZG96cmVuaWUsIMW+ZSBtw7TFvnUgaGV0ZXJvc2tlZGFzdGljaXR1IHNww7Rzb2JvdmHFpS4gIAoKQnVkZW1lIHBvc3Vkem92YcWlIGR2YSBtb2RlbHk6Ci0gYG1vZGVsYCDigJMgcMO0dm9kbsO9IG1vZGVsLAotIGBtb2RlbDJgIOKAkyBtb2RlbCBzbyAqKnpsb2dhcml0bW92YW5vdSB2b2Rpdm9zxaVvdSoqIChgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCksIAogIGt0b3LDqWhvIGNpZcS+b20gYm9sbyB6bsOtxb5pxaUgdnBseXYgZXh0csOpbW55Y2ggaG9kbsO0dC4KCmBgYHtyfQojIEhldGVyb3NrZWRhc3RpY2l0YSDigJMgbG9rw6FsbmUgYmV6IHJpYWRrdSAxOTEgKGdsb2LDoWxuZSAnZGF0YScgbmVtZW7DrW1lKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQoKIyAxKSBMb2vDoWxuYSBrw7NwaWEgYSB2eWhvZGVuaWUgMTkxLiByaWFka3UKZGF0YV9oIDwtIGRhdGEKaWYgKG5yb3coZGF0YV9oKSA+PSAxOTEpIHsKICBkYXRhX2ggPC0gZGF0YV9oWy0xOTEsICwgZHJvcCA9IEZBTFNFXQp9CgojIDIpIFJlZml0IG1vZGVsb3YgbmEgZGF0YV9oCm1vZGVsX2ggPC0gbG0oCiAgcEguLi5NYXggfiBUZW1wZXJhdHVyZS4uQy4uLi5NYXggKyBEaXNzb2x2ZWQuLi5NYXggKwogICAgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4ICsgQk9ELi5tZy5MLi4uLk1heCArCiAgICBOaXRyYXRlTi4ubWcuTC4uLi5NYXggKyBGZWNhbC5Db2xpZm9ybS4uTVBOLjEwMG1sLi4uLk1heCwKICBkYXRhID0gZGF0YV9oLCBuYS5hY3Rpb24gPSBuYS5leGNsdWRlCikKCm1vZGVsMl9oIDwtIGxtKAogIHBILi4uTWF4IH4gVGVtcGVyYXR1cmUuLkMuLi4uTWF4ICsgRGlzc29sdmVkLi4uTWF4ICsKICAgIEkobG9nKENvbmR1Y3Rpdml0eS4uLsK1bWhvLmNtLi4uLk1heCkpICsKICAgIEJPRC4ubWcuTC4uLi5NYXggKyBOaXRyYXRlTi4ubWcuTC4uLi5NYXgsCiAgZGF0YSA9IGRhdGFfaCwgbmEuYWN0aW9uID0gbmEuZXhjbHVkZQopCgojIDMpIETDoXRhIHBvdcW+aXTDqSB2IG1vZGVsb2NoIChsZW4gcmlhZGt5LCBrdG9yw6kgbW9kZWwgc2t1dG/EjW5lIHBvdcW+aWwpCmRmX21vZGVsICA8LSBhcy5kYXRhLmZyYW1lKG1vZGVsLmZyYW1lKG1vZGVsX2gpKQpkZl9tb2RlbDIgPC0gYXMuZGF0YS5mcmFtZShtb2RlbC5mcmFtZShtb2RlbDJfaCkpCgojIC0tLSBaQVJPVk5BTklFIFJFWsONRFXDjSBQT0TEvUEgTUlFTiBSSUFES09WIChrcml0aWNrw6kpIC0tLQpyMSA8LSByZXNpZHVhbHMobW9kZWxfaCkKZGZfbW9kZWwkUmVzaWR1YWxzIDwtIGFzLm51bWVyaWMocjFbbWF0Y2gocm93bmFtZXMoZGZfbW9kZWwpLCBuYW1lcyhyMSkpXSkKCnIyIDwtIHJlc2lkdWFscyhtb2RlbDJfaCkKZGZfbW9kZWwyJFJlc2lkdWFscyA8LSBhcy5udW1lcmljKHIyW21hdGNoKHJvd25hbWVzKGRmX21vZGVsMiksIG5hbWVzKHIyKSldKQoKIyA0KSBHcmFmeSDigJMgcMO0dm9kbsO9IG1vZGVsIChhbmFsw7NnIEdEUC9TY2hvb2xpbmcpCnAxIDwtIGdncGxvdChkZl9tb2RlbCwgYWVzKHggPSBgQ29uZHVjdGl2aXR5Li4uwrVtaG8uY20uLi4uTWF4YCwgeSA9IFJlc2lkdWFsc14yKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIGNvbG9yID0gInN0ZWVsYmx1ZSIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicyh4ID0gIlZvZGl2b3PFpSAowrVtaG8vY20pIiwKICAgICAgIHkgPSAixaB0dm9yY2UgcmV6w61kdcOtIiwKICAgICAgIHRpdGxlID0gIsWgdHZvcmNlIHJlesOtZHXDrSB2cyBWb2Rpdm9zxaUiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMiA8LSBnZ3Bsb3QoZGZfbW9kZWwsIGFlcyh4ID0gYFRlbXBlcmF0dXJlLi5DLi4uLk1heGAsIHkgPSBSZXNpZHVhbHNeMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJUZXBsb3RhICjCsEMpIiwKICAgICAgIHkgPSAixaB0dm9yY2UgcmV6w61kdcOtIiwKICAgICAgIHRpdGxlID0gIsWgdHZvcmNlIHJlesOtZHXDrSB2cyBUZXBsb3RhIikgKwogIHRoZW1lX21pbmltYWwoKQoKcDEgKyBwMgpgYGAKYSB0ZXJheiB0cmFuc2Zvcm1vdmFuw70gbW9kZWwKYGBge3J9CiMgZG9wbMWIIHN1cm92w7ogdm9kaXZvc8WlIChhIHByZSBpc3RvdHUgYWogdGVwbG90dSkgZG8gZGZfbW9kZWwyIHBvZMS+YSByb3ZuYWvDvWNoIHJpYWRrb3YKaWR4MiA8LSBhcy5pbnRlZ2VyKHJvd25hbWVzKGRmX21vZGVsMikpCmRmX21vZGVsMiRDb25kdWN0aXZpdHkgPC0gZGF0YV9oJGBDb25kdWN0aXZpdHkuLi7CtW1oby5jbS4uLi5NYXhgW2lkeDJdCmRmX21vZGVsMiRUZW1wZXJhdHVyZSAgPC0gZGF0YV9oJGBUZW1wZXJhdHVyZS4uQy4uLi5NYXhgW2lkeDJdCgojIDUpIEdyYWZ5IOKAkyB0cmFuc2Zvcm1vdmFuw70gbW9kZWwgKGxvZyB2b2Rpdm9zdGkpCnAzIDwtIGdncGxvdChkZl9tb2RlbDIsIGFlcyh4ID0gbG9nKENvbmR1Y3Rpdml0eSksIHkgPSBSZXNpZHVhbHNeMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJsb2coVm9kaXZvc8WlKSIsCiAgICAgICB5ID0gIsWgdHZvcmNlIHJlesOtZHXDrSIsCiAgICAgICB0aXRsZSA9ICLFoHR2b3JjZSByZXrDrWR1w60gdnMgbG9nKFZvZGl2b3PFpSkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwNCA8LSBnZ3Bsb3QoZGZfbW9kZWwyLCBhZXMoeCA9IFRlbXBlcmF0dXJlLCB5ID0gUmVzaWR1YWxzXjIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNiwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiVGVwbG90YSAowrBDKSIsCiAgICAgICB5ID0gIsWgdHZvcmNlIHJlesOtZHXDrSIsCiAgICAgICB0aXRsZSA9ICLFoHR2b3JjZSByZXrDrWR1w60gdnMgVGVwbG90YSIpICsKICB0aGVtZV9taW5pbWFsKCkKCnAzICsgcDQKYGBgCk5hIHRvbXRvIG9icsOhemt1IHBvZMS+YSB2eWhsYWRlbsO9Y2ggaG9kbsO0dCDFoXR2b3Jjb3YgcmV6w61kdcOtICjEjWVydmVuw6Ega3JpdmthKSBtw7TFvmVtZSBrb27FoXRhdG92YcWlLCDFvmUgcG8gbG9nYXJpdG1pY2tlaiB0cmFuc2Zvcm3DoWNpaSB2b2Rpdm9zdGkgKipsb2coVm9kaXZvc8WlKSoqIChwcmF2w70gcGFuZWwgcHJ2w6lobyByaWFka3UpIGtyaXZrYSBuZXZ5a2F6dWplIHN5c3RlbWF0aWNrw70gdHJlbmQgcyB2eXN2ZXTEvnVqw7pjb3UgcHJlbWVubm91IGEgdmFyaWFuY2lhIGNow71iIGplIHByaWJsacW+bmUga29uxaF0YW50bsOhLiBQb2RvYm5lIHByaSAqKlRlcGxvdGUqKiB2aWTDrW1lIGliYSBtaWVybnkgbG9rw6Fsbnkg4oCeaHJib2zigJwgb2tvbG8gMjXigJMzMyDCsEMsIGt0b3LDvSB2xaFhayBuZXByZWRzdGF2dWplIHbDvXJhem7DvSByYXN0IHZhcmlhYmlsaXR5LgoKS3bDtGxpIGRlbW9uxaF0csOhY2lpIGFsZSB1a8Ohxb5tZSwgxb5lIGJleiBwcmVkY2jDoWR6YWrDumNlaiBsb2dhcml0bWlja2VqIHRyYW5zZm9ybcOhY2llIGJ5IHRvIGRvcGFkbG8gaW5hay4gViBww7R2b2Rub20gbW9kZWxpICjEvmF2w70gcGFuZWwgcHJ2w6lobyByaWFka3UpIGplIMSNZXJ2ZW7DoSBrcml2a2EgcHJpICoqVm9kaXZvc3RpKiogbWllcm5lIGtsZXNhasO6Y2Eg4oCTIG5hem5hxI11amUgdG8gKipzbGFiw7ogaGV0ZXJvc2tlZGFzdGljaXR1KiogKHbDpMSNxaHDrSByb3pwdHlsIGNow71iIHByaSBuacW+xaFlaiB2b2Rpdm9zdGkpLCBrdG9yw6Egc2EgcG8gcHJlY2hvZGUgbmEgKipsb2coVm9kaXZvc8WlKSoqIHZ5dHLDoWNhIGEga3JpdmthIHNhIHbDvXJhem5lIHNwbG/FocWldWplLgoKKipaaHJudXRpZToqKiBUcmFuc2Zvcm3DoWNpYSAqKmxvZyhWb2Rpdm9zxaUpKiogemphdm5lIHN0YWJpbGl6dWplIHJvenB0eWwgYSB2aXp1w6FsbmUgbmV2aWTDrW1lIHbDvXpuYW1uw70gdsO9dm9qIMWhdHZvcmNvdiByZXrDrWR1w60gcyB2eXN2ZXTEvnVqw7pjaW1pIHByZW1lbm7DvW1pLiBQcmUgw7pwbG5vc8WlIGplIHZob2Ruw6kgdGVudG8gZG9qZW0gcG90dnJkacWlIGZvcm3DoWxueW0gdGVzdG9tIChuYXByLiAqKkJyZXVzY2jigJNQYWdhbi9Lb2Vua2Vy4oCTQmFzc2V0dCoqKSBhIHJlcG9ydG92YcWlIGluZmVyZW5jaXUgcyAqKnJvYnVzdG7DvW1pIChIQzEpKiogY2h5YmFtaS4KCiMjIFRlc3RvdmFuaWUgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eQoKTmFqcHJ2IG90ZXN0dWplbWUgcHLDrXRvbW5vc8WlIGhldGVyb3NrZWRhc3RpY2l0eSBwb21vY291ICoqQnJldXNjaOKAk1BhZ2FuKiogdGVzdHUgKMWhdHVkZW50aXpvdmFuw6EgdmVyemlhID0gS29lbmtlcuKAk0Jhc3NldHQpLiAgCk7DoXNsZWRuZSDigJMgYWsgYnkgaGV0ZXJvc2tlZGFzdGljaXRhIHByZXRydsOhdmFsYSDigJMgcmVwb3J0dWplbWUgb2RoYWR5IHMgKipXaGl0ZS9IQy1yb2J1c3Ruw71taSoqIHNtZXJvZGFqbsO9bWkgY2h5YmFtaSAodHlwICoqSEMxKiopLgpgYGB7cn0KbTEgPC0gaWYgKGV4aXN0cygibW9kZWxfaCIpKSBtb2RlbF9oIGVsc2UgaWYgKGV4aXN0cygibW9kZWwiKSkgbW9kZWwgZWxzZSBzdG9wKCJNb2RlbCBtMSBuZWV4aXN0dWplLiIpCm0yIDwtIGlmIChleGlzdHMoIm1vZGVsMl9oIikpIG1vZGVsMl9oIGVsc2UgaWYgKGV4aXN0cygibW9kZWwyIikpIG1vZGVsMiBlbHNlIHN0b3AoIk1vZGVsIG0yIG5lZXhpc3R1amUuIikKCmxpYnJhcnkobG10ZXN0KQoKI0JyZXVzY2jigJNQYWdhbiAoS29lbmtlcuKAk0Jhc3NldHQpIHByZSBvYmEgbW9kZWx5CgpicF9tMSA8LSBicHRlc3QobTEsIHN0dWRlbnRpemUgPSBUUlVFKQpicF9tMiA8LSBicHRlc3QobTIsIHN0dWRlbnRpemUgPSBUUlVFKQoKYnBfbTEKYnBfbTIKYGBgCk5hIHrDoWtsYWRlIHbDvXNsZWRrb3YgcmVncmVzaWUgbcO0xb5lbWUgcG92ZWRhxaUsIMW+ZSAqKmhldGVyb3NrZWRhc3RpY2l0YSByZXrDrWR1w60gbmllIGplIHYgbW9kZWxpIGBtMmAgcHLDrXRvbW7DoSoqLCB6YXRpYcS+IMSNbyB2IHByw61wYWRlICoqbW9kZWx1IGBtMWAgcHLDrXRvbW7DoSBqZSoqLiBBayBieSB2xaFhayBoZXRlcm9za2VkYXN0aWNpdGEgcHJldHJ2w6F2YWxhIGEgKipsb2dhcml0bWl6w6FjaWEgcHJlbWVubsO9Y2gqKiBhbGVibyAqKm9kc3Ryw6FuZW5pZSBvZMS+YWhsw71jaCBob2Ruw7R0KiogbmVwb21vaGxpLCBtw7TFvmVtZSBqdSBvxaFldHJpxaUgcG9tb2NvdSB0enYuICoqV2hpdGUgaGV0ZXJvc2tlZGFzdGljaXR5LWNvbnNpc3RlbnQgbWF0aWNlKiogKEhDKSwga2RlIHNhIHYgKnQqLXRlc3RvY2ggdsO9em5hbW5vc3RpIHJlZ3Jlc27DvWNoIGtvZWZpY2llbnRvdiBwb3XFvsOtdmFqw7og4oCeaHJ1YsWhaWXigJwgKHJvYnVzdG7DqSkgb2RoYWR5IHJvenB0eWxvdi4gUG9zdHVwIGplIHBvdG9tIHphbG/FvmVuw70gbmEgb2RoYWRvY2ggcyAqKkhDMS9IQzMqKiDFoXRhbmRhcmRuw71taSBjaHliYW1pLgoKKipWw71zbGVka3kgQlAgKEtvZW5rZXLigJNCYXNzZXR0KSB0ZXN0dToqKgoKLSAqKm0xOioqIFwocCA9IDAuMDM3OCA8IDAuMDVcKSDihpIgKip6YW1pZXRhbWUgSOKCgCoqIG5hIDUgJSBobGFkaW5lLiBWIHDDtHZvZG5vbSBtb2RlbGkgc8O6IGTDtGthenkgKipoZXRlcm9za2VkYXN0aWNpdHkqKi4gIAotICoqbTI6KiogXChwID0gMC4wNjkwID4gMC4wNVwpICgqYWxlKiBcKDwgMC4xMFwpKSDihpIgbmEgNSAlIGhsYWRpbmUgKipI4oKAIG5lemFtaWV0YW1lKiosIG5hIDEwICUgamUgdG8gKipocmFuacSNbsOpKiouICoqTG9nLXRyYW5zZm9ybcOhY2lhIHZvZGl2b3N0aSoqIHRlZGEgaGV0ZXJvc2tlZGFzdGljaXR1ICoqem7DrcW+aWxhKiouCgoKYGBge3J9CiMgUm9idXN0bsOpIChoZXRlcm9za2VkYXN0aWNpdHktY29uc2lzdGVudCkgY2h5Ynkg4oCTIEhDMQoKbGlicmFyeShzYW5kd2ljaCkKCmNhdCgiXG5Sb2J1c3Ruw6kgKEhDMSkgdC10ZXN0eSBrb2VmaWNpZW50b3Yg4oCTIG0xOlxuIikKY29lZnRlc3QobTEsIHZjb3YgPSB2Y292SEMobTEsIHR5cGUgPSAiSEMxIikpCgpgYGAKVsWhaW1uaW1lIHNpLCDFvmUgcG8gcG91xb5pdMOtICoqcm9idXN0bsO9Y2ggKEhDKSoqIHNtZXJvZGFqbsO9Y2ggY2jDvWIgdnljaMOhZHphasO6IGFrbyDFoXRhdGlzdGlja3kgdsO9em5hbW5lIHNwb2plbsOpIHMgcEjigKZNYXggbmFqbcOkIHByZW1lbm7DqSAqKlRlcGxvdGEgKOKAkykqKiwgKipSb3pwdXN0ZW7DvSBP4oKCICgrKSoqLCAqKlZvZGl2b3PFpSAoKykqKiBhICoqTml0cmF0ZU4gKCspKiouIFByZW1lbm7DoSAqKkJPRCoqIMWhdGF0aXN0aWNreSB2w716bmFtbsOhIG5pZSBqZSBhICoqRmVrw6FsbmUga29saWZvcm15Kiogc8O6IGxlbiAqKmhyYW5pxI1uZSB2w716bmFtbsOpKiogKOKJiCAxMCAlIGhsYWRpbmEpLiBUbyBqZSB2IHPDumxhZGUgcyB0w71tLCDFvmUgcm9idXN0bsOpIGNoeWJ5IOKAnnNwcsOtc25pYeKAnCBpbmZlcmVuY2l1IHYgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eS4gTmEgZHJ1aGVqIHN0cmFuZSB0cmViYSBwb2RvdGtuw7rFpSwgxb5lIHBvdcW+aXRpZSB0ZWp0byBtZXTDs2R5IGplIG5hanNwb8S+YWhsaXZlasWhaWUgcHJpIHbDpMSNxaHDrWNoIHbDvWJlcm9jaCAob3JpZW50YcSNbmUgKio+IDEwMCBwb3pvcm92YW7DrSoqKS4KCg==