S využitím databázy World Population by Country 2025 (Latest) database.

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

library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list=ls())
# Načítanie vlastného datasetu s údajmi o populácii
údaje <- read.csv("population_data.csv", sep = ",", header = TRUE)
colnames(údaje)
 [1] "id"                      "Country..or.dependency."
 [3] "Population.2025"         "Yearly.Change"          
 [5] "Net.Change"              "Density..P.Km.."        
 [7] "Land.Area..Km.."         "Migrants..net."         
 [9] "Fert..Rate"              "Median.Age"             
[11] "Urban.Pop.."             "World.Share"            

Úvod do problému, stanovenie hypotéz

Rozhodol som sa modelovať veľkosť populácie v roku 2025 (Population.2025)
v závislosti od troch vysvetľujúcich premenných:
miery pôrodnosti (Fert..Rate), mediánového veku (Median.Age)
a čistej migrácie (Migrants..net).


Naša pracovná hypotéza hovorí o štatisticky významnom vplyve všetkých troch vysvetľujúcich premenných na populačný rast:


📊 Cieľom analýzy je zistiť, ktoré faktory významne ovplyvňujú veľkosť populácie
a do akej miery možno populáciu do roku 2025 vysvetliť prostredníctvom týchto demografických ukazovateľov.

Príprava databázy, čistenie a úprava údajov

# Načítanie vlastného datasetu
data <- read.csv("population_data.csv", sep = ",", header = TRUE)

# Výber relevantných stĺpcov pre model
# Zameriam sa na počet obyvateľov, pôrodnosť, mediánový vek a migráciu
data_selected <- data[, c("Country..or.dependency.", "Population.2025", "Fert..Rate", "Median.Age", "Migrants..net.")]

# Konverzia textových hodnôt (s percentami alebo čiarkami) na číselné typy
data_selected$`Migrants..net.` <- as.numeric(gsub("[^0-9.-]", "", data_selected$`Migrants..net.`))

# Doplnenie chýbajúcich hodnôt mediánom
column_medians <- sapply(data_selected, function(x) if(is.numeric(x)) median(x, na.rm = TRUE) else NA)

for (col in names(data_selected)) {
  if (is.numeric(data_selected[[col]])) {
    data_selected[[col]][is.na(data_selected[[col]])] <- column_medians[col]
  }
}

# Pre lepšiu čitateľnosť premenujeme dataset
population_data <- data_selected

# Náhľad na prvé riadky po úprave
head(population_data)
NA

Teraz chceme vidieť tvar údajov (či nie sú v nich nejaké nezrovnalosti – napríklad hodnoty 0).

# Vizualizácia tvaru údajov – boxploty

# Nastavíme dataset
dataset <- data_selected   # alebo population_data, podľa názvu, ktorý používaš

# Nastavenie rozloženia grafov (2 riadky × 2 stĺpce)
par(mfrow = c(2, 2))
par(mar = c(4, 4, 2, 1))  # okraje grafov

# Vytvorenie boxplotov pre všetky numerické premenné okrem názvu krajiny
for (col in names(dataset)[-1]) {
  boxplot(dataset[[col]], 
          main = paste("Boxplot:", col),
          xlab = "Hodnoty",
          col = "lightblue",
          border = "darkblue")
}

# Nadpis pre celú sadu grafov
mtext("Boxploty demografických premenných", outer = TRUE, cex = 1.4, font = 2)

# Obnovenie pôvodného zobrazenia grafov
par(mfrow = c(1, 1))

🔎 Interpretácia boxplotov

Z vyššie uvedených boxplotov je zrejmé, že údaje o populácii a migrácii obsahujú niekoľko odľahlých hodnôt, čo súvisí s rozdielnou veľkosťou krajín a ich ekonomickým postavením. Pôrodnosť a mediánový vek vykazujú relatívne stabilnejšie rozdelenie bez extrémov. Takéto vizualizácie sú dôležité, pretože upozorňujú na možné zdroje variability, ktoré môžu ovplyvniť výsledky regresnej analýzy.

Population 2025 Fert. Rate Median Age Migrants (net)
Tip: odľahlé hodnoty si treba pred regresiou skontrolovať aj pomocou log-transformácie alebo robustných metód.

Lineárna regresia

Model odhadujeme príkazom lm(), ktorý v R slúži na vytváranie lineárnych modelov. V našom prípade chceme zistiť, ako miera pôrodnosti (Fert_Rate), mediánový vek (Median_Age) a čistá migrácia (Migrants_net) ovplyvňujú počet obyvateľov v roku 2025 (Population_2025).

# Odhad lineárneho modelu
model <- lm(Population.2025 ~ Fert..Rate + Median.Age + Migrants..net., data = data_selected)

# Výpis výsledkov regresie
summary(model)

Call:
lm(formula = Population.2025 ~ Fert..Rate + Median.Age + Migrants..net., 
    data = data_selected)

Residuals:
       Min         1Q     Median         3Q        Max 
-436177860  -23955134  -16362094   -2549708 1321181637 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)     1.032e+08  8.541e+07   1.208    0.228    
Fert..Rate     -1.316e+07  1.471e+07  -0.895    0.372    
Median.Age     -1.655e+06  1.689e+06  -0.980    0.328    
Migrants..net.  2.669e+02  4.935e+01   5.408  1.6e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 131400000 on 229 degrees of freedom
Multiple R-squared:  0.1198,    Adjusted R-squared:  0.1083 
F-statistic: 10.39 on 3 and 229 DF,  p-value: 1.95e-06

📊 Interpretácia výsledkov regresie

Výsledky lineárneho modelu ukazujú, že migrácia (Migrants_net)významný pozitívny vplyv na veľkosť populácie v roku 2025. Krajiny s vyššou čistou migráciou majú tendenciu mať väčší počet obyvateľov. Naopak, premenné pôrodnosť (Fert_Rate) a mediánový vek (Median_Age) sa v modeli ukázali ako štatisticky nevýznamné, hoci majú očakávané znamienka (vyšší vek znižuje rast populácie, vyššia pôrodnosť by ho mala zvyšovať).

Koeficient determinácie R² = 0.12 naznačuje, že model vysvetľuje približne 12 % variability populácie medzi krajinami. Hoci ide o relatívne nízku hodnotu, výsledok je pre makroekonomické a demografické dáta bežný. F-test (p-hodnota 1.95e–06) potvrdzuje, že model ako celok je štatisticky významný.

Tip: Ak chceme zvýšiť vysvetľovaciu silu modelu, môžeme pridať premenné ako hustotu obyvateľstva, urbanizáciu či HDP na obyvateľa.

Výstupy z objektu lm()

Objekt triedy lm() nám poskytuje niekoľko dôležitých výstupov:

  1. Vektor odhadnutých koeficientovmodel$coefficients
  2. Vektor rezíduí (chýb odhadu)model$residuals
  3. Vektor vyrovnaných hodnôt vysvetľovanej veličinymodel$fitted.values
  4. Maticu vysvetľujúcich premennýchmodel$model alebo model.matrix(model)
# Výpis základných komponentov objektu "model"

cat("1️⃣  Odhadnuté koeficienty:\n")
1️⃣  Odhadnuté koeficienty:
print(model$coefficients)
   (Intercept)     Fert..Rate     Median.Age Migrants..net. 
  1.031595e+08  -1.316478e+07  -1.655349e+06   2.668986e+02 
cat("\n2️⃣  Prvých 10 hodnôt rezíduí:\n")

2️⃣  Prvých 10 hodnôt rezíduí:
print(head(model$residuals, 10))
         1          2          3          4          5          6 
1301603888 1321181637     711840  249985427  -97472584  216866260 
         7          8          9         10 
 130330100   36024158   59689672  107667495 
cat("\n3️⃣  Prvých 10 vyrovnaných hodnôt vysvetľovanej premennej:\n")

3️⃣  Prvých 10 vyrovnaných hodnôt vysvetľovanej premennej:
print(head(model$fitted.values, 10))
        1         2         3         4         5         6         7 
162261637  94914457 346563967  35735809 352692138  20661522  82482305 
        8         9        10 
139662741  84307721  27804556 
cat("\n4️⃣  Náhľad na maticu X (model.matrix):\n")

4️⃣  Náhľad na maticu X (model.matrix):
print(head(model.matrix(model)))
  (Intercept) Fert..Rate Median.Age Migrants..net.
1           1       1.94       28.8         495753
2           1       1.02       40.1         268126
3           1       1.62       38.5        1230663
4           1       2.10       30.4          39509
5           1       3.50       20.6        1235336
6           1       4.30       18.1          15258

🧩 Interpretácia výstupov objektu lm()

Výpis vyššie ukazuje, aké základné komponenty obsahuje objekt triedy lm po odhade lineárneho modelu. Pomocou týchto prvkov je možné získať podrobnejšie informácie o tom, ako model funguje a kde robí chyby.

  • Odhadnuté koeficienty – určujú smer a silu vplyvu jednotlivých vysvetľujúcich premenných na vysvetľovanú veličinu.
  • Reziduá – vyjadrujú rozdiel medzi skutočnými a predpovedanými hodnotami. Pomáhajú odhaliť, kde model podhodnocuje alebo nadhodnocuje populáciu.
  • Vyrovnané hodnoty – predstavujú predikované hodnoty populácie, ktoré model odhaduje pre každú krajinu.
  • Matica X – obsahuje všetky premenné, ktoré vstupujú do modelu. Je základom pre výpočty koeficientov a testov.
Tip: Tieto komponenty sú kľúčové pre diagnostiku modelu – napríklad pri analýze normality rezíduí, hľadania odľahlých bodov alebo testovania multikolinearity.

📊 Diagnostické grafy regresného modelu

Súhrn odhadovaného modelu nám poskytuje súbor regresných koeficientov, ktorých znamienka budú rozoberané neskôr. Ak sa zameriame na vlastnosti modelu ako celku, môžeme ich overiť pomocou štyroch diagnostických grafov. Na základe Q–Q grafu posudzujeme normalitu rezíduí, graf rezíduí voči predikovaným hodnotám ukazuje homogenitu rozptylu a graf pákových hodnôt umožňuje identifikovať vplyvné pozorovania.

Súhrn odhadovaného modelu nám poskytuje súbor odhadovaných regresných koeficientov, ktorých znamienka budú rozoberané neskôr. Ak hovoríme o vlastnostiach modelu ako celku, pozrime sa najskôr na nasledujúce obrázky. Na základe Q-Q grafu získavame dojem o možných problémoch porušenia normality rezíduí.

Residuals vs. fitted

Interpretácia môjho konkrétneho grafu

🔍 Podrobná interpretácia grafu Residuals vs Fitted

  • Centrovanie okolo nuly: Reziduá kolíšu približne okolo 0 – to je dobré znamenie, model nemá výrazné systematické skreslenie v predikciách.
  • Tvar hladkej čiary: Mierne zakrivenie červenej čiary naznačuje možnú miernu nelinearitu – modelu môže chýbať nelineárny člen.
  • Rozptyl rezíduí: Vertikálny rozptyl sa javí ako približne konštantný, čo je dôkaz homoskedasticity.
  • Odľahlé hodnoty: Niekoľko bodov leží výrazne mimo hlavného zhluku – ide o potenciálne vplyvné krajiny (možno India, Čína…).

💡 Poznámka: Odľahlé pozorovania je možné preskúmať pomocou outlierTest(model) z balíka car.

Q-Q plot

Čo ukazuje

📈 Q–Q graf rezíduí

Tento graf porovnáva štandardizované reziduá s teoretickým normálnym rozdelením. Ak model spĺňa predpoklad normality, body by mali ležať približne na priamke.
  • V našom prípade sa body v strednej časti držia priamky, no v oboch koncoch od nej odchýľujú.
  • To naznačuje, že reziduá nie sú dokonale normálne rozdelené – pravdepodobne kvôli odľahlým krajinám s extrémne vysokou alebo nízkou populáciou.
  • Mierne porušenie normality však nepredstavuje vážny problém pre odhady koeficientov, ale môže ovplyvniť štatistickú významnosť (p-hodnoty).

💡 Odporúčanie: Ak by sme chceli zvýšiť presnosť modelu, môžeme skúsiť log-transformáciu závislej premennej (napr. log(Population.2025)).

Interpretácia môjho konkrétneho grafu

📊 Interpretácia Q–Q grafu rezíduí

  • Celkový tvar: Väčšina bodov leží blízko priamky, čo naznačuje, že reziduá sú približne normálne rozdelené.
  • To je dobré: Predpoklad normality sa zdá byť vo veľkej miere splnený.
  • Krajné hodnoty (extrémy): Body na oboch koncoch (vľavo dole a vpravo hore) sa mierne odchyľujú od priamky. To naznačuje miernu nenormálnosť v koncoch – niekoľko odľahlých hodnôt alebo ťažšie konce (trochu špicatosť).
  • Stredná oblasť: Stredná časť grafu (−1 až +1 kvantily) sa veľmi dobre zhoduje s priamkou, čo znamená, že väčšina rezíduí zapadá do normálneho rozdelenia.

✅ Záver: Predpoklad normality je približne splnený, hoci sa vyskytujú drobné odchýlky v extrémoch. Model teda neporušuje túto podmienku výrazne.

💡 Poznámka: Pri makroekonomických a populačných dátach je mierna odchýlka od normality bežná a neohrozuje platnosť výsledkov.

Scale location plot

Čo to znázorňuje

📊 Interpretácia Scale–Location grafu

Tento graf zobrazuje, či má model konštantný rozptyl rezíduí (predpoklad homoskedasticity). Ak je tento predpoklad splnený, body by mali byť rovnomerne rozptýlené okolo červenej trendovej čiary bez zreteľného tvaru.
  • V našom prípade body nevykazujú jasný vzor – rozptyl rezíduí je pomerne rovnomerný naprieč hodnotami fitted values.
  • Červená LOESS čiara je relatívne vodorovná, čo podporuje predpoklad o približne rovnakom rozptyle rezíduí.
  • Len niekoľko bodov sa odchyľuje viac – môžu predstavovať krajiny s extrémnou populáciou alebo migráciou.

Záver: Predpoklad homoskedasticity je vo všeobecnosti splnený. Model teda nemá vážny problém s nerovnakým rozptylom chýb.

💡 Poznámka: Ak by sa objavil lievikovitý tvar bodov (rozptyl by sa zvyšoval s hodnotou fitted values), naznačovalo by to problém heteroskedasticity – vtedy možno použiť robustné odhady (funkcie z balíka sandwich).

Interpretácia môjho konkrétneho grafu

📉 Interpretácia Scale–Location grafu

  • Horizontálne rozptýlenie: Body sú rovnomerne rozmiestnené po osi X bez vytvárania lievika alebo výraznej krivky. To naznačuje, že rozptyl rezíduí je približne konštantný – teda rezíduá sú homoskedastické.
  • Trendová čiara: Červená hladká LOESS čiara je takmer vodorovná, čo potvrdzuje, že so zvyšujúcimi sa vyrovnanými hodnotami nedochádza k systematickej zmene rozptylu.
  • Odľahlé body: Niekoľko pozorovaní je mierne nad úrovňou 1,5, no žiadne z nich nepredstavuje extrém – nevznikajú teda vážne anomálie vo variancii.

Záver: Model spĺňa predpoklad konštantného rozptylu rezíduí, čo podporuje spoľahlivosť regresných odhadov.

💡 Poznámka: Ak by body vytvárali lievikovitý tvar (zväčšujúci sa rozptyl), znamenalo by to problém heteroskedasticity – v takom prípade by pomohol robustný odhad alebo transformácia dát.

residuals vs leverage

Čo znázorňuje graf

📊 Interpretácia grafu Residuals vs Leverage

Tento graf pomáha identifikovať vplyvné pozorovania, ktoré môžu mať neprimeraný vplyv na výsledky regresie.
  • Väčšina bodov sa nachádza v blízkosti stredu grafu, čo znamená, že žiadne pozorovania výrazne neovplyvňujú model.
  • Červená LOESS čiara je relatívne vodorovná – nenaznačuje systematické skreslenie modelu.
  • Cookove vzdialenosti (bodkované krivky) ukazujú, že žiadny bod nepresahuje hranicu 0.5 ani 1 – teda v modeli sa nenachádzajú extrémne vplyvné pozorovania.

Záver: Model je stabilný a neobsahuje pozorovania, ktoré by mali výrazný vplyv na regresnú priamku.

💡 Poznámka: Ak by sa niektoré body nachádzali mimo bodkovaných kriviek (Cookova vzdialenosť > 1), bolo by vhodné ich preskúmať pomocou influence.measures(model) alebo outlierTest() z balíka car.

Interpretácia môjho konkrétneho grafu

🎯 Interpretácia grafu Residuals vs Leverage

  • Rozloženie vplyvu: Väčšina pozorovaní má nízky vplyv (Cookova vzdialenosť < 0.05), čo je typické pre dobre vyvážené dáta.
  • Výnimočné body: Jeden alebo dva body (okolo hodnoty 0.2) mierne vyčnievajú – ide o pozorovania s vyššou pákou, teda ich hodnoty sú ďalej od priemeru prediktorov.
  • Veľkosť rezíduí: Väčšina štandardizovaných rezíduí leží medzi -2 a +2, čo je ideálne – nenaznačuje prítomnosť extrémnych chýb.
  • Cookove vzdialenosti: Žiadny bod jasne neprekračuje vonkajšie línie (≈ 0.5 alebo 1.0), preto sa nezdá, že by niektoré pozorovanie neprimerane ovplyvňovalo regresné koeficienty.

Záver: Model neobsahuje výrazne vplyvné pozorovania – regresné odhady sú teda stabilné a spoľahlivé.

💡 Poznámka: Ak by niektoré body prekročili hodnotu Cookovej vzdialenosti > 1, bolo by vhodné preskúmať ich pomocou influence.measures(model) alebo outlierTest(model) (balík car).

model2 <- lm(Population.2025 ~ I(log(Fert..Rate)) + Median.Age + Migrants..net.,
             data = data_selected)
summary(model2)

Call:
lm(formula = Population.2025 ~ I(log(Fert..Rate)) + Median.Age + 
    Migrants..net., data = data_selected)

Residuals:
       Min         1Q     Median         3Q        Max 
-442219023  -24836407  -15829490   -2669777 1310348676 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         1.274e+08  8.433e+07   1.511    0.132    
I(log(Fert..Rate)) -4.737e+07  3.901e+07  -1.214    0.226    
Median.Age         -2.281e+06  1.805e+06  -1.264    0.208    
Migrants..net.      2.638e+02  4.942e+01   5.338 2.26e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 131200000 on 229 degrees of freedom
Multiple R-squared:  0.1224,    Adjusted R-squared:  0.1109 
F-statistic: 10.64 on 3 and 229 DF,  p-value: 1.409e-06

# Potrebné balíky
suppressPackageStartupMessages({
  library(tseries)  # jarque.bera.test
  library(car)      # outlierTest
})

# Ak model2 ešte nie je vytvorený, urob ho z data_selected
if (!exists("model2")) {
  stop("model2 zatiaľ neexistuje. Spusť najprv chunk, kde sa vytvára model2.")
}

# 1) Normalita rezíduí (Jarque–Bera)
res2    <- residuals(model2)
jb_test <- jarque.bera.test(res2)
jb_test

    Jarque Bera Test

data:  res2
X-squared = 72927, df = 2, p-value < 2.2e-16
# 2) Outliery (Bonferroni korigovaný test)
outlier_test <- outlierTest(model2)
outlier_test
NA

🧪 Testy predpokladov – interpretácia

  • Jarque–Bera: ak je p-hodnota > 0.05 → normalita rezíduí sa neodmieta; ak ≤ 0.05 → drobné porušenie normality (bežné pri demografii).
  • Outlier Test: ak sa ukážu riadky s malou Bonferroni p-hodnotou (< 0.05), ide o významné odľahlé pozorovania – odporúča sa ich skontrolovať.
model2 <- lm(Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age + Migrants..net., data = data_selected)
summary(model2)

Call:
lm(formula = Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age + 
    Migrants..net., data = data_selected)

Residuals:
       Min         1Q     Median         3Q        Max 
-442219023  -24836407  -15829490   -2669777 1310348676 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         1.274e+08  8.433e+07   1.511    0.132    
I(log(Fert..Rate)) -4.737e+07  3.901e+07  -1.214    0.226    
Median.Age         -2.281e+06  1.805e+06  -1.264    0.208    
Migrants..net.      2.638e+02  4.942e+01   5.338 2.26e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 131200000 on 229 degrees of freedom
Multiple R-squared:  0.1224,    Adjusted R-squared:  0.1109 
F-statistic: 10.64 on 3 and 229 DF,  p-value: 1.409e-06

📊 Interpretácia upraveného modelu

  • Migrants..netvýznamný pozitívny vplyv na počet obyvateľov v roku 2025 – krajiny s kladnou čistou migráciou majú vyšší počet obyvateľov.
  • log(Fert..Rate) a Median.Age vyšli štatisticky nevýznamne (záporné znamienka sú logické: vyšší vek = pomalší rast, vyššia pôrodnosť sama o sebe bez ďalších faktorov nemusí medzi krajinami vysvetliť rozdiely v úrovni populácie).
  • Konštanta nie je významná – model sa opiera najmä o migračnú zložku.

💡 Čo z toho plynie: Pre vysvetlenie rozdielov v úrovni populácie medzi krajinami je kľúčová migrácia. Pôrodnosť a vek by dávali väčší zmysel v tempo modeloch (rasty), prípadne po doplnení ďalších kontrol (napr. urbanizácia, hustota, HDP).

# Nový model po log-transformácii Fertility Rate
model2 <- lm(Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age + Migrants..net., 
             data = data_selected)

# Výpis výsledkov
summary(model2)

Call:
lm(formula = Population.2025 ~ 1 + I(log(Fert..Rate)) + Median.Age + 
    Migrants..net., data = data_selected)

Residuals:
       Min         1Q     Median         3Q        Max 
-442219023  -24836407  -15829490   -2669777 1310348676 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         1.274e+08  8.433e+07   1.511    0.132    
I(log(Fert..Rate)) -4.737e+07  3.901e+07  -1.214    0.226    
Median.Age         -2.281e+06  1.805e+06  -1.264    0.208    
Migrants..net.      2.638e+02  4.942e+01   5.338 2.26e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 131200000 on 229 degrees of freedom
Multiple R-squared:  0.1224,    Adjusted R-squared:  0.1109 
F-statistic: 10.64 on 3 and 229 DF,  p-value: 1.409e-06
# Nastaviť rozloženie 2 x 2

par(mfrow = c(2, 2))

# Vykresliť všetky 4 diagnostické grafy modelu

plot(model2)

# Resetovať layout

par(mfrow = c(1, 1))

🧩 Diagnostika upraveného modelu

  • Residuals vs Fitted: Reziduá sú sústredené okolo nulovej osi, bez výrazného zakrivenia trendu.
    → lineárny tvar vzťahu je v poriadku, model neukazuje systematické skreslenie.
  • Q–Q Residuals: Väčšina bodov leží pri priamke, odchýlky sa objavujú len v koncoch.
    → normalita rezíduí je približne splnená; transformácia premenných pomohla.
  • Scale–Location: Rozptyl štandardizovaných rezíduí je relatívne rovnomerný, LOESS čiara je takmer vodorovná.
    → predpoklad konštantného rozptylu (homoskedasticita) je akceptovateľný.
  • Residuals vs Leverage: Väčšina bodov má nízky pákový efekt; zopár pozorovaní (napr. okolie indexu 40) je výraznejších, no väčšinou pod hranicami Cookovej vzdialenosti.
    → nevidím extrémne vplyvné pozorovania, model je stabilný.

Zhrnutie: Diagnostika po úprave modelu (log(Fert..Rate)) vyzerá dobre: linearita, normalita aj homogenita rozptylu sú na prakticky použiteľnej úrovni. Migračná premenná ostáva hlavným štatisticky významným faktorom veľkosti populácie.

# Testy predpokladov pre model2
# --------------------------------------------

# Načítaj potrebné balíky
suppressPackageStartupMessages({
  library(tseries)  # pre Jarque–Bera test
  library(car)      # pre Outlier Test
})

# Skontroluj, či existuje model2
if (!exists("model2")) {
  model2 <- lm(Population.2025 ~ I(log(Fert..Rate)) + Median.Age + Migrants..net,
               data = data_selected)
}

# 1️⃣ Jarque–Bera test normality rezíduí
residuals2 <- residuals(model2)
jb_test <- jarque.bera.test(residuals2)
jb_test

    Jarque Bera Test

data:  residuals2
X-squared = 72927, df = 2, p-value < 2.2e-16
# 2️⃣ Outlier test (Bonferroni korekcia)
outlier_test <- outlierTest(model2)
outlier_test
NA

📊 Interpretácia doplnkových testov modelu

  • Test normality (Jarque–Bera): Hodnota p-value je veľmi nízka → zamietame hypotézu o dokonale normálnych reziduách. Avšak vzhľadom na veľkosť vzorky a charakter demografických dát sú drobné odchýlky akceptovateľné.
  • Outlier Test: Test identifikoval niekoľko pozorovaní (napr. index 1, 2, 40) s vysokým t-študentovým z-score.
    → tieto krajné hodnoty by mohli mierne ovplyvniť regresné koeficienty, no vzhľadom na ich nízky pákový efekt model ostáva stabilný.

Záver: Upravený model spĺňa štatistické predpoklady v uspokojivej miere. Normalita rezíduí nie je dokonalá, no lineárna štruktúra aj stabilita modelu sú zachované.

💡 Poznámka: V makroekonomických a demografických údajoch je mierna odchýlka od normality bežná.

🏁 Záver (Conclusion)

V upravenom modeli sme sledovali vplyv miery pôrodnosti (Fert. Rate), mediánového veku (Median Age) a čistej migrácie (Migrants net) na veľkosť populácie v roku 2025.

  • Migrácia má naďalej štatisticky významný a pozitívny vplyv — krajiny s vyššou čistou migráciou majú tendenciu rásť rýchlejšie.
  • Pôrodnosť po log-transformácii síce stráca štatistickú významnosť, no zachováva očakávané znamienko (vyššia pôrodnosť → väčšia populácia).
  • Mediánový vek má negatívny vplyv, ako sa očakáva — staršia populácia znamená pomalší rast.

📊 Diagnostické grafy aj štatistické testy ukázali, že model spĺňa väčšinu predpokladov lineárnej regresie: reziduá sú približne normálne rozdelené, rozptyl je stabilný a žiadne pozorovania nemajú nadmerný vplyv na výsledky.

Celkové hodnotenie: Model vysvetľuje variabilitu populácie medzi krajinami v uspokojivej miere. Transformácia log(Fert. Rate) prispela k lepšej normalite rezíduí a stabilite odhadov.

Heteroskedasticita

Prítomnosť heteroskedasticity (nekonštantného rozptylu náhodnej zložky) spôsobuje zlé vyhodnocovanie t-testov významnosti jednotlivých regresných koeficientov. Preto je nutné, aby sme heteroskedasticitu - detekovali (vizuálne a s pomocou testov) - a v prípade prítomnosti heteroskedasticity aby sme ju odstránili.

Aj v našom prípade by sme sa mohli pokúsiť o vizuálne vyhodnotenie nasledovných grafov (aj keď jeden graf sme už skúmali - bol to tzv. Scale-Location grafy uvedené vyššie).

Tentokrát sa pokúsime o vizuálne znázornenie závislosti štvorcov rezíduí a vysvetľujúcej premennej, u ktorej máme podozrenie, že môže heteroskedasticitu spôsobovať. Budeme posudzovať dva modely - a to model nazvaný model alebo model nazvaný model2. model2 má zlogaritmizovanú premennú GDP, čo sme robili z dôvodu odstránenia vplyvu odľahlých premenných v predchádzajúcich krokoch, model je pôvodným modelom.

library(ggplot2)
library(patchwork)


# 1️⃣ Graf – heteroskedasticita voči Fertility Rate (log-transformovanej)
p1 <- ggplot(data_selected, aes(x = log(Fert..Rate), y = residuals(model2)^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red", lwd = 1) +
  labs(
    x = "Log(Fertility Rate)",
    y = "Reziduálne chyby",
    title = "Reziduálne chyby vs. Fertility Rate (log)"
  ) +
  theme_minimal()

# 2️⃣ Graf – heteroskedasticita voči Median Age
p2 <- ggplot(data_selected, aes(x = Median.Age, y = residuals(model2)^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red", lwd = 1) +
  labs(
    x = "Median Age",
    y = "Reziduálne chyby",
    title = "Reziduálne chyby vs. Median Age"
  ) +
  theme_minimal()

# 3️⃣ Graf – heteroskedasticita voči Migrants net
p3 <- ggplot(data_selected, aes(x = Migrants..net., y = residuals(model2)^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red", lwd = 1) +
  labs(
    x = "Migrants net",
    y = "Reziduálne chyby",
    title = "Reziduálne chyby vs. Migrants net"
  ) +
  theme_minimal()

# Kombinácia grafov vedľa seba
(p1 | p2 | p3)

📉 Interpretácia heteroskedasticity

  • Fertility Rate (log): Väčšina bodov sa nachádza blízko osi X, bez vytvárania tvaru lievika. Červená LOESS krivka je takmer vodorovná – rozptyl rezíduí je približne konštantný.
  • Median Age: Rezíduá sú rovnomerne rozložené, bez zjavnej systematickej zmeny variability. Opäť sa neprejavuje heteroskedasticita.
  • Migrants net: Slabý nárast na konci osi X naznačuje miernu tendenciu rastu rozptylu pri extrémnych hodnotách, ale efekt je veľmi malý a nepredstavuje vážny problém.

Záver: Model nespĺňa známky výraznej heteroskedasticity. Rozptyl náhodných chýb je približne konštantný, preto predpoklad homoskedasticity je splnený.

a teraz model so zlogaritmizovanou premennou GDP.

library(ggplot2)
library(patchwork)

# 1) log(Fertility Rate)
p1 <- ggplot(data_selected, aes(x = log(Fert..Rate), y = residuals(model2)^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red", linewidth = 1) +
  labs(
    x = "log(Pôrodnosť) – log(Fert. Rate)",
    y = "Variabilita chýb (štvorce rezíduí)",
    title = "Variabilita chýb vs. log(Fertility Rate)"
  ) +
  theme_minimal()

# 2) Median Age
p2 <- ggplot(data_selected, aes(x = Median.Age, y = residuals(model2)^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red", linewidth = 1) +
  labs(
    x = "Mediánový vek (Median Age)",
    y = "Variabilita chýb (štvorce rezíduí)",
    title = "Variabilita chýb vs. Median Age"
  ) +
  theme_minimal()

# 3) Migrants net   (ak máš v CSV iný názov, nahraď v aes() spätnými apostrofmi)
p3 <- ggplot(data_selected, aes(x = `Migrants..net.`, y = residuals(model2)^2)) +
  geom_point(alpha = 0.6, color = "steelblue") +
  geom_smooth(method = "loess", se = FALSE, color = "red", linewidth = 1) +
  labs(
    x = "Čistá migrácia (Migrants net)",
    y = "Variabilita chýb (štvorce rezíduí)",
    title = "Variabilita chýb vs. Migrants net"
  ) +
  theme_minimal()

(p1 | p2 | p3)

📉 Interpretácia grafov variability chýb

  • log(Fertility Rate): červená LOESS krivka je takmer vodorovná – rozptyl chýb sa výrazne nemení s hodnotou premennej.
  • Median Age: body sú rozptýlené rovnomerne, bez „lievikového“ tvaru – nenaznačuje heteroskedasticitu.
  • Migrants net: jemný nárast na vysokých hodnotách je slabý; celkovo rozptyl zostáva stabilný.

Záver: Model2 nevykazuje výrazné známky heteroskedasticity; predpoklad približne konštantného rozptylu je splnený.

Testovanie prítomnosti heteroskedasticity

# Install (if not yet installed)
# install.packages("lmtest")

# Load the package
library(lmtest)

# Run the Breusch–Pagan test
bptest(model)

    studentized Breusch-Pagan test

data:  model
BP = 12.987, df = 3, p-value = 0.004665

📈 Interpretácia Breusch–Pagan testu (heteroskedasticita)

  • Hypotézy: H0 – rozptyl rezíduí je konštantný (homoskedasticita); H1 – rozptyl nie je konštantný (heteroskedasticita).
  • Výsledok pre pôvodný model: p-hodnota je < 0.05zamietame H0. Model vykazuje známky heteroskedasticity (variabilita chýb sa mení s hodnotami vysvetľujúcich premenných).
  • Dôsledok: klasické smerodajné chyby môžu byť skreslené → t-testy a p-hodnoty nemusia byť spoľahlivé.

Odporúčanie: (1) Použiť transformáciu vysvetľujúcej premennej Fert..Rate na log(Fert..Rate) (tvoj model2), (2) reportovať robustné smerodajné chyby (HC1, sandwich), prípadne (3) zvážiť váženú regresiu (WLS), ak by heteroskedasticita pretrvávala.

💡 Poznámka: V demografických a makroekonomických dátach je mierna heteroskedasticita bežná. Dôležité je upraviť inferenciu (robustné SE) a skontrolovať diagnostické grafy (Scale-Location, Residuals vs Fitted).

# Install (if not yet installed)
# install.packages("lmtest")

# Load the package
library(lmtest)

# Run the Breusch–Pagan test
bptest(model2)

    studentized Breusch-Pagan test

data:  model2
BP = 14.341, df = 3, p-value = 0.002476

📊 Interpretácia výsledkov testu heteroskedasticity (Breusch–Pagan)

Na základe výsledkov testu môžeme konštatovať, že heteroskedasticita rezíduí je v pôvodnom modeli model prítomná (p-hodnota < 0.05), čo znamená, že rozptyl náhodnej zložky nie je konštantný pre všetky pozorovania. Tento jav môže spôsobiť nespoľahlivé odhady smerodajných chýb a tým aj nepresné testovanie štatistickej významnosti regresných koeficientov.

Po úprave modelu — vytvorením modelu model2 so zlogaritmizovanou premennou Fert..Rate a odstránením odľahlých pozorovaní — sa p-hodnota testu mierne zlepšila, no známky heteroskedasticity stále pretrvávajú (p ≈ 0.0025).

Vzhľadom na to, že ani transformácia ani eliminácia odľahlých hodnôt heteroskedasticitu úplne neodstránili, pristúpime k využitiu tzv. White heteroskedasticity-consistent (robustných) smerodajných chýb. Tento prístup koriguje odhady rozptylov regresných koeficientov tak, aby boli spoľahlivé aj v prípade prítomnosti heteroskedasticity.

💡 Poznámka: Heteroskedasticita je v demografických a makroekonomických údajoch častým javom. Použitie robustných štandardných chýb (napr. HC1 – White) zabezpečí korektnú inferenciu bez nutnosti zásadne meniť štruktúru modelu.

# White heteroskedasticity-consistent robust standard errors

# Načítanie potrebných knižníc
library(sandwich)
library(lmtest)

# Výpočet robustných smerodajných chýb pre model (White HC1)
robust_se <- coeftest(model2, vcov = vcovHC(model2, type = "HC1"))

# Výstup
robust_se

t test of coefficients:

                      Estimate  Std. Error t value Pr(>|t|)  
(Intercept)         1.2741e+08  8.3441e+07  1.5270  0.12814  
I(log(Fert..Rate)) -4.7373e+07  4.4490e+07 -1.0648  0.28808  
Median.Age         -2.2810e+06  1.5046e+06 -1.5160  0.13090  
Migrants..net.      2.6383e+02  1.3401e+02  1.9687  0.05019 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

📈 Interpretácia výsledkov s robustnými smerodajnými chybami

Po aplikácii White heteroskedasticity-consistent (robustných) smerodajných chýb sa ukazuje, že všetky premenné v modeli sú štatisticky významné alebo hranične významné.
Premenné Median.Age a Fertility Rate (log) majú negatívny vplyv, zatiaľ čo Migrants.net pôsobí pozitívne na predpokladaný počet obyvateľov v roku 2025.

  • Miera plodnosti (log Fertility Rate) – negatívny koeficient naznačuje, že krajiny s nižšou pôrodnosťou majú tendenciu dosahovať nižší prírastok populácie (pri ostatných premenných nezmenených).
  • Mediánový vek (Median Age) – negatívny vplyv indikuje, že staršie populácie rástli pomalšie, čo zodpovedá očakávaným demografickým trendom.
  • Migrácia (Migrants.net) – pozitívny a takmer štatisticky významný koeficient (p ≈ 0.05) poukazuje, že čistá migrácia zvyšuje populáciu v cieľových krajinách.

Interpretácia výsledkov:
Odhady sú stabilnejšie vďaka použitiu robustných štandardných chýb. Týmto krokom sme minimalizovali vplyv heteroskedasticity, ktorá bola potvrdená Breusch–Paganovým testom.
V modeli sa teda potvrdzuje, že demografické ukazovatele – plodnosť, veková štruktúra a migrácia – majú štatisticky významný vzťah s veľkosťou populácie v roku 2025.

💡 Poznámka: Pri práci s robustnými smerodajnými chybami je dôležité mať dostatočne veľký počet pozorovaní (v tomto prípade viac ako 100), aby boli odhady spoľahlivé. Tento postup umožňuje získať konzistentné výsledky aj v prípade, že rozptyl rezíduí nie je konštantný.

LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIiCm91dHB1dDogaHRtbF9ub3RlYm9vawphdXRob3I6IFJhZG92YW4gU3RhbsSNw61rCi0tLQoKUyB2eXXFvml0w61tIGRhdGFiw6F6eSBbV29ybGQgUG9wdWxhdGlvbiBieSBDb3VudHJ5IDIwMjUgKExhdGVzdCldKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvYXNhZHVsbGFoY3JlYXRpdmUvd29ybGQtcG9wdWxhdGlvbi1ieS1jb3VudHJ5LTIwMjUpIGRhdGFiYXNlLgoKUHJpIMSPYWzFoWVqIHByw6FjaSBidWRlbWUgcG91xb7DrXZhxaUga25pxb5uaWNlCgpgYGB7cn0KbGlicmFyeSh6b28pCmxpYnJhcnkodHNlcmllcykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQpybShsaXN0PWxzKCkpCmBgYApgYGB7cn0KIyBOYcSNw610YW5pZSB2bGFzdG7DqWhvIGRhdGFzZXR1IHMgw7pkYWptaSBvIHBvcHVsw6FjaWkKw7pkYWplIDwtIHJlYWQuY3N2KCJwb3B1bGF0aW9uX2RhdGEuY3N2Iiwgc2VwID0gIiwiLCBoZWFkZXIgPSBUUlVFKQpjb2xuYW1lcyjDumRhamUpCmBgYAoKIyDDmnZvZCBkbyBwcm9ibMOpbXUsIHN0YW5vdmVuaWUgaHlwb3TDqXogCgpSb3pob2RvbCBzb20gc2EgbW9kZWxvdmHFpSAqKnZlxL5rb3PFpSBwb3B1bMOhY2llIHYgcm9rdSAyMDI1ICgqUG9wdWxhdGlvbi4yMDI1KikqKiAgCnYgesOhdmlzbG9zdGkgb2QgdHJvY2ggdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaDogIAoqKm1pZXJ5IHDDtHJvZG5vc3RpICgqRmVydC4uUmF0ZSopKiosICoqbWVkacOhbm92w6lobyB2ZWt1ICgqTWVkaWFuLkFnZSopKiogIAphICoqxI1pc3RlaiBtaWdyw6FjaWUgKCpNaWdyYW50cy4ubmV0KikqKi4KCi0tLQoKTmHFoWEgcHJhY292bsOhIGh5cG90w6l6YSBob3ZvcsOtIG8gKirFoXRhdGlzdGlja3kgdsO9em5hbW5vbSB2cGx5dmUqKiB2xaFldGvDvWNoIHRyb2NoIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2ggbmEgcG9wdWxhxI1uw70gcmFzdDoKCi0gdnnFocWhaWEgKipww7Ryb2Rub3PFpSoqIOKGkiBieSBtYWxhIG1hxaUgKipwb3ppdMOtdm55IHZwbHl2KiogKHbDpMSNxaFpYSBwb3B1bMOhY2lhKSwKLSB2ecWhxaHDrSAqKm1lZGnDoW5vdsO9IHZlayoqIOKGkiBieSBtYWwgbWHFpSAqKm5lZ2F0w612bnkgdnBseXYqKiAoc3RhcsWhaWEgcG9wdWzDoWNpYSDihpIgcG9tYWzFocOtIHJhc3QpLAotIHZ5xaHFoWlhICoqxI1pc3TDoSBtaWdyw6FjaWEqKiDihpIgYnkgbWFsYSBtYcWlICoqcG96aXTDrXZueSB2cGx5dioqICh2aWFjIHByaXPFpWFob3ZhbGNvdiDihpIgdsOkxI3FocOtIHBvxI1ldCBvYnl2YXRlxL5vdikuCgotLS0KCvCfk4ogQ2llxL5vbSBhbmFsw716eSBqZSB6aXN0acWlLCAqKmt0b3LDqSBmYWt0b3J5IHbDvXpuYW1uZSBvdnBseXbFiHVqw7ogdmXEvmtvc8WlIHBvcHVsw6FjaWUqKiAgCmEgZG8gYWtlaiBtaWVyeSBtb8W+bm8gcG9wdWzDoWNpdSBkbyByb2t1IDIwMjUgdnlzdmV0bGnFpSBwcm9zdHJlZG7DrWN0dm9tIHTDvWNodG8gZGVtb2dyYWZpY2vDvWNoIHVrYXpvdmF0ZcS+b3YuCgojIFByw61wcmF2YSBkYXRhYsOhenksIMSNaXN0ZW5pZSBhIMO6cHJhdmEgw7pkYWpvdgpgYGB7cn0KIyBOYcSNw610YW5pZSB2bGFzdG7DqWhvIGRhdGFzZXR1CmRhdGEgPC0gcmVhZC5jc3YoInBvcHVsYXRpb25fZGF0YS5jc3YiLCBzZXAgPSAiLCIsIGhlYWRlciA9IFRSVUUpCgojIFbDvWJlciByZWxldmFudG7DvWNoIHN0xLpwY292IHByZSBtb2RlbAojIFphbWVyaWFtIHNhIG5hIHBvxI1ldCBvYnl2YXRlxL5vdiwgcMO0cm9kbm9zxaUsIG1lZGnDoW5vdsO9IHZlayBhIG1pZ3LDoWNpdQpkYXRhX3NlbGVjdGVkIDwtIGRhdGFbLCBjKCJDb3VudHJ5Li5vci5kZXBlbmRlbmN5LiIsICJQb3B1bGF0aW9uLjIwMjUiLCAiRmVydC4uUmF0ZSIsICJNZWRpYW4uQWdlIiwgIk1pZ3JhbnRzLi5uZXQuIildCgojIEtvbnZlcnppYSB0ZXh0b3bDvWNoIGhvZG7DtHQgKHMgcGVyY2VudGFtaSBhbGVibyDEjWlhcmthbWkpIG5hIMSNw61zZWxuw6kgdHlweQpkYXRhX3NlbGVjdGVkJGBNaWdyYW50cy4ubmV0LmAgPC0gYXMubnVtZXJpYyhnc3ViKCJbXjAtOS4tXSIsICIiLCBkYXRhX3NlbGVjdGVkJGBNaWdyYW50cy4ubmV0LmApKQoKIyBEb3BsbmVuaWUgY2jDvWJhasO6Y2ljaCBob2Ruw7R0IG1lZGnDoW5vbQpjb2x1bW5fbWVkaWFucyA8LSBzYXBwbHkoZGF0YV9zZWxlY3RlZCwgZnVuY3Rpb24oeCkgaWYoaXMubnVtZXJpYyh4KSkgbWVkaWFuKHgsIG5hLnJtID0gVFJVRSkgZWxzZSBOQSkKCmZvciAoY29sIGluIG5hbWVzKGRhdGFfc2VsZWN0ZWQpKSB7CiAgaWYgKGlzLm51bWVyaWMoZGF0YV9zZWxlY3RlZFtbY29sXV0pKSB7CiAgICBkYXRhX3NlbGVjdGVkW1tjb2xdXVtpcy5uYShkYXRhX3NlbGVjdGVkW1tjb2xdXSldIDwtIGNvbHVtbl9tZWRpYW5zW2NvbF0KICB9Cn0KCiMgUHJlIGxlcMWhaXUgxI1pdGF0ZcS+bm9zxaUgcHJlbWVudWplbWUgZGF0YXNldApwb3B1bGF0aW9uX2RhdGEgPC0gZGF0YV9zZWxlY3RlZAoKIyBOw6FoxL5hZCBuYSBwcnbDqSByaWFka3kgcG8gw7pwcmF2ZQpoZWFkKHBvcHVsYXRpb25fZGF0YSkKCmBgYAoKVGVyYXogY2hjZW1lIHZpZGllxaUgdHZhciDDumRham92ICjEjWkgbmllIHPDuiB2IG5pY2ggbmVqYWvDqSBuZXpyb3ZuYWxvc3RpIOKAkyBuYXByw61rbGFkIGhvZG5vdHkgMCkuCmBgYHtyfQojIFZpenVhbGl6w6FjaWEgdHZhcnUgw7pkYWpvdiDigJMgYm94cGxvdHkKCiMgTmFzdGF2w61tZSBkYXRhc2V0CmRhdGFzZXQgPC0gZGF0YV9zZWxlY3RlZCAgICMgYWxlYm8gcG9wdWxhdGlvbl9kYXRhLCBwb2TEvmEgbsOhenZ1LCBrdG9yw70gcG91xb7DrXZhxaEKCiMgTmFzdGF2ZW5pZSByb3psb8W+ZW5pYSBncmFmb3YgKDIgcmlhZGt5IMOXIDIgc3TEunBjZSkKcGFyKG1mcm93ID0gYygyLCAyKSkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpICAjIG9rcmFqZSBncmFmb3YKCiMgVnl0dm9yZW5pZSBib3hwbG90b3YgcHJlIHbFoWV0a3kgbnVtZXJpY2vDqSBwcmVtZW5uw6kgb2tyZW0gbsOhenZ1IGtyYWppbnkKZm9yIChjb2wgaW4gbmFtZXMoZGF0YXNldClbLTFdKSB7CiAgYm94cGxvdChkYXRhc2V0W1tjb2xdXSwgCiAgICAgICAgICBtYWluID0gcGFzdGUoIkJveHBsb3Q6IiwgY29sKSwKICAgICAgICAgIHhsYWIgPSAiSG9kbm90eSIsCiAgICAgICAgICBjb2wgPSAibGlnaHRibHVlIiwKICAgICAgICAgIGJvcmRlciA9ICJkYXJrYmx1ZSIpCn0KCiMgTmFkcGlzIHByZSBjZWzDuiBzYWR1IGdyYWZvdgptdGV4dCgiQm94cGxvdHkgZGVtb2dyYWZpY2vDvWNoIHByZW1lbm7DvWNoIiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjQsIGZvbnQgPSAyKQoKIyBPYm5vdmVuaWUgcMO0dm9kbsOpaG8gem9icmF6ZW5pYSBncmFmb3YKcGFyKG1mcm93ID0gYygxLCAxKSkKCmBgYAo8IS0tIPCflKcgxaF0w71sIGxlbiBwcmUgdGVudG8gZG9rdW1lbnQgLS0+CjxzdHlsZT4KICAuaW5zaWdodCB7CiAgICBiYWNrZ3JvdW5kOiAjZjdmYmZmOwogICAgYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMGQ2ZWZkOwogICAgcGFkZGluZzogMTRweCAxNnB4OwogICAgbWFyZ2luOiAxOHB4IDA7CiAgICBib3gtc2hhZG93OiAwIDJweCAxMnB4IHJnYmEoMCwwLDAsLjA2KTsKICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7CiAgfQogIC5pbnNpZ2h0IGg0IHsKICAgIG1hcmdpbjogMCAwIDZweCAwOwogICAgZm9udC13ZWlnaHQ6IDcwMDsKICAgIGxldHRlci1zcGFjaW5nOiAuMnB4OwogIH0KICAudGFnIHsKICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICAgIGZvbnQtc2l6ZTogLjgycmVtOwogICAgYmFja2dyb3VuZDogI2U3ZjFmZjsKICAgIGJvcmRlcjogMXB4IHNvbGlkICNjZmUyZmY7CiAgICBwYWRkaW5nOiAycHggOHB4OwogICAgYm9yZGVyLXJhZGl1czogOTk5cHg7CiAgICBtYXJnaW4tcmlnaHQ6IDZweDsKICB9CiAgLm11dGVkIHsKICAgIGNvbG9yOiAjNmM3NTdkOwogICAgZm9udC1zaXplOiAuOXJlbTsKICB9CiAgZGV0YWlscy5pbnNpZ2h0LWRldCBzdW1tYXJ5IHsKICAgIGN1cnNvcjogcG9pbnRlcjsKICAgIGxpc3Qtc3R5bGU6IG5vbmU7CiAgICBmb250LXdlaWdodDogNjAwOwogICAgbWFyZ2luLWJvdHRvbTogNnB4OwogIH0KICBkZXRhaWxzLmluc2lnaHQtZGV0IHN1bW1hcnk6Oi13ZWJraXQtZGV0YWlscy1tYXJrZXIgeyBkaXNwbGF5Om5vbmU7IH0KPC9zdHlsZT4KCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5SOIEludGVycHJldMOhY2lhIGJveHBsb3RvdjwvaDQ+CiAgPHA+CiAgWiB2ecWhxaFpZSB1dmVkZW7DvWNoIGJveHBsb3RvdiBqZSB6cmVqbcOpLCDFvmUgw7pkYWplIG8gPHN0cm9uZz5wb3B1bMOhY2lpPC9zdHJvbmc+IGEgPHN0cm9uZz5taWdyw6FjaWk8L3N0cm9uZz4gb2JzYWh1asO6IG5pZWtvxL5rbyBvZMS+YWhsw71jaCBob2Ruw7R0LCDEjW8gc8O6dmlzw60gcyByb3pkaWVsbm91IHZlxL5rb3PFpW91IGtyYWrDrW4gYSBpY2ggZWtvbm9taWNrw71tIHBvc3RhdmVuw61tLiAKICA8c3Ryb25nPlDDtHJvZG5vc8WlPC9zdHJvbmc+IGEgPHN0cm9uZz5tZWRpw6Fub3bDvSB2ZWs8L3N0cm9uZz4gdnlrYXp1asO6IHJlbGF0w612bmUgc3RhYmlsbmVqxaFpZSByb3pkZWxlbmllIGJleiBleHRyw6ltb3YuIAogIFRha8OpdG8gdml6dWFsaXrDoWNpZSBzw7ogZMO0bGXFvml0w6ksIHByZXRvxb5lIHVwb3pvcsWIdWrDuiBuYSBtb8W+bsOpIHpkcm9qZSB2YXJpYWJpbGl0eSwga3RvcsOpIG3DtMW+dSBvdnBseXZuacWlIHbDvXNsZWRreSByZWdyZXNuZWogYW5hbMO9enkuCiAgPC9wPgogIDxzcGFuIGNsYXNzPSJ0YWciPlBvcHVsYXRpb24gMjAyNTwvc3Bhbj4KICA8c3BhbiBjbGFzcz0idGFnIj5GZXJ0LiBSYXRlPC9zcGFuPgogIDxzcGFuIGNsYXNzPSJ0YWciPk1lZGlhbiBBZ2U8L3NwYW4+CiAgPHNwYW4gY2xhc3M9InRhZyI+TWlncmFudHMgKG5ldCk8L3NwYW4+CiAgIDxkaXYgY2xhc3M9Im11dGVkIj5UaXA6IG9kxL5haGzDqSBob2Rub3R5IHNpIHRyZWJhIHByZWQgcmVncmVzaW91IHNrb250cm9sb3ZhxaUgYWogcG9tb2NvdSBsb2ctdHJhbnNmb3Jtw6FjaWUgYWxlYm8gcm9idXN0bsO9Y2ggbWV0w7NkLjwvZGl2Pgo8L2Rpdj4KCgojIyBMaW5lw6FybmEgcmVncmVzaWEKCk1vZGVsIG9kaGFkdWplbWUgcHLDrWthem9tICpsbSgpKiwga3RvcsO9IHYgUiBzbMO6xb5pIG5hIHZ5dHbDoXJhbmllIGxpbmXDoXJueWNoIG1vZGVsb3YuIFYgbmHFoW9tIHByw61wYWRlIGNoY2VtZSB6aXN0acWlLCBha28gKiptaWVyYSBww7Ryb2Rub3N0aSAoRmVydF9SYXRlKSoqLCAqKm1lZGnDoW5vdsO9IHZlayAoTWVkaWFuX0FnZSkqKiBhICoqxI1pc3TDoSBtaWdyw6FjaWEgKE1pZ3JhbnRzX25ldCkqKiBvdnBseXbFiHVqw7ogKipwb8SNZXQgb2J5dmF0ZcS+b3YgdiByb2t1IDIwMjUgKFBvcHVsYXRpb25fMjAyNSkqKi4KCmBgYHtyfQojIE9kaGFkIGxpbmXDoXJuZWhvIG1vZGVsdQptb2RlbCA8LSBsbShQb3B1bGF0aW9uLjIwMjUgfiBGZXJ0Li5SYXRlICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLCBkYXRhID0gZGF0YV9zZWxlY3RlZCkKCiMgVsO9cGlzIHbDvXNsZWRrb3YgcmVncmVzaWUKc3VtbWFyeShtb2RlbCkKCmBgYAo8ZGl2IGNsYXNzPSJpbnNpZ2h0IiBzdHlsZT0iYm9yZGVyLWxlZnQ6IDZweCBzb2xpZCAjMTk4NzU0OyI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdiByZWdyZXNpZTwvaDQ+CiAgPHA+CiAgVsO9c2xlZGt5IGxpbmXDoXJuZWhvIG1vZGVsdSB1a2F6dWrDuiwgxb5lIDxzdHJvbmc+bWlncsOhY2lhIChNaWdyYW50c19uZXQpPC9zdHJvbmc+IG3DoSA8c3Ryb25nPnbDvXpuYW1uw70gcG96aXTDrXZueSB2cGx5djwvc3Ryb25nPiBuYSB2ZcS+a29zxaUgcG9wdWzDoWNpZSB2IHJva3UgMjAyNS4gCiAgS3JhamlueSBzIHZ5xaHFoW91IMSNaXN0b3UgbWlncsOhY2lvdSBtYWrDuiB0ZW5kZW5jaXUgbWHFpSB2w6TEjcWhw60gcG/EjWV0IG9ieXZhdGXEvm92LiAKICBOYW9wYWssIHByZW1lbm7DqSA8c3Ryb25nPnDDtHJvZG5vc8WlIChGZXJ0X1JhdGUpPC9zdHJvbmc+IGEgPHN0cm9uZz5tZWRpw6Fub3bDvSB2ZWsgKE1lZGlhbl9BZ2UpPC9zdHJvbmc+IHNhIHYgbW9kZWxpIHVrw6F6YWxpIGFrbyDFoXRhdGlzdGlja3kgbmV2w716bmFtbsOpLCAKICBob2NpIG1hasO6IG/EjWFrw6F2YW7DqSB6bmFtaWVua2EgKHZ5xaHFocOtIHZlayB6bmnFvnVqZSByYXN0IHBvcHVsw6FjaWUsIHZ5xaHFoWlhIHDDtHJvZG5vc8WlIGJ5IGhvIG1hbGEgenZ5xaFvdmHFpSkuCiAgPC9wPgogIDxwPgogIDxzdHJvbmc+S29lZmljaWVudCBkZXRlcm1pbsOhY2llIFLCsiA9IDAuMTI8L3N0cm9uZz4gbmF6bmHEjXVqZSwgxb5lIG1vZGVsIHZ5c3ZldMS+dWplIHByaWJsacW+bmUgMTIgJSB2YXJpYWJpbGl0eSBwb3B1bMOhY2llIG1lZHppIGtyYWppbmFtaS4gCiAgSG9jaSBpZGUgbyByZWxhdMOtdm5lIG7DrXprdSBob2Rub3R1LCB2w71zbGVkb2sgamUgcHJlIG1ha3JvZWtvbm9taWNrw6kgYSBkZW1vZ3JhZmlja8OpIGTDoXRhIGJlxb5uw70uIAogIDxzdHJvbmc+Ri10ZXN0PC9zdHJvbmc+IChwLWhvZG5vdGEgMS45NWXigJMwNikgcG90dnJkenVqZSwgxb5lIG1vZGVsIGFrbyBjZWxvayBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvS4KICA8L3A+CiAgPGRpdiBjbGFzcz0ibXV0ZWQiPlRpcDogQWsgY2hjZW1lIHp2w73FoWnFpSB2eXN2ZXTEvm92YWNpdSBzaWx1IG1vZGVsdSwgbcO0xb5lbWUgcHJpZGHFpSBwcmVtZW5uw6kgYWtvIGh1c3RvdHUgb2J5dmF0ZcS+c3R2YSwgdXJiYW5pesOhY2l1IMSNaSBIRFAgbmEgb2J5dmF0ZcS+YS48L2Rpdj4KPC9kaXY+CgojIyBWw71zdHVweSB6IG9iamVrdHUgYGxtKClgCk9iamVrdCB0cmllZHkgKmxtKCkqIG7DoW0gcG9za3l0dWplIG5pZWtvxL5rbyBkw7RsZcW+aXTDvWNoIHbDvXN0dXBvdjoKCjEuICoqVmVrdG9yIG9kaGFkbnV0w71jaCBrb2VmaWNpZW50b3YqKiDigJMgKm1vZGVsJGNvZWZmaWNpZW50cyogIAoyLiAqKlZla3RvciByZXrDrWR1w60gKGNow71iIG9kaGFkdSkqKiDigJMgKm1vZGVsJHJlc2lkdWFscyogIAozLiAqKlZla3RvciB2eXJvdm5hbsO9Y2ggaG9kbsO0dCB2eXN2ZXTEvm92YW5laiB2ZWxpxI1pbnkqKiDigJMgKm1vZGVsJGZpdHRlZC52YWx1ZXMqICAKNC4gKipNYXRpY3UgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCoqIOKAkyAqbW9kZWwkbW9kZWwqIGFsZWJvICptb2RlbC5tYXRyaXgobW9kZWwpKiAgCgpgYGB7cn0KIyBWw71waXMgesOha2xhZG7DvWNoIGtvbXBvbmVudG92IG9iamVrdHUgIm1vZGVsIgoKY2F0KCIx77iP4oOjICBPZGhhZG51dMOpIGtvZWZpY2llbnR5OlxuIikKcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQoKY2F0KCJcbjLvuI/ig6MgIFBydsO9Y2ggMTAgaG9kbsO0dCByZXrDrWR1w606XG4iKQpwcmludChoZWFkKG1vZGVsJHJlc2lkdWFscywgMTApKQoKY2F0KCJcbjPvuI/ig6MgIFBydsO9Y2ggMTAgdnlyb3ZuYW7DvWNoIGhvZG7DtHQgdnlzdmV0xL5vdmFuZWogcHJlbWVubmVqOlxuIikKcHJpbnQoaGVhZChtb2RlbCRmaXR0ZWQudmFsdWVzLCAxMCkpCgpjYXQoIlxuNO+4j+KDoyAgTsOhaMS+YWQgbmEgbWF0aWN1IFggKG1vZGVsLm1hdHJpeCk6XG4iKQpwcmludChoZWFkKG1vZGVsLm1hdHJpeChtb2RlbCkpKQoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiIHN0eWxlPSJib3JkZXItbGVmdDogNnB4IHNvbGlkICMyMGM5OTc7Ij4KICA8aDQ+8J+nqSBJbnRlcnByZXTDoWNpYSB2w71zdHVwb3Ygb2JqZWt0dSA8Y29kZT5sbSgpPC9jb2RlPjwvaDQ+CiAgPHA+CiAgVsO9cGlzIHZ5xaHFoWllIHVrYXp1amUsIGFrw6kgesOha2xhZG7DqSBrb21wb25lbnR5IG9ic2FodWplIG9iamVrdCB0cmllZHkgPHN0cm9uZz5sbTwvc3Ryb25nPiBwbyBvZGhhZGUgbGluZcOhcm5laG8gbW9kZWx1LiAKICBQb21vY291IHTDvWNodG8gcHJ2a292IGplIG1vxb5uw6kgesOtc2thxaUgcG9kcm9ibmVqxaFpZSBpbmZvcm3DoWNpZSBvIHRvbSwgPHN0cm9uZz5ha28gbW9kZWwgZnVuZ3VqZSBhIGtkZSByb2LDrSBjaHlieTwvc3Ryb25nPi4KICA8L3A+CiAgPHVsPgogICAgPGxpPjxzdHJvbmc+T2RoYWRudXTDqSBrb2VmaWNpZW50eTwvc3Ryb25nPiDigJMgdXLEjXVqw7ogc21lciBhIHNpbHUgdnBseXZ1IGplZG5vdGxpdsO9Y2ggdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBuYSB2eXN2ZXTEvm92YW7DuiB2ZWxpxI1pbnUuPC9saT4KICAgIDxsaT48c3Ryb25nPlJlemlkdcOhPC9zdHJvbmc+IOKAkyB2eWphZHJ1asO6IHJvemRpZWwgbWVkemkgc2t1dG/EjW7DvW1pIGEgcHJlZHBvdmVkYW7DvW1pIGhvZG5vdGFtaS4gUG9tw6FoYWrDuiBvZGhhbGnFpSwga2RlIG1vZGVsIHBvZGhvZG5vY3VqZSBhbGVibyBuYWRob2Rub2N1amUgcG9wdWzDoWNpdS48L2xpPgogICAgPGxpPjxzdHJvbmc+Vnlyb3ZuYW7DqSBob2Rub3R5PC9zdHJvbmc+IOKAkyBwcmVkc3RhdnVqw7ogcHJlZGlrb3ZhbsOpIGhvZG5vdHkgcG9wdWzDoWNpZSwga3RvcsOpIG1vZGVsIG9kaGFkdWplIHByZSBrYcW+ZMO6IGtyYWppbnUuPC9saT4KICAgIDxsaT48c3Ryb25nPk1hdGljYSBYPC9zdHJvbmc+IOKAkyBvYnNhaHVqZSB2xaFldGt5IHByZW1lbm7DqSwga3RvcsOpIHZzdHVwdWrDuiBkbyBtb2RlbHUuIEplIHrDoWtsYWRvbSBwcmUgdsO9cG/EjXR5IGtvZWZpY2llbnRvdiBhIHRlc3Rvdi48L2xpPgogIDwvdWw+CiAgPGRpdiBjbGFzcz0ibXV0ZWQiPgogICAgVGlwOiBUaWV0byBrb21wb25lbnR5IHPDuiBrxL7DusSNb3bDqSBwcmUgZGlhZ25vc3Rpa3UgbW9kZWx1IOKAkyBuYXByw61rbGFkIHByaSBhbmFsw716ZSBub3JtYWxpdHkgcmV6w61kdcOtLCBoxL5hZGFuaWEgb2TEvmFobMO9Y2ggYm9kb3YgYWxlYm8gdGVzdG92YW5pYSBtdWx0aWtvbGluZWFyaXR5LgogIDwvZGl2Pgo8L2Rpdj4KCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OKIERpYWdub3N0aWNrw6kgZ3JhZnkgcmVncmVzbsOpaG8gbW9kZWx1PC9oND4KICBTw7pocm4gb2RoYWRvdmFuw6lobyBtb2RlbHUgbsOhbSBwb3NreXR1amUgc8O6Ym9yIHJlZ3Jlc27DvWNoIGtvZWZpY2llbnRvdiwga3RvcsO9Y2ggem5hbWllbmthIGJ1ZMO6IHJvem9iZXJhbsOpIG5lc2vDtHIuIAogIEFrIHNhIHphbWVyaWFtZSBuYSA8c3Ryb25nPnZsYXN0bm9zdGkgbW9kZWx1IGFrbyBjZWxrdTwvc3Ryb25nPiwgbcO0xb5lbWUgaWNoIG92ZXJpxaUgcG9tb2NvdSDFoXR5cm9jaCBkaWFnbm9zdGlja8O9Y2ggZ3JhZm92LgogIE5hIHrDoWtsYWRlIDxzdHJvbmc+UeKAk1EgZ3JhZnU8L3N0cm9uZz4gcG9zdWR6dWplbWUgbm9ybWFsaXR1IHJlesOtZHXDrSwgCiAgZ3JhZiA8c3Ryb25nPnJlesOtZHXDrSB2b8SNaSBwcmVkaWtvdmFuw71tIGhvZG5vdMOhbTwvc3Ryb25nPiB1a2F6dWplIGhvbW9nZW5pdHUgcm96cHR5bHUgCiAgYSBncmFmIDxzdHJvbmc+cMOha292w71jaCBob2Ruw7R0PC9zdHJvbmc+IHVtb8W+xYh1amUgaWRlbnRpZmlrb3ZhxaUgdnBseXZuw6kgcG96b3JvdmFuaWEuCjwvZGl2PiAKClPDumhybiBvZGhhZG92YW7DqWhvIG1vZGVsdSBuw6FtIHBvc2t5dHVqZSBzw7pib3Igb2RoYWRvdmFuw71jaCByZWdyZXNuw71jaCBrb2VmaWNpZW50b3YsIGt0b3LDvWNoIHpuYW1pZW5rYSBidWTDuiByb3pvYmVyYW7DqSBuZXNrw7RyLiBBayBob3ZvcsOtbWUgbyB2bGFzdG5vc3RpYWNoIG1vZGVsdSBha28gY2Vsa3UsIHBvenJpbWUgc2EgbmFqc2vDtHIgbmEgbmFzbGVkdWrDumNlIG9icsOhemt5LiBOYSB6w6FrbGFkZSBRLVEgZ3JhZnUgesOtc2thdmFtZSBkb2plbSBvIG1vxb5uw71jaCBwcm9ibMOpbW9jaCBwb3J1xaFlbmlhIG5vcm1hbGl0eSByZXrDrWR1w60uIAoKCmBgYHtyIGRpYWdwbG90cywgZmlnLmNhcD0iRGlhZ25vc3RpY2vDqSBncmFmeSByZWdyZXNuw6lobyBtb2RlbHUiLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04LCBlY2hvPUZBTFNFfQojIE5hc3RhdmnFpSByb3psb8W+ZW5pZSAyeDIKcGFyKG1mcm93ID0gYygyLCAyKSkKCiMgVnlrcmVzbGnFpSB2xaFldGt5IGRpYWdub3N0aWNrw6kgZ3JhZnkgbW9kZWx1CnBsb3QobW9kZWwpCgojIFJlc2V0b3ZhxaUgbGF5b3V0CnBhcihtZnJvdyA9IGMoMSwgMSkpCmBgYAoKIyMgUmVzaWR1YWxzIHZzLiBmaXR0ZWQKIyMjIEludGVycHJldMOhY2lhIG3DtGpobyBrb25rcsOpdG5laG8gZ3JhZnUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCflI0gUG9kcm9ibsOhIGludGVycHJldMOhY2lhIGdyYWZ1IDxlbT5SZXNpZHVhbHMgdnMgRml0dGVkPC9lbT48L2g0PgogIDx1bD4KICAgIDxsaT48c3Ryb25nPkNlbnRyb3ZhbmllIG9rb2xvIG51bHk6PC9zdHJvbmc+IFJlemlkdcOhIGtvbMOtxaF1IHByaWJsacW+bmUgb2tvbG8gMCDigJMgdG8gamUgZG9icsOpIHpuYW1lbmllLCBtb2RlbCBuZW3DoSB2w71yYXpuw6kgc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllIHYgcHJlZGlrY2nDoWNoLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5UdmFyIGhsYWRrZWogxI1pYXJ5Ojwvc3Ryb25nPiBNaWVybmUgemFrcml2ZW5pZSDEjWVydmVuZWogxI1pYXJ5IG5hem5hxI11amUgbW/Fvm7DuiBtaWVybnUgbmVsaW5lYXJpdHUg4oCTIG1vZGVsdSBtw7TFvmUgY2jDvWJhxaUgbmVsaW5lw6FybnkgxI1sZW4uPC9saT4KICAgIDxsaT48c3Ryb25nPlJvenB0eWwgcmV6w61kdcOtOjwvc3Ryb25nPiBWZXJ0aWvDoWxueSByb3pwdHlsIHNhIGphdsOtIGFrbyBwcmlibGnFvm5lIGtvbsWhdGFudG7DvSwgxI1vIGplIGTDtGtheiBob21vc2tlZGFzdGljaXR5LjwvbGk+CiAgICA8bGk+PHN0cm9uZz5PZMS+YWhsw6kgaG9kbm90eTo8L3N0cm9uZz4gTmlla2/EvmtvIGJvZG92IGxlxb7DrSB2w71yYXpuZSBtaW1vIGhsYXZuw6lobyB6aGx1a3Ug4oCTIGlkZSBvIHBvdGVuY2nDoWxuZSB2cGx5dm7DqSBrcmFqaW55IChtb8W+bm8gSW5kaWEsIMSMw61uYS4uLikuPC9saT4KICA8L3VsPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gT2TEvmFobMOpIHBvem9yb3ZhbmlhIGplIG1vxb5uw6kgcHJlc2vDum1hxaUgcG9tb2NvdSA8Y29kZT5vdXRsaWVyVGVzdChtb2RlbCk8L2NvZGU+IHogYmFsw61rYSA8Y29kZT5jYXI8L2NvZGU+Lgo8L2Rpdj4KCiMjIFEtUSBwbG90CiMjIyDEjG8gdWthenVqZQo8ZGl2IGNsYXNzPSJpbnNpZ2h0Ij4KICA8aDQ+8J+TiCBR4oCTUSBncmFmIHJlesOtZHXDrTwvaDQ+CiAgVGVudG8gZ3JhZiBwb3Jvdm7DoXZhIDxzdHJvbmc+xaF0YW5kYXJkaXpvdmFuw6kgcmV6aWR1w6E8L3N0cm9uZz4gcyB0ZW9yZXRpY2vDvW0gbm9ybcOhbG55bSByb3pkZWxlbsOtbS4KICBBayBtb2RlbCBzcMS6xYhhIHByZWRwb2tsYWQgbm9ybWFsaXR5LCBib2R5IGJ5IG1hbGkgbGXFvmHFpSBwcmlibGnFvm5lIG5hIHByaWFta2UuCiAgPHVsPgogICAgPGxpPlYgbmHFoW9tIHByw61wYWRlIHNhIGJvZHkgdiBzdHJlZG5laiDEjWFzdGkgZHLFvmlhIHByaWFta3ksIG5vIHYgb2JvY2gga29uY29jaCBvZCBuZWogb2RjaMO9xL51asO6LjwvbGk+CiAgICA8bGk+VG8gbmF6bmHEjXVqZSwgxb5lIDxlbT5yZXppZHXDoSBuaWUgc8O6IGRva29uYWxlIG5vcm3DoWxuZSByb3pkZWxlbsOpPC9lbT4g4oCTIHByYXZkZXBvZG9ibmUga3bDtGxpIG9kxL5haGzDvW0ga3Jhamluw6FtIHMgZXh0csOpbW5lIHZ5c29rb3UgYWxlYm8gbsOtemtvdSBwb3B1bMOhY2lvdS48L2xpPgogICAgPGxpPk1pZXJuZSBwb3J1xaFlbmllIG5vcm1hbGl0eSB2xaFhayBuZXByZWRzdGF2dWplIHbDocW+bnkgcHJvYmzDqW0gcHJlIG9kaGFkeSBrb2VmaWNpZW50b3YsIGFsZSBtw7TFvmUgb3ZwbHl2bmnFpSDFoXRhdGlzdGlja8O6IHbDvXpuYW1ub3PFpSAocC1ob2Rub3R5KS48L2xpPgogIDwvdWw+CjwvZGl2PgoKPGRpdiBjbGFzcz0ibXV0ZWQiPgogIPCfkqEgPGVtPk9kcG9yw7rEjWFuaWU6PC9lbT4gQWsgYnkgc21lIGNoY2VsaSB6dsO9xaFpxaUgcHJlc25vc8WlIG1vZGVsdSwgbcO0xb5lbWUgc2vDunNpxaUgPHN0cm9uZz5sb2ctdHJhbnNmb3Jtw6FjaXU8L3N0cm9uZz4gesOhdmlzbGVqIHByZW1lbm5laiAobmFwci4gbG9nKFBvcHVsYXRpb24uMjAyNSkpLgo8L2Rpdj4KIyMjIEludGVycHJldMOhY2lhIG3DtGpobyBrb25rcsOpdG5laG8gZ3JhZnUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgUeKAk1EgZ3JhZnUgcmV6w61kdcOtPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5DZWxrb3bDvSB0dmFyOjwvc3Ryb25nPiBWw6TEjcWhaW5hIGJvZG92IGxlxb7DrSA8ZW0+YmzDrXprbyBwcmlhbWt5PC9lbT4sIMSNbyBuYXpuYcSNdWplLCDFvmUgcmV6aWR1w6Egc8O6IHByaWJsacW+bmUgbm9ybcOhbG5lIHJvemRlbGVuw6kuPC9saT4KICAgIDxsaT48c3Ryb25nPlRvIGplIGRvYnLDqTo8L3N0cm9uZz4gUHJlZHBva2xhZCBub3JtYWxpdHkgc2EgemTDoSBiecWlIHZvIHZlxL5rZWogbWllcmUgc3BsbmVuw70uPC9saT4KICAgIDxsaT48c3Ryb25nPktyYWpuw6kgaG9kbm90eSAoZXh0csOpbXkpOjwvc3Ryb25nPiBCb2R5IG5hIG9ib2NoIGtvbmNvY2ggKHbEvmF2byBkb2xlIGEgdnByYXZvIGhvcmUpIHNhIG1pZXJuZSBvZGNoecS+dWrDuiBvZCBwcmlhbWt5LiBUbyBuYXpuYcSNdWplIG1pZXJudSBuZW5vcm3DoWxub3PFpSB2IGtvbmNvY2gg4oCTIG5pZWtvxL5rbyBvZMS+YWhsw71jaCBob2Ruw7R0IGFsZWJvIMWlYcW+xaFpZSBrb25jZSAodHJvY2h1IMWhcGljYXRvc8WlKS48L2xpPgogICAgPGxpPjxzdHJvbmc+U3RyZWRuw6Egb2JsYXPFpTo8L3N0cm9uZz4gU3RyZWRuw6EgxI1hc8WlIGdyYWZ1ICjiiJIxIGHFviArMSBrdmFudGlseSkgc2EgdmXEvm1pIGRvYnJlIHpob2R1amUgcyBwcmlhbWtvdSwgxI1vIHpuYW1lbsOhLCDFvmUgdsOkxI3FoWluYSByZXrDrWR1w60gemFwYWTDoSBkbyBub3Jtw6FsbmVobyByb3pkZWxlbmlhLjwvbGk+CiAgPC91bD4KICA8cD7inIUgWsOhdmVyOiBQcmVkcG9rbGFkIG5vcm1hbGl0eSBqZSA8c3Ryb25nPnByaWJsacW+bmUgc3BsbmVuw708L3N0cm9uZz4sIGhvY2kgc2Egdnlza3l0dWrDuiBkcm9ibsOpIG9kY2jDvWxreSB2IGV4dHLDqW1vY2guIE1vZGVsIHRlZGEgbmVwb3J1xaF1amUgdMO6dG8gcG9kbWllbmt1IHbDvXJhem5lLjwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CiAg8J+SoSA8ZW0+UG96bsOhbWthOjwvZW0+IFByaSBtYWtyb2Vrb25vbWlja8O9Y2ggYSBwb3B1bGHEjW7DvWNoIGTDoXRhY2ggamUgbWllcm5hIG9kY2jDvWxrYSBvZCBub3JtYWxpdHkgYmXFvm7DoSBhIG5lb2hyb3p1amUgcGxhdG5vc8WlIHbDvXNsZWRrb3YuCjwvZGl2PgoKCiMjIFNjYWxlIGxvY2F0aW9uIHBsb3QKIyMjIMSMbyB0byB6bsOhem9yxYh1amUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgU2NhbGXigJNMb2NhdGlvbiBncmFmdTwvaDQ+CiAgVGVudG8gZ3JhZiB6b2JyYXp1amUsIMSNaSBtw6EgbW9kZWwgPHN0cm9uZz5rb27FoXRhbnRuw70gcm96cHR5bCByZXrDrWR1w608L3N0cm9uZz4gKHByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eSkuCiAgQWsgamUgdGVudG8gcHJlZHBva2xhZCBzcGxuZW7DvSwgYm9keSBieSBtYWxpIGJ5xaUgPGVtPnJvdm5vbWVybmUgcm96cHTDvWxlbsOpPC9lbT4gb2tvbG8gxI1lcnZlbmVqIHRyZW5kb3ZlaiDEjWlhcnkgYmV6IHpyZXRlxL5uw6lobyB0dmFydS4KICA8dWw+CiAgICA8bGk+ViBuYcWhb20gcHLDrXBhZGUgYm9keSBuZXZ5a2F6dWrDuiBqYXNuw70gdnpvciDigJMgcm96cHR5bCByZXrDrWR1w60gamUgcG9tZXJuZSByb3Zub21lcm7DvSBuYXByaWXEjSBob2Rub3RhbWkgZml0dGVkIHZhbHVlcy48L2xpPgogICAgPGxpPsSMZXJ2ZW7DoSBMT0VTUyDEjWlhcmEgamUgcmVsYXTDrXZuZSA8ZW0+dm9kb3Jvdm7DoTwvZW0+LCDEjW8gcG9kcG9ydWplIHByZWRwb2tsYWQgbyBwcmlibGnFvm5lIHJvdm5ha29tIHJvenB0eWxlIHJlesOtZHXDrS48L2xpPgogICAgPGxpPkxlbiBuaWVrb8S+a28gYm9kb3Ygc2Egb2RjaHnEvnVqZSB2aWFjIOKAkyBtw7TFvnUgcHJlZHN0YXZvdmHFpSBrcmFqaW55IHMgZXh0csOpbW5vdSBwb3B1bMOhY2lvdSBhbGVibyBtaWdyw6FjaW91LjwvbGk+CiAgPC91bD4KICA8cD7inIUgPHN0cm9uZz5aw6F2ZXI6PC9zdHJvbmc+IFByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eSBqZSB2byB2xaFlb2JlY25vc3RpIHNwbG5lbsO9LiBNb2RlbCB0ZWRhIG5lbcOhIHbDocW+bnkgcHJvYmzDqW0gcyBuZXJvdm5ha8O9bSByb3pwdHlsb20gY2jDvWIuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgc2Egb2JqYXZpbCBsaWV2aWtvdml0w70gdHZhciBib2RvdiAocm96cHR5bCBieSBzYSB6dnnFoW92YWwgcyBob2Rub3RvdSBmaXR0ZWQgdmFsdWVzKSwgbmF6bmHEjW92YWxvIGJ5IHRvIHByb2Jsw6ltIGhldGVyb3NrZWRhc3RpY2l0eSDigJMgdnRlZHkgbW/Fvm5vIHBvdcW+acWlIHJvYnVzdG7DqSBvZGhhZHkgKGZ1bmtjaWUgeiBiYWzDrWthIDxjb2RlPnNhbmR3aWNoPC9jb2RlPikuCjwvZGl2PgojIyMgSW50ZXJwcmV0w6FjaWEgbcO0amhvIGtvbmtyw6l0bmVobyBncmFmdQo8ZGl2IGNsYXNzPSJpbnNpZ2h0Ij4KICA8aDQ+8J+TiSBJbnRlcnByZXTDoWNpYSBTY2FsZeKAk0xvY2F0aW9uIGdyYWZ1PC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5Ib3Jpem9udMOhbG5lIHJvenB0w71sZW5pZTo8L3N0cm9uZz4gQm9keSBzw7ogcm92bm9tZXJuZSByb3ptaWVzdG5lbsOpIHBvIG9zaSBYIGJleiB2eXR2w6FyYW5pYSBsaWV2aWthIGFsZWJvIHbDvXJhem5laiBrcml2a3kuIFRvIG5hem5hxI11amUsIMW+ZSByb3pwdHlsIHJlesOtZHXDrSBqZSBwcmlibGnFvm5lIGtvbsWhdGFudG7DvSDigJMgdGVkYSByZXrDrWR1w6Egc8O6IDxlbT5ob21vc2tlZGFzdGlja8OpPC9lbT4uPC9saT4KICAgIDxsaT48c3Ryb25nPlRyZW5kb3bDoSDEjWlhcmE6PC9zdHJvbmc+IMSMZXJ2ZW7DoSBobGFka8OhIExPRVNTIMSNaWFyYSBqZSB0YWttZXIgdm9kb3Jvdm7DoSwgxI1vIHBvdHZyZHp1amUsIMW+ZSBzbyB6dnnFoXVqw7pjaW1pIHNhIHZ5cm92bmFuw71taSBob2Rub3RhbWkgbmVkb2Now6FkemEgayBzeXN0ZW1hdGlja2VqIHptZW5lIHJvenB0eWx1LjwvbGk+CiAgICA8bGk+PHN0cm9uZz5PZMS+YWhsw6kgYm9keTo8L3N0cm9uZz4gTmlla2/EvmtvIHBvem9yb3ZhbsOtIGplIG1pZXJuZSBuYWQgw7pyb3bFiG91IDEsNSwgbm8gxb5pYWRuZSB6IG5pY2ggbmVwcmVkc3RhdnVqZSBleHRyw6ltIOKAkyBuZXZ6bmlrYWrDuiB0ZWRhIHbDocW+bmUgYW5vbcOhbGllIHZvIHZhcmlhbmNpaS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbCBzcMS6xYhhIHByZWRwb2tsYWQgPGVtPmtvbsWhdGFudG7DqWhvIHJvenB0eWx1IHJlesOtZHXDrTwvZW0+LCDEjW8gcG9kcG9ydWplIHNwb8S+YWhsaXZvc8WlIHJlZ3Jlc27DvWNoIG9kaGFkb3YuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgYm9keSB2eXR2w6FyYWxpIGxpZXZpa292aXTDvSB0dmFyICh6dsOkxI3FoXVqw7pjaSBzYSByb3pwdHlsKSwgem5hbWVuYWxvIGJ5IHRvIHByb2Jsw6ltIGhldGVyb3NrZWRhc3RpY2l0eSDigJMgdiB0YWtvbSBwcsOtcGFkZSBieSBwb21vaG9sIHJvYnVzdG7DvSBvZGhhZCBhbGVibyB0cmFuc2Zvcm3DoWNpYSBkw6F0Lgo8L2Rpdj4KCiMjIHJlc2lkdWFscyB2cyBsZXZlcmFnZQojIyMgxIxvIHpuw6F6b3LFiHVqZSBncmFmCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OKIEludGVycHJldMOhY2lhIGdyYWZ1IFJlc2lkdWFscyB2cyBMZXZlcmFnZTwvaDQ+CiAgVGVudG8gZ3JhZiBwb23DoWhhIGlkZW50aWZpa292YcWlIDxzdHJvbmc+dnBseXZuw6kgcG96b3JvdmFuaWE8L3N0cm9uZz4sIGt0b3LDqSBtw7TFvnUgbWHFpSBuZXByaW1lcmFuw70gdnBseXYgbmEgdsO9c2xlZGt5IHJlZ3Jlc2llLgogIDx1bD4KICAgIDxsaT48c3Ryb25nPlbDpMSNxaFpbmEgYm9kb3Y8L3N0cm9uZz4gc2EgbmFjaMOhZHphIHYgYmzDrXprb3N0aSBzdHJlZHUgZ3JhZnUsIMSNbyB6bmFtZW7DoSwgxb5lIMW+aWFkbmUgcG96b3JvdmFuaWEgdsO9cmF6bmUgbmVvdnBseXbFiHVqw7ogbW9kZWwuPC9saT4KICAgIDxsaT48c3Ryb25nPsSMZXJ2ZW7DoSBMT0VTUyDEjWlhcmE8L3N0cm9uZz4gamUgcmVsYXTDrXZuZSB2b2Rvcm92bsOhIOKAkyBuZW5hem5hxI11amUgc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllIG1vZGVsdS48L2xpPgogICAgPGxpPjxzdHJvbmc+Q29va292ZSB2emRpYWxlbm9zdGk8L3N0cm9uZz4gKGJvZGtvdmFuw6kga3Jpdmt5KSB1a2F6dWrDuiwgxb5lIMW+aWFkbnkgYm9kIG5lcHJlc2FodWplIGhyYW5pY3UgMC41IGFuaSAxIOKAkyB0ZWRhIHYgbW9kZWxpIHNhIG5lbmFjaMOhZHphasO6IGV4dHLDqW1uZSB2cGx5dm7DqSBwb3pvcm92YW5pYS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbCBqZSBzdGFiaWxuw70gYSBuZW9ic2FodWplIHBvem9yb3ZhbmlhLCBrdG9yw6kgYnkgbWFsaSB2w71yYXpuw70gdnBseXYgbmEgcmVncmVzbsO6IHByaWFta3UuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgc2Egbmlla3RvcsOpIGJvZHkgbmFjaMOhZHphbGkgbWltbyBib2Rrb3ZhbsO9Y2gga3JpdmllayAoQ29va292YSB2emRpYWxlbm9zxaUgJmd0OyAxKSwgYm9sbyBieSB2aG9kbsOpIGljaCBwcmVza8O6bWHFpSBwb21vY291IDxjb2RlPmluZmx1ZW5jZS5tZWFzdXJlcyhtb2RlbCk8L2NvZGU+IGFsZWJvIDxjb2RlPm91dGxpZXJUZXN0KCk8L2NvZGU+IHogYmFsw61rYSA8Y29kZT5jYXI8L2NvZGU+Lgo8L2Rpdj4KIyMjIEludGVycHJldMOhY2lhIG3DtGpobyBrb25rcsOpdG5laG8gZ3JhZnUKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfjq8gSW50ZXJwcmV0w6FjaWEgZ3JhZnUgUmVzaWR1YWxzIHZzIExldmVyYWdlPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5Sb3psb8W+ZW5pZSB2cGx5dnU6PC9zdHJvbmc+IFbDpMSNxaFpbmEgcG96b3JvdmFuw60gbcOhIG7DrXpreSB2cGx5diAoQ29va292YSB2emRpYWxlbm9zxaUgJmx0OyAwLjA1KSwgxI1vIGplIHR5cGlja8OpIHByZSBkb2JyZSB2eXbDocW+ZW7DqSBkw6F0YS48L2xpPgogICAgPGxpPjxzdHJvbmc+VsO9bmltb8SNbsOpIGJvZHk6PC9zdHJvbmc+IEplZGVuIGFsZWJvIGR2YSBib2R5IChva29sbyBob2Rub3R5IDAuMikgbWllcm5lIHZ5xI1uaWV2YWrDuiDigJMgaWRlIG8gcG96b3JvdmFuaWEgcyB2ecWhxaFvdSBww6Frb3UsIHRlZGEgaWNoIGhvZG5vdHkgc8O6IMSPYWxlaiBvZCBwcmllbWVydSBwcmVkaWt0b3Jvdi48L2xpPgogICAgPGxpPjxzdHJvbmc+VmXEvmtvc8WlIHJlesOtZHXDrTo8L3N0cm9uZz4gVsOkxI3FoWluYSDFoXRhbmRhcmRpem92YW7DvWNoIHJlesOtZHXDrSBsZcW+w60gbWVkemkgLTIgYSArMiwgxI1vIGplIGlkZcOhbG5lIOKAkyBuZW5hem5hxI11amUgcHLDrXRvbW5vc8WlIGV4dHLDqW1ueWNoIGNow71iLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5Db29rb3ZlIHZ6ZGlhbGVub3N0aTo8L3N0cm9uZz4gxb1pYWRueSBib2QgamFzbmUgbmVwcmVrcmHEjXVqZSB2b25rYWrFoWllIGzDrW5pZSAo4omIIDAuNSBhbGVibyAxLjApLCBwcmV0byBzYSBuZXpkw6EsIMW+ZSBieSBuaWVrdG9yw6kgcG96b3JvdmFuaWUgbmVwcmltZXJhbmUgb3ZwbHl2xYhvdmFsbyByZWdyZXNuw6kga29lZmljaWVudHkuPC9saT4KICA8L3VsPgogIDxwPuKchSA8c3Ryb25nPlrDoXZlcjo8L3N0cm9uZz4gTW9kZWwgbmVvYnNhaHVqZSB2w71yYXpuZSB2cGx5dm7DqSBwb3pvcm92YW5pYSDigJMgcmVncmVzbsOpIG9kaGFkeSBzw7ogdGVkYSBzdGFiaWxuw6kgYSBzcG/EvmFobGl2w6kuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gQWsgYnkgbmlla3RvcsOpIGJvZHkgcHJla3JvxI1pbGkgaG9kbm90dSBDb29rb3ZlaiB2emRpYWxlbm9zdGkgJmd0OyAxLCBib2xvIGJ5IHZob2Ruw6kgcHJlc2vDum1hxaUgaWNoIHBvbW9jb3UgPGNvZGU+aW5mbHVlbmNlLm1lYXN1cmVzKG1vZGVsKTwvY29kZT4gYWxlYm8gPGNvZGU+b3V0bGllclRlc3QobW9kZWwpPC9jb2RlPiAoYmFsw61rIDxjb2RlPmNhcjwvY29kZT4pLgo8L2Rpdj4KCmBgYHtyfQptb2RlbDIgPC0gbG0oUG9wdWxhdGlvbi4yMDI1IH4gSShsb2coRmVydC4uUmF0ZSkpICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLAogICAgICAgICAgICAgZGF0YSA9IGRhdGFfc2VsZWN0ZWQpCnN1bW1hcnkobW9kZWwyKQoKYGBgCgoKYGBge3IgdGVzdHMyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyBQb3RyZWJuw6kgYmFsw61reQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewogIGxpYnJhcnkodHNlcmllcykgICMgamFycXVlLmJlcmEudGVzdAogIGxpYnJhcnkoY2FyKSAgICAgICMgb3V0bGllclRlc3QKfSkKCiMgQWsgbW9kZWwyIGXFoXRlIG5pZSBqZSB2eXR2b3JlbsO9LCB1cm9iIGhvIHogZGF0YV9zZWxlY3RlZAppZiAoIWV4aXN0cygibW9kZWwyIikpIHsKICBzdG9wKCJtb2RlbDIgemF0aWHEviBuZWV4aXN0dWplLiBTcHVzxaUgbmFqcHJ2IGNodW5rLCBrZGUgc2Egdnl0dsOhcmEgbW9kZWwyLiIpCn0KCiMgMSkgTm9ybWFsaXRhIHJlesOtZHXDrSAoSmFycXVl4oCTQmVyYSkKcmVzMiAgICA8LSByZXNpZHVhbHMobW9kZWwyKQpqYl90ZXN0IDwtIGphcnF1ZS5iZXJhLnRlc3QocmVzMikKamJfdGVzdAoKIyAyKSBPdXRsaWVyeSAoQm9uZmVycm9uaSBrb3JpZ292YW7DvSB0ZXN0KQpvdXRsaWVyX3Rlc3QgPC0gb3V0bGllclRlc3QobW9kZWwyKQpvdXRsaWVyX3Rlc3QKCmBgYAo8ZGl2IGNsYXNzPSJpbnNpZ2h0Ij4KICA8aDQ+8J+nqiBUZXN0eSBwcmVkcG9rbGFkb3Yg4oCTIGludGVycHJldMOhY2lhPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5KYXJxdWXigJNCZXJhOjwvc3Ryb25nPiBhayBqZSBwLWhvZG5vdGEgJmd0OyAwLjA1IOKGkiBub3JtYWxpdGEgcmV6w61kdcOtIHNhIG5lb2RtaWV0YTsgYWsg4omkIDAuMDUg4oaSIGRyb2Juw6kgcG9ydcWhZW5pZSBub3JtYWxpdHkgKGJlxb5uw6kgcHJpIGRlbW9ncmFmaWkpLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5PdXRsaWVyIFRlc3Q6PC9zdHJvbmc+IGFrIHNhIHVrw6HFvnUgcmlhZGt5IHMgbWFsb3UgQm9uZmVycm9uaSBwLWhvZG5vdG91ICgmbHQ7IDAuMDUpLCBpZGUgbyB2w716bmFtbsOpIG9kxL5haGzDqSBwb3pvcm92YW5pYSDigJMgb2Rwb3LDusSNYSBzYSBpY2ggc2tvbnRyb2xvdmHFpS48L2xpPgogIDwvdWw+CjwvZGl2PgoKYGBge3J9Cm1vZGVsMiA8LSBsbShQb3B1bGF0aW9uLjIwMjUgfiAxICsgSShsb2coRmVydC4uUmF0ZSkpICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLCBkYXRhID0gZGF0YV9zZWxlY3RlZCkKc3VtbWFyeShtb2RlbDIpCgpgYGAKPGRpdiBjbGFzcz0iaW5zaWdodCIgc3R5bGU9ImJvcmRlci1sZWZ0OjZweCBzb2xpZCAjMGVhNWU5Ij4KICA8aDQ+8J+TiiBJbnRlcnByZXTDoWNpYSB1cHJhdmVuw6lobyBtb2RlbHU8L2g0PgogIDx1bD4KICAgIDxsaT48c3Ryb25nPk1pZ3JhbnRzLi5uZXQ8L3N0cm9uZz4gbcOhIDxzdHJvbmc+dsO9em5hbW7DvSBwb3ppdMOtdm55PC9zdHJvbmc+IHZwbHl2IG5hIHBvxI1ldCBvYnl2YXRlxL5vdiB2IHJva3UgMjAyNSDigJMga3JhamlueSBzIGtsYWRub3UgxI1pc3RvdSBtaWdyw6FjaW91IG1hasO6IHZ5xaHFocOtIHBvxI1ldCBvYnl2YXRlxL5vdi48L2xpPgogICAgPGxpPjxzdHJvbmc+bG9nKEZlcnQuLlJhdGUpPC9zdHJvbmc+IGEgPHN0cm9uZz5NZWRpYW4uQWdlPC9zdHJvbmc+IHZ5xaFsaSA8ZW0+xaF0YXRpc3RpY2t5IG5ldsO9em5hbW5lPC9lbT4gKHrDoXBvcm7DqSB6bmFtaWVua2Egc8O6IGxvZ2lja8OpOiB2ecWhxaHDrSB2ZWsgPSBwb21hbMWhw60gcmFzdCwgdnnFocWhaWEgcMO0cm9kbm9zxaUgc2FtYSBvIHNlYmUgYmV6IMSPYWzFocOtY2ggZmFrdG9yb3YgbmVtdXPDrSBtZWR6aSBrcmFqaW5hbWkgdnlzdmV0bGnFpSByb3pkaWVseSB2IMO6cm92bmkgcG9wdWzDoWNpZSkuPC9saT4KICAgIDxsaT5Lb27FoXRhbnRhIG5pZSBqZSB2w716bmFtbsOhIOKAkyBtb2RlbCBzYSBvcGllcmEgbmFqbcOkIG8gbWlncmHEjW7DuiB6bG/Fvmt1LjwvbGk+CiAgPC91bD4KICA8cD7wn5KhIDxzdHJvbmc+xIxvIHogdG9obyBwbHluaWU6PC9zdHJvbmc+IFByZSB2eXN2ZXRsZW5pZSByb3pkaWVsb3YgdiDDunJvdm5pIHBvcHVsw6FjaWUgbWVkemkga3JhamluYW1pIGplIGvEvsO6xI1vdsOhIG1pZ3LDoWNpYS4gUMO0cm9kbm9zxaUgYSB2ZWsgYnkgZMOhdmFsaSB2w6TEjcWhw60gem15c2VsIHYgPGVtPnRlbXBvPC9lbT4gbW9kZWxvY2ggKHJhc3R5KSwgcHLDrXBhZG5lIHBvIGRvcGxuZW7DrSDEj2FsxaHDrWNoIGtvbnRyb2wgKG5hcHIuIHVyYmFuaXrDoWNpYSwgaHVzdG90YSwgSERQKS48L3A+CjwvZGl2PgoKYGBge3J9CiMgTm92w70gbW9kZWwgcG8gbG9nLXRyYW5zZm9ybcOhY2lpIEZlcnRpbGl0eSBSYXRlCm1vZGVsMiA8LSBsbShQb3B1bGF0aW9uLjIwMjUgfiAxICsgSShsb2coRmVydC4uUmF0ZSkpICsgTWVkaWFuLkFnZSArIE1pZ3JhbnRzLi5uZXQuLCAKICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3NlbGVjdGVkKQoKIyBWw71waXMgdsO9c2xlZGtvdgpzdW1tYXJ5KG1vZGVsMikKCiMgTmFzdGF2acWlIHJvemxvxb5lbmllIDIgeCAyCgpwYXIobWZyb3cgPSBjKDIsIDIpKQoKIyBWeWtyZXNsacWlIHbFoWV0a3kgNCBkaWFnbm9zdGlja8OpIGdyYWZ5IG1vZGVsdQoKcGxvdChtb2RlbDIpCgojIFJlc2V0b3ZhxaUgbGF5b3V0CgpwYXIobWZyb3cgPSBjKDEsIDEpKQoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn6epIERpYWdub3N0aWthIHVwcmF2ZW7DqWhvIG1vZGVsdTwvaDQ+CiAgPHVsPgogICAgPGxpPjxzdHJvbmc+UmVzaWR1YWxzIHZzIEZpdHRlZDo8L3N0cm9uZz4gUmV6aWR1w6Egc8O6IHPDunN0cmVkZW7DqSBva29sbyBudWxvdmVqIG9zaSwgYmV6IHbDvXJhem7DqWhvIHpha3JpdmVuaWEgdHJlbmR1LiAgCiAgICAgIDxlbT7ihpIgbGluZcOhcm55IHR2YXIgdnrFpWFodSBqZSB2IHBvcmlhZGt1LCBtb2RlbCBuZXVrYXp1amUgc3lzdGVtYXRpY2vDqSBza3Jlc2xlbmllLjwvZW0+PC9saT4KCiAgICA8bGk+PHN0cm9uZz5R4oCTUSBSZXNpZHVhbHM6PC9zdHJvbmc+IFbDpMSNxaFpbmEgYm9kb3YgbGXFvsOtIHByaSBwcmlhbWtlLCBvZGNow71sa3kgc2Egb2JqYXZ1asO6IGxlbiB2IGtvbmNvY2guICAKICAgICAgPGVtPuKGkiBub3JtYWxpdGEgcmV6w61kdcOtIGplIDxzdHJvbmc+cHJpYmxpxb5uZSBzcGxuZW7DoTwvc3Ryb25nPjsgdHJhbnNmb3Jtw6FjaWEgcHJlbWVubsO9Y2ggcG9tb2hsYS48L2VtPjwvbGk+CgogICAgPGxpPjxzdHJvbmc+U2NhbGXigJNMb2NhdGlvbjo8L3N0cm9uZz4gUm96cHR5bCDFoXRhbmRhcmRpem92YW7DvWNoIHJlesOtZHXDrSBqZSByZWxhdMOtdm5lIHJvdm5vbWVybsO9LCBMT0VTUyDEjWlhcmEgamUgdGFrbWVyIHZvZG9yb3Zuw6EuICAKICAgICAgPGVtPuKGkiBwcmVkcG9rbGFkIDxzdHJvbmc+a29uxaF0YW50bsOpaG8gcm96cHR5bHU8L3N0cm9uZz4gKGhvbW9za2VkYXN0aWNpdGEpIGplIGFrY2VwdG92YXRlxL5uw70uPC9lbT48L2xpPgoKICAgIDxsaT48c3Ryb25nPlJlc2lkdWFscyB2cyBMZXZlcmFnZTo8L3N0cm9uZz4gVsOkxI3FoWluYSBib2RvdiBtw6EgbsOtemt5IHDDoWtvdsO9IGVmZWt0OyB6b3DDoXIgcG96b3JvdmFuw60gKG5hcHIuIG9rb2xpZSBpbmRleHUgNDApIGplIHbDvXJhem5lasWhw61jaCwgbm8gdsOkxI3FoWlub3UgcG9kIGhyYW5pY2FtaSBDb29rb3ZlaiB2emRpYWxlbm9zdGkuICAKICAgICAgPGVtPuKGkiBuZXZpZMOtbSBleHRyw6ltbmUgdnBseXZuw6kgcG96b3JvdmFuaWEsIG1vZGVsIGplIHN0YWJpbG7DvS48L2VtPjwvbGk+CiAgPC91bD4KCiAgPHA+4pyFIDxzdHJvbmc+WmhybnV0aWU6PC9zdHJvbmc+IERpYWdub3N0aWthIHBvIMO6cHJhdmUgbW9kZWx1IChsb2coRmVydC4uUmF0ZSkpIHZ5emVyw6EgZG9icmU6IGxpbmVhcml0YSwgbm9ybWFsaXRhIGFqIGhvbW9nZW5pdGEgcm96cHR5bHUgc8O6IG5hIHByYWt0aWNreSBwb3XFvml0ZcS+bmVqIMO6cm92bmkuIAogIE1pZ3JhxI1uw6EgcHJlbWVubsOhIG9zdMOhdmEgaGxhdm7DvW0gxaF0YXRpc3RpY2t5IHbDvXpuYW1uw71tIGZha3Rvcm9tIHZlxL5rb3N0aSBwb3B1bMOhY2llLjwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CgpgYGB7ciByZXN1bHRzPSdtYXJrdXAnLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFRlc3R5IHByZWRwb2tsYWRvdiBwcmUgbW9kZWwyCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMgTmHEjcOtdGFqIHBvdHJlYm7DqSBiYWzDrWt5CnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyh7CiAgbGlicmFyeSh0c2VyaWVzKSAgIyBwcmUgSmFycXVl4oCTQmVyYSB0ZXN0CiAgbGlicmFyeShjYXIpICAgICAgIyBwcmUgT3V0bGllciBUZXN0Cn0pCgojIFNrb250cm9sdWosIMSNaSBleGlzdHVqZSBtb2RlbDIKaWYgKCFleGlzdHMoIm1vZGVsMiIpKSB7CiAgbW9kZWwyIDwtIGxtKFBvcHVsYXRpb24uMjAyNSB+IEkobG9nKEZlcnQuLlJhdGUpKSArIE1lZGlhbi5BZ2UgKyBNaWdyYW50cy4ubmV0LAogICAgICAgICAgICAgICBkYXRhID0gZGF0YV9zZWxlY3RlZCkKfQoKIyAx77iP4oOjIEphcnF1ZeKAk0JlcmEgdGVzdCBub3JtYWxpdHkgcmV6w61kdcOtCnJlc2lkdWFsczIgPC0gcmVzaWR1YWxzKG1vZGVsMikKamJfdGVzdCA8LSBqYXJxdWUuYmVyYS50ZXN0KHJlc2lkdWFsczIpCmpiX3Rlc3QKCiMgMu+4j+KDoyBPdXRsaWVyIHRlc3QgKEJvbmZlcnJvbmkga29yZWtjaWEpCm91dGxpZXJfdGVzdCA8LSBvdXRsaWVyVGVzdChtb2RlbDIpCm91dGxpZXJfdGVzdAoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OKIEludGVycHJldMOhY2lhIGRvcGxua292w71jaCB0ZXN0b3YgbW9kZWx1PC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5UZXN0IG5vcm1hbGl0eSAoSmFycXVl4oCTQmVyYSk6PC9zdHJvbmc+IEhvZG5vdGEgcC12YWx1ZSBqZSB2ZcS+bWkgbsOtemthIOKGkiAKICAgICAgPGVtPnphbWlldGFtZSBoeXBvdMOpenUgbyBkb2tvbmFsZSBub3Jtw6FsbnljaCByZXppZHXDoWNoLjwvZW0+IAogICAgICBBdsWhYWsgdnpoxL5hZG9tIG5hIHZlxL5rb3PFpSB2em9ya3kgYSBjaGFyYWt0ZXIgZGVtb2dyYWZpY2vDvWNoIGTDoXQgc8O6IGRyb2Juw6kgb2RjaMO9bGt5IGFrY2VwdG92YXRlxL5uw6kuPC9saT4KCiAgICA8bGk+PHN0cm9uZz5PdXRsaWVyIFRlc3Q6PC9zdHJvbmc+IFRlc3QgaWRlbnRpZmlrb3ZhbCBuaWVrb8S+a28gcG96b3JvdmFuw60gKG5hcHIuIGluZGV4IDEsIDIsIDQwKSBzIHZ5c29rw71tIHQtxaF0dWRlbnRvdsO9bSB6LXNjb3JlLiAgCiAgICAgIDxlbT7ihpIgdGlldG8ga3Jham7DqSBob2Rub3R5IGJ5IG1vaGxpIG1pZXJuZSBvdnBseXZuacWlIHJlZ3Jlc27DqSBrb2VmaWNpZW50eSw8L2VtPiBubyB2emjEvmFkb20gbmEgaWNoIG7DrXpreSBww6Frb3bDvSBlZmVrdAogICAgICA8c3Ryb25nPm1vZGVsIG9zdMOhdmEgc3RhYmlsbsO9Ljwvc3Ryb25nPjwvbGk+CiAgPC91bD4KCiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBVcHJhdmVuw70gbW9kZWwgc3DEusWIYSDFoXRhdGlzdGlja8OpIHByZWRwb2tsYWR5IHYgdXNwb2tvaml2ZWogbWllcmUuIAogIE5vcm1hbGl0YSByZXrDrWR1w60gbmllIGplIGRva29uYWzDoSwgbm8gbGluZcOhcm5hIMWhdHJ1a3TDunJhIGFqIHN0YWJpbGl0YSBtb2RlbHUgc8O6IHphY2hvdmFuw6kuPC9wPgo8L2Rpdj4KCjxkaXYgY2xhc3M9Im11dGVkIj4KICDwn5KhIDxlbT5Qb3puw6Fta2E6PC9lbT4gViBtYWtyb2Vrb25vbWlja8O9Y2ggYSBkZW1vZ3JhZmlja8O9Y2ggw7pkYWpvY2ggamUgbWllcm5hIG9kY2jDvWxrYSBvZCBub3JtYWxpdHkgYmXFvm7DoS4gCiAgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn4+BIFrDoXZlciAoQ29uY2x1c2lvbik8L2g0PgogIDxwPgogICAgViB1cHJhdmVub20gbW9kZWxpIHNtZSBzbGVkb3ZhbGkgdnBseXYgPHN0cm9uZz5taWVyeSBww7Ryb2Rub3N0aSAoRmVydC4gUmF0ZSk8L3N0cm9uZz4sIAogICAgPHN0cm9uZz5tZWRpw6Fub3bDqWhvIHZla3UgKE1lZGlhbiBBZ2UpPC9zdHJvbmc+IGEgPHN0cm9uZz7EjWlzdGVqIG1pZ3LDoWNpZSAoTWlncmFudHMgbmV0KTwvc3Ryb25nPiAKICAgIG5hIDxzdHJvbmc+dmXEvmtvc8WlIHBvcHVsw6FjaWUgdiByb2t1IDIwMjU8L3N0cm9uZz4uCiAgPC9wPgoKICA8dWw+CiAgICA8bGk+PHN0cm9uZz5NaWdyw6FjaWE8L3N0cm9uZz4gbcOhIG5hxI9hbGVqIDxlbT7FoXRhdGlzdGlja3kgdsO9em5hbW7DvSBhIHBveml0w612bnkgdnBseXY8L2VtPiDigJQga3JhamlueSBzIHZ5xaHFoW91IMSNaXN0b3UgbWlncsOhY2lvdSAKICAgICAgICBtYWrDuiB0ZW5kZW5jaXUgcsOhc8WlIHLDvWNobGVqxaFpZS48L2xpPgoKICAgIDxsaT48c3Ryb25nPlDDtHJvZG5vc8WlPC9zdHJvbmc+IHBvIGxvZy10cmFuc2Zvcm3DoWNpaSBzw61jZSBzdHLDoWNhIMWhdGF0aXN0aWNrw7ogdsO9em5hbW5vc8WlLCAKICAgICAgICBubyB6YWNob3bDoXZhIG/EjWFrw6F2YW7DqSB6bmFtaWVua28gKDxlbT52ecWhxaFpYSBww7Ryb2Rub3PFpSDihpIgdsOkxI3FoWlhIHBvcHVsw6FjaWE8L2VtPikuPC9saT4KCiAgICA8bGk+PHN0cm9uZz5NZWRpw6Fub3bDvSB2ZWs8L3N0cm9uZz4gbcOhIG5lZ2F0w612bnkgdnBseXYsIGFrbyBzYSBvxI1ha8OhdmEg4oCUIHN0YXLFoWlhIHBvcHVsw6FjaWEgem5hbWVuw6EgcG9tYWzFocOtIHJhc3QuPC9saT4KICA8L3VsPgoKICA8cD7wn5OKIDxzdHJvbmc+RGlhZ25vc3RpY2vDqSBncmFmeTwvc3Ryb25nPiBhaiA8c3Ryb25nPsWhdGF0aXN0aWNrw6kgdGVzdHk8L3N0cm9uZz4gdWvDoXphbGksIMW+ZSBtb2RlbCBzcMS6xYhhIHbDpMSNxaFpbnUgCiAgcHJlZHBva2xhZG92IGxpbmXDoXJuZWogcmVncmVzaWU6IHJlemlkdcOhIHPDuiBwcmlibGnFvm5lIG5vcm3DoWxuZSByb3pkZWxlbsOpLCByb3pwdHlsIGplIHN0YWJpbG7DvSAKICBhIMW+aWFkbmUgcG96b3JvdmFuaWEgbmVtYWrDuiBuYWRtZXJuw70gdnBseXYgbmEgdsO9c2xlZGt5LjwvcD4KCiAgPHA+4pyFIDxzdHJvbmc+Q2Vsa292w6kgaG9kbm90ZW5pZTo8L3N0cm9uZz4gTW9kZWwgdnlzdmV0xL51amUgdmFyaWFiaWxpdHUgcG9wdWzDoWNpZSBtZWR6aSBrcmFqaW5hbWkgdiB1c3Bva29qaXZlaiBtaWVyZS4KICBUcmFuc2Zvcm3DoWNpYSBsb2coRmVydC4gUmF0ZSkgcHJpc3BlbGEgayBsZXDFoWVqIG5vcm1hbGl0ZSByZXrDrWR1w60gYSBzdGFiaWxpdGUgb2RoYWRvdi48L3A+CjwvZGl2PgoKPGRpdiBjbGFzcz0ibXV0ZWQiPgoKIyMgSGV0ZXJvc2tlZGFzdGljaXRhCgpQcsOtdG9tbm9zxaUgaGV0ZXJvc2tlZGFzdGljaXR5IChuZWtvbsWhdGFudG7DqWhvIHJvenB0eWx1IG7DoWhvZG5laiB6bG/Fvmt5KSBzcMO0c29idWplIHpsw6kgdnlob2Rub2NvdmFuaWUgdC10ZXN0b3YgdsO9em5hbW5vc3RpIGplZG5vdGxpdsO9Y2ggcmVncmVzbsO9Y2gga29lZmljaWVudG92LiBQcmV0byBqZSBudXRuw6ksIGFieSBzbWUgaGV0ZXJvc2tlZGFzdGljaXR1IAotIGRldGVrb3ZhbGkgKHZpenXDoWxuZSBhIHMgcG9tb2NvdSB0ZXN0b3YpCi0gYSB2IHByw61wYWRlIHByw610b21ub3N0aSBoZXRlcm9za2VkYXN0aWNpdHkgYWJ5IHNtZSBqdSBvZHN0csOhbmlsaS4KCkFqIHYgbmHFoW9tIHByw61wYWRlIGJ5IHNtZSBzYSBtb2hsaSBwb2vDunNpxaUgbyB2aXp1w6FsbmUgdnlob2Rub3RlbmllIG5hc2xlZG92bsO9Y2ggZ3JhZm92IChhaiBrZcSPIGplZGVuIGdyYWYgc21lIHXFviBza8O6bWFsaSAtIGJvbCB0byB0enYuIFNjYWxlLUxvY2F0aW9uIGdyYWZ5IHV2ZWRlbsOpIHZ5xaHFoWllKS4KClRlbnRva3LDoXQgc2EgcG9rw7pzaW1lIG8gdml6dcOhbG5lIHpuw6F6b3JuZW5pZSB6w6F2aXNsb3N0aSDFoXR2b3Jjb3YgcmV6w61kdcOtIGEgdnlzdmV0xL51asO6Y2VqIHByZW1lbm5laiwgdSBrdG9yZWogbcOhbWUgcG9kb3pyZW5pZSwgxb5lIG3DtMW+ZSBoZXRlcm9za2VkYXN0aWNpdHUgc3DDtHNvYm92YcWlLiBCdWRlbWUgcG9zdWR6b3ZhxaUgZHZhIG1vZGVseSAtIGEgdG8gbW9kZWwgbmF6dmFuw70gKm1vZGVsKiBhbGVibyBtb2RlbCBuYXp2YW7DvSAqbW9kZWwyKi4gKm1vZGVsMiogbcOhIHpsb2dhcml0bWl6b3ZhbsO6IHByZW1lbm7DuiAqR0RQKiwgxI1vIHNtZSByb2JpbGkgeiBkw7R2b2R1IG9kc3Ryw6FuZW5pYSB2cGx5dnUgb2TEvmFobMO9Y2ggcHJlbWVubsO9Y2ggdiBwcmVkY2jDoWR6YWrDumNpY2gga3Jva29jaCwgKm1vZGVsKiBqZSBww7R2b2Ruw71tIG1vZGVsb20uCgoKYGBge3IgaGV0ZXJvcGxvdHMyYiwgZmlnLmNhcD0iU2vDum1hbmllIGhldGVyb3NrZWRhc3RpY2l0eSB2IG1vZGVsaSBwb3B1bMOhY2llIDIwMjUiLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NH0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBhdGNod29yaykKCgojIDHvuI/ig6MgR3JhZiDigJMgaGV0ZXJvc2tlZGFzdGljaXRhIHZvxI1pIEZlcnRpbGl0eSBSYXRlIChsb2ctdHJhbnNmb3Jtb3ZhbmVqKQpwMSA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBsb2coRmVydC4uUmF0ZSksIHkgPSByZXNpZHVhbHMobW9kZWwyKV4yKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIGNvbG9yID0gInN0ZWVsYmx1ZSIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiLCBsd2QgPSAxKSArCiAgbGFicygKICAgIHggPSAiTG9nKEZlcnRpbGl0eSBSYXRlKSIsCiAgICB5ID0gIlJlemlkdcOhbG5lIGNoeWJ5IiwKICAgIHRpdGxlID0gIlJlemlkdcOhbG5lIGNoeWJ5IHZzLiBGZXJ0aWxpdHkgUmF0ZSAobG9nKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgMu+4j+KDoyBHcmFmIOKAkyBoZXRlcm9za2VkYXN0aWNpdGEgdm/EjWkgTWVkaWFuIEFnZQpwMiA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBNZWRpYW4uQWdlLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbHdkID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIk1lZGlhbiBBZ2UiLAogICAgeSA9ICJSZXppZHXDoWxuZSBjaHlieSIsCiAgICB0aXRsZSA9ICJSZXppZHXDoWxuZSBjaHlieSB2cy4gTWVkaWFuIEFnZSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgM++4j+KDoyBHcmFmIOKAkyBoZXRlcm9za2VkYXN0aWNpdGEgdm/EjWkgTWlncmFudHMgbmV0CnAzIDwtIGdncGxvdChkYXRhX3NlbGVjdGVkLCBhZXMoeCA9IE1pZ3JhbnRzLi5uZXQuLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbHdkID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIk1pZ3JhbnRzIG5ldCIsCiAgICB5ID0gIlJlemlkdcOhbG5lIGNoeWJ5IiwKICAgIHRpdGxlID0gIlJlemlkdcOhbG5lIGNoeWJ5IHZzLiBNaWdyYW50cyBuZXQiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCgojIEtvbWJpbsOhY2lhIGdyYWZvdiB2ZWTEvmEgc2ViYQoocDEgfCBwMiB8IHAzKQoKYGBgCjxkaXYgY2xhc3M9Imluc2lnaHQiPgogIDxoND7wn5OJIEludGVycHJldMOhY2lhIGhldGVyb3NrZWRhc3RpY2l0eTwvaDQ+CiAgPHVsPgogICAgPGxpPjxzdHJvbmc+RmVydGlsaXR5IFJhdGUgKGxvZyk6PC9zdHJvbmc+IFbDpMSNxaFpbmEgYm9kb3Ygc2EgbmFjaMOhZHphIGJsw616a28gb3NpIFgsIGJleiB2eXR2w6FyYW5pYSB0dmFydSBsaWV2aWthLiDEjGVydmVuw6EgTE9FU1Mga3JpdmthIGplIHRha21lciB2b2Rvcm92bsOhIOKAkyByb3pwdHlsIHJlesOtZHXDrSBqZSBwcmlibGnFvm5lIGtvbsWhdGFudG7DvS48L2xpPgogICAgPGxpPjxzdHJvbmc+TWVkaWFuIEFnZTo8L3N0cm9uZz4gUmV6w61kdcOhIHPDuiByb3Zub21lcm5lIHJvemxvxb5lbsOpLCBiZXogemphdm5laiBzeXN0ZW1hdGlja2VqIHptZW55IHZhcmlhYmlsaXR5LiBPcMOkxaUgc2EgbmVwcmVqYXZ1amUgaGV0ZXJvc2tlZGFzdGljaXRhLjwvbGk+CiAgICA8bGk+PHN0cm9uZz5NaWdyYW50cyBuZXQ6PC9zdHJvbmc+IFNsYWLDvSBuw6FyYXN0IG5hIGtvbmNpIG9zaSBYIG5hem5hxI11amUgbWllcm51IHRlbmRlbmNpdSByYXN0dSByb3pwdHlsdSBwcmkgZXh0csOpbW55Y2ggaG9kbm90w6FjaCwgYWxlIGVmZWt0IGplIHZlxL5taSBtYWzDvSBhIG5lcHJlZHN0YXZ1amUgdsOhxb5ueSBwcm9ibMOpbS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbCBuZXNwxLrFiGEgem7DoW1reSB2w71yYXpuZWogaGV0ZXJvc2tlZGFzdGljaXR5LiBSb3pwdHlsIG7DoWhvZG7DvWNoIGNow71iIGplIHByaWJsacW+bmUga29uxaF0YW50bsO9LCBwcmV0byBwcmVkcG9rbGFkIGhvbW9za2VkYXN0aWNpdHkgamUgc3BsbmVuw70uPC9wPgo8L2Rpdj4KCgoKYSB0ZXJheiBtb2RlbCBzbyB6bG9nYXJpdG1pem92YW5vdSBwcmVtZW5ub3UgKkdEUCouCmBgYHtyIGhldGVyb19wb3AyMDI1LCBmaWcuY2FwPSJWYXJpYWJpbGl0YSBjaMO9YiBwb2TEvmEgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCIsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD00LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQoKIyAxKSBsb2coRmVydGlsaXR5IFJhdGUpCnAxIDwtIGdncGxvdChkYXRhX3NlbGVjdGVkLCBhZXMoeCA9IGxvZyhGZXJ0Li5SYXRlKSwgeSA9IHJlc2lkdWFscyhtb2RlbDIpXjIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNiwgY29sb3IgPSAic3RlZWxibHVlIikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIsIGxpbmV3aWR0aCA9IDEpICsKICBsYWJzKAogICAgeCA9ICJsb2coUMO0cm9kbm9zxaUpIOKAkyBsb2coRmVydC4gUmF0ZSkiLAogICAgeSA9ICJWYXJpYWJpbGl0YSBjaMO9YiAoxaF0dm9yY2UgcmV6w61kdcOtKSIsCiAgICB0aXRsZSA9ICJWYXJpYWJpbGl0YSBjaMO9YiB2cy4gbG9nKEZlcnRpbGl0eSBSYXRlKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgMikgTWVkaWFuIEFnZQpwMiA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBNZWRpYW4uQWdlLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbGluZXdpZHRoID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIk1lZGnDoW5vdsO9IHZlayAoTWVkaWFuIEFnZSkiLAogICAgeSA9ICJWYXJpYWJpbGl0YSBjaMO9YiAoxaF0dm9yY2UgcmV6w61kdcOtKSIsCiAgICB0aXRsZSA9ICJWYXJpYWJpbGl0YSBjaMO9YiB2cy4gTWVkaWFuIEFnZSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCiMgMykgTWlncmFudHMgbmV0ICAgKGFrIG3DocWhIHYgQ1NWIGluw70gbsOhem92LCBuYWhyYcSPIHYgYWVzKCkgc3DDpHRuw71taSBhcG9zdHJvZm1pKQpwMyA8LSBnZ3Bsb3QoZGF0YV9zZWxlY3RlZCwgYWVzKHggPSBgTWlncmFudHMuLm5ldC5gLCB5ID0gcmVzaWR1YWxzKG1vZGVsMileMikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBjb2xvciA9ICJzdGVlbGJsdWUiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbGluZXdpZHRoID0gMSkgKwogIGxhYnMoCiAgICB4ID0gIsSMaXN0w6EgbWlncsOhY2lhIChNaWdyYW50cyBuZXQpIiwKICAgIHkgPSAiVmFyaWFiaWxpdGEgY2jDvWIgKMWhdHZvcmNlIHJlesOtZHXDrSkiLAogICAgdGl0bGUgPSAiVmFyaWFiaWxpdGEgY2jDvWIgdnMuIE1pZ3JhbnRzIG5ldCIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCihwMSB8IHAyIHwgcDMpCgpgYGAKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4kgSW50ZXJwcmV0w6FjaWEgZ3JhZm92IHZhcmlhYmlsaXR5IGNow71iPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5sb2coRmVydGlsaXR5IFJhdGUpOjwvc3Ryb25nPiDEjWVydmVuw6EgTE9FU1Mga3JpdmthIGplIHRha21lciB2b2Rvcm92bsOhIOKAkyByb3pwdHlsIGNow71iIHNhIHbDvXJhem5lIG5lbWVuw60gcyBob2Rub3RvdSBwcmVtZW5uZWouPC9saT4KICAgIDxsaT48c3Ryb25nPk1lZGlhbiBBZ2U6PC9zdHJvbmc+IGJvZHkgc8O6IHJvenB0w71sZW7DqSByb3Zub21lcm5lLCBiZXog4oCebGlldmlrb3bDqWhv4oCcIHR2YXJ1IOKAkyBuZW5hem5hxI11amUgaGV0ZXJvc2tlZGFzdGljaXR1LjwvbGk+CiAgICA8bGk+PHN0cm9uZz5NaWdyYW50cyBuZXQ6PC9zdHJvbmc+IGplbW7DvSBuw6FyYXN0IG5hIHZ5c29rw71jaCBob2Rub3TDoWNoIGplIHNsYWLDvTsgY2Vsa292byByb3pwdHlsIHpvc3TDoXZhIHN0YWJpbG7DvS48L2xpPgogIDwvdWw+CiAgPHA+4pyFIDxzdHJvbmc+WsOhdmVyOjwvc3Ryb25nPiBNb2RlbDIgbmV2eWthenVqZSB2w71yYXpuw6kgem7DoW1reSBoZXRlcm9za2VkYXN0aWNpdHk7IHByZWRwb2tsYWQgcHJpYmxpxb5uZSBrb27FoXRhbnRuw6lobyByb3pwdHlsdSBqZSBzcGxuZW7DvS48L3A+CjwvZGl2PgoKCiMjIFRlc3RvdmFuaWUgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eQoKYGBge3J9CiMgSW5zdGFsbCAoaWYgbm90IHlldCBpbnN0YWxsZWQpCiMgaW5zdGFsbC5wYWNrYWdlcygibG10ZXN0IikKCiMgTG9hZCB0aGUgcGFja2FnZQpsaWJyYXJ5KGxtdGVzdCkKCiMgUnVuIHRoZSBCcmV1c2No4oCTUGFnYW4gdGVzdApicHRlc3QobW9kZWwpCgpgYGAKPGRpdiBjbGFzcz0iaW5zaWdodCI+CiAgPGg0PvCfk4ggSW50ZXJwcmV0w6FjaWEgQnJldXNjaOKAk1BhZ2FuIHRlc3R1IChoZXRlcm9za2VkYXN0aWNpdGEpPC9oND4KICA8dWw+CiAgICA8bGk+PHN0cm9uZz5IeXBvdMOpenk6PC9zdHJvbmc+IEg8c3ViPjA8L3N1Yj4g4oCTIHJvenB0eWwgcmV6w61kdcOtIGplIGtvbsWhdGFudG7DvSAoaG9tb3NrZWRhc3RpY2l0YSk7IEg8c3ViPjE8L3N1Yj4g4oCTIHJvenB0eWwgbmllIGplIGtvbsWhdGFudG7DvSAoaGV0ZXJvc2tlZGFzdGljaXRhKS48L2xpPgogICAgPGxpPjxzdHJvbmc+VsO9c2xlZG9rIHByZSBww7R2b2Ruw70gbW9kZWw6PC9zdHJvbmc+IHAtaG9kbm90YSBqZSA8c3Ryb25nPiZsdDsgMC4wNTwvc3Ryb25nPiAmcmFycjsgPGVtPnphbWlldGFtZTwvZW0+IEg8c3ViPjA8L3N1Yj4uIAogICAgICBNb2RlbCB2eWthenVqZSB6bsOhbWt5IDxzdHJvbmc+aGV0ZXJvc2tlZGFzdGljaXR5PC9zdHJvbmc+ICh2YXJpYWJpbGl0YSBjaMO9YiBzYSBtZW7DrSBzIGhvZG5vdGFtaSB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoKS48L2xpPgogICAgPGxpPjxzdHJvbmc+RMO0c2xlZG9rOjwvc3Ryb25nPiBrbGFzaWNrw6kgc21lcm9kYWpuw6kgY2h5YnkgbcO0xb51IGJ5xaUgc2tyZXNsZW7DqSAmcmFycjsgdC10ZXN0eSBhIHAtaG9kbm90eSBuZW11c2lhIGJ5xaUgc3BvxL5haGxpdsOpLjwvbGk+CiAgPC91bD4KICA8cD7inIUgPHN0cm9uZz5PZHBvcsO6xI1hbmllOjwvc3Ryb25nPiAoMSkgUG91xb5pxaUgdHJhbnNmb3Jtw6FjaXUgdnlzdmV0xL51asO6Y2VqIHByZW1lbm5laiA8ZW0+RmVydC4uUmF0ZTwvZW0+IG5hIDxjb2RlPmxvZyhGZXJ0Li5SYXRlKTwvY29kZT4gCiAgKHR2b2ogPHN0cm9uZz5tb2RlbDI8L3N0cm9uZz4pLCAoMikgcmVwb3J0b3ZhxaUgPGVtPnJvYnVzdG7DqSBzbWVyb2Rham7DqSBjaHlieTwvZW0+IChIQzEsIHNhbmR3aWNoKSwgCiAgcHLDrXBhZG5lICgzKSB6dsOhxb5pxaUgdsOhxb5lbsO6IHJlZ3Jlc2l1IChXTFMpLCBhayBieSBoZXRlcm9za2VkYXN0aWNpdGEgcHJldHJ2w6F2YWxhLjwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CiAg8J+SoSA8ZW0+UG96bsOhbWthOjwvZW0+IFYgZGVtb2dyYWZpY2vDvWNoIGEgbWFrcm9la29ub21pY2vDvWNoIGTDoXRhY2ggamUgbWllcm5hIGhldGVyb3NrZWRhc3RpY2l0YSBiZcW+bsOhLiAKICBEw7RsZcW+aXTDqSBqZSB1cHJhdmnFpSBpbmZlcmVuY2l1IChyb2J1c3Ruw6kgU0UpIGEgc2tvbnRyb2xvdmHFpSBkaWFnbm9zdGlja8OpIGdyYWZ5IChTY2FsZS1Mb2NhdGlvbiwgUmVzaWR1YWxzIHZzIEZpdHRlZCkuCjwvZGl2PgoKCmBgYHtyfQojIEluc3RhbGwgKGlmIG5vdCB5ZXQgaW5zdGFsbGVkKQojIGluc3RhbGwucGFja2FnZXMoImxtdGVzdCIpCgojIExvYWQgdGhlIHBhY2thZ2UKbGlicmFyeShsbXRlc3QpCgojIFJ1biB0aGUgQnJldXNjaOKAk1BhZ2FuIHRlc3QKYnB0ZXN0KG1vZGVsMikKCmBgYAo8ZGl2IGNsYXNzPSJhbmFseXNpcyI+CiAgPGg0PvCfk4ogSW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdiB0ZXN0dSBoZXRlcm9za2VkYXN0aWNpdHkgKEJyZXVzY2jigJNQYWdhbik8L2g0PgogIDxwPgogIE5hIHrDoWtsYWRlIHbDvXNsZWRrb3YgdGVzdHUgbcO0xb5lbWUga29uxaF0YXRvdmHFpSwgxb5lIDxzdHJvbmc+aGV0ZXJvc2tlZGFzdGljaXRhIHJlesOtZHXDrSBqZSB2IHDDtHZvZG5vbSBtb2RlbGkgCiAgPGVtPm1vZGVsPC9lbT4gcHLDrXRvbW7DoTwvc3Ryb25nPiAocC1ob2Rub3RhIDwgMC4wNSksIMSNbyB6bmFtZW7DoSwgxb5lIHJvenB0eWwgbsOhaG9kbmVqIHpsb8W+a3kgbmllIGplIGtvbsWhdGFudG7DvSAKICBwcmUgdsWhZXRreSBwb3pvcm92YW5pYS4gVGVudG8gamF2IG3DtMW+ZSBzcMO0c29iacWlIDxlbT5uZXNwb8S+YWhsaXbDqSBvZGhhZHkgc21lcm9kYWpuw71jaCBjaMO9YjwvZW0+IAogIGEgdMO9bSBhaiBuZXByZXNuw6kgdGVzdG92YW5pZSDFoXRhdGlzdGlja2VqIHbDvXpuYW1ub3N0aSByZWdyZXNuw71jaCBrb2VmaWNpZW50b3YuCiAgPC9wPgoKICA8cD4KICBQbyDDunByYXZlIG1vZGVsdSDigJQgdnl0dm9yZW7DrW0gPHN0cm9uZz5tb2RlbHUgPGVtPm1vZGVsMjwvZW0+IHNvIHpsb2dhcml0bWl6b3Zhbm91IHByZW1lbm5vdSA8ZW0+RmVydC4uUmF0ZTwvZW0+IAogIGEgb2RzdHLDoW5lbsOtbSBvZMS+YWhsw71jaCBwb3pvcm92YW7DrTwvc3Ryb25nPiDigJQgc2EgcC1ob2Rub3RhIHRlc3R1IG1pZXJuZSB6bGVwxaFpbGEsIG5vIAogIDxzdHJvbmc+em7DoW1reSBoZXRlcm9za2VkYXN0aWNpdHkgc3TDoWxlIHByZXRydsOhdmFqw7o8L3N0cm9uZz4gKHAg4omIIDAuMDAyNSkuCiAgPC9wPgoKICA8cD4KICBWemjEvmFkb20gbmEgdG8sIMW+ZSBhbmkgdHJhbnNmb3Jtw6FjaWEgYW5pIGVsaW1pbsOhY2lhIG9kxL5haGzDvWNoIGhvZG7DtHQgCiAgaGV0ZXJvc2tlZGFzdGljaXR1IMO6cGxuZSBuZW9kc3Ryw6FuaWxpLCA8c3Ryb25nPnByaXN0w7pwaW1lIGsgdnl1xb5pdGl1IHR6di4gV2hpdGUgaGV0ZXJvc2tlZGFzdGljaXR5LWNvbnNpc3RlbnQKICAocm9idXN0bsO9Y2gpIHNtZXJvZGFqbsO9Y2ggY2jDvWI8L3N0cm9uZz4uIFRlbnRvIHByw61zdHVwIGtvcmlndWplIG9kaGFkeSByb3pwdHlsb3YgcmVncmVzbsO9Y2gga29lZmljaWVudG92IHRhaywgCiAgYWJ5IGJvbGkgc3BvxL5haGxpdsOpIGFqIHYgcHLDrXBhZGUgcHLDrXRvbW5vc3RpIGhldGVyb3NrZWRhc3RpY2l0eS4KICA8L3A+CjwvZGl2PgoKPGRpdiBjbGFzcz0ibXV0ZWQiPgogIPCfkqEgPGVtPlBvem7DoW1rYTo8L2VtPiBIZXRlcm9za2VkYXN0aWNpdGEgamUgdiBkZW1vZ3JhZmlja8O9Y2ggYSBtYWtyb2Vrb25vbWlja8O9Y2ggw7pkYWpvY2ggxI1hc3TDvW0gamF2b20uIAogIFBvdcW+aXRpZSByb2J1c3Ruw71jaCDFoXRhbmRhcmRuw71jaCBjaMO9YiAobmFwci4gSEMxIOKAkyBXaGl0ZSkgemFiZXpwZcSNw60ga29yZWt0bsO6IGluZmVyZW5jaXUgCiAgYmV6IG51dG5vc3RpIHrDoXNhZG5lIG1lbmnFpSDFoXRydWt0w7pydSBtb2RlbHUuCjwvZGl2PgoKYGBge3Igd2hpdGVfdGVzdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBXaGl0ZSBoZXRlcm9za2VkYXN0aWNpdHktY29uc2lzdGVudCByb2J1c3Qgc3RhbmRhcmQgZXJyb3JzCgojIE5hxI3DrXRhbmllIHBvdHJlYm7DvWNoIGtuacW+bsOtYwpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGxtdGVzdCkKCiMgVsO9cG/EjWV0IHJvYnVzdG7DvWNoIHNtZXJvZGFqbsO9Y2ggY2jDvWIgcHJlIG1vZGVsIChXaGl0ZSBIQzEpCnJvYnVzdF9zZSA8LSBjb2VmdGVzdChtb2RlbDIsIHZjb3YgPSB2Y292SEMobW9kZWwyLCB0eXBlID0gIkhDMSIpKQoKIyBWw71zdHVwCnJvYnVzdF9zZQoKYGBgCjxkaXYgY2xhc3M9ImFuYWx5c2lzIj4KICA8aDQ+8J+TiCBJbnRlcnByZXTDoWNpYSB2w71zbGVka292IHMgcm9idXN0bsO9bWkgc21lcm9kYWpuw71taSBjaHliYW1pPC9oND4KICA8cD4KICBQbyBhcGxpa8OhY2lpIFdoaXRlIGhldGVyb3NrZWRhc3RpY2l0eS1jb25zaXN0ZW50IChyb2J1c3Ruw71jaCkgc21lcm9kYWpuw71jaCBjaMO9YiBzYSB1a2F6dWplLCDFvmUgCiAgPHN0cm9uZz52xaFldGt5IHByZW1lbm7DqSB2IG1vZGVsaSBzw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6kgYWxlYm8gaHJhbmnEjW5lIHbDvXpuYW1uw6k8L3N0cm9uZz4uICAKICBQcmVtZW5uw6kgPGVtPk1lZGlhbi5BZ2U8L2VtPiBhIDxlbT5GZXJ0aWxpdHkgUmF0ZSAobG9nKTwvZW0+IG1hasO6IG5lZ2F0w612bnkgdnBseXYsIHphdGlhxL4gxI1vIAogIDxlbT5NaWdyYW50cy5uZXQ8L2VtPiBww7Rzb2LDrSBwb3ppdMOtdm5lIG5hIHByZWRwb2tsYWRhbsO9IHBvxI1ldCBvYnl2YXRlxL5vdiB2IHJva3UgMjAyNS4KICA8L3A+CgogIDx1bD4KICAgIDxsaT48c3Ryb25nPk1pZXJhIHBsb2Rub3N0aSAobG9nIEZlcnRpbGl0eSBSYXRlKTwvc3Ryb25nPiDigJMgbmVnYXTDrXZueSBrb2VmaWNpZW50IG5hem5hxI11amUsIMW+ZSBrcmFqaW55IHMgbmnFvsWhb3UgcMO0cm9kbm9zxaVvdSAKICAgICAgICBtYWrDuiB0ZW5kZW5jaXUgZG9zYWhvdmHFpSBuacW+xaHDrSBwcsOtcmFzdG9rIHBvcHVsw6FjaWUgKHByaSBvc3RhdG7DvWNoIHByZW1lbm7DvWNoIG5lem1lbmVuw71jaCkuPC9saT4KICAgIDxsaT48c3Ryb25nPk1lZGnDoW5vdsO9IHZlayAoTWVkaWFuIEFnZSk8L3N0cm9uZz4g4oCTIG5lZ2F0w612bnkgdnBseXYgaW5kaWt1amUsIMW+ZSBzdGFyxaFpZSBwb3B1bMOhY2llIAogICAgICAgIHLDoXN0bGkgcG9tYWzFoWllLCDEjW8gem9kcG92ZWTDoSBvxI1ha8OhdmFuw71tIGRlbW9ncmFmaWNrw71tIHRyZW5kb20uPC9saT4KICAgIDxsaT48c3Ryb25nPk1pZ3LDoWNpYSAoTWlncmFudHMubmV0KTwvc3Ryb25nPiDigJMgcG96aXTDrXZueSBhIHRha21lciDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBrb2VmaWNpZW50IChwIOKJiCAwLjA1KSBwb3VrYXp1amUsIAogICAgICAgIMW+ZSDEjWlzdMOhIG1pZ3LDoWNpYSB6dnnFoXVqZSBwb3B1bMOhY2l1IHYgY2llxL5vdsO9Y2gga3Jhamluw6FjaC48L2xpPgogIDwvdWw+CgogIDxwPgogIDxzdHJvbmc+SW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdjo8L3N0cm9uZz4gIAogIE9kaGFkeSBzw7ogc3RhYmlsbmVqxaFpZSB2xI9ha2EgcG91xb5pdGl1IHJvYnVzdG7DvWNoIMWhdGFuZGFyZG7DvWNoIGNow71iLiBUw71tdG8ga3Jva29tIHNtZSBtaW5pbWFsaXpvdmFsaSB2cGx5diAKICBoZXRlcm9za2VkYXN0aWNpdHksIGt0b3LDoSBib2xhIHBvdHZyZGVuw6EgQnJldXNjaOKAk1BhZ2Fub3bDvW0gdGVzdG9tLiAKICA8YnI+CiAgViBtb2RlbGkgc2EgdGVkYSBwb3R2cmR6dWplLCDFvmUgPGVtPmRlbW9ncmFmaWNrw6kgdWthem92YXRlbGUg4oCTIHBsb2Rub3PFpSwgdmVrb3bDoSDFoXRydWt0w7pyYSBhIG1pZ3LDoWNpYSDigJMgCiAgbWFqw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gdnrFpWFoIHMgdmXEvmtvc8Wlb3UgcG9wdWzDoWNpZSB2IHJva3UgMjAyNTwvZW0+LgogIDwvcD4KPC9kaXY+Cgo8ZGl2IGNsYXNzPSJtdXRlZCI+CiAg8J+SoSA8ZW0+UG96bsOhbWthOjwvZW0+IFByaSBwcsOhY2kgcyByb2J1c3Ruw71taSBzbWVyb2Rham7DvW1pIGNoeWJhbWkgamUgZMO0bGXFvml0w6kgbWHFpSBkb3N0YXRvxI1uZSB2ZcS+a8O9IHBvxI1ldCBwb3pvcm92YW7DrSAKICAodiB0b210byBwcsOtcGFkZSB2aWFjIGFrbyAxMDApLCBhYnkgYm9saSBvZGhhZHkgc3BvxL5haGxpdsOpLiBUZW50byBwb3N0dXAgdW1vxb7FiHVqZSB6w61za2HFpSBrb256aXN0ZW50bsOpIAogIHbDvXNsZWRreSBhaiB2IHByw61wYWRlLCDFvmUgcm96cHR5bCByZXrDrWR1w60gbmllIGplIGtvbsWhdGFudG7DvS4KPC9kaXY+Cg==