1 Dados dos municípios

data = read.csv("https://hedibert.org/wp-content/uploads/2024/05/eleicoes-presidenciais-2022.csv")
data = data[!is.na(data[,4]),]

head(data)
##   code_muni             name_muni abbrev_state eleitores prop_Lula    prop_B
## 1   1100015 Alta Floresta D'oeste           RO     19397 0.2898382 0.6585508
## 2   1100023             Ariquemes           RO     69761 0.2097480 0.7352028
## 3   1100031                Cabixi           RO      4781 0.3231863 0.6275960
## 4   1100049                Cacoal           RO     66497 0.2403642 0.6954839
## 5   1100056            Cerejeiras           RO     12930 0.1993061 0.7473212
## 6   1100064     Colorado Do Oeste           RO     13741 0.2610487 0.6819821
##   prop_abstencoes
## 1       0.2739083
## 2       0.2623816
## 3       0.2486927
## 4       0.2317849
## 5       0.2240526
## 6       0.2735609

1.1 Análise exploratória de dados

lulaSP    = data[data[,3]=="SP",5]
lulaBA    = data[data[,3]=="BA",5]
lulaSPBA  = c(lulaSP,lulaBA)
lulaBR    = data[,5]

plot(density(lulaSP),xlim=c(0,1),ylim=c(0,6),lwd=2,xlab="Prop. votos para Lula nos municipios",main="")
lines(density(lulaBA),col=2,lwd=2)
lines(density(lulaSPBA),col=3,lwd=2)
lines(density(lulaBR),col=4,lwd=2)
abline(v=0.5,lty=2)
legend("topleft",legend=c("SP","BA","SP+BA","BR"),col=1:4,lty=1,bty="n",lwd=2)

hist(lulaBR,xlim=c(0,1),prob=TRUE,xlab="Prop. votos para Lula nos municipios",main="",col=grey(0.8),ylab="Densidade")
theta = seq(0,1,length=1000)
lines(density(lulaBR),lwd=3)
lines(theta,0.525*dbeta(theta,7.5,10.5)+0.475*dbeta(theta,10,4),lwd=3,col=2)
legend("topleft",legend=c("Prop. Lula","Estimação de densidade","Mixtura of Betas"),col=c(grey(0.7),1,2),lwd=2,lty=1,bty="n")
title("0.525Beta(7.5,10.5)+0.475Beta(10,4)\n Mode=(0.41,0.75) - StDev=(0.113,0.117)")

1.2 Preparando as covariáveis

n   = nrow(data)
ABS = data[,7]
SP  = rep(0,n)
BA  = rep(0,n)
POP = rep(0,n)
SP[data[,3]=="SP"]=1
BA[data[,3]=="BA"]=1
POP[data[,4]>20000]=1

1.3 Regressão linear Gaussiana

fit.ols = lm(lulaBR ~ ABS+POP+SP+BA)

summary(fit.ols)
## 
## Call:
## lm(formula = lulaBR ~ ABS + POP + SP + BA)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.42608 -0.11898 -0.00976  0.12673  0.38034 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.461867   0.010182  45.360   <2e-16 ***
## ABS          0.458619   0.047353   9.685   <2e-16 ***
## POP         -0.044056   0.005170  -8.521   <2e-16 ***
## SP          -0.162875   0.006969 -23.372   <2e-16 ***
## BA           0.183394   0.008472  21.648   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1635 on 5560 degrees of freedom
## Multiple R-squared:  0.1944, Adjusted R-squared:  0.1938 
## F-statistic: 335.3 on 4 and 5560 DF,  p-value: < 2.2e-16
coef = fit.ols$coef

par(mfrow=c(1,1))
plot(ABS,lulaBR,ylim=c(0,1),xlim=c(0,0.6),ylab="Prop. votos para Lula nos municipios",xlab="Prop. Abstenções")
points(ABS,lm(lulaBR~ABS)$fit,col=8,pch=16)
points(ABS,coef[1]+coef[2]*ABS,col=2,pch=16)
points(ABS,coef[1]+coef[2]*ABS+coef[3],col=3,pch=16)
points(ABS,coef[1]+coef[2]*ABS+coef[4],col=4,pch=16)
points(ABS,coef[1]+coef[2]*ABS+coef[3]+coef[4],col=5,pch=16)
points(ABS,coef[1]+coef[2]*ABS+coef[3]+coef[5],col=6,pch=16)
points(ABS,coef[1]+coef[2]*ABS+coef[5],col=7,pch=16)
legend("bottomright",legend=c("Pop<20mil & BR-SP-BA","Pop>20mil & BR-SP-BA","Pop<20mil & SP","Pop>20mil & SP","Pop>20mil & BA","Pop<20mil & BA"),col=2:7,lwd=2,bty="n",pch=16)
legend("topright",legend="Irrestrito",col=8,lty=1,pch=16,bty="n",lwd=2)
abline(h=0.5,lty=2,lwd=3)
abline(h=0.3,lty=2,lwd=3)
abline(h=0.65,lty=2,lwd=3)
title("Regressão linear Gaussiana")

2 Regressão Beta

Francisco Cribari-Neto & Achim Zelleis, Beta Regression in R. Journal of Statistical Software, 34(2), 1–24. 2010. https://www.jstatsoft.org/article/view/v034i02

# install.packages("betareg")
library("betareg")

fit.beta0 = betareg(lulaBR ~ ABS,link="logit")
fit.beta  = betareg(lulaBR ~ ABS+POP+SP+BA,link="logit")
summary(fit.beta0)
## 
## Call:
## betareg(formula = lulaBR ~ ABS, link = "logit")
## 
## Standardized weighted residuals 2:
##     Min      1Q  Median      3Q     Max 
## -2.7407 -0.7812 -0.1275  0.8108  2.7350 
## 
## Coefficients (mean model with logit link):
##             Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -0.17593    0.04391  -4.007 6.16e-05 ***
## ABS          1.68106    0.20180   8.330  < 2e-16 ***
## 
## Phi coefficients (precision model with identity link):
##       Estimate Std. Error z value Pr(>|z|)    
## (phi)    6.925      0.123   56.32   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 
## 
## Type of estimator: ML (maximum likelihood)
## Log-likelihood:  1848 on 3 Df
## Pseudo R-squared: 0.01281
## Number of iterations: 10 (BFGS) + 2 (Fisher scoring)
summary(fit.beta)
## 
## Call:
## betareg(formula = lulaBR ~ ABS + POP + SP + BA, link = "logit")
## 
## Standardized weighted residuals 2:
##     Min      1Q  Median      3Q     Max 
## -3.1300 -0.6946 -0.0876  0.7005  2.9513 
## 
## Coefficients (mean model with logit link):
##             Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -0.13875    0.04096  -3.388 0.000705 ***
## ABS          1.81096    0.19100   9.481  < 2e-16 ***
## POP         -0.17760    0.02079  -8.541  < 2e-16 ***
## SP          -0.62518    0.02818 -22.183  < 2e-16 ***
## BA           0.71528    0.03624  19.735  < 2e-16 ***
## 
## Phi coefficients (precision model with identity link):
##       Estimate Std. Error z value Pr(>|z|)    
## (phi)   8.3691     0.1504   55.66   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 
## 
## Type of estimator: ML (maximum likelihood)
## Log-likelihood:  2371 on 6 Df
## Pseudo R-squared: 0.1875
## Number of iterations: 13 (BFGS) + 2 (Fisher scoring)
coef0 = fit.beta0$coef$mean
coef = fit.beta$coef$mean

plot(ABS,lulaBR,ylim=c(0,1),xlim=c(0,0.6),ylab="Prop. votos para Lula nos municipios",xlab="Prop. Abstenções")
eta = coef0[1]+coef0[2]*ABS
points(ABS,1/(1+exp(-eta)),col=8)
eta = coef[1]+coef[2]*ABS
points(ABS,1/(1+exp(-eta)),col=2)
eta = coef[1]+coef[2]*ABS+coef[3]
points(ABS,1/(1+exp(-eta)),col=3)
eta = coef[1]+coef[2]*ABS+coef[4]
points(ABS,1/(1+exp(-eta)),col=4)
eta = coef[1]+coef[2]*ABS+coef[3]+coef[4]
points(ABS,1/(1+exp(-eta)),col=5)
eta = coef[1]+coef[2]*ABS+coef[3]+coef[5]
points(ABS,1/(1+exp(-eta)),col=6)
eta = coef[1]+coef[2]*ABS+coef[5]
points(ABS,1/(1+exp(-eta)),col=7)
legend("bottomright",legend=c("Pop<20mil & BR-SP-BA","Pop>20mil & BR-SP-BA",
       "Pop<20mil & SP","Pop>20mil & SP","Pop>20mil & BA","Pop<20mil & BA",
       "Irrestrito"),col=2:8,lwd=2,bty="n",pch=16)
abline(h=0.5,lty=2,lwd=3)
abline(h=0.3,lty=2,lwd=3)
abline(h=0.65,lty=2,lwd=3)
title("Regressão Beta")

3 Regressão Beta Bayesiana

Abaixo usamos o pacote betaBayes: Bayesian Beta Regression, Zhou and Huang (2022) doi:10.1016/j.csda.2021.107345

#install.packages("betaBayes")
library("betaBayes")

fit.bbeta0 = beta4reg(lulaBR ~ ABS,link="logit",model="mean",mcmc=list(nburn=5000, nsave=5000, nskip=0, ndisplay=1000))
## scan = 1000
## scan = 2000
## scan = 3000
## scan = 4000
## scan = 5000
coef0 = fit.bbeta0$coef[1:2]
eta0  = coef0[1]+coef0[2]*ABS
eta0  = 1/(1+exp(-eta0))

fit.bbeta = beta4reg(lulaBR ~ ABS+POP+SP+BA,link="logit",model="mean",mcmc=list(nburn=5000, nsave=5000, nskip=0, ndisplay=1000))
## scan = 1000
## scan = 2000
## scan = 3000
## scan = 4000
## scan = 5000
coef = fit.bbeta$coef[1:5]

3.1 Amostras da posteriori

betas = fit.bbeta$beta
namecoef = c("Intercepto","Abstenções","POP>20mil","SP","BA")
par(mfrow=c(3,5))
for (i in 1:5)
  ts.plot(betas[i,],xlab="Iteration",ylab="",main=namecoef[i])
for (i in 1:5)
  acf(betas[i,],main="")
for (i in 1:5)
  hist(betas[i,],prob=TRUE,xlab="",main="")

3.2 Explorando a posteriori

par(mfrow=c(1,1))
plot(ABS,lulaBR,ylim=c(0,1),xlim=c(0,0.6),ylab="Prop. votos para Lula nos municipios",xlab="Prop. Abstenções")
points(ABS,eta0,col=8)
eta = coef[1]+coef[2]*ABS
points(ABS,1/(1+exp(-eta)),col=2)
eta = coef[1]+coef[2]*ABS+coef[3]
points(ABS,1/(1+exp(-eta)),col=3)
eta = coef[1]+coef[2]*ABS+coef[4]
points(ABS,1/(1+exp(-eta)),col=4)
eta = coef[1]+coef[2]*ABS+coef[3]+coef[4]
points(ABS,1/(1+exp(-eta)),col=5)
eta = coef[1]+coef[2]*ABS+coef[3]+coef[5]
points(ABS,1/(1+exp(-eta)),col=6)
eta = coef[1]+coef[2]*ABS+coef[5]
points(ABS,1/(1+exp(-eta)),col=7)
legend("bottomright",legend=c("Pop<20mil & BR-SP-BA","Pop>20mil & BR-SP-BA",
       "Pop<20mil & SP","Pop>20mil & SP","Pop>20mil & BA","Pop<20mil & BA",
       "Irrestrito"),col=2:8,lwd=2,bty="n",pch=16)
abline(h=0.5,lty=2,lwd=3)
abline(h=0.3,lty=2,lwd=3)
abline(h=0.65,lty=2,lwd=3)
title("Regressão Beta Bayesiana")

3.3 Mais posteriori

par(mfrow=c(1,1))
plot(density(1/(1+exp(-betas[1,]))),col=2,xlim=c(0,1),ylim=c(0,40),lwd=2,ylab="Densidade",
main="Intercepto para os diferentes grupos",xlab="Prop. votos para Lula nos municipios")
lines(density(1/(1+exp(-betas[1,]-betas[3,]))),col=3,lwd=2)
lines(density(1/(1+exp(-betas[1,]-betas[4,]))),col=4,lwd=2)
lines(density(1/(1+exp(-betas[1,]-betas[3,]-betas[4,]))),col=5,lwd=2)
lines(density(1/(1+exp(-betas[1,]-betas[3,]-betas[5,]))),col=6,lwd=2)
lines(density(1/(1+exp(-betas[1,]-betas[5,]))),col=7,lwd=2)
legend("topright",legend=c("Pop<20mil & BR-SP-BA","Pop>20mil & BR-SP-BA",
       "Pop<20mil & SP","Pop>20mil & SP","Pop>20mil & BA","Pop<20mil & BA"),
       col=2:7,lwd=2,bty="n",pch=16)
abline(v=0.5,lty=2)
abline(v=0.3,lty=2)
abline(v=0.65,lty=2)

LS0tCnRpdGxlOiAiUmVncmVzc8OjbyBCZXRhIgpzdWJ0aXRsZTogIlByb3BvcsOnw6NvIGRlIHZvdG9zIC0gMm8gdHVybm8gMjAyMiIKYXV0aG9yOiAiSGVkaWJlcnQgRnJlaXRhcyBMb3BlcyIKZGF0ZTogIjEwLzI4LzIwMjQiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiAKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogeWVzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKYGBgCgojIERhZG9zIGRvcyBtdW5pY8OtcGlvcwoKYGBge3J9CmRhdGEgPSByZWFkLmNzdigiaHR0cHM6Ly9oZWRpYmVydC5vcmcvd3AtY29udGVudC91cGxvYWRzLzIwMjQvMDUvZWxlaWNvZXMtcHJlc2lkZW5jaWFpcy0yMDIyLmNzdiIpCmRhdGEgPSBkYXRhWyFpcy5uYShkYXRhWyw0XSksXQoKaGVhZChkYXRhKQpgYGAKCiMjIEFuw6FsaXNlIGV4cGxvcmF0w7NyaWEgZGUgZGFkb3MKCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9Cmx1bGFTUCAgICA9IGRhdGFbZGF0YVssM109PSJTUCIsNV0KbHVsYUJBICAgID0gZGF0YVtkYXRhWywzXT09IkJBIiw1XQpsdWxhU1BCQSAgPSBjKGx1bGFTUCxsdWxhQkEpCmx1bGFCUiAgICA9IGRhdGFbLDVdCgpwbG90KGRlbnNpdHkobHVsYVNQKSx4bGltPWMoMCwxKSx5bGltPWMoMCw2KSxsd2Q9Mix4bGFiPSJQcm9wLiB2b3RvcyBwYXJhIEx1bGEgbm9zIG11bmljaXBpb3MiLG1haW49IiIpCmxpbmVzKGRlbnNpdHkobHVsYUJBKSxjb2w9Mixsd2Q9MikKbGluZXMoZGVuc2l0eShsdWxhU1BCQSksY29sPTMsbHdkPTIpCmxpbmVzKGRlbnNpdHkobHVsYUJSKSxjb2w9NCxsd2Q9MikKYWJsaW5lKHY9MC41LGx0eT0yKQpsZWdlbmQoInRvcGxlZnQiLGxlZ2VuZD1jKCJTUCIsIkJBIiwiU1ArQkEiLCJCUiIpLGNvbD0xOjQsbHR5PTEsYnR5PSJuIixsd2Q9MikKCmhpc3QobHVsYUJSLHhsaW09YygwLDEpLHByb2I9VFJVRSx4bGFiPSJQcm9wLiB2b3RvcyBwYXJhIEx1bGEgbm9zIG11bmljaXBpb3MiLG1haW49IiIsY29sPWdyZXkoMC44KSx5bGFiPSJEZW5zaWRhZGUiKQp0aGV0YSA9IHNlcSgwLDEsbGVuZ3RoPTEwMDApCmxpbmVzKGRlbnNpdHkobHVsYUJSKSxsd2Q9MykKbGluZXModGhldGEsMC41MjUqZGJldGEodGhldGEsNy41LDEwLjUpKzAuNDc1KmRiZXRhKHRoZXRhLDEwLDQpLGx3ZD0zLGNvbD0yKQpsZWdlbmQoInRvcGxlZnQiLGxlZ2VuZD1jKCJQcm9wLiBMdWxhIiwiRXN0aW1hw6fDo28gZGUgZGVuc2lkYWRlIiwiTWl4dHVyYSBvZiBCZXRhcyIpLGNvbD1jKGdyZXkoMC43KSwxLDIpLGx3ZD0yLGx0eT0xLGJ0eT0ibiIpCnRpdGxlKCIwLjUyNUJldGEoNy41LDEwLjUpKzAuNDc1QmV0YSgxMCw0KVxuIE1vZGU9KDAuNDEsMC43NSkgLSBTdERldj0oMC4xMTMsMC4xMTcpIikKYGBgCgoKIyMgUHJlcGFyYW5kbyBhcyBjb3ZhcmnDoXZlaXMKCmBgYHtyfQpuICAgPSBucm93KGRhdGEpCkFCUyA9IGRhdGFbLDddClNQICA9IHJlcCgwLG4pCkJBICA9IHJlcCgwLG4pClBPUCA9IHJlcCgwLG4pClNQW2RhdGFbLDNdPT0iU1AiXT0xCkJBW2RhdGFbLDNdPT0iQkEiXT0xClBPUFtkYXRhWyw0XT4yMDAwMF09MQpgYGAKCiMjIFJlZ3Jlc3PDo28gbGluZWFyIEdhdXNzaWFuYQoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KZml0Lm9scyA9IGxtKGx1bGFCUiB+IEFCUytQT1ArU1ArQkEpCgpzdW1tYXJ5KGZpdC5vbHMpCgpjb2VmID0gZml0Lm9scyRjb2VmCgpwYXIobWZyb3c9YygxLDEpKQpwbG90KEFCUyxsdWxhQlIseWxpbT1jKDAsMSkseGxpbT1jKDAsMC42KSx5bGFiPSJQcm9wLiB2b3RvcyBwYXJhIEx1bGEgbm9zIG11bmljaXBpb3MiLHhsYWI9IlByb3AuIEFic3RlbsOnw7VlcyIpCnBvaW50cyhBQlMsbG0obHVsYUJSfkFCUykkZml0LGNvbD04LHBjaD0xNikKcG9pbnRzKEFCUyxjb2VmWzFdK2NvZWZbMl0qQUJTLGNvbD0yLHBjaD0xNikKcG9pbnRzKEFCUyxjb2VmWzFdK2NvZWZbMl0qQUJTK2NvZWZbM10sY29sPTMscGNoPTE2KQpwb2ludHMoQUJTLGNvZWZbMV0rY29lZlsyXSpBQlMrY29lZls0XSxjb2w9NCxwY2g9MTYpCnBvaW50cyhBQlMsY29lZlsxXStjb2VmWzJdKkFCUytjb2VmWzNdK2NvZWZbNF0sY29sPTUscGNoPTE2KQpwb2ludHMoQUJTLGNvZWZbMV0rY29lZlsyXSpBQlMrY29lZlszXStjb2VmWzVdLGNvbD02LHBjaD0xNikKcG9pbnRzKEFCUyxjb2VmWzFdK2NvZWZbMl0qQUJTK2NvZWZbNV0sY29sPTcscGNoPTE2KQpsZWdlbmQoImJvdHRvbXJpZ2h0IixsZWdlbmQ9YygiUG9wPDIwbWlsICYgQlItU1AtQkEiLCJQb3A+MjBtaWwgJiBCUi1TUC1CQSIsIlBvcDwyMG1pbCAmIFNQIiwiUG9wPjIwbWlsICYgU1AiLCJQb3A+MjBtaWwgJiBCQSIsIlBvcDwyMG1pbCAmIEJBIiksY29sPTI6Nyxsd2Q9MixidHk9Im4iLHBjaD0xNikKbGVnZW5kKCJ0b3ByaWdodCIsbGVnZW5kPSJJcnJlc3RyaXRvIixjb2w9OCxsdHk9MSxwY2g9MTYsYnR5PSJuIixsd2Q9MikKYWJsaW5lKGg9MC41LGx0eT0yLGx3ZD0zKQphYmxpbmUoaD0wLjMsbHR5PTIsbHdkPTMpCmFibGluZShoPTAuNjUsbHR5PTIsbHdkPTMpCnRpdGxlKCJSZWdyZXNzw6NvIGxpbmVhciBHYXVzc2lhbmEiKQpgYGAKCiMgUmVncmVzc8OjbyBCZXRhCgpGcmFuY2lzY28gQ3JpYmFyaS1OZXRvICYgQWNoaW0gWmVsbGVpcywgQmV0YSBSZWdyZXNzaW9uIGluIFIuICpKb3VybmFsIG9mIFN0YXRpc3RpY2FsIFNvZnR3YXJlKiwgMzQoMiksIDHigJMyNC4gMjAxMC4KaHR0cHM6Ly93d3cuanN0YXRzb2Z0Lm9yZy9hcnRpY2xlL3ZpZXcvdjAzNGkwMgoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KIyBpbnN0YWxsLnBhY2thZ2VzKCJiZXRhcmVnIikKbGlicmFyeSgiYmV0YXJlZyIpCgpmaXQuYmV0YTAgPSBiZXRhcmVnKGx1bGFCUiB+IEFCUyxsaW5rPSJsb2dpdCIpCmZpdC5iZXRhICA9IGJldGFyZWcobHVsYUJSIH4gQUJTK1BPUCtTUCtCQSxsaW5rPSJsb2dpdCIpCnN1bW1hcnkoZml0LmJldGEwKQpzdW1tYXJ5KGZpdC5iZXRhKQpjb2VmMCA9IGZpdC5iZXRhMCRjb2VmJG1lYW4KY29lZiA9IGZpdC5iZXRhJGNvZWYkbWVhbgoKcGxvdChBQlMsbHVsYUJSLHlsaW09YygwLDEpLHhsaW09YygwLDAuNikseWxhYj0iUHJvcC4gdm90b3MgcGFyYSBMdWxhIG5vcyBtdW5pY2lwaW9zIix4bGFiPSJQcm9wLiBBYnN0ZW7Dp8O1ZXMiKQpldGEgPSBjb2VmMFsxXStjb2VmMFsyXSpBQlMKcG9pbnRzKEFCUywxLygxK2V4cCgtZXRhKSksY29sPTgpCmV0YSA9IGNvZWZbMV0rY29lZlsyXSpBQlMKcG9pbnRzKEFCUywxLygxK2V4cCgtZXRhKSksY29sPTIpCmV0YSA9IGNvZWZbMV0rY29lZlsyXSpBQlMrY29lZlszXQpwb2ludHMoQUJTLDEvKDErZXhwKC1ldGEpKSxjb2w9MykKZXRhID0gY29lZlsxXStjb2VmWzJdKkFCUytjb2VmWzRdCnBvaW50cyhBQlMsMS8oMStleHAoLWV0YSkpLGNvbD00KQpldGEgPSBjb2VmWzFdK2NvZWZbMl0qQUJTK2NvZWZbM10rY29lZls0XQpwb2ludHMoQUJTLDEvKDErZXhwKC1ldGEpKSxjb2w9NSkKZXRhID0gY29lZlsxXStjb2VmWzJdKkFCUytjb2VmWzNdK2NvZWZbNV0KcG9pbnRzKEFCUywxLygxK2V4cCgtZXRhKSksY29sPTYpCmV0YSA9IGNvZWZbMV0rY29lZlsyXSpBQlMrY29lZls1XQpwb2ludHMoQUJTLDEvKDErZXhwKC1ldGEpKSxjb2w9NykKbGVnZW5kKCJib3R0b21yaWdodCIsbGVnZW5kPWMoIlBvcDwyMG1pbCAmIEJSLVNQLUJBIiwiUG9wPjIwbWlsICYgQlItU1AtQkEiLAogICAgICAgIlBvcDwyMG1pbCAmIFNQIiwiUG9wPjIwbWlsICYgU1AiLCJQb3A+MjBtaWwgJiBCQSIsIlBvcDwyMG1pbCAmIEJBIiwKICAgICAgICJJcnJlc3RyaXRvIiksY29sPTI6OCxsd2Q9MixidHk9Im4iLHBjaD0xNikKYWJsaW5lKGg9MC41LGx0eT0yLGx3ZD0zKQphYmxpbmUoaD0wLjMsbHR5PTIsbHdkPTMpCmFibGluZShoPTAuNjUsbHR5PTIsbHdkPTMpCnRpdGxlKCJSZWdyZXNzw6NvIEJldGEiKQpgYGAKCgojIFJlZ3Jlc3PDo28gQmV0YSBCYXllc2lhbmEKCkFiYWl4byB1c2Ftb3MgbyBwYWNvdGUgKipiZXRhQmF5ZXMqKjogQmF5ZXNpYW4gQmV0YSBSZWdyZXNzaW9uLCAKWmhvdSBhbmQgSHVhbmcgKDIwMjIpIGRvaToxMC4xMDE2L2ouY3NkYS4yMDIxLjEwNzM0NQoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KI2luc3RhbGwucGFja2FnZXMoImJldGFCYXllcyIpCmxpYnJhcnkoImJldGFCYXllcyIpCgpmaXQuYmJldGEwID0gYmV0YTRyZWcobHVsYUJSIH4gQUJTLGxpbms9ImxvZ2l0Iixtb2RlbD0ibWVhbiIsbWNtYz1saXN0KG5idXJuPTUwMDAsIG5zYXZlPTUwMDAsIG5za2lwPTAsIG5kaXNwbGF5PTEwMDApKQpjb2VmMCA9IGZpdC5iYmV0YTAkY29lZlsxOjJdCmV0YTAgID0gY29lZjBbMV0rY29lZjBbMl0qQUJTCmV0YTAgID0gMS8oMStleHAoLWV0YTApKQoKZml0LmJiZXRhID0gYmV0YTRyZWcobHVsYUJSIH4gQUJTK1BPUCtTUCtCQSxsaW5rPSJsb2dpdCIsbW9kZWw9Im1lYW4iLG1jbWM9bGlzdChuYnVybj01MDAwLCBuc2F2ZT01MDAwLCBuc2tpcD0wLCBuZGlzcGxheT0xMDAwKSkKY29lZiA9IGZpdC5iYmV0YSRjb2VmWzE6NV0KYGBgCgojIyBBbW9zdHJhcyBkYSBwb3N0ZXJpb3JpCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9CmJldGFzID0gZml0LmJiZXRhJGJldGEKbmFtZWNvZWYgPSBjKCJJbnRlcmNlcHRvIiwiQWJzdGVuw6fDtWVzIiwiUE9QPjIwbWlsIiwiU1AiLCJCQSIpCnBhcihtZnJvdz1jKDMsNSkpCmZvciAoaSBpbiAxOjUpCiAgdHMucGxvdChiZXRhc1tpLF0seGxhYj0iSXRlcmF0aW9uIix5bGFiPSIiLG1haW49bmFtZWNvZWZbaV0pCmZvciAoaSBpbiAxOjUpCiAgYWNmKGJldGFzW2ksXSxtYWluPSIiKQpmb3IgKGkgaW4gMTo1KQogIGhpc3QoYmV0YXNbaSxdLHByb2I9VFJVRSx4bGFiPSIiLG1haW49IiIpCmBgYCAgCgojIyBFeHBsb3JhbmRvIGEgcG9zdGVyaW9yaQoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KcGFyKG1mcm93PWMoMSwxKSkKcGxvdChBQlMsbHVsYUJSLHlsaW09YygwLDEpLHhsaW09YygwLDAuNikseWxhYj0iUHJvcC4gdm90b3MgcGFyYSBMdWxhIG5vcyBtdW5pY2lwaW9zIix4bGFiPSJQcm9wLiBBYnN0ZW7Dp8O1ZXMiKQpwb2ludHMoQUJTLGV0YTAsY29sPTgpCmV0YSA9IGNvZWZbMV0rY29lZlsyXSpBQlMKcG9pbnRzKEFCUywxLygxK2V4cCgtZXRhKSksY29sPTIpCmV0YSA9IGNvZWZbMV0rY29lZlsyXSpBQlMrY29lZlszXQpwb2ludHMoQUJTLDEvKDErZXhwKC1ldGEpKSxjb2w9MykKZXRhID0gY29lZlsxXStjb2VmWzJdKkFCUytjb2VmWzRdCnBvaW50cyhBQlMsMS8oMStleHAoLWV0YSkpLGNvbD00KQpldGEgPSBjb2VmWzFdK2NvZWZbMl0qQUJTK2NvZWZbM10rY29lZls0XQpwb2ludHMoQUJTLDEvKDErZXhwKC1ldGEpKSxjb2w9NSkKZXRhID0gY29lZlsxXStjb2VmWzJdKkFCUytjb2VmWzNdK2NvZWZbNV0KcG9pbnRzKEFCUywxLygxK2V4cCgtZXRhKSksY29sPTYpCmV0YSA9IGNvZWZbMV0rY29lZlsyXSpBQlMrY29lZls1XQpwb2ludHMoQUJTLDEvKDErZXhwKC1ldGEpKSxjb2w9NykKbGVnZW5kKCJib3R0b21yaWdodCIsbGVnZW5kPWMoIlBvcDwyMG1pbCAmIEJSLVNQLUJBIiwiUG9wPjIwbWlsICYgQlItU1AtQkEiLAogICAgICAgIlBvcDwyMG1pbCAmIFNQIiwiUG9wPjIwbWlsICYgU1AiLCJQb3A+MjBtaWwgJiBCQSIsIlBvcDwyMG1pbCAmIEJBIiwKICAgICAgICJJcnJlc3RyaXRvIiksY29sPTI6OCxsd2Q9MixidHk9Im4iLHBjaD0xNikKYWJsaW5lKGg9MC41LGx0eT0yLGx3ZD0zKQphYmxpbmUoaD0wLjMsbHR5PTIsbHdkPTMpCmFibGluZShoPTAuNjUsbHR5PTIsbHdkPTMpCnRpdGxlKCJSZWdyZXNzw6NvIEJldGEgQmF5ZXNpYW5hIikKYGBgCgojIyBNYWlzIHBvc3RlcmlvcmkKCmBgYHtyIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9CnBhcihtZnJvdz1jKDEsMSkpCnBsb3QoZGVuc2l0eSgxLygxK2V4cCgtYmV0YXNbMSxdKSkpLGNvbD0yLHhsaW09YygwLDEpLHlsaW09YygwLDQwKSxsd2Q9Mix5bGFiPSJEZW5zaWRhZGUiLAptYWluPSJJbnRlcmNlcHRvIHBhcmEgb3MgZGlmZXJlbnRlcyBncnVwb3MiLHhsYWI9IlByb3AuIHZvdG9zIHBhcmEgTHVsYSBub3MgbXVuaWNpcGlvcyIpCmxpbmVzKGRlbnNpdHkoMS8oMStleHAoLWJldGFzWzEsXS1iZXRhc1szLF0pKSksY29sPTMsbHdkPTIpCmxpbmVzKGRlbnNpdHkoMS8oMStleHAoLWJldGFzWzEsXS1iZXRhc1s0LF0pKSksY29sPTQsbHdkPTIpCmxpbmVzKGRlbnNpdHkoMS8oMStleHAoLWJldGFzWzEsXS1iZXRhc1szLF0tYmV0YXNbNCxdKSkpLGNvbD01LGx3ZD0yKQpsaW5lcyhkZW5zaXR5KDEvKDErZXhwKC1iZXRhc1sxLF0tYmV0YXNbMyxdLWJldGFzWzUsXSkpKSxjb2w9Nixsd2Q9MikKbGluZXMoZGVuc2l0eSgxLygxK2V4cCgtYmV0YXNbMSxdLWJldGFzWzUsXSkpKSxjb2w9Nyxsd2Q9MikKbGVnZW5kKCJ0b3ByaWdodCIsbGVnZW5kPWMoIlBvcDwyMG1pbCAmIEJSLVNQLUJBIiwiUG9wPjIwbWlsICYgQlItU1AtQkEiLAogICAgICAgIlBvcDwyMG1pbCAmIFNQIiwiUG9wPjIwbWlsICYgU1AiLCJQb3A+MjBtaWwgJiBCQSIsIlBvcDwyMG1pbCAmIEJBIiksCiAgICAgICBjb2w9Mjo3LGx3ZD0yLGJ0eT0ibiIscGNoPTE2KQphYmxpbmUodj0wLjUsbHR5PTIpCmFibGluZSh2PTAuMyxsdHk9MikKYWJsaW5lKHY9MC42NSxsdHk9MikKYGBg