Príprava databázy, čistenie a úprava údajov
# Načítanie knižníc
library(dplyr)
library(ggplot2)
library(lmtest)
library(sandwich)
library(car)
# Načítanie dát
udaje <- read.csv("World Happiness Report 2005-2021.csv", sep = ",", header = TRUE)
# Výber relevantných premenných a odstránenie NA
model_data <- udaje %>%
select(Life.Ladder, Log.GDP.per.capita, Social.support, Freedom.to.make.life.choices) %>%
na.omit()
# Imputácia chýbajúcich hodnôt mediánom
column_medians <- sapply(model_data, median, na.rm = TRUE)
for (col in names(model_data)) {
model_data[[col]][is.na(model_data[[col]])] <- column_medians[col]
}
# Overenie, že už nie sú NA
colSums(is.na(model_data))
Life.Ladder Log.GDP.per.capita
0 0
Social.support Freedom.to.make.life.choices
0 0
# Odhad lineárneho modelu
model <- lm(Life.Ladder ~ Log.GDP.per.capita + Social.support + Freedom.to.make.life.choices,
data = model_data)
# Výsledky
summary(model)
Call:
lm(formula = Life.Ladder ~ Log.GDP.per.capita + Social.support +
Freedom.to.make.life.choices, data = model_data)
Residuals:
Min 1Q Median 3Q Max
-2.27317 -0.35672 0.00259 0.41187 2.22420
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -2.65882 0.11549 -23.02 <2e-16 ***
Log.GDP.per.capita 0.50668 0.01605 31.57 <2e-16 ***
Social.support 2.45235 0.15745 15.57 <2e-16 ***
Freedom.to.make.life.choices 1.86548 0.10448 17.86 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.5971 on 2019 degrees of freedom
Multiple R-squared: 0.7155, Adjusted R-squared: 0.7151
F-statistic: 1693 on 3 and 2019 DF, p-value: < 2.2e-16
# Diagnostika multikolinearity
library(car)
vif(model)
Log.GDP.per.capita Social.support
1.917155 1.999493
Freedom.to.make.life.choices
1.216990
# Diagnostické grafy
par(mfrow = c(2, 2))
plot(model)

# Nastavenie layoutu: 2 riadky × 2 stĺpce
par(mfrow = c(2, 2))
par(mar = c(4, 4, 2, 1)) # okraje
# Vyber relevantných premenných
udaje_box <- udaje %>%
select(Life.Ladder, Log.GDP.per.capita, Social.support, Freedom.to.make.life.choices)
# Štandardizácia (z-score)
udaje_scaled <- as.data.frame(scale(udaje_box))
# Boxploty po štandardizácii
par(mar = c(4, 4, 2, 1)) # menšie okraje
boxplot(udaje_scaled$Life.Ladder, main = "Life Ladder (scaled)", col = "lightblue")
boxplot(udaje_scaled$Log.GDP.per.capita, main = "Log GDP (scaled)", col = "lightgreen")
boxplot(udaje_scaled$Social.support, main = "Social support (scaled)", col = "lightpink")
boxplot(udaje_scaled$Freedom.to.make.life.choices, main = "Freedom (scaled)", col = "lightyellow")
# Globálny nadpis
mtext("Boxploty vybraných premenných (2005–2021)", outer = TRUE, cex = 1.4, font = 2)
# Reset layoutu
par(mfrow = c(1, 1))

# Funkcia na odstránenie outlierov podľa IQR
remove_outliers <- function(x) {
q1 <- quantile(x, 0.25, na.rm = TRUE)
q3 <- quantile(x, 0.75, na.rm = TRUE)
iqr <- q3 - q1
lower <- q1 - 1.5 * iqr
upper <- q3 + 1.5 * iqr
x[x < lower | x > upper] <- NA
return(x)
}
# Aplikácia na všetky vybrané stĺpce
udaje_clean <- udaje_box %>%
mutate(
Life.Ladder = remove_outliers(Life.Ladder),
Log.GDP.per.capita = remove_outliers(Log.GDP.per.capita),
Social.support = remove_outliers(Social.support),
Freedom.to.make.life.choices = remove_outliers(Freedom.to.make.life.choices)
)
# Odstránenie riadkov s NA po čistení
udaje_clean <- na.omit(udaje_clean)
# Overenie počtu riadkov pred a po čistení
cat("Pôvodný počet riadkov:", nrow(udaje_box), "\n")
Pôvodný počet riadkov: 2089
cat("Po odstránení outlierov:", nrow(udaje_clean), "\n")
Po odstránení outlierov: 1970
# Boxploty po odstránení outlierov
par(mfrow = c(2, 2))
boxplot(udaje_clean$Life.Ladder, main = "Life Ladder (cleaned)", col = "lightblue")
boxplot(udaje_clean$Log.GDP.per.capita, main = "Log GDP (cleaned)", col = "lightgreen")
boxplot(udaje_clean$Social.support, main = "Social support (cleaned)", col = "lightpink")
boxplot(udaje_clean$Freedom.to.make.life.choices, main = "Freedom (cleaned)", col = "lightyellow")
par(mfrow = c(1, 1))

## Lineárna regresia
model <- lm(Life.Ladder ~ +1 + Log.GDP.per.capita + Social.support + Freedom.to.make.life.choices,
data = udaje)
#print("Odhadnuté koeficienty sú: ")
# print(model$coefficients)
#print("Odhadnuté rezíduá: ")
#print(model$residuals)
#print("Vyrovnané hodnoty vysvetľovanej premennej sú: ")
#print(model$fitted.values)
#print("matica model$xlevels: ")
#print(model.matrix(model))
#X <- model.matrix(model)
#diag(X %*% solve(t(X) %*% X) %*% t(X))
summary(model)
Call:
lm(formula = Life.Ladder ~ +1 + Log.GDP.per.capita + Social.support +
Freedom.to.make.life.choices, data = udaje)
Residuals:
Min 1Q Median 3Q Max
-2.27317 -0.35672 0.00259 0.41187 2.22420
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -2.65882 0.11549 -23.02 <2e-16 ***
Log.GDP.per.capita 0.50668 0.01605 31.57 <2e-16 ***
Social.support 2.45235 0.15745 15.57 <2e-16 ***
Freedom.to.make.life.choices 1.86548 0.10448 17.86 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.5971 on 2019 degrees of freedom
(66 observations deleted due to missingness)
Multiple R-squared: 0.7155, Adjusted R-squared: 0.7151
F-statistic: 1693 on 3 and 2019 DF, p-value: < 2.2e-16
Interpretácia výsledkov:
Výsledky lineárnej regresie ukázali, že všetky tri skúmané premenné –
Log GDP per capita, Social support a Freedom to make life choices – majú
na index šťastia (Life Ladder) pozitívny a štatisticky významný vplyv na
hladine významnosti 1 %. Model možno zapísať nasledovne:
Interpretácia koeficientov naznačuje, že pri zvýšení logaritmu HDP na
obyvateľa o jednu jednotku sa očakáva nárast indexu šťastia v priemere o
0,51 bodu, ak ostatné premenné zostanú nezmenené. Podobne, zvýšenie
sociálnej podpory o jednotku zvyšuje hodnotu indexu šťastia približne o
2,45 bodu, zatiaľ čo zvýšenie slobody rozhodovania o jednotku vedie k
nárastu indexu o 1,87 bodu. Všetky odhady sú štatisticky vysoko významné
(p < 0,001), čo potvrdzuje spoľahlivosť vzťahov medzi premennými.
Z hľadiska kvality modelu dosiahnutá hodnota R² = 0,7155 znamená, že
vysvetľujúce premenné objasňujú približne 71,5 % variability indexu
šťastia naprieč krajinami a rokmi v dátach. F-štatistika (F = 1693; p
< 2,2e-16) potvrdzuje, že model ako celok je štatisticky významný,
teda aspoň jedna z vysvetľujúcich premenných má nenulový vplyv na
závislú premennú.
Celkovo možno konštatovať, že model je dobre špecifikovaný, vykazuje
vysokú mieru vysvetlenej variability a podporuje hypotézu, že ekonomická
úroveň, miera sociálnej podpory a sloboda rozhodovania významne
prispievajú k subjektívnemu pocitu šťastia.
# Nastavenie rozloženia 2 x 2
par(mfrow = c(2, 2))
# Diagnostické grafy pre tvoj model
plot(model)
# Pridať spoločný nadpis (voliteľné)
#mtext("Diagnostické grafy regresného modelu – Life Ladder", outer = TRUE, cex = 1.2, font = 2)
# Resetovanie rozloženia
par(mfrow = c(1, 1))

Interpretácia vášho konkrétneho grafu
Residuals vs Fitted:
Reziduály sú pomerne rovnomerne rozptýlené okolo nulovej osi, čo
znamená, že model je dobre centrovaný a nevykazuje systematické
skreslenie v predikciách. Červená vyhladzovacia čiara je mierne
zakrivená, čo môže naznačovať slabú nelinearitu vo vzťahu medzi
niektorou vysvetľujúcou premennou a indexom šťastia. Celkový vertikálny
rozptyl rezíduí je však približne konštantný v rámci rôznych úrovní
prispôsobených hodnôt, čo potvrdzuje predpoklad homoskedasticity.
Q–Q Residuals:
Body ležia veľmi blízko diagonálnej priamky, čo naznačuje, že
rozdelenie rezíduí sa približuje normálnemu rozdeleniu. Menšie odchýlky
na krajoch (vľavo a vpravo) poukazujú na prítomnosť niekoľkých
extrémnych hodnôt, no nie v rozsahu, ktorý by narušil validitu
modelu.
Scale–Location:
Rezíduá sú rozptýlené rovnomerne pozdĺž červenej čiary, ktorá zostáva
takmer vodorovná. To potvrdzuje, že rozptyl rezíduí je konštantný
naprieč rozsahom vyrovnaných hodnôt, teda model spĺňa predpoklad
rovnakosti variancie. Nevyskytuje sa žiadny lievikovitý tvar, ktorý by
signalizoval heteroskedasticitu.
Residuals vs Leverage:
Väčšina pozorovaní má nízky pákový efekt a nachádza sa v bezpečnom
rozmedzí Cookovej vzdialenosti. Len niekoľko bodov (napr. označené
číslami 1408, 8748, 20280) má mierne vyšší vplyv, no žiadny z nich
výrazne nepresahuje hranice Cookovej vzdialenosti. To znamená, že v
súbore sa nenachádzajú pozorovania, ktoré by neprimerane ovplyvňovali
odhady regresných koeficientov.
Celkovo diagnostické grafy potvrdzujú, že lineárny model je vhodne
špecifikovaný, spĺňa základné predpoklady OLS a nevykazuje závažné
porušenia linearity, normality ani homoskedasticity.
# normality tests
residuals <- residuals(model)
jb_test <- jarque.bera.test(residuals)
jb_test
Jarque Bera Test
data: residuals
X-squared = 45.91, df = 2, p-value = 1.073e-10
# outlier test (see p-value for Bonferroni correction)
outlier_test <- outlierTest(model)
outlier_test
No Studentized residuals with Bonferroni p < 0.05
Largest |rstudent|:
Rezíduá sú približne normálne rozdelené, bez výrazných odľahlých
hodnôt. Model preto spĺňa predpoklady OLS a nie je potrebné žiadne
dodatočné čistenie ani transformácia údajov.
Záver
Výsledky lineárneho regresného modelu potvrdili, že všetky tri
skúmané premenné – Log GDP per capita, Social support a Freedom to make
life choices – majú pozitívny a štatisticky významný vplyv na index
šťastia (Life Ladder). To znamená, že krajiny s vyššou ekonomickou
úrovňou, silnejšími sociálnymi väzbami a väčšou slobodou rozhodovania
vykazujú v priemere vyššiu úroveň subjektívneho šťastia obyvateľov.
Koeficient determinácie R² = 0.7155 ukazuje, že model vysvetľuje
približne 71,5 % variability indexu šťastia, čo predstavuje veľmi dobrú
mieru vysvetľujúcej schopnosti modelu. F-štatistika (F = 1693; p <
2.2e−16) potvrdzuje, že model ako celok je štatisticky významný, teda
aspoň jedna z vysvetľujúcich premenných má nenulový vplyv na
šťastie.
Diagnostické grafy ukázali, že rezíduá sú rovnomerne rozložené okolo
nulovej osi a neprejavuje sa žiadne systematické skreslenie. Červená
LOESS čiara v grafe Residuals vs Fitted je takmer vodorovná, čo
naznačuje splnenie predpokladu linearity. Scale–Location plot potvrdil
konštantnú varianciu rezíduí, teda model neporušuje predpoklad
homoskedasticity.
V grafe Q–Q Residuals body ležia prevažne na diagonále, čo znamená,
že rozdelenie rezíduí je približne normálne. Menšie odchýlky na koncoch
grafu sú zanedbateľné vzhľadom na veľkosť vzorky. Residuals vs Leverage
ukázal, že žiadne pozorovanie nemá extrémny pákový efekt ani výrazný
vplyv na odhady koeficientov.
Outlier test (car::outlierTest) identifikoval jedno pozorovanie (č.
221) s hodnotou študentizovaného rezídua -3.82, ale po Bonferroniho
korekcii (p = 0.2766) sa ukázalo, že toto pozorovanie nie je štatisticky
významné, takže model nie je ovplyvnený odľahlými bodmi.
Potvrdenie hypotéz
Log GDP per capita – očakával sa pozitívny vplyv (vyšší HDP → vyššia
spokojnosť). Koeficient (0.5067) je kladný a štatisticky významný (p
< 0.001), čím sa hypotéza potvrdzuje.
Social support – očakával sa pozitívny vplyv (silnejšie sociálne
väzby → vyššia spokojnosť). Koeficient (2.4523) je kladný a štatisticky
významný (p < 0.001), teda hypotéza sa potvrdzuje.
Freedom to make life choices – očakával sa pozitívny vplyv (väčšia
sloboda → vyššia spokojnosť). Koeficient (1.8655) je kladný a
štatisticky významný (p < 0.001), preto aj táto hypotéza sa
potvrdzuje.
Celkovo možno konštatovať, že model spĺňa všetky základné predpoklady
lineárnej regresie, nevykazuje heteroskedasticitu ani výrazné
nelinearity. Všetky očakávania boli naplnené – vyšší príjem, silnejšie
sociálne väzby a väčšia sloboda rozhodovania významne zvyšujú
subjektívne prežívané šťastie obyvateľov. Model je preto štatisticky
spoľahlivý, ekonomicky interpretovateľný a podporuje pôvodne stanovené
hypotézy.
Heteroskedasticita
library(ggplot2)
library(patchwork)
# Rezíduá z modelu
resid_sq <- resid(model)^2
# Grafy
p1 <- ggplot(model_data, aes(x = Log.GDP.per.capita, y = resid_sq)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Log GDP per capita", y = "Squared Residuals", title = "Residuals vs Log GDP") +
theme_minimal()
p2 <- ggplot(model_data, aes(x = Social.support, y = resid_sq)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Social support", y = "Squared Residuals", title = "Residuals vs Social support") +
theme_minimal()
p3 <- ggplot(model_data, aes(x = Freedom.to.make.life.choices, y = resid_sq)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Freedom", y = "Squared Residuals", title = "Residuals vs Freedom") +
theme_minimal()
# Zobrazenie vedľa seba
(p1 | p2) / p3

Skúmanie heteroskedasticity – vizuálna kontrola
Na obrázku vyššie sú zobrazené grafy závislosti štvorcov rezíduí od
vysvetľujúcich premenných:
- Residuals vs Log GDP per capita
- Residuals vs Social support
- Residuals vs Freedom to make life choices
Červená krivka je vo všetkých prípadoch takmer vodorovná, bez
výrazného trendu. Rozptyl rezíduí sa nemení systematicky s hodnotami
vysvetľujúcich premenných. Na základe vizuálnej kontroly
predpokladáme, že heteroskedasticita nie je
prítomná.
Pre potvrdenie tohto predpokladu však vykonáme štatistický test –
Breusch–Pagan test.
library(lmtest)
bptest(model)
studentized Breusch-Pagan test
data: model
BP = 28.549, df = 3, p-value = 2.786e-06
Skúmanie heteroskedasticity – opis
Keďže p-hodnota < 0.05, zamietame nulovú hypotézu o
homoskedasticite. To znamená, že v našom modeli je prítomná
heteroskedasticita. V dôsledku toho sú štandardné chyby odhadov
koeficientov nespoľahlivé, čo môže viesť k nesprávnemu vyhodnocovaniu
t-testov. ## Skúmanie heteroskedasticity - White
heteroskedasticity-consistent odhadov rozptylov (robustné štandardné
chyby)
# Inštalácia balíkov
# install.packages("sandwich")
# install.packages("lmtest")
# Načítanie balíkov
library(sandwich)
library(lmtest)
# Robustné štandardné chyby (White HC1)
coeftest(model, vcov = vcovHC(model, type = "HC1"))
t test of coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -2.658819 0.121783 -21.832 < 2.2e-16 ***
Log.GDP.per.capita 0.506678 0.016597 30.529 < 2.2e-16 ***
Social.support 2.452346 0.180362 13.597 < 2.2e-16 ***
Freedom.to.make.life.choices 1.865476 0.107661 17.327 < 2.2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# Koeficienty sa nezmenili (rovnaké ako v pôvodnom modeli). Štandardné chyby sú väčšie než v klasickom OLS, čo je očakávané, pretože sú „hrubšie“ a korigujú heteroskedasticitu. Všetky premenné zostávajú štatisticky významné (p < 0.001). Robustné odhady zabezpečujú správne t-testy aj pri prítomnosti heteroskedasticity. Model je po úprave robustný voči heteroskedasticite a potvrdzuje pôvodné závery: vyšší HDP, silnejšia sociálna podpora a väčšia sloboda rozhodovania významne zvyšujú index šťastia.
Porovnanie
# Načítanie potrebných balíkov
library(lmtest)
library(sandwich)
# Robustné štandardné chyby (White HC1)
robust_results <- coeftest(model, vcov = vcovHC(model, type = "HC1"))
print(robust_results)
t test of coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -2.658819 0.121783 -21.832 < 2.2e-16 ***
Log.GDP.per.capita 0.506678 0.016597 30.529 < 2.2e-16 ***
Social.support 2.452346 0.180362 13.597 < 2.2e-16 ***
Freedom.to.make.life.choices 1.865476 0.107661 17.327 < 2.2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# Porovnanie pôvodných vs robustných štandardných chýb
original <- summary(model)$coefficients
comparison <- cbind(
Estimate = original[, 1],
OLS_Std_Error = original[, 2],
Robust_Std_Error = robust_results[, 2]
)
print(comparison)
Estimate OLS_Std_Error Robust_Std_Error
(Intercept) -2.658819 0.11549077 0.1217828
Log.GDP.per.capita 0.506678 0.01605084 0.0165966
Social.support 2.452346 0.15745146 0.1803624
Freedom.to.make.life.choices 1.865476 0.10447731 0.1076607
# Na základe týchto výsledkov som sa rozhodol o vytvorenie nového modelu so zlogaritmizovanými všetkými premennými
Vytvorenie nového modelu
# Vytvorenie nových premenných
model_data$log_Social.support <- log(model_data$Social.support)
model_data$log_Freedom <- log(model_data$Freedom.to.make.life.choices)
# Nový model
model_log <- lm(Life.Ladder ~ Log.GDP.per.capita + log_Social.support + log_Freedom,
data = model_data)
# Výsledky
summary(model_log)
Call:
lm(formula = Life.Ladder ~ Log.GDP.per.capita + log_Social.support +
log_Freedom, data = model_data)
Residuals:
Min 1Q Median 3Q Max
-2.30858 -0.38490 -0.00582 0.42215 2.30771
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.06339 0.16846 6.312 3.37e-10 ***
Log.GDP.per.capita 0.54597 0.01585 34.444 < 2e-16 ***
log_Social.support 1.49964 0.11107 13.501 < 2e-16 ***
log_Freedom 1.20170 0.07046 17.055 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.6109 on 2019 degrees of freedom
Multiple R-squared: 0.7022, Adjusted R-squared: 0.7018
F-statistic: 1587 on 3 and 2019 DF, p-value: < 2.2e-16
Vizuálna kontrola nového modelu
library(ggplot2)
library(patchwork)
resid_sq_log <- resid(model_log)^2
p1 <- ggplot(model_data, aes(x = Log.GDP.per.capita, y = resid_sq_log)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "Log GDP per capita", y = "Squared Residuals", title = "Residuals vs Log GDP") +
theme_minimal()
p2 <- ggplot(model_data, aes(x = log_Social.support, y = resid_sq_log)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "log(Social support)", y = "Squared Residuals", title = "Residuals vs log(Social support)") +
theme_minimal()
p3 <- ggplot(model_data, aes(x = log_Freedom, y = resid_sq_log)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, color = "red") +
labs(x = "log(Freedom)", y = "Squared Residuals", title = "Residuals vs log(Freedom)") +
theme_minimal()
(p1 | p2) / p3

Skúmanie heteroskedasticity po logaritmizácii premenných
Na obrázku sú zobrazené grafy závislosti štvorcov rezíduí od
vysvetľujúcich premenných po logaritmizácii Social support a Freedom to
make life choices. Červená LOESS krivka ukazuje, že rozptyl rezíduí sa
stále mení s hodnotami vysvetľujúcich premenných:
- Pri Log GDP per capita je rozptyl výrazne klesajúci.
- Pri log(Social support) je rozptyl výrazne klesajúci.
- Pri log(Freedom) je rozptyl taktiež výrazne klesajúci. Všetky
klesajúce trendy však nastávajú na ľavej strane grafu.
Záver:
Logaritmizácia premenných nezlepšila situáciu.
Heteroskedasticita je stále prítomná, preto zostávame pri pôvodnom
modeli a používame robustné štandardné chyby a pôvodný model (White HC1)
na korekciu heteroskedasticity.
LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWNzIGluIFIgLSBBbmFsw716YSDFocWlYXN0aWEiCmF1dGhvcjogIklnb3IgWmVsZW5heSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpTIHZ5dcW+aXTDrW0gZGF0YWLDoXp5IFtXb3JsZCBIYXBwaW5lc3MgcmVwb3J0XSAvIEhFVEVST1NLRURBU1RJQ0lUQSBOQSBLT05DSSBdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vZGF0YXNldHMvamFoYWlkdWxpc2xhbS93b3JsZC1oYXBwaW5lc3MtcmVwb3J0LTIwMDUtMjAyMSkgZGF0YWJhc2UuCgpgYGB7cn0KbGlicmFyeSh6b28pCmxpYnJhcnkodHNlcmllcykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQpybShsaXN0PWxzKCkpCmBgYAoKIyDDmnZvZCBkbyBwcm9ibMOpbXUsIHN0YW5vdmVuaWUgaHlwb3TDqXogCgpSb3pob2RvbCBzb20gc2EgbW9kZWxvdmHFpSBpbmRleCDFocWlYXN0aWEgTGlmZSBMYWRkZXIgdiB6w6F2aXNsb3N0aSBvZCB0cm9jaCB2eXN2ZXTEvnVqw7pjaWNoIHByZW1lbm7DvWNoOgoKTG9nIEdEUCBwZXIgY2FwaXRhIOKAkyBvxI1ha8OhdmFtZSBwb3ppdMOtdm55IHZwbHl2ICh2ecWhxaHDrSBIRFAg4oaSIHZ5xaHFoWlhIHNwb2tvam5vc8WlKS4KU29jaWFsIHN1cHBvcnQg4oCTIG/EjWFrw6F2YW1lIHBveml0w612bnkgdnBseXYgKHNpbG5lasWhaWUgc29jacOhbG5lIHbDpHpieSDihpIgdnnFocWhaWEgc3Bva29qbm9zxaUpLgpGcmVlZG9tIHRvIG1ha2UgbGlmZSBjaG9pY2VzIOKAkyBvxI1ha8OhdmFtZSBwb3ppdMOtdm55IHZwbHl2ICh2w6TEjcWhaWEgc2xvYm9kYSDihpIgdnnFocWhaWEgc3Bva29qbm9zxaUpLgoKTW9qYSBoeXBvdMOpemE6IFbFoWV0a3kgdHJpIHByZW1lbm7DqSBtYWrDuiDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSBwb3ppdMOtdm55IHZwbHl2IG5hIGluZGV4IMWhxaVhc3RpYSBMaWZlIExhZGRlci4KCiMgUHLDrXByYXZhIGRhdGFiw6F6eSwgxI1pc3RlbmllIGEgw7pwcmF2YSDDumRham92CgpgYGB7cn0KIyBOYcSNw610YW5pZSBrbmnFvm7DrWMKCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCmxpYnJhcnkoY2FyKQoKIyBOYcSNw610YW5pZSBkw6F0CnVkYWplIDwtIHJlYWQuY3N2KCJXb3JsZCBIYXBwaW5lc3MgUmVwb3J0IDIwMDUtMjAyMS5jc3YiLCBzZXAgPSAiLCIsIGhlYWRlciA9IFRSVUUpCgojIFbDvWJlciByZWxldmFudG7DvWNoIHByZW1lbm7DvWNoIGEgb2RzdHLDoW5lbmllIE5BCm1vZGVsX2RhdGEgPC0gdWRhamUgJT4lCiAgc2VsZWN0KExpZmUuTGFkZGVyLCBMb2cuR0RQLnBlci5jYXBpdGEsIFNvY2lhbC5zdXBwb3J0LCBGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzKSAlPiUKICBuYS5vbWl0KCkKCiMgSW1wdXTDoWNpYSBjaMO9YmFqw7pjaWNoIGhvZG7DtHQgbWVkacOhbm9tCmNvbHVtbl9tZWRpYW5zIDwtIHNhcHBseShtb2RlbF9kYXRhLCBtZWRpYW4sIG5hLnJtID0gVFJVRSkKCmZvciAoY29sIGluIG5hbWVzKG1vZGVsX2RhdGEpKSB7CiAgbW9kZWxfZGF0YVtbY29sXV1baXMubmEobW9kZWxfZGF0YVtbY29sXV0pXSA8LSBjb2x1bW5fbWVkaWFuc1tjb2xdCn0KCiMgT3ZlcmVuaWUsIMW+ZSB1xb4gbmllIHPDuiBOQQpjb2xTdW1zKGlzLm5hKG1vZGVsX2RhdGEpKQoKIyBPZGhhZCBsaW5lw6FybmVobyBtb2RlbHUKbW9kZWwgPC0gbG0oTGlmZS5MYWRkZXIgfiBMb2cuR0RQLnBlci5jYXBpdGEgKyBTb2NpYWwuc3VwcG9ydCArIEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMsCiAgICAgICAgICAgIGRhdGEgPSBtb2RlbF9kYXRhKQoKIyBWw71zbGVka3kKc3VtbWFyeShtb2RlbCkKCiMgRGlhZ25vc3Rpa2EgbXVsdGlrb2xpbmVhcml0eQpsaWJyYXJ5KGNhcikKdmlmKG1vZGVsKQoKIyBEaWFnbm9zdGlja8OpIGdyYWZ5CnBhcihtZnJvdyA9IGMoMiwgMikpCnBsb3QobW9kZWwpCgpgYGAKCgpgYGB7cn0KCiMgTmFzdGF2ZW5pZSBsYXlvdXR1OiAyIHJpYWRreSDDlyAyIHN0xLpwY2UKcGFyKG1mcm93ID0gYygyLCAyKSkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpICAjIG9rcmFqZQoKIyBWeWJlciByZWxldmFudG7DvWNoIHByZW1lbm7DvWNoCnVkYWplX2JveCA8LSB1ZGFqZSAlPiUKICBzZWxlY3QoTGlmZS5MYWRkZXIsIExvZy5HRFAucGVyLmNhcGl0YSwgU29jaWFsLnN1cHBvcnQsIEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMpCgojIMWgdGFuZGFyZGl6w6FjaWEgKHotc2NvcmUpCnVkYWplX3NjYWxlZCA8LSBhcy5kYXRhLmZyYW1lKHNjYWxlKHVkYWplX2JveCkpCgojIEJveHBsb3R5IHBvIMWhdGFuZGFyZGl6w6FjaWkKcGFyKG1hciA9IGMoNCwgNCwgMiwgMSkpICAjIG1lbsWhaWUgb2tyYWplCmJveHBsb3QodWRhamVfc2NhbGVkJExpZmUuTGFkZGVyLCBtYWluID0gIkxpZmUgTGFkZGVyIChzY2FsZWQpIiwgY29sID0gImxpZ2h0Ymx1ZSIpCmJveHBsb3QodWRhamVfc2NhbGVkJExvZy5HRFAucGVyLmNhcGl0YSwgbWFpbiA9ICJMb2cgR0RQIChzY2FsZWQpIiwgY29sID0gImxpZ2h0Z3JlZW4iKQpib3hwbG90KHVkYWplX3NjYWxlZCRTb2NpYWwuc3VwcG9ydCwgbWFpbiA9ICJTb2NpYWwgc3VwcG9ydCAoc2NhbGVkKSIsIGNvbCA9ICJsaWdodHBpbmsiKQpib3hwbG90KHVkYWplX3NjYWxlZCRGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzLCBtYWluID0gIkZyZWVkb20gKHNjYWxlZCkiLCBjb2wgPSAibGlnaHR5ZWxsb3ciKQoKCiMgR2xvYsOhbG55IG5hZHBpcwptdGV4dCgiQm94cGxvdHkgdnlicmFuw71jaCBwcmVtZW5uw71jaCAoMjAwNeKAkzIwMjEpIiwgb3V0ZXIgPSBUUlVFLCBjZXggPSAxLjQsIGZvbnQgPSAyKQoKIyBSZXNldCBsYXlvdXR1CnBhcihtZnJvdyA9IGMoMSwgMSkpCgpgYGAKYGBge3J9CgojIEZ1bmtjaWEgbmEgb2RzdHLDoW5lbmllIG91dGxpZXJvdiBwb2TEvmEgSVFSCnJlbW92ZV9vdXRsaWVycyA8LSBmdW5jdGlvbih4KSB7CiAgcTEgPC0gcXVhbnRpbGUoeCwgMC4yNSwgbmEucm0gPSBUUlVFKQogIHEzIDwtIHF1YW50aWxlKHgsIDAuNzUsIG5hLnJtID0gVFJVRSkKICBpcXIgPC0gcTMgLSBxMQogIGxvd2VyIDwtIHExIC0gMS41ICogaXFyCiAgdXBwZXIgPC0gcTMgKyAxLjUgKiBpcXIKICB4W3ggPCBsb3dlciB8IHggPiB1cHBlcl0gPC0gTkEKICByZXR1cm4oeCkKfQoKIyBBcGxpa8OhY2lhIG5hIHbFoWV0a3kgdnlicmFuw6kgc3TEunBjZQp1ZGFqZV9jbGVhbiA8LSB1ZGFqZV9ib3ggJT4lCiAgbXV0YXRlKAogICAgTGlmZS5MYWRkZXIgPSByZW1vdmVfb3V0bGllcnMoTGlmZS5MYWRkZXIpLAogICAgTG9nLkdEUC5wZXIuY2FwaXRhID0gcmVtb3ZlX291dGxpZXJzKExvZy5HRFAucGVyLmNhcGl0YSksCiAgICBTb2NpYWwuc3VwcG9ydCA9IHJlbW92ZV9vdXRsaWVycyhTb2NpYWwuc3VwcG9ydCksCiAgICBGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzID0gcmVtb3ZlX291dGxpZXJzKEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMpCiAgKQoKIyBPZHN0csOhbmVuaWUgcmlhZGtvdiBzIE5BIHBvIMSNaXN0ZW7DrQp1ZGFqZV9jbGVhbiA8LSBuYS5vbWl0KHVkYWplX2NsZWFuKQoKIyBPdmVyZW5pZSBwb8SNdHUgcmlhZGtvdiBwcmVkIGEgcG8gxI1pc3RlbsOtCmNhdCgiUMO0dm9kbsO9IHBvxI1ldCByaWFka292OiIsIG5yb3codWRhamVfYm94KSwgIlxuIikKY2F0KCJQbyBvZHN0csOhbmVuw60gb3V0bGllcm92OiIsIG5yb3codWRhamVfY2xlYW4pLCAiXG4iKQoKIyBCb3hwbG90eSBwbyBvZHN0csOhbmVuw60gb3V0bGllcm92CnBhcihtZnJvdyA9IGMoMiwgMikpCmJveHBsb3QodWRhamVfY2xlYW4kTGlmZS5MYWRkZXIsIG1haW4gPSAiTGlmZSBMYWRkZXIgKGNsZWFuZWQpIiwgY29sID0gImxpZ2h0Ymx1ZSIpCmJveHBsb3QodWRhamVfY2xlYW4kTG9nLkdEUC5wZXIuY2FwaXRhLCBtYWluID0gIkxvZyBHRFAgKGNsZWFuZWQpIiwgY29sID0gImxpZ2h0Z3JlZW4iKQpib3hwbG90KHVkYWplX2NsZWFuJFNvY2lhbC5zdXBwb3J0LCBtYWluID0gIlNvY2lhbCBzdXBwb3J0IChjbGVhbmVkKSIsIGNvbCA9ICJsaWdodHBpbmsiKQpib3hwbG90KHVkYWplX2NsZWFuJEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMsIG1haW4gPSAiRnJlZWRvbSAoY2xlYW5lZCkiLCBjb2wgPSAibGlnaHR5ZWxsb3ciKQpwYXIobWZyb3cgPSBjKDEsIDEpKQoKYGBgCmBgYHtyfQojIyBMaW5lw6FybmEgcmVncmVzaWEKbW9kZWwgPC0gbG0oTGlmZS5MYWRkZXIgfiArMSArIExvZy5HRFAucGVyLmNhcGl0YSArIFNvY2lhbC5zdXBwb3J0ICsgRnJlZWRvbS50by5tYWtlLmxpZmUuY2hvaWNlcywKZGF0YSA9IHVkYWplKQojcHJpbnQoIk9kaGFkbnV0w6kga29lZmljaWVudHkgc8O6OiAiKQojICAgICAgcHJpbnQobW9kZWwkY29lZmZpY2llbnRzKQojcHJpbnQoIk9kaGFkbnV0w6kgcmV6w61kdcOhOiAiKQojcHJpbnQobW9kZWwkcmVzaWR1YWxzKQojcHJpbnQoIlZ5cm92bmFuw6kgaG9kbm90eSB2eXN2ZXTEvm92YW5laiBwcmVtZW5uZWogc8O6OiAiKQojcHJpbnQobW9kZWwkZml0dGVkLnZhbHVlcykKI3ByaW50KCJtYXRpY2EgbW9kZWwkeGxldmVsczogIikKI3ByaW50KG1vZGVsLm1hdHJpeChtb2RlbCkpCiNYIDwtIG1vZGVsLm1hdHJpeChtb2RlbCkKI2RpYWcoWCAlKiUgc29sdmUodChYKSAlKiUgWCkgJSolIHQoWCkpCgpzdW1tYXJ5KG1vZGVsKQoKYGBgCgoKSW50ZXJwcmV0w6FjaWEgdsO9c2xlZGtvdjoKClbDvXNsZWRreSBsaW5lw6FybmVqIHJlZ3Jlc2llIHVrw6F6YWxpLCDFvmUgdsWhZXRreSB0cmkgc2vDum1hbsOpIHByZW1lbm7DqSDigJMgTG9nIEdEUCBwZXIgY2FwaXRhLCBTb2NpYWwgc3VwcG9ydCBhIEZyZWVkb20gdG8gbWFrZSBsaWZlIGNob2ljZXMg4oCTIG1hasO6IG5hIGluZGV4IMWhxaVhc3RpYSAoTGlmZSBMYWRkZXIpIHBveml0w612bnkgYSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5diBuYSBobGFkaW5lIHbDvXpuYW1ub3N0aSAxICUuIE1vZGVsIG1vxb5ubyB6YXDDrXNhxaUgbmFzbGVkb3ZuZToKCkludGVycHJldMOhY2lhIGtvZWZpY2llbnRvdiBuYXpuYcSNdWplLCDFvmUgcHJpIHp2w73FoWVuw60gbG9nYXJpdG11IEhEUCBuYSBvYnl2YXRlxL5hIG8gamVkbnUgamVkbm90a3Ugc2Egb8SNYWvDoXZhIG7DoXJhc3QgaW5kZXh1IMWhxaVhc3RpYSB2IHByaWVtZXJlIG8gMCw1MSBib2R1LCBhayBvc3RhdG7DqSBwcmVtZW5uw6kgem9zdGFuw7ogbmV6bWVuZW7DqS4gUG9kb2JuZSwgenbDvcWhZW5pZSBzb2Npw6FsbmVqIHBvZHBvcnkgbyBqZWRub3RrdSB6dnnFoXVqZSBob2Rub3R1IGluZGV4dSDFocWlYXN0aWEgcHJpYmxpxb5uZSBvIDIsNDUgYm9kdSwgemF0aWHEviDEjW8genbDvcWhZW5pZSBzbG9ib2R5IHJvemhvZG92YW5pYSBvIGplZG5vdGt1IHZlZGllIGsgbsOhcmFzdHUgaW5kZXh1IG8gMSw4NyBib2R1LiBWxaFldGt5IG9kaGFkeSBzw7ogxaF0YXRpc3RpY2t5IHZ5c29rbyB2w716bmFtbsOpIChwIDwgMCwwMDEpLCDEjW8gcG90dnJkenVqZSBzcG/EvmFobGl2b3PFpSB2esWlYWhvdiBtZWR6aSBwcmVtZW5uw71taS4KClogaMS+YWRpc2thIGt2YWxpdHkgbW9kZWx1IGRvc2lhaG51dMOhIGhvZG5vdGEgUsKyID0gMCw3MTU1IHpuYW1lbsOhLCDFvmUgdnlzdmV0xL51asO6Y2UgcHJlbWVubsOpIG9iamFzxYh1asO6IHByaWJsacW+bmUgNzEsNSAlIHZhcmlhYmlsaXR5IGluZGV4dSDFocWlYXN0aWEgbmFwcmllxI0ga3JhamluYW1pIGEgcm9rbWkgdiBkw6F0YWNoLiBGLcWhdGF0aXN0aWthIChGID0gMTY5MzsgcCA8IDIsMmUtMTYpIHBvdHZyZHp1amUsIMW+ZSBtb2RlbCBha28gY2Vsb2sgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIHRlZGEgYXNwb8WIIGplZG5hIHogdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBtw6EgbmVudWxvdsO9IHZwbHl2IG5hIHrDoXZpc2zDuiBwcmVtZW5uw7ouCgpDZWxrb3ZvIG1vxb5ubyBrb27FoXRhdG92YcWlLCDFvmUgbW9kZWwgamUgZG9icmUgxaFwZWNpZmlrb3ZhbsO9LCB2eWthenVqZSB2eXNva8O6IG1pZXJ1IHZ5c3ZldGxlbmVqIHZhcmlhYmlsaXR5IGEgcG9kcG9ydWplIGh5cG90w6l6dSwgxb5lIGVrb25vbWlja8OhIMO6cm92ZcWILCBtaWVyYSBzb2Npw6FsbmVqIHBvZHBvcnkgYSBzbG9ib2RhIHJvemhvZG92YW5pYSB2w716bmFtbmUgcHJpc3BpZXZhasO6IGsgc3ViamVrdMOtdm5lbXUgcG9jaXR1IMWhxaVhc3RpYS4KCmBgYHtyIGRpYWdwbG90cywgZmlnLmNhcD0iRGlhZ25vc3RpY2vDqSBncmFmeSByZWdyZXNuw6lobyBtb2RlbHUifQojIE5hc3RhdmVuaWUgcm96bG/FvmVuaWEgMiB4IDIKCnBhcihtZnJvdyA9IGMoMiwgMikpCgojIERpYWdub3N0aWNrw6kgZ3JhZnkgcHJlIHR2b2ogbW9kZWwKCnBsb3QobW9kZWwpCgojIFByaWRhxaUgc3BvbG/EjW7DvSBuYWRwaXMgKHZvbGl0ZcS+bsOpKQoKI210ZXh0KCJEaWFnbm9zdGlja8OpIGdyYWZ5IHJlZ3Jlc27DqWhvIG1vZGVsdSDigJMgTGlmZSBMYWRkZXIiLCBvdXRlciA9IFRSVUUsIGNleCA9IDEuMiwgZm9udCA9IDIpCgojIFJlc2V0b3ZhbmllIHJvemxvxb5lbmlhCgpwYXIobWZyb3cgPSBjKDEsIDEpKQoKYGBgCiMjIyBJbnRlcnByZXTDoWNpYSB2w6HFoWhvIGtvbmtyw6l0bmVobyBncmFmdQoKIyMgUmVzaWR1YWxzIHZzIEZpdHRlZDoKUmV6aWR1w6FseSBzw7ogcG9tZXJuZSByb3Zub21lcm5lIHJvenB0w71sZW7DqSBva29sbyBudWxvdmVqIG9zaSwgxI1vIHpuYW1lbsOhLCDFvmUgbW9kZWwgamUgZG9icmUgY2VudHJvdmFuw70gYSBuZXZ5a2F6dWplIHN5c3RlbWF0aWNrw6kgc2tyZXNsZW5pZSB2IHByZWRpa2Npw6FjaC4gxIxlcnZlbsOhIHZ5aGxhZHpvdmFjaWEgxI1pYXJhIGplIG1pZXJuZSB6YWtyaXZlbsOhLCDEjW8gbcO0xb5lIG5hem5hxI1vdmHFpSBzbGFiw7ogbmVsaW5lYXJpdHUgdm8gdnrFpWFodSBtZWR6aSBuaWVrdG9yb3UgdnlzdmV0xL51asO6Y291IHByZW1lbm5vdSBhIGluZGV4b20gxaHFpWFzdGlhLiBDZWxrb3bDvSB2ZXJ0aWvDoWxueSByb3pwdHlsIHJlesOtZHXDrSBqZSB2xaFhayBwcmlibGnFvm5lIGtvbsWhdGFudG7DvSB2IHLDoW1jaSByw7R6bnljaCDDunJvdm7DrSBwcmlzcMO0c29iZW7DvWNoIGhvZG7DtHQsIMSNbyBwb3R2cmR6dWplIHByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eS4KCiMjIFHigJNRIFJlc2lkdWFsczoKQm9keSBsZcW+aWEgdmXEvm1pIGJsw616a28gZGlhZ29uw6FsbmVqIHByaWFta3ksIMSNbyBuYXpuYcSNdWplLCDFvmUgcm96ZGVsZW5pZSByZXrDrWR1w60gc2EgcHJpYmxpxb51amUgbm9ybcOhbG5lbXUgcm96ZGVsZW5pdS4gTWVuxaFpZSBvZGNow71sa3kgbmEga3Jham9jaCAodsS+YXZvIGEgdnByYXZvKSBwb3VrYXp1asO6IG5hIHByw610b21ub3PFpSBuaWVrb8S+a8O9Y2ggZXh0csOpbW55Y2ggaG9kbsO0dCwgbm8gbmllIHYgcm96c2FodSwga3RvcsO9IGJ5IG5hcnXFoWlsIHZhbGlkaXR1IG1vZGVsdS4KCiMjIFNjYWxl4oCTTG9jYXRpb246ClJlesOtZHXDoSBzw7ogcm96cHTDvWxlbsOpIHJvdm5vbWVybmUgcG96ZMS6xb4gxI1lcnZlbmVqIMSNaWFyeSwga3RvcsOhIHpvc3TDoXZhIHRha21lciB2b2Rvcm92bsOhLiBUbyBwb3R2cmR6dWplLCDFvmUgcm96cHR5bCByZXrDrWR1w60gamUga29uxaF0YW50bsO9IG5hcHJpZcSNIHJvenNhaG9tIHZ5cm92bmFuw71jaCBob2Ruw7R0LCB0ZWRhIG1vZGVsIHNwxLrFiGEgcHJlZHBva2xhZCByb3ZuYWtvc3RpIHZhcmlhbmNpZS4gTmV2eXNreXR1amUgc2Egxb5pYWRueSBsaWV2aWtvdml0w70gdHZhciwga3RvcsO9IGJ5IHNpZ25hbGl6b3ZhbCBoZXRlcm9za2VkYXN0aWNpdHUuCgojIyBSZXNpZHVhbHMgdnMgTGV2ZXJhZ2U6ClbDpMSNxaFpbmEgcG96b3JvdmFuw60gbcOhIG7DrXpreSBww6Frb3bDvSBlZmVrdCBhIG5hY2jDoWR6YSBzYSB2IGJlenBlxI1ub20gcm96bWVkesOtIENvb2tvdmVqIHZ6ZGlhbGVub3N0aS4gTGVuIG5pZWtvxL5rbyBib2RvdiAobmFwci4gb3puYcSNZW7DqSDEjcOtc2xhbWkgMTQwOCwgODc0OCwgMjAyODApIG3DoSBtaWVybmUgdnnFocWhw60gdnBseXYsIG5vIMW+aWFkbnkgeiBuaWNoIHbDvXJhem5lIG5lcHJlc2FodWplIGhyYW5pY2UgQ29va292ZWogdnpkaWFsZW5vc3RpLiBUbyB6bmFtZW7DoSwgxb5lIHYgc8O6Ym9yZSBzYSBuZW5hY2jDoWR6YWrDuiBwb3pvcm92YW5pYSwga3RvcsOpIGJ5IG5lcHJpbWVyYW5lIG92cGx5dsWIb3ZhbGkgb2RoYWR5IHJlZ3Jlc27DvWNoIGtvZWZpY2llbnRvdi4KCkNlbGtvdm8gZGlhZ25vc3RpY2vDqSBncmFmeSBwb3R2cmR6dWrDuiwgxb5lIGxpbmXDoXJueSBtb2RlbCBqZSB2aG9kbmUgxaFwZWNpZmlrb3ZhbsO9LCBzcMS6xYhhIHrDoWtsYWRuw6kgcHJlZHBva2xhZHkgT0xTIGEgbmV2eWthenVqZSB6w6F2YcW+bsOpIHBvcnXFoWVuaWEgbGluZWFyaXR5LCBub3JtYWxpdHkgYW5pIGhvbW9za2VkYXN0aWNpdHkuCmBgYHtyfQojIG5vcm1hbGl0eSB0ZXN0cwpyZXNpZHVhbHMgPC0gcmVzaWR1YWxzKG1vZGVsKQpqYl90ZXN0IDwtIGphcnF1ZS5iZXJhLnRlc3QocmVzaWR1YWxzKQpqYl90ZXN0CiMgb3V0bGllciB0ZXN0IChzZWUgcC12YWx1ZSBmb3IgQm9uZmVycm9uaSBjb3JyZWN0aW9uKQpvdXRsaWVyX3Rlc3QgPC0gb3V0bGllclRlc3QobW9kZWwpCm91dGxpZXJfdGVzdApgYGAKUmV6w61kdcOhIHPDuiBwcmlibGnFvm5lIG5vcm3DoWxuZSByb3pkZWxlbsOpLCBiZXogdsO9cmF6bsO9Y2ggb2TEvmFobMO9Y2ggaG9kbsO0dC4KTW9kZWwgcHJldG8gc3DEusWIYSBwcmVkcG9rbGFkeSBPTFMgYSBuaWUgamUgcG90cmVibsOpIMW+aWFkbmUgZG9kYXRvxI1uw6kgxI1pc3RlbmllIGFuaSB0cmFuc2Zvcm3DoWNpYSDDumRham92LgoKIyMgWsOhdmVyClbDvXNsZWRreSBsaW5lw6FybmVobyByZWdyZXNuw6lobyBtb2RlbHUgcG90dnJkaWxpLCDFvmUgdsWhZXRreSB0cmkgc2vDum1hbsOpIHByZW1lbm7DqSDigJMgTG9nIEdEUCBwZXIgY2FwaXRhLCBTb2NpYWwgc3VwcG9ydCBhIEZyZWVkb20gdG8gbWFrZSBsaWZlIGNob2ljZXMg4oCTIG1hasO6IHBveml0w612bnkgYSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSB2cGx5diBuYSBpbmRleCDFocWlYXN0aWEgKExpZmUgTGFkZGVyKS4gVG8gem5hbWVuw6EsIMW+ZSBrcmFqaW55IHMgdnnFocWhb3UgZWtvbm9taWNrb3Ugw7pyb3bFiG91LCBzaWxuZWrFocOtbWkgc29jacOhbG55bWkgdsOkemJhbWkgYSB2w6TEjcWhb3Ugc2xvYm9kb3Ugcm96aG9kb3ZhbmlhIHZ5a2F6dWrDuiB2IHByaWVtZXJlIHZ5xaHFoWl1IMO6cm92ZcWIIHN1Ympla3TDrXZuZWhvIMWhxaVhc3RpYSBvYnl2YXRlxL5vdi4KCktvZWZpY2llbnQgZGV0ZXJtaW7DoWNpZSBSwrIgPSAwLjcxNTUgdWthenVqZSwgxb5lIG1vZGVsIHZ5c3ZldMS+dWplIHByaWJsacW+bmUgNzEsNSAlIHZhcmlhYmlsaXR5IGluZGV4dSDFocWlYXN0aWEsIMSNbyBwcmVkc3RhdnVqZSB2ZcS+bWkgZG9icsO6IG1pZXJ1IHZ5c3ZldMS+dWrDumNlaiBzY2hvcG5vc3RpIG1vZGVsdS4gRi3FoXRhdGlzdGlrYSAoRiA9IDE2OTM7IHAgPCAyLjJl4oiSMTYpIHBvdHZyZHp1amUsIMW+ZSBtb2RlbCBha28gY2Vsb2sgamUgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70sIHRlZGEgYXNwb8WIIGplZG5hIHogdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBtw6EgbmVudWxvdsO9IHZwbHl2IG5hIMWhxaVhc3RpZS4KCkRpYWdub3N0aWNrw6kgZ3JhZnkgdWvDoXphbGksIMW+ZSByZXrDrWR1w6Egc8O6IHJvdm5vbWVybmUgcm96bG/FvmVuw6kgb2tvbG8gbnVsb3ZlaiBvc2kgYSBuZXByZWphdnVqZSBzYSDFvmlhZG5lIHN5c3RlbWF0aWNrw6kgc2tyZXNsZW5pZS4gxIxlcnZlbsOhIExPRVNTIMSNaWFyYSB2IGdyYWZlIFJlc2lkdWFscyB2cyBGaXR0ZWQgamUgdGFrbWVyIHZvZG9yb3Zuw6EsIMSNbyBuYXpuYcSNdWplIHNwbG5lbmllIHByZWRwb2tsYWR1IGxpbmVhcml0eS4gU2NhbGXigJNMb2NhdGlvbiBwbG90IHBvdHZyZGlsIGtvbsWhdGFudG7DuiB2YXJpYW5jaXUgcmV6w61kdcOtLCB0ZWRhIG1vZGVsIG5lcG9ydcWhdWplIHByZWRwb2tsYWQgaG9tb3NrZWRhc3RpY2l0eS4KClYgZ3JhZmUgUeKAk1EgUmVzaWR1YWxzIGJvZHkgbGXFvmlhIHByZXZhxb5uZSBuYSBkaWFnb27DoWxlLCDEjW8gem5hbWVuw6EsIMW+ZSByb3pkZWxlbmllIHJlesOtZHXDrSBqZSBwcmlibGnFvm5lIG5vcm3DoWxuZS4gTWVuxaFpZSBvZGNow71sa3kgbmEga29uY29jaCBncmFmdSBzw7ogemFuZWRiYXRlxL5uw6kgdnpoxL5hZG9tIG5hIHZlxL5rb3PFpSB2em9ya3kuIFJlc2lkdWFscyB2cyBMZXZlcmFnZSB1a8OhemFsLCDFvmUgxb5pYWRuZSBwb3pvcm92YW5pZSBuZW3DoSBleHRyw6ltbnkgcMOha292w70gZWZla3QgYW5pIHbDvXJhem7DvSB2cGx5diBuYSBvZGhhZHkga29lZmljaWVudG92LgoKT3V0bGllciB0ZXN0IChjYXI6Om91dGxpZXJUZXN0KSBpZGVudGlmaWtvdmFsIGplZG5vIHBvem9yb3ZhbmllICjEjS4gMjIxKSBzIGhvZG5vdG91IMWhdHVkZW50aXpvdmFuw6lobyByZXrDrWR1YSAtMy44MiwgYWxlIHBvIEJvbmZlcnJvbmlobyBrb3Jla2NpaSAocCA9IDAuMjc2Nikgc2EgdWvDoXphbG8sIMW+ZSB0b3RvIHBvem9yb3ZhbmllIG5pZSBqZSDFoXRhdGlzdGlja3kgdsO9em5hbW7DqSwgdGFrxb5lIG1vZGVsIG5pZSBqZSBvdnBseXZuZW7DvSBvZMS+YWhsw71taSBib2RtaS4KClBvdHZyZGVuaWUgaHlwb3TDqXoKCkxvZyBHRFAgcGVyIGNhcGl0YSDigJMgb8SNYWvDoXZhbCBzYSBwb3ppdMOtdm55IHZwbHl2ICh2ecWhxaHDrSBIRFAg4oaSIHZ5xaHFoWlhIHNwb2tvam5vc8WlKS4gS29lZmljaWVudCAoMC41MDY3KSBqZSBrbGFkbsO9IGEgxaF0YXRpc3RpY2t5IHbDvXpuYW1uw70gKHAgPCAwLjAwMSksIMSNw61tIHNhIGh5cG90w6l6YSBwb3R2cmR6dWplLgoKU29jaWFsIHN1cHBvcnQg4oCTIG/EjWFrw6F2YWwgc2EgcG96aXTDrXZueSB2cGx5diAoc2lsbmVqxaFpZSBzb2Npw6FsbmUgdsOkemJ5IOKGkiB2ecWhxaFpYSBzcG9rb2pub3PFpSkuIEtvZWZpY2llbnQgKDIuNDUyMykgamUga2xhZG7DvSBhIMWhdGF0aXN0aWNreSB2w716bmFtbsO9IChwIDwgMC4wMDEpLCB0ZWRhIGh5cG90w6l6YSBzYSBwb3R2cmR6dWplLgoKRnJlZWRvbSB0byBtYWtlIGxpZmUgY2hvaWNlcyDigJMgb8SNYWvDoXZhbCBzYSBwb3ppdMOtdm55IHZwbHl2ICh2w6TEjcWhaWEgc2xvYm9kYSDihpIgdnnFocWhaWEgc3Bva29qbm9zxaUpLiBLb2VmaWNpZW50ICgxLjg2NTUpIGplIGtsYWRuw70gYSDFoXRhdGlzdGlja3kgdsO9em5hbW7DvSAocCA8IDAuMDAxKSwgcHJldG8gYWogdMOhdG8gaHlwb3TDqXphIHNhIHBvdHZyZHp1amUuCgpDZWxrb3ZvIG1vxb5ubyBrb27FoXRhdG92YcWlLCDFvmUgbW9kZWwgc3DEusWIYSB2xaFldGt5IHrDoWtsYWRuw6kgcHJlZHBva2xhZHkgbGluZcOhcm5laiByZWdyZXNpZSwgbmV2eWthenVqZSBoZXRlcm9za2VkYXN0aWNpdHUgYW5pIHbDvXJhem7DqSBuZWxpbmVhcml0eS4gVsWhZXRreSBvxI1ha8OhdmFuaWEgYm9saSBuYXBsbmVuw6kg4oCTIHZ5xaHFocOtIHByw61qZW0sIHNpbG5lasWhaWUgc29jacOhbG5lIHbDpHpieSBhIHbDpMSNxaFpYSBzbG9ib2RhIHJvemhvZG92YW5pYSB2w716bmFtbmUgenZ5xaF1asO6IHN1Ympla3TDrXZuZSBwcmXFvsOtdmFuw6kgxaHFpWFzdGllIG9ieXZhdGXEvm92LiBNb2RlbCBqZSBwcmV0byDFoXRhdGlzdGlja3kgc3BvxL5haGxpdsO9LCBla29ub21pY2t5IGludGVycHJldG92YXRlxL5uw70gYSBwb2Rwb3J1amUgcMO0dm9kbmUgc3Rhbm92ZW7DqSBoeXBvdMOpenkuCgojIyBIZXRlcm9za2VkYXN0aWNpdGEKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQoKIyBSZXrDrWR1w6EgeiBtb2RlbHUKcmVzaWRfc3EgPC0gcmVzaWQobW9kZWwpXjIKCiMgR3JhZnkKcDEgPC0gZ2dwbG90KG1vZGVsX2RhdGEsIGFlcyh4ID0gTG9nLkdEUC5wZXIuY2FwaXRhLCB5ID0gcmVzaWRfc3EpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiTG9nIEdEUCBwZXIgY2FwaXRhIiwgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsIHRpdGxlID0gIlJlc2lkdWFscyB2cyBMb2cgR0RQIikgKwogIHRoZW1lX21pbmltYWwoKQoKcDIgPC0gZ2dwbG90KG1vZGVsX2RhdGEsIGFlcyh4ID0gU29jaWFsLnN1cHBvcnQsIHkgPSByZXNpZF9zcSkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJTb2NpYWwgc3VwcG9ydCIsIHkgPSAiU3F1YXJlZCBSZXNpZHVhbHMiLCB0aXRsZSA9ICJSZXNpZHVhbHMgdnMgU29jaWFsIHN1cHBvcnQiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMyA8LSBnZ3Bsb3QobW9kZWxfZGF0YSwgYWVzKHggPSBGcmVlZG9tLnRvLm1ha2UubGlmZS5jaG9pY2VzLCB5ID0gcmVzaWRfc3EpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiRnJlZWRvbSIsIHkgPSAiU3F1YXJlZCBSZXNpZHVhbHMiLCB0aXRsZSA9ICJSZXNpZHVhbHMgdnMgRnJlZWRvbSIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgWm9icmF6ZW5pZSB2ZWTEvmEgc2ViYQoocDEgfCBwMikgLyBwMwpgYGAKIyMgU2vDum1hbmllIGhldGVyb3NrZWRhc3RpY2l0eSDigJMgdml6dcOhbG5hIGtvbnRyb2xhCgpOYSBvYnLDoXprdSB2ecWhxaFpZSBzw7ogem9icmF6ZW7DqSBncmFmeSB6w6F2aXNsb3N0aSDFoXR2b3Jjb3YgcmV6w61kdcOtIG9kIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2g6CgotICoqUmVzaWR1YWxzIHZzIExvZyBHRFAgcGVyIGNhcGl0YSoqCi0gKipSZXNpZHVhbHMgdnMgU29jaWFsIHN1cHBvcnQqKgotICoqUmVzaWR1YWxzIHZzIEZyZWVkb20gdG8gbWFrZSBsaWZlIGNob2ljZXMqKgoKxIxlcnZlbsOhIGtyaXZrYSBqZSB2byB2xaFldGvDvWNoIHByw61wYWRvY2ggdGFrbWVyIHZvZG9yb3Zuw6EsIGJleiB2w71yYXpuw6lobyB0cmVuZHUuIFJvenB0eWwgcmV6w61kdcOtIHNhIG5lbWVuw60gc3lzdGVtYXRpY2t5IHMgaG9kbm90YW1pIHZ5c3ZldMS+dWrDumNpY2ggcHJlbWVubsO9Y2guIE5hIHrDoWtsYWRlIHZpenXDoWxuZWoga29udHJvbHkgKipwcmVkcG9rbGFkw6FtZSwgxb5lIGhldGVyb3NrZWRhc3RpY2l0YSBuaWUgamUgcHLDrXRvbW7DoSoqLgoKUHJlIHBvdHZyZGVuaWUgdG9odG8gcHJlZHBva2xhZHUgdsWhYWsgdnlrb27DoW1lIMWhdGF0aXN0aWNrw70gdGVzdCDigJMgKipCcmV1c2No4oCTUGFnYW4gdGVzdCoqLgoKYGBge3J9CmxpYnJhcnkobG10ZXN0KQpicHRlc3QobW9kZWwpCmBgYAojIyBTa8O6bWFuaWUgaGV0ZXJvc2tlZGFzdGljaXR5IOKAkyBvcGlzCktlxI/FvmUgcC1ob2Rub3RhIDwgMC4wNSwgemFtaWV0YW1lIG51bG92w7ogaHlwb3TDqXp1IG8gaG9tb3NrZWRhc3RpY2l0ZS4gVG8gem5hbWVuw6EsIMW+ZSB2IG5hxaFvbSBtb2RlbGkgamUgcHLDrXRvbW7DoSBoZXRlcm9za2VkYXN0aWNpdGEuIFYgZMO0c2xlZGt1IHRvaG8gc8O6IMWhdGFuZGFyZG7DqSBjaHlieSBvZGhhZG92IGtvZWZpY2llbnRvdiBuZXNwb8S+YWhsaXbDqSwgxI1vIG3DtMW+ZSB2aWVzxaUgayBuZXNwcsOhdm5lbXUgdnlob2Rub2NvdmFuaXUgdC10ZXN0b3YuCiMjIFNrw7ptYW5pZSBoZXRlcm9za2VkYXN0aWNpdHkgLSBXaGl0ZSBoZXRlcm9za2VkYXN0aWNpdHktY29uc2lzdGVudCBvZGhhZG92IHJvenB0eWxvdiAocm9idXN0bsOpIMWhdGFuZGFyZG7DqSBjaHlieSkKCmBgYHtyfQojIEluxaF0YWzDoWNpYSBiYWzDrWtvdgojIGluc3RhbGwucGFja2FnZXMoInNhbmR3aWNoIikKIyBpbnN0YWxsLnBhY2thZ2VzKCJsbXRlc3QiKQoKIyBOYcSNw610YW5pZSBiYWzDrWtvdgpsaWJyYXJ5KHNhbmR3aWNoKQpsaWJyYXJ5KGxtdGVzdCkKCiMgUm9idXN0bsOpIMWhdGFuZGFyZG7DqSBjaHlieSAoV2hpdGUgSEMxKQpjb2VmdGVzdChtb2RlbCwgdmNvdiA9IHZjb3ZIQyhtb2RlbCwgdHlwZSA9ICJIQzEiKSkKYGBgCgpgYGB7cn0KIyBLb2VmaWNpZW50eSBzYSBuZXptZW5pbGkgKHJvdm5ha8OpIGFrbyB2IHDDtHZvZG5vbSBtb2RlbGkpLiDFoHRhbmRhcmRuw6kgY2h5Ynkgc8O6IHbDpMSNxaFpZSBuZcW+IHYga2xhc2lja29tIE9MUywgxI1vIGplIG/EjWFrw6F2YW7DqSwgcHJldG/FvmUgc8O6IOKAnmhydWLFoWll4oCcIGEga29yaWd1asO6IGhldGVyb3NrZWRhc3RpY2l0dS4gVsWhZXRreSBwcmVtZW5uw6kgem9zdMOhdmFqw7ogxaF0YXRpc3RpY2t5IHbDvXpuYW1uw6kgKHAgPCAwLjAwMSkuIFJvYnVzdG7DqSBvZGhhZHkgemFiZXpwZcSNdWrDuiBzcHLDoXZuZSB0LXRlc3R5IGFqIHByaSBwcsOtdG9tbm9zdGkgaGV0ZXJvc2tlZGFzdGljaXR5LiBNb2RlbCBqZSBwbyDDunByYXZlIHJvYnVzdG7DvSB2b8SNaSBoZXRlcm9za2VkYXN0aWNpdGUgYSBwb3R2cmR6dWplIHDDtHZvZG7DqSB6w6F2ZXJ5OiB2ecWhxaHDrSBIRFAsIHNpbG5lasWhaWEgc29jacOhbG5hIHBvZHBvcmEgYSB2w6TEjcWhaWEgc2xvYm9kYSByb3pob2RvdmFuaWEgdsO9em5hbW5lIHp2ecWhdWrDuiBpbmRleCDFocWlYXN0aWEuCmBgYAoKIyMgUG9yb3ZuYW5pZQoKYGBge3J9CiMgTmHEjcOtdGFuaWUgcG90cmVibsO9Y2ggYmFsw61rb3YKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoc2FuZHdpY2gpCgojIFJvYnVzdG7DqSDFoXRhbmRhcmRuw6kgY2h5YnkgKFdoaXRlIEhDMSkKcm9idXN0X3Jlc3VsdHMgPC0gY29lZnRlc3QobW9kZWwsIHZjb3YgPSB2Y292SEMobW9kZWwsIHR5cGUgPSAiSEMxIikpCnByaW50KHJvYnVzdF9yZXN1bHRzKQoKIyBQb3Jvdm5hbmllIHDDtHZvZG7DvWNoIHZzIHJvYnVzdG7DvWNoIMWhdGFuZGFyZG7DvWNoIGNow71iCm9yaWdpbmFsIDwtIHN1bW1hcnkobW9kZWwpJGNvZWZmaWNpZW50cwpjb21wYXJpc29uIDwtIGNiaW5kKAogIEVzdGltYXRlID0gb3JpZ2luYWxbLCAxXSwKICBPTFNfU3RkX0Vycm9yID0gb3JpZ2luYWxbLCAyXSwKICBSb2J1c3RfU3RkX0Vycm9yID0gcm9idXN0X3Jlc3VsdHNbLCAyXQopCnByaW50KGNvbXBhcmlzb24pCmBgYAoKYGBge3J9CiMgTmEgesOha2xhZGUgdMO9Y2h0byB2w71zbGVka292IHNvbSBzYSByb3pob2RvbCBvIHZ5dHZvcmVuaWUgbm92w6lobyBtb2RlbHUgc28gemxvZ2FyaXRtaXpvdmFuw71taSB2xaFldGvDvW1pIHByZW1lbm7DvW1pCmBgYAoKIyMgVnl0dm9yZW5pZSBub3bDqWhvIG1vZGVsdQoKYGBge3J9CiMgVnl0dm9yZW5pZSBub3bDvWNoIHByZW1lbm7DvWNoCm1vZGVsX2RhdGEkbG9nX1NvY2lhbC5zdXBwb3J0IDwtIGxvZyhtb2RlbF9kYXRhJFNvY2lhbC5zdXBwb3J0KQptb2RlbF9kYXRhJGxvZ19GcmVlZG9tIDwtIGxvZyhtb2RlbF9kYXRhJEZyZWVkb20udG8ubWFrZS5saWZlLmNob2ljZXMpCgojIE5vdsO9IG1vZGVsCm1vZGVsX2xvZyA8LSBsbShMaWZlLkxhZGRlciB+IExvZy5HRFAucGVyLmNhcGl0YSArIGxvZ19Tb2NpYWwuc3VwcG9ydCArIGxvZ19GcmVlZG9tLAogICAgICAgICAgICAgICAgZGF0YSA9IG1vZGVsX2RhdGEpCgojIFbDvXNsZWRreQpzdW1tYXJ5KG1vZGVsX2xvZykKYGBgCgojIyBWaXp1w6FsbmEga29udHJvbGEgbm92w6lobyBtb2RlbHUKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspCgpyZXNpZF9zcV9sb2cgPC0gcmVzaWQobW9kZWxfbG9nKV4yCgpwMSA8LSBnZ3Bsb3QobW9kZWxfZGF0YSwgYWVzKHggPSBMb2cuR0RQLnBlci5jYXBpdGEsIHkgPSByZXNpZF9zcV9sb2cpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIpICsKICBsYWJzKHggPSAiTG9nIEdEUCBwZXIgY2FwaXRhIiwgeSA9ICJTcXVhcmVkIFJlc2lkdWFscyIsIHRpdGxlID0gIlJlc2lkdWFscyB2cyBMb2cgR0RQIikgKwogIHRoZW1lX21pbmltYWwoKQoKcDIgPC0gZ2dwbG90KG1vZGVsX2RhdGEsIGFlcyh4ID0gbG9nX1NvY2lhbC5zdXBwb3J0LCB5ID0gcmVzaWRfc3FfbG9nKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicyh4ID0gImxvZyhTb2NpYWwgc3VwcG9ydCkiLCB5ID0gIlNxdWFyZWQgUmVzaWR1YWxzIiwgdGl0bGUgPSAiUmVzaWR1YWxzIHZzIGxvZyhTb2NpYWwgc3VwcG9ydCkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMyA8LSBnZ3Bsb3QobW9kZWxfZGF0YSwgYWVzKHggPSBsb2dfRnJlZWRvbSwgeSA9IHJlc2lkX3NxX2xvZykpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxvZXNzIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoeCA9ICJsb2coRnJlZWRvbSkiLCB5ID0gIlNxdWFyZWQgUmVzaWR1YWxzIiwgdGl0bGUgPSAiUmVzaWR1YWxzIHZzIGxvZyhGcmVlZG9tKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCihwMSB8IHAyKSAvIHAzCmBgYAoKIyMgU2vDum1hbmllIGhldGVyb3NrZWRhc3RpY2l0eSBwbyBsb2dhcml0bWl6w6FjaWkgcHJlbWVubsO9Y2gKCk5hIG9icsOhemt1IHPDuiB6b2JyYXplbsOpIGdyYWZ5IHrDoXZpc2xvc3RpIMWhdHZvcmNvdiByZXrDrWR1w60gb2QgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaCBwbyBsb2dhcml0bWl6w6FjaWkgU29jaWFsIHN1cHBvcnQgYSBGcmVlZG9tIHRvIG1ha2UgbGlmZSBjaG9pY2VzLiDEjGVydmVuw6EgTE9FU1Mga3JpdmthIHVrYXp1amUsIMW+ZSByb3pwdHlsIHJlesOtZHXDrSBzYSBzdMOhbGUgbWVuw60gcyBob2Rub3RhbWkgdnlzdmV0xL51asO6Y2ljaCBwcmVtZW5uw71jaDoKCi0gUHJpIExvZyBHRFAgcGVyIGNhcGl0YSBqZSByb3pwdHlsIHbDvXJhem5lIGtsZXNhasO6Y2kuCi0gUHJpIGxvZyhTb2NpYWwgc3VwcG9ydCkgamUgcm96cHR5bCB2w71yYXpuZSBrbGVzYWrDumNpLgotIFByaSBsb2coRnJlZWRvbSkgamUgcm96cHR5bCB0YWt0aWXFviB2w71yYXpuZSBrbGVzYWrDumNpLgpWxaFldGt5IGtsZXNhasO6Y2UgdHJlbmR5IHbFoWFrIG5hc3TDoXZhasO6IG5hIMS+YXZlaiBzdHJhbmUgZ3JhZnUuCgojIyMgWsOhdmVyOgoKTG9nYXJpdG1pesOhY2lhIHByZW1lbm7DvWNoICoqbmV6bGVwxaFpbGEgc2l0dcOhY2l1KiouIEhldGVyb3NrZWRhc3RpY2l0YSBqZSBzdMOhbGUgcHLDrXRvbW7DoSwgcHJldG8gem9zdMOhdmFtZSBwcmkgcMO0dm9kbm9tIG1vZGVsaSBhIHBvdcW+w612YW1lIHJvYnVzdG7DqSDFoXRhbmRhcmRuw6kgY2h5YnkgYSBww7R2b2Ruw70gbW9kZWwgKFdoaXRlIEhDMSkgbmEga29yZWtjaXUgaGV0ZXJvc2tlZGFzdGljaXR5LgoKCgo=