library(tidyverse)
library(haven) # importa, entre otros software, de Stata
library(sjlabelled) # manejar labels de las variables
library(openxlsx) # leer archivos de excel
library(DT) # visualizar a tablas
library(data.table) # convertir a tablas
library(highcharter) # gráficas interactivas
library(foreign)
library(stargazer)
library(ggplot2)
library(survival)
library(broom)
library(gridExtra)
Funciones de carga
cargar_esru<- function(){
return(read_stata(
path = "Datos/ESRU-EMOVI-2017/ESRU-EMOVI-2017-Entrevistado.dta",
atomic.to.fac = TRUE,
enc = NULL,
))
}
cargar_enigh<- function(docu){
return(read_stata(
path = paste("Datos/ENIGH-2016/",docu,".dta",sep=""),
atomic.to.fac = TRUE,
enc = NULL,
))
}
cargar_enigh_sav<- function(docu){
return(read_spss(
path = paste("Datos/ENIGH-2016/",docu,".sav",sep=""),
atomic.to.fac = TRUE,
enc = NULL,
))
}
cargar_enigh_18<- function(docu){
return(read_stata(
path = paste("Datos/ENIGH-2018/",docu,".dta",sep=""),
atomic.to.fac = TRUE,
enc = NULL,
))
}
cargar_enigh_sav_18<- function(docu){
return(read_spss(
path = paste("Datos/ENIGH-2018/",docu,".sav",sep=""),
atomic.to.fac = TRUE,
enc = NULL,
))
}
Filtrar hijos ESRU
Creamos per movilidad
data_emovi2017<-cargar_esru()
data_emovi2017<-data_emovi2017%>%
mutate(mov = ifelse(p147>p148,"mejor",
ifelse(p147<p148,"peor","igual")),
id_ho = as.integer(row.names(data_emovi2017)))
data_emovi2017$mov<-set_labels(
data_emovi2017$mov,
labels = c("mejor" = "mejor",
"peor" = "peor",
"igual" = "igual"))
seleccion de hijos
Criterios de filtrado - pregunta p2, comparten el mimso gasto para comer: 1 ) Si 2 ) No - pregunta 5 Edades entre 25 y 45 años - pregunta p08, es el jefe del hogar: 1 ) jefe 2) cónyuge NO IMPLEMENTADO - pregunta p12, actualmente estudia, 1)Si 2)No - p26 Había un jefe de hogar en la infancia (1 padre 2 madre) - p43 y p43m Reporta educación del padre o madre priciapl - p68, Personas que trabajan, 1. Si, 2. No - p69 si trabaja pero la semana pasada no - p132 numero de personas que aportan ingreso - p133 cohort de todas las personas y todos los ingresos (1 ingreso)
Variables de selección para estimar ingreso
Estado
pregunta 5, edad
pregunta 6, sexo
Pregunta 13, nivel de escuela
p76 ocupación –SINCO3 codificación ocupación entrevistado
p133 cohort de todas las personas y todos los ingresos
# pensamos que los datos se leeen como factores cando corresponda, si se leen como enteros no debe hacerse el casting
#data_emovi2017<-datos_e
hijos <- data_emovi2017 %>%
filter(p02 == 1) %>% #compartir gasot para comer
filter(between(p05,25,50)) %>% # edad, criterio 1 de 25 a 40,criterio2 aumentamos los ingreos, criterio 3 de 25 a 50
#filter(p08 == 1) %>%
filter(p12 == 2) %>% # ya no estudia
filter(p26 == 1 | p26==2 ) %>% # sosten principal papa, mama,
filter((!is.na(p43) & p43!=98 & p26 == 1 & cmo1_2!="." & !is.na(p38_11)) |
(!is.na(p43m) & p43m!=98 & p26 == 2 & cmo2_2!="." & !is.na(p38m_11) )) %>% # reporta educación de pp
filter(!is.na(p13))%>% # reporta educación
filter(SINCO3 !="") %>%# reporta oficio actual
filter(p68 == 1 | p69 == 1) %>% # si trabaja
filter(p132 %in% c(1)) %>%# persona que aportan ingreso
filter(!p133 %in% c(8,9,NA) ) # reporta ingresos
# no estan los ingresos hogar aislados.
#edad_promedio_padres <- mean(hijos$p38_11, na.rm = TRUE)
#edad_promedio_padres-21
unique(hijos$region)
unique(hijos$p43)
nrow(hijos)
hijos seleccionados
Hacemos un cohort del 1 y el 2
var<-c("Estado","p05","p06","p13","SINCO3","p133","mov","id_ho","region")
hijos_para_sal<-hijos%>%
select(var)#%>%
#mutate(p133 = ifelse(p133==1,2,p133)-1)# juntamos el cohort 1 y 2
hijos_para_sal <- hijos_para_sal%>%
mutate(estrato = ifelse(p133 %in% c(1,2),1,
ifelse(p133 %in% c(3),2,
ifelse(p133 %in% c(4,5),3,4)))
)
ajustamos region
# ajsutajos a 4 regiones
hijos_para_sal <- hijos_para_sal%>%
mutate(
region = ifelse(Estado %in% as.integer(c("02","26","08","05","19","28")),1,
ifelse(Estado %in%as.integer(c("12","20","07","30","27","04","31","23")),4,
ifelse(Estado %in% as.integer(c("03","25","18","10","32","16","06","14","01","24")),2,3)))
)
#sum(hijos_para_sal$p133==1)
unique(hijos_para_sal$region)
nrow(hijos_para_sal)
Hijos fijos
base_hijos_fija <- hijos_para_sal%>%filter(p133==2)
#ingreso_hijo_e18_emovi
base_hijos_fija_f<-base_hijos_fija%>%
summarise(
id_hijo = "fijo",
id_ho = id_ho,
mov= mov,
regionh = region,
edad = p05,
cohort = 100,# paa que sepueda hacer la resta pero no significa nada
ing_men_p_h = list(2400),
estrato = estrato,
estado = Estado,
sexo = p06
)
base_hijos_fija_f
saveRDS(base_hijos_fija_f, file="Datos/base_hijos_fija_f_cri3.Rda")
Hijos para estimar
hijos_para_sal_1<-hijos_para_sal%>%
mutate(p133 = ifelse(p133==1,2,p133)-1)# transformamos
unique(hijos_para_sal_1$p133)
saveRDS(hijos_para_sal_1, file="Datos/hijos_emovi2017_p1.Rda")
unique(hijos_para_sal_1$p133)
Hijos construcción ingresos 16
poblacion enigh 16
poblacion_e16<-cargar_enigh_sav("poblacion")
poblacion_e16f<- poblacion_e16%>%
#filter(asis_esc == "2")%>% # ya no asiste a la escuela
select(folioviv,foliohog,numren,sexo,edad,nivelaprob)%>%
filter(between(as.integer(edad),23,52))#criterio 1 entre 25-40, criterio 3 entre 25-50
# no filtramos por jefe de hogar
nrow(poblacion_e16f)
sum(is.na(poblacion_e16f))
creamos region 16
poblacion_e16f<- poblacion_e16f%>%
mutate(
region = ifelse(substr(folioviv,1,2) %in% c("02","26","08","05","19","28"),1,
ifelse(substr(folioviv,1,2) %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(substr(folioviv,1,2) %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
unique(poblacion_e16f$region)
nrow(poblacion_e16f)
sum(is.na(poblacion_e16f))
trabajos enigh 16
Filtrams los trabajos
trabajos_e16<-cargar_enigh_sav("trabajos")
trabajos_e16f<-trabajos_e16%>%
select(folioviv,foliohog,numren,sinco)%>%
filter(!is.na(sinco))
NROW(trabajos_e16f)
#NROW(trabajos)
sum(is.na(trabajos_e16f))
Ingresos enigh 2016
ingresos_e16<-cargar_enigh_sav("ingresos")
familias_integrantes_e16 <- function(df,folhog,nr){
dfn <- df %>%
filter(foliohog %in% folhog)%>%
filter(numren %in% nr)
return(dfn)
}
ingresos_acu_e16 <- function(df,clavs=get_labels(ingresos_e16$clave)){
dfn <- df %>%
group_by(folioviv, foliohog, numren) %>%
filter(clave %in% clavs)%>%
summarise(
claves_a = paste(clave,collapse = ","),
ing_tri_t = sum(ing_tri),
ing_men_p = ing_tri_t/3,
ling_men_p = log(ing_men_p)
) %>% ungroup()
return(dfn)
}
hogares <- c("1","2","3","4","5")
personas_h <- c('01','02','03','04','05')
a<-familias_integrantes_e16(ingresos_e16,hogares,personas_h)
head(a)
### criterio 1 algunos ingresos no todos los de abajo
#claves<-c("P001","P002","P003","P010","P011","P012","P013","P014","P015", "P016","P017","P018","P020","P021","P026","P027","P035","P040","P041","P042","P044","P045")
## criterio 2 flexibilidad en los ingresos, criterio 3
claves<-c("P001","P002","P003","P011","P13","P023","P024","P025","P026","P027","P028","P029","P030","P031","P032","P033","P054","P055","P056", "P059","P060","P061","P062","P063","P068","P069","P070","P071","P072","P073","P074","P075","P076","P077","P078","P079","P080")
ingresos_e16a<-ingresos_acu_e16(a,claves)
ingresos_e16a<- ingresos_e16a%>%
mutate(coh_ing = ifelse(ing_men_p<=2400,1,
ifelse(ing_men_p<=4800,2,
ifelse(ing_men_p<=7200,3,
ifelse(ing_men_p<=12000,4,
ifelse(ing_men_p<=24000,5,6))))))
ingresos_e16a<- ingresos_e16a%>%mutate(
region = ifelse(substr(folioviv,1,2) %in% c("02","26","08","05","19","28"),1,
ifelse(substr(folioviv,1,2) %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(substr(folioviv,1,2) %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
ingresos_e16fc<-ingresos_e16a%>%
select(folioviv,foliohog,numren,coh_ing)
sort(unique(as.character(ingresos_e16$clave)))[]
rango percentil 16
#IN<-(100/110.907)
IN<-(100/93.6)
ingresos_e16a$ling_men_pd <- ingresos_e16a$ling_men_p + log(IN)
rp_e16 <- rank(ingresos_e16a$ling_men_pd)/length(ingresos_e16a$ling_men_pd)
ingresos_e16a1 <- data.frame(ling_men_pd=ingresos_e16a%>%filter(region==1)%>%pull(ling_men_p) + log(IN))
rp_e161 <- rank(ingresos_e16a1$ling_men_pd)/length(ingresos_e16a1$ling_men_pd)
ingresos_e16a2 <- data.frame(ling_men_pd=ingresos_e16a%>%filter(region==2)%>%pull(ling_men_p) + log(IN))
rp_e162 <- rank(ingresos_e16a2$ling_men_pd)/length(ingresos_e16a2$ling_men_pd)
ingresos_e16a3 <- data.frame(ling_men_pd=ingresos_e16a%>%filter(region==3)%>%pull(ling_men_p) + log(IN))
rp_e163 <- rank(ingresos_e16a3$ling_men_pd)/length(ingresos_e16a3$ling_men_pd)
ingresos_e16a4 <- data.frame(ling_men_pd=ingresos_e16a%>%filter(region==4)%>%pull(ling_men_p) + log(IN))
rp_e164 <- rank(ingresos_e16a4$ling_men_pd)/length(ingresos_e16a4$ling_men_pd)
hist(rp_e16)
Base cruzada pob-tra 16
enigh_16<- full_join(poblacion_e16f,trabajos_e16f)%>%
drop_na()
#enigh<-full_join(enigh,concentrado)%>%
# drop_na()
nrow(enigh_16)
sum(is.na(enigh_16))
Cambio etiquetado educacion 16
Pasamos las etiqeuteas de educación de emovi a
hijos_emovi <- readRDS(file="Datos/hijos_emovi2017_p1.Rda")#criterio 1 y 3
hijos_emovi<- hijos_emovi %>%
mutate(p13_m = ifelse(p13 %in% c(1),"1",
ifelse( p13 == 2,"2",
ifelse(p13 %in% c(3,4),"3",
ifelse( p13 %in% c(5,6),"4",
ifelse(p13 %in% c(7,8),"6",
ifelse(p13 %in% c(9,10),"5",
ifelse(p13==11,"7",
ifelse(p13==12,"8","0")))))))))
unique(hijos_emovi$p13_m)
enigh_16<-enigh_16%>%
mutate(nivelaprob=ifelse(nivelaprob=="9","8",nivelaprob))
unique(enigh_16$nivelaprob)
enigh_16f<-enigh_16%>%
filter(nivelaprob %in% unique(hijos_emovi$p13_m))
nrow(enigh_16f)
Buscar folios con caracteristicas 16
busca<-function(i){
return(enigh_16f%>%
filter(
#as.integer(substr(folioviv,1,2))==hijos_emovi[i,]$Estado &
region == hijos_emovi[i,]$region &
sexo == hijos_emovi[i,]$p06 &
((edad-2) <= hijos_emovi[i,]$p05) &
(hijos_emovi[i,]$p05 <= (edad+2)) &
#as.character(sinco) == hijos_emovi[i,]$SINCO3 &
substr(as.character(sinco),1,1)== substr(hijos_emovi[i,]$SINCO3,1,1)&
nivelaprob == hijos_emovi[i,]$p13_m)%>%
select(folioviv,foliohog))
}
a<-lapply(1:nrow(hijos_emovi), busca)
contador<-0
for(i in 1:nrow(hijos_emovi))
{if(nrow(a[[i]])>0)
contador<-contador +1
}
contador
#saveRDS(a, file="Datos/folhijos_enigh16_emovi_re_ch.Rda")
#saveRDS(a, file="Datos/folhijos_enigh16_emovi_re_ch_cri3.Rda")
saveRDS(a, file="Datos/folhijos_enigh16_emovi_sinm1_re_p1.Rda")
#saveRDS(a, file="Datos/folhijos_enigh16_emovi_est_ch_cri3.Rda")
- Con ocupacion y region del total, 668 personas tienen gemelos
- Con region,
Criterio 3 - ocupacion y region y, 979 - estado, mas al rato cohort en el ingreso ### filtamos solo los hijos encontrados 16
# etiquetamos para no perder la numeracion respecto a los hijos originales
folhijos_e16_emovi <- readRDS(file="Datos/folhijos_enigh16_emovi_sinm1_re_p1.Rda")
names(folhijos_e16_emovi) <- as.character(1:nrow(hijos_emovi))
length(folhijos_e16_emovi)
L <- c()
for(i in 1:length(folhijos_e16_emovi)){
if(!(nrow(folhijos_e16_emovi[[i]])>0)){
L<-c(L,i)}
}
# Solo hijos que se les pudo encontrar en enigh-2016 1077/1131
folhijos_e16_emovif<-folhijos_e16_emovi[-L]
length(folhijos_e16_emovif)
#names(folhijos_emovif)
#names(folhijos_emovi)
Unicos folios, diferentes trabajos 16
unicos_folios<-function(i){
folhijos_e16_emovif[[i]]%>%
distinct()
}
# filtramos unicos folios por diferentes trabajos de la misma persona
a<-lapply(1:length(folhijos_e16_emovif), unicos_folios)
names(a)<-names(folhijos_e16_emovif)
length(a)
folhijos_e16_emovif<-a
Observamos las edades de los encontrados 16
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
hijos_emovi%>%
slice(as.integer(names(folhijos_e16_emovif)))%>%
select(p05)%>%
count(p05)%>%
hchart('column',
hcaes( y = 'n'))%>%
hc_add_theme(hc_theme_ffx())%>%
hc_title(
text = ""
) %>%
#hc_subtitle(text = "Las edades están agrupadas en intervalos
# de 10 años (da clic sobre F o M)") %>%
# hc_credits(
# enabled = TRUE, text = "Source: SSS",
# style = list(fontSize = "12px"))%>%
hc_yAxis(title = list(text = "Número de participantes"))%>%
hc_xAxis(title=list(text="Número de personas"),
categories = as.character(25:50)) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
Observamos las estados de los encontrados 16
hijos_emovi%>%
slice(as.integer(names(folhijos_e16_emovif)))%>%
count(Estado)%>%
hchart('column',
hcaes( y = 'n'))%>%
hc_add_theme(hc_theme_ffx())%>%
hc_title(
text = ""
) %>%
#hc_subtitle(text = "Las edades están agrupadas en intervalos
# de 10 años (da clic sobre F o M)") %>%
# hc_credits(
# enabled = TRUE, text = "Source: SSS",
# style = list(fontSize = "12px"))%>%
hc_yAxis(title = list(text = "Número de participantes"))%>%
hc_xAxis(title=list(text="Número de personas"),
categories = get_labels(hijos_emovi$Estado)) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
Ingreso hijo enigh_16 - emovi
ingreso_hijo_e16_emovi<-function(i){
ingresos_e16a%>%
filter(folioviv %in% folhijos_e16_emovif[[i]]$folioviv &
foliohog %in% folhijos_e16_emovif[[i]]$foliohog)%>%
#filter(coh_ing==hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"p133"])%>%
summarise(
id_hijo = names(folhijos_e16_emovif[i]),
id_ho = hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"id_ho"],
mov= hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"mov"],
regionh = hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"region"],
edad = hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"p05"],
cohort = hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"p133"],
ing_men_p_h =list(ing_men_p),
estrato = hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"estrato"],
estado = hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"Estado"],
sexo = hijos_emovi[as.integer(names(folhijos_e16_emovif[i])),"p06"]
)
}
#273,332 son vacios
# ingreso hijo pero ualgunos no podrian estar por no tener registro de salario
a<-lapply(1:length(folhijos_e16_emovif), ingreso_hijo_e16_emovi)
ingreso_hijog_e16_emovi<-a
length(ingreso_hijog_e16_emovi)
#ingreso_hijog_e16_emovi[[332]]
#x<-ingreso_hijog_e16_emovi[[332]]$ing_men_p_h[1]
#sum(ingreso_hijog_e16_emovi[[332]]$ing_men_p_h[[1]],na.rm = TRUE)
Filtramos sobre ingresos encontrados 16
L <- c()
for(i in 1:length(ingreso_hijog_e16_emovi)){
if(sum(ingreso_hijog_e16_emovi[[i]]$ing_men_p_h[[1]],na.rm = TRUE)==0){
L<-c(L,i)}
}
length(L)
ingreso_hijog_e16_emovi<-ingreso_hijog_e16_emovi[-L]
length(ingreso_hijog_e16_emovi)
ingreso_hijog_e16_emovi[1]
ingreso_hijog_e16_emovi[2]
ingreso_hijog_e16_emovif<-bind_rows(ingreso_hijog_e16_emovi[1:length(ingreso_hijog_e16_emovi)])
nrow(ingreso_hijog_e16_emovif)
saveRDS(ingreso_hijog_e16_emovif, file="Datos/ingreso_hij_f_emovi_sinm1_re_p1.Rda")
gemelos<-c()
for( i in 1:nrow(ingreso_hijog_e16_emovif)){
gemelos<-c(gemelos,length(ingreso_hijog_e16_emovif$ing_men_p_h[[i]]))
}
#gemelos
#min(ingreso_hijog_e16_emovif$ing_men_p_h[[459]])
#max(ingreso_hijog_e16_emovif$ing_men_p_h[[459]])
ingreso_hijog_e16_emovif%>%select(id_ho)
Promedio de gemelos por individuo
len<-0
for(i in 1:nrow(ingreso_hijog_e16_emovif)){
len<- len + length(ingreso_hijog_e16_emovif$ing_men_p_h[[i]])
}
len/nrow(ingreso_hijog_e16_emovif)
CRITERIO 1 - con region 1117 tienen salario - con region y en cohort de ingreso tienen salario 1100 - con ocupacion y region 659 tienen salario - con ocupacion y region y cohort de ingreso 436 tienen salario
CRITERIO 2 (ingresoso aumentamos las claves) - con region y en cohort de ingreso tienen salario 1103
CRITERIO 3 (ingresoso aumentamos las claves, y los rangos de edad) - con region y en cohort de ingreso tienen salario 1658 - con region, ocupación y en el cohort de ingreso tienen 683 - cone estado, cohort en el ingreso, 1473
Hijos construcción ingresos 18
poblacion enigh 18
poblacion_e18<-cargar_enigh_sav_18("poblacion")
poblacion_e18f<- poblacion_e18%>%
#filter(asis_esc == "2")%>% # ya no asiste a la escuela
select(folioviv,foliohog,numren,sexo,edad,nivelaprob)%>%
filter(between(as.integer(edad),23,52))#criterio 1 entre 25-40, criterio 3 entre 25-50
# no filtramos por jefe de hogar
nrow(poblacion_e18f)
sum(is.na(poblacion_e18f))
creamos region 18
poblacion_e18f<- poblacion_e18f%>%
mutate(
region = ifelse(substr(folioviv,1,2) %in% c("02","26","08","05","19","28"),1,
ifelse(substr(folioviv,1,2) %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(substr(folioviv,1,2) %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
unique(poblacion_e18f$region)
nrow(poblacion_e18f)
sum(is.na(poblacion_e18f))
trabajos enigh 18
Filtrams los trabajos
trabajos_e18<-cargar_enigh_sav_18("trabajos")
trabajos_e18f<-trabajos_e18%>%
select(folioviv,foliohog,numren,sinco)%>%
filter(!is.na(sinco))
NROW(trabajos_e18f)
#NROW(trabajos)
sum(is.na(trabajos_e18f))
Ingresos enigh 2018
ingresos_e18<-cargar_enigh_sav_18("ingresos")
familias_integrantes_e18 <- function(df,folhog,nr){
dfn <- df %>%
filter(foliohog %in% folhog)%>%
filter(numren %in% nr)
return(dfn)
}
ingresos_acu_e18 <- function(df,clavs=get_labels(ingresos_e18$clave)){
dfn <- df %>%
group_by(folioviv, foliohog, numren) %>%
filter(clave %in% clavs)%>%
summarise(
claves_a = paste(clave,collapse = ","),
ing_tri_t = sum(ing_tri),
ing_men_p = ing_tri_t/3,
ling_men_p = log(ing_men_p)
) %>% ungroup()
return(dfn)
}
hogares <- c("1","2","3","4","5")
personas_h <- c('01','02','03','04','05')
a<-familias_integrantes_e18(ingresos_e18,hogares,personas_h)
head(a)
### criterio 1 algunos ingresos no todos los de abajo
#claves<-c("P001","P002","P003","P010","P011","P012","P013","P014","P015", "P016","P017","P018","P020","P021","P026","P027","P035","P040","P041","P042","P044","P045")
## criterio 2 flexibilidad en los ingresos, criterio 3
claves<-c("P001","P002","P003","P011","P13","P023","P024","P025","P026","P027","P028","P029","P030","P031","P032","P033","P054","P055","P056", "P059","P060","P061","P062","P063","P068","P069","P070","P071","P072","P073","P074","P075","P076","P077","P078","P079","P080")
ingresos_e18a<-ingresos_acu_e18(a,claves)
ingresos_e18a<- ingresos_e18a%>%
mutate(coh_ing = ifelse(ing_men_p<=2400,1,
ifelse(ing_men_p<=4800,2,
ifelse(ing_men_p<=7200,3,
ifelse(ing_men_p<=12000,4,
ifelse(ing_men_p<=24000,5,6))))))
ingresos_e18a
ingresos_e18fc<-ingresos_e18a%>%
select(folioviv,foliohog,numren,coh_ing)
rango percentil 18
#IN<-(100/110.907)
IN<-(100/93.6)
ingresos_e18a$ling_men_pd <- ingresos_e18a$ling_men_p + log(IN)
rp_e18 <- rank(ingresos_e18a$ling_men_pd)/length(ingresos_e18a$ling_men_pd)
hist(rp_e18)
Base cruzada pob-tra 18
enigh_18<- full_join(poblacion_e18f,trabajos_e18f)%>%
drop_na()
#enigh<-full_join(enigh,concentrado)%>%
# drop_na()
nrow(enigh_18)
sum(is.na(enigh_18))
Cambio etiquetado educacion 18
Pasamos las etiqeuteas de educación de emovi a
hijos_emovi <- readRDS(file="Datos/hijos_emovi2017_p1.Rda")#criterio 1 y 3
hijos_emovi<- hijos_emovi %>%
mutate(p13_m = ifelse(p13 %in% c(1),"1",
ifelse( p13 == 2,"2",
ifelse(p13 %in% c(3,4),"3",
ifelse( p13 %in% c(5,6),"4",
ifelse(p13 %in% c(7,8),"6",
ifelse(p13 %in% c(9,10),"5",
ifelse(p13==11,"7",
ifelse(p13==12,"8","0")))))))))
unique(hijos_emovi$p13_m)
enigh_18<-enigh_18%>%
mutate(nivelaprob=ifelse(nivelaprob=="9","8",nivelaprob))
unique(enigh_18$nivelaprob)
enigh_18f<-enigh_18%>%
filter(nivelaprob %in% unique(hijos_emovi$p13_m))
nrow(enigh_18f)
Buscar folios con caracteristicas 18
busca<-function(i){
return(enigh_18f%>%
filter(
#as.integer(substr(folioviv,1,2))==hijos_emovi[i,]$Estado &
region == hijos_emovi[i,]$region &
sexo == hijos_emovi[i,]$p06 &
((edad-2) <= hijos_emovi[i,]$p05) &
(hijos_emovi[i,]$p05 <= (edad+2)) &
#as.character(sinco) == hijos_emovi[i,]$SINCO3 &
substr(as.character(sinco),1,1) == substr(hijos_emovi[i,]$SINCO3,1,1)&
nivelaprob == hijos_emovi[i,]$p13_m)%>%
select(folioviv,foliohog))
}
a<-lapply(1:nrow(hijos_emovi), busca)
contador<-0
for(i in 1:nrow(hijos_emovi))
{if(nrow(a[[i]])>0)
contador<-contador +1
}
contador
saveRDS(a, file="Datos/folhijos_enigh18_emovi_sinm1_re_p1.Rda")
filtamos solo los hijos encontrados 18
# etiquetamos para no perder la numeracion respecto a los hijos originales
folhijos_e18_emovi <- readRDS(file="Datos/folhijos_enigh18_emovi_sinm1_re_p1.Rda")
names(folhijos_e18_emovi) <- as.character(1:nrow(hijos_emovi))
length(folhijos_e18_emovi)
L <- c()
for(i in 1:length(folhijos_e18_emovi)){
if(!(nrow(folhijos_e18_emovi[[i]])>0)){
L<-c(L,i)}
}
# Solo hijos que se les pudo encontrar en enigh-2016 1077/1131
folhijos_e18_emovif<-folhijos_e18_emovi[-L]
length(folhijos_e18_emovif)
#names(folhijos_emovif)
#names(folhijos_emovi)
Unicos folios, diferentes trabajos 18
unicos_folios<-function(i){
folhijos_e18_emovif[[i]]%>%
distinct()
}
# filtramos unicos folios por diferentes trabajos de la misma persona
a<-lapply(1:length(folhijos_e18_emovif), unicos_folios)
names(a)<-names(folhijos_e18_emovif)
length(a)
folhijos_e18_emovif<-a
Observamos las edades de los encontrados 18
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
hijos_emovi%>%
slice(as.integer(names(folhijos_e18_emovif)))%>%
select(p05)%>%
count(p05)%>%
hchart('column',
hcaes( y = 'n'))%>%
hc_add_theme(hc_theme_ffx())%>%
hc_title(
text = ""
) %>%
#hc_subtitle(text = "Las edades están agrupadas en intervalos
# de 10 años (da clic sobre F o M)") %>%
# hc_credits(
# enabled = TRUE, text = "Source: SSS",
# style = list(fontSize = "12px"))%>%
hc_yAxis(title = list(text = "Número de participantes"))%>%
hc_xAxis(title=list(text="Número de personas"),
categories = as.character(25:50)) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
Observamos las estados de los encontrados 18
hijos_emovi%>%
slice(as.integer(names(folhijos_e18_emovif)))%>%
count(Estado)%>%
hchart('column',
hcaes( y = 'n'))%>%
hc_add_theme(hc_theme_ffx())%>%
hc_title(
text = ""
) %>%
#hc_subtitle(text = "Las edades están agrupadas en intervalos
# de 10 años (da clic sobre F o M)") %>%
# hc_credits(
# enabled = TRUE, text = "Source: SSS",
# style = list(fontSize = "12px"))%>%
hc_yAxis(title = list(text = "Número de participantes"))%>%
hc_xAxis(title=list(text="Número de personas"),
categories = get_labels(hijos_emovi$Estado)) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
Ingreso hijo enigh 18 - emovi
ingreso_hijo_e18_emovi<-function(i){
ingresos_e18a%>%
filter(folioviv %in% folhijos_e18_emovif[[i]]$folioviv &
foliohog %in% folhijos_e18_emovif[[i]]$foliohog)%>%
# filter(coh_ing==hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"p133"])%>%
summarise(
id_hijo = names(folhijos_e18_emovif[i]),
id_ho = hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"id_ho"],
mov= hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"mov"],
regionh = hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"region"],
edad = hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"p05"],
cohort = hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"p133"],
ing_men_p_h =list(ing_men_p),
estrato = hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"estrato"],
estado = hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"Estado"],
sexo = hijos_emovi[as.integer(names(folhijos_e18_emovif[i])),"p06"]
)
}
#273,332 son vacios
# ingreso hijo pero ualgunos no podrian estar por no tener registro de salario
a<-lapply(1:length(folhijos_e18_emovif), ingreso_hijo_e18_emovi)
ingreso_hijog_e18_emovi<-a
length(ingreso_hijog_e18_emovi)
#ingreso_hijog_e16_emovi[[332]]
#x<-ingreso_hijog_e16_emovi[[332]]$ing_men_p_h[1]
#sum(ingreso_hijog_e16_emovi[[332]]$ing_men_p_h[[1]],na.rm = TRUE)
Filtramos sobre ingresos encontrados 18
L <- c()
for(i in 1:length(ingreso_hijog_e18_emovi)){
if(sum(ingreso_hijog_e18_emovi[[i]]$ing_men_p_h[[1]],na.rm = TRUE)==0){
L<-c(L,i)}
}
length(L)
ingreso_hijog_e18_emovi<-ingreso_hijog_e18_emovi[-L]
length(ingreso_hijog_e18_emovi)
ingreso_hijog_e18_emovi[1]
ingreso_hijog_e18_emovi[2]
ingreso_hijog_e18_emovif<-bind_rows(ingreso_hijog_e18_emovi[1:length(ingreso_hijog_e18_emovi)])
nrow(ingreso_hijog_e18_emovif)
saveRDS(ingreso_hijog_e18_emovif, file="Datos/ingreso18_hij_f_emovi_sinm1_re_p1.Rda")
gemelos<-c()
for( i in 1:nrow(ingreso_hijog_e18_emovif)){
gemelos<-c(gemelos,length(ingreso_hijog_e18_emovif$ing_men_p_h[[i]]))
}
#gemelos
#min(ingreso_hijog_e16_emovif$ing_men_p_h[[459]])
#max(ingreso_hijog_e16_emovif$ing_men_p_h[[459]])
CRITERIO 3 (ingresoso aumentamos las claves, y los rangos de edad) - con region, ocupación y en el cohort de ingreso tienen 717
ingreso_hijog_e18_emovif%>%select(id_hijo,id_ho)
len<-0
for(i in 1:nrow(ingreso_hijog_e18_emovif)){
len<- len + length(ingreso_hijog_e18_emovif$ing_men_p_h[[i]])
}
len/nrow(ingreso_hijog_e18_emovif)
Base de ingresos hijos final
base1<- readRDS(file="Datos/ingreso_hij_f_emovi_sin_re_p1.Rda")
nrow(base1)#1148 +89 = 1237
base2<- readRDS(file="Datos/ingreso18_hij_f_emovi_sin_re_p1.Rda")
nrow(base2)#1148 + 89 = 1237
#base1%>%filter(!(id_ho %in% base2$id_ho))
basep<-base2%>%filter(!(id_ho %in% base1$id_ho))
nrow(basep)
basep2<-full_join(base1, basep)
nrow(basep2) # 1237 + 62 = 1299
#_______________________________________
base3<- readRDS(file="Datos/ingreso18_hij_f_emovi_sinm3_re_p1.Rda")
nrow(base3) # 1266 + 33 = 1299
#basep2%>%filter(!(id_ho %in% base3$id_ho))
basep3<- base3%>%filter(!(id_ho %in% basep2$id_ho))
nrow(basep3)
basep4<- full_join(basep3,basep2)
nrow(basep4)# 1299
#____________________________________________
base4<- readRDS(file="Datos/ingreso18_hij_f_emovi_sinm2_re_p1.Rda")
nrow(base4) # 1346
#basep4%>%filter(!(id_ho %in% base4$id_ho))
basep5<-base4%>%filter(!(id_ho %in% basep4$id_ho))
nrow(basep5)#59
basep6<-full_join(basep5,basep4)
nrow(basep6)# 1358
#______________________________
base5<- readRDS(file="Datos/ingreso18_hij_f_emovi_sinm1_re_p1.Rda")
nrow(base5)# 1473
#basep6%>%filter(!(id_ho %in% base5$id_ho))
basep7<-base5%>%filter(!(id_ho %in% basep6$id_ho))
nrow(basep7)# 119
basep8<-full_join(basep7,basep6)
nrow(basep8)# 1477
#______________________________________________
base6<- readRDS(file="Datos/ingreso_hij_f_emovi_sinm3_re_p1.Rda")
nrow(base6)#1270
#basep8%>%filter(!(id_ho %in% base6$id_ho))
basep9<-base6%>%filter(!(id_ho %in% basep8$id_ho))
nrow(basep9)# 1
basep10<-full_join(basep9,basep8)
nrow(basep10) # 1478
#__________________________________________________________________
base7<- readRDS(file="Datos/ingreso_hij_f_emovi_sinm2_re_p1.Rda")
nrow(base7)#1342
#basep10%>%filter(!(id_ho %in% base7$id_ho))
basep11<-base7%>%filter(!(id_ho %in% basep10$id_ho))
nrow(basep11)# 2
basep12<-full_join(basep11,basep10)
nrow(basep12)# 1480
#__________________________________________________________________
base8<- readRDS(file="Datos/ingreso_hij_f_emovi_sinm1_re_p1.Rda")
nrow(base8) # 1476
#basep12%>%filter(!(id_ho %in% base8$id_ho))
basep13<-base8%>%filter(!(id_ho %in% basep12$id_ho))
nrow(basep13) # 6
basep14<-full_join(basep13,basep12)
nrow(basep14)# 1486
base_cf<-basep14
saveRDS(base_cf,file="Datos/ingreso_hij_f_emovi_combinada_p1.Rda")
base1<- readRDS(file="Datos/ingreso_hij_f_emovi_sin_re_ch_cri3.Rda")
nrow(base1) # 504 + 158 = 662
base2<- readRDS(file="Datos/ingreso18_hij_f_emovi_sin_re_ch_cri3.Rda")
nrow(base2) # 526 + 136 = 662
#base1%>%filter(!(id_ho %in% base2$id_ho))
basep<-base2%>%filter(!(id_ho %in% base1$id_ho))
basep2<-full_join(base1, basep)
nrow(basep2) # 662 + 106 = 768
#_______________________________________
base3<- readRDS(file="Datos/ingreso_hij_f_emovi_sinm3_re_ch_cri3.Rda")
nrow(base3) # 648 + 120 = 768
#basep2%>%filter(!(id_ho %in% base3$id_ho))
basep3<- base3%>%filter(!(id_ho %in% basep2$id_ho))
nrow(basep3)
basep4<- full_join(basep3,basep2)
nrow(basep4)# 768 + 48 = 816
#____________________________________________
base4<- readRDS(file="Datos/ingreso18_hij_f_emovi_sinm3_re_ch_cri3.Rda")
nrow(base4)# 671 + 145 = 816
#basep4%>%filter(!(id_ho %in% base4$id_ho))
basep5<-base4%>%filter(!(id_ho %in% basep4$id_ho))
nrow(basep5)# 48
basep6<-full_join(basep5,basep4)
nrow(basep6)# 816 + 111 = 927
#______________________________
base5<- readRDS(file="Datos/ingreso_hij_f_emovi_sinm2_re_ch_cri3.Rda")
nrow(base5)# 840 + 87 = 927
#basep6%>%filter(!(id_ho %in% base5$id_ho))
basep7<-base5%>%filter(!(id_ho %in% basep6$id_ho))
nrow(basep7)# 111
basep8<-full_join(basep7,basep6)
nrow(basep8)# 927 + 46 = 973
#______________________________________________
base6<- readRDS(file="Datos/ingreso18_hij_f_emovi_sinm2_re_ch_cri3.Rda")
nrow(base6)# 841 + 132 = 973
#basep8%>%filter(!(id_ho %in% base6$id_ho))
basep9<-base6%>%filter(!(id_ho %in% basep8$id_ho))
nrow(basep9)# 46
basep10<-full_join(basep9,basep8)
nrow(basep10) # 973 + 197 = 1170
#__________________________________________________________________
base7<- readRDS(file="Datos/ingreso_hij_f_emovi_sinm1_re_ch_cri3.Rda")
nrow(base7)# 1127 + 43 = 1170
#basep10%>%filter(!(id_ho %in% base7$id_ho))
basep11<-base7%>%filter(!(id_ho %in% basep10$id_ho))
nrow(basep11)# 197
basep12<-full_join(basep11,basep10)
nrow(basep12)# 1170 + 41 = 1211
#___________________________________________________________________
base8<- readRDS(file="Datos/ingreso18_hij_f_emovi_sinm1_re_ch_cri3.Rda")
nrow(base8) # 1140 + 71 = 1211
#basep12%>%filter(!(id_ho %in% base8$id_ho))
basep13<-base8%>%filter(!(id_ho %in% basep12$id_ho))
nrow(basep13) # 41
basep14<-full_join(basep13,basep12)
nrow(basep14)# 1211
base_cf<-full_join(base_hijos_fija_f, basep14)
str(unique(base_cf$id_ho))
Ingreso hijos directo
hijos_para_sal_2 <- hijos_para_sal%>%filter(!(id_ho %in%base_cf$id_ho ))
nrow(hijos_para_sal_2)
hijos_para_sal_2%>%count(p133)
hacemos su intervalo
hijos_para_sal_2<-hijos_para_sal_2%>%mutate(
low=ifelse(p133==1,0,
ifelse(p133==3, 2401.0,
ifelse(p133==4,4801.0,
ifelse(p133==5,7201.0,
ifelse(p133==6,12001.0,24001))) )),
upper = ifelse(p133==1,2399.0,
ifelse(p133==3, 4800.0,
ifelse(p133==4,7200.0,
ifelse(p133==5,12000.0,
ifelse(p133==6,24000,40000))) ))
#type = ifelse(p133!=7,"interval","left"),
#event = ifelse(p133!=7,3,2)
)
hings<-hijos_para_sal_2%>%mutate(p052=p05*p05)
Z <-with(hings, Surv(low,
upper,
event = rep(3,nrow(hings)),
type = "interval"))
modelo<-survreg(Z~ factor(p133) + p05 + p052 + p06 + p13 + factor(substr(SINCO3,1,1))-1, data=hings,
dist = "gaussian")
summary(modelo)
newd<- data.frame(#region = factor(hings$region),
p133 = factor(hings$p133),
p05=hings$p05,
p052=hings$p052,
p06=hings$p06,
p13=hings$p13,
SINCO3=factor(substr(hings$SINCO3,1,1)))
hings$ingress<-predict(modelo,newd, type="response")
hings%>%select(-ingreso)
pro<-full_join(hings,hijos_para_sal2%>%select(-ingreso))
pro%>%mutate(ingress=ifelse(p133==2,2400,ingress))%>%
mutate(cohort_h = ifelse(ingress<=2400,1,
ifelse(ingress<=4800,2,
ifelse(ingress<=7200,3,
ifelse(ingress<=12000,4,
ifelse(ingress<=24000,5,6))))),
cohort_dif= as.integer(p133)-cohort_h)%>%filter(p133==2)%>%nrow()
saveRDS(base_cf,file="Datos/ingreso_hij_f_emovi_combinada_cri3.Rda")
rango percentil 16-18
#IN<-(100/110.907)
IN<-(100/93.6)
#
ingre1618<-bind_rows(ingresos_e16a%>%select(ling_men_pd),ingresos_e18a%>%select(ling_men_pd))
rp_e1618 <- rank(ingre1618$ling_men_pd)/length(ingre1618$ling_men_pd)
#rp_e1618<-percent_rank(ingre1618$ling_men_pd)
hist(rp_e1618)
Hijos con ingreso
hijos_emovi_hp <- readRDS(file="Datos/ingreso_hij_f_emovi_combinada_p1.Rda")
#hijos_emovi_hp <- readRDS(file="Datos/ingreso_hij_f_emovi_combinada_cri3.Rda")
#hijos_emovi_hp <- readRDS(file="Datos/ingreso_hij_f_emovi_sin_re_ch_cri3.Rda")
#hijos_emovi_hp <- readRDS(file="Datos/ingreso_hij_f_emovi_re_ch_cri3.Rda")
#hijos_emovi_hp <- readRDS(file="Datos/ingreso_hij_f_emovi_re_ch_cri2.Rda")
#hijos_emovi_hp <- readRDS(file="Datos/ingreso_hij_f_emovi_re.Rda")
#hijos_emovi_hp <- readRDS(file="Datos/ingreso_hij_f_emovi_sin_re_ch.Rda")
nrow(hijos_emovi_hp)
hijos_emovi_hp
# p05 edad act
# p06 sexo act
# p13 educ hijo
# SINCO3, ocupación hijo
# p23 en qeu estado vivia a los 14
# p26 principal sosten ecómico
# p38_11 edad padre 2016
# p38m_11 edad madre 2016
# p43 nivel educativo padre
#p43m nivel educativo madre
# cmo1_2 ocupacion del padre
# cmo2_2 ocupacion de la madre
varp<-c("Estado","p05","p06","p13","SINCO3","p23","p26","p38_11","p38m_11","p43","p44",
"p43m","p44m","cmo1_2","cmo2_2","mov",
"region","p133","id_ho")
padres_h<-data_emovi2017%>%
# # filter(p02 == 1) %>% #compartir gasot para comer
# filter(between(p05,25,50)) %>% # edad <-----------------criterio 1 y 3
# #filter(p08 == 1) %>%
# filter(p12 == 2) %>%# ya no estudia
# filter(p26 == 1 | p26==2 ) %>% # sosten principal papa, mama,
# filter((!is.na(p43) & p43!=98 & p26 == 1 & cmo1_2!="." & !is.na(p38_11))|#<----------ojo ocupacion ns
# (!is.na(p43m) & p43m!=98 & p26 == 2 & cmo2_2!="." & !is.na(p38m_11))) %>% # reporta educación de pp
# filter(!is.na(p13))%>% # reporta educación
# filter(SINCO3 !="") %>%# reporta oficio actual
# filter(p68 == 1 | p69 == 1) %>% # si trabaja
# filter(p132 %in% c(1)) %>%# persona que aportan ingreso
# filter(!p133 %in% c(8,9,NA) )%>%
select(varp)%>%
slice(as.integer(unlist(hijos_emovi_hp%>%select(id_ho))))%>%#<---------oojooo ers id_hijo
# filter(id_ho %in% hijos_emovi_hp$id_ho )%>%
mutate(
pp_id_hijo = hijos_emovi_hp%>%pull(id_ho),# era id_hijo
ing_h = hijos_emovi_hp%>%pull(ing_men_p_h),
cohort = ifelse(p133==1,2,p133)-1,
region = hijos_emovi_hp%>%pull(regionh)
)%>%
rename(
edad_h = p05,
sexo_h = p06,
edu_h = p13,
ocu_h = SINCO3,
pp_estado = p23,
pp = p26,
p_edad_2016= p38_11,
m_edad_2016 = p38m_11,
p_edu = p43,
p_edug = p44,
m_edu = p43m,
m_edug = p44m,
p_ocu = cmo1_2,
m_ocu = cmo2_2
)%>%
mutate(
p_edu = as.integer(p_edu),
m_edu = as.integer(m_edu)
)
length(padres_h)
# las ocupaciones no encontradas las sustituimos por un NA
padres_h<-padres_h%>%
mutate(p_ocu = ifelse(p_ocu==".",NA,p_ocu),
m_ocu = ifelse(m_ocu==".",NA,m_ocu))
unique(padres_h$p_ocu)
unique(padres_h$m_ocu)
head(padres_h)
Crear base limpia
filtro_pp_c<-function(df_1,general = 0)
{
#recibe un hijo de un dataframe, para polimorfismo
# general = 0y regresa un data frame con los datos
# ordenados del hijo
if(df_1["pp"]==1)
{
dfn <- df_1%>%
filter(pp==1)%>%
select(starts_with(c("pp","p_")),
ing_h,edu_h,ocu_h,edad_h,p_edad_2016,
region,cohort,sexo_h)%>%
mutate(pp_edad2016 = p_edad_2016)%>%
rename(
id_ho = pp_id_hijo,
pp_sexo = pp,
pp_edad = p_edad_2016,
pp_educ = p_edu,
pp_educg = p_edug,
pp_ocup = p_ocu
)%>%
mutate(pp_edad = pp_edad + (14-edad_h))
}
if(df_1["pp"]==2)
{
dfn<-df_1%>%
filter(pp==2)%>%
select(starts_with(c("pp","m_")),ing_h,edu_h,
ocu_h,edad_h,m_edad_2016,
region,cohort,sexo_h)%>%
mutate(pp_edad2016 = m_edad_2016)%>%
rename(
id_ho = pp_id_hijo,
pp_sexo = pp,
pp_edad = m_edad_2016,
pp_educ = m_edu,
pp_educg = m_edug,
pp_ocup = m_ocu
)%>%
mutate(pp_edad = pp_edad + (14-edad_h))
}
if(is.na(dfn$pp_edad) & general){
return("ND")
}
return(dfn)
}
#comporbamos qeu funcione bien
filtro_pp_c(padres_h[1,])
acomoda_df_c<-function(df){
#damos un df de una edad, y
# nos regresa un data frame acomodado
aux<-function(i){
return(df[i,])
}
a<-lapply(1:nrow(df),aux)
L<-lapply(a,filtro_pp_c)
dfn <-bind_rows(L[1:length(L)])
return(dfn)
}
dfh<-acomoda_df_c(padres_h)
pro_edad_c <- function(df){
#le damos el df y nos regresa el promedio de la edade los padres
df%>%summarise(
promedi_edad_padres = mean(pp_edad2016,na.rm=TRUE))
}
edades_pro<- pro_edad_c(dfh)
mean(dfh$edad_h)
edades_pro
#edades de padres faltantes
sum(is.na(dfh$pp_edad2016))
#
head(dfh)
# 2016-21
Codificacion eduación
dfh_c<- dfh%>%
mutate(
pp_educ_a = ifelse(pp_educ==1,1, #sin instruccion(1)
ifelse(pp_educ==2,1+pp_educg,
ifelse(pp_educ %in% c(3,4),7+pp_educg,
ifelse(pp_educ %in% c(5,6,7,8,9),10+pp_educg,
ifelse(pp_educ %in% c(10,11),13+pp_educg,17+pp_educg)))))
)
unique(dfh_c$pp_educ_a)
dfh_c<-dfh_c%>%
mutate(
pp_educ_ac = ifelse(pp_educ_a %in% 0:5,"C1",
ifelse(pp_educ_a %in% 6:10 ,"C2",
ifelse(pp_educ_a %in% 11:12,"C3",
ifelse(pp_educ_a %in% 13:14,"C4","C5"))))
)
### Guardamos base de datos de hijos final
saveRDS(dfh_c, file="Datos/dfh_c_combinada_p1.Rda")
#saveRDS(dfh_c, file="Datos/dfh_c_sin_re_ch_cri3.Rda")
#saveRDS(dfh_c, file="Datos/dfh_c_re_ch_cri3.Rda")
#saveRDS(dfh_c, file="Datos/dfh_c_re_ch_cri2.Rda")
#saveRDS(dfh_c, file="Datos/dfh_c_sin_re_ch.Rda")
Padres 1998
criterio 1, Seleccionamos de la ENIGH 1997, no hay entonces 1998
criterio 2 NO tenemos enigh 93 agarramos enigh 94 (cuando la tengamos)
Poblacion enigh 98
poblacion<-read.dbf(
file="Datos/ENIGH-Historica/1998/POBLA98.dbf"
)
poblacion_e98<-poblacion%>%
filter(
parentesco == "01",
between(edad,25,60),#<------------------ criterio 1 y 3 cambiar
!is.na(ed_formal),
!is.na(ed_tecnica),
!is.na(ocupacion),
n_empleos==1, # el entrevistado solo proporciona una ocupación
)%>%
select(
folio,
num_ren,
edad,
sexo,
ed_formal,
ed_tecnica,
ocupacion
)%>%
mutate(
ed_formal = as.integer(as.character(ed_formal)),
ed_tecnica= as.integer(as.character(ed_tecnica)),
estado = substr(folio,5,6)
)
#unique(pobla_enigh1998$ed_formal)
#pobla_enigh1998$ed_formal
nrow(poblacion_e98)
head(poblacion_e98$ed_formal)
str(poblacion_e98$ed_formal)#caracter 2 espacios
unique(poblacion_e98$ed_formal)
#pobla_enigh1998$ed_formal=="03"
head(poblacion_e98$ed_tecnica)
str(poblacion_e98$ed_tecnica)#caracter 1 espacio
unique(poblacion_e98$ed_tecnica)
#pobla_enigh1998%>%count(n_empleos), se exploro para quitar una ocupacion
names(poblacion)
str(poblacion$per_ing)
unique(poblacion_e98$estado)
folios de gente con hijos menores de 14 años
folios98<-as.character(poblacion%>%filter(parentesco %in% c("04","05"),edad<=18)%>%select(folio)%>%pull())
poblacion_e98<-poblacion_e98%>%filter(folio %in% folios98 )
Codificación educación enigh 1998
# hacemos la codificación de ENIGH2018 a ESRU
#1 Preescolar o kínder
# 2 Primaria
# 3 Secundaria técnica
# 4 Secundaria general
# 5 Preparatoria técnica
# 6 Preparatoria general
# 7 Técnica o comercial con secundaria
# 8 Técnica o comercial con preparatoria
# 9 Normal básica (con primaria o secundari
# 10 Normal de licenciatura
# 11 Profesional (licenciatura o ingeniería)
# 12 Postgrado (maestría o doctorado)
#_____________________________________________________
# 98 NS, no aplica porque pedimos la edución del pp como instrumento
# vemso las combinaciones de educación para codificar
comb<-poblacion_e98%>%
mutate( combi = paste(as.character(ed_formal),as.character(ed_tecnica)))%>%
select(ed_formal,ed_tecnica,combi)
sort(unique(comb$combi))
# [1] "01 1" "02 1" "03 1" "03 2" "04 1" "05 1" "06 1" "07 1" "07 2" "08 1"
# [11] "08 2" "08 3" "08 4" "08 5" "09 1" "09 4" "09 5" "10 1" "10 2" "10 4"
# [21] "10 5" "11 1" "11 3" "11 4" "11 5" "11 6" "11 7" "12 1" "12 3" "12 5"
# [31] "12 6" "12 7" "13 1" "13 5" "13 6" "13 7" "13 8" "13 9" "14 1" "14 3"
# [41] "14 5" "14 6" "14 7" "14 9" "15 1" "15 3" "15 4" "15 5" "15 6" "15 7"
# [51] "15 9" "16 1" "16 5" "16 7" "16 9"
# "16 1" "16 5" "16 7" "16 9"
#codificamos a a años de educación
poblacion_e98c<-poblacion_e98%>%
mutate(
edu_a = ifelse(ed_formal==1 & ed_tecnica==1,0, #sin instruccion(1)
ifelse((ed_formal %in% c(2,3,4,5,6,7,8,9,10,11,12,13))
& (ed_tecnica %in% c(1,2)),ed_formal-1,
ifelse(ed_formal==8 & (ed_tecnica %in% c(3,4,5)),9,
ifelse(ed_formal==9 & (ed_tecnica %in% c(4,5)),10,
ifelse(ed_formal==10 & (ed_tecnica %in% c(2,4,5)),11,
ifelse(ed_formal==11 & (ed_tecnica %in% c(3,4,5,5,7)),12,
ifelse((ed_formal %in%c(12)) & (ed_tecnica %in% c(3,5,6,7)),12,
ifelse(ed_formal==13 & (ed_tecnica %in% c(5,6,7,8,9)),13,
ifelse(ed_formal==14 & (ed_tecnica %in% c(1,3,5,6,7,9)),14,
ifelse(ed_formal==15 & (ed_tecnica %in% c(1,3,4,5,6,7,9)),17,19))))))))))
)
unique(poblacion_e98c$edu_a)
#codificamos a coghort de educación
poblacion_e98c<-poblacion_e98c%>%
mutate(
edu_ac = ifelse(edu_a %in% 0:5,"C1",
ifelse(edu_a %in% 6:10 ,"C2",
ifelse(edu_a %in% 11:12,"C3",
ifelse(edu_a %in% 13:14,"C4","C5"))))
)
unique(poblacion_e98c$edu_ac )
Creacion de region
poblacion_e98c<-poblacion_e98c%>%
mutate(
region = ifelse(estado %in% c("02","26","08","05","19","28"),1,
ifelse(estado %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(estado %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
Ingresos enigh 98
ingresos<-read.dbf(
file="Datos/ENIGH-Historica/1998/ingresos.dbf"
)
familias_integrantes <- function(df,nr){
dfn <- df %>%
filter(NUM_REN %in% nr)
return(dfn)
}
ingresos_acu <- function(df,clavs){
dfn <- df %>%
group_by(FOLIO, NUM_REN) %>%
filter(CLAVE %in% clavs)%>%
summarise(
claves_a = paste(CLAVE,collapse = ","),
ing_tri_t = sum(ING_TRI),
ing_men_p = ing_tri_t/3,
ling_men_p = log(ing_men_p)
) %>% ungroup()
return(dfn)
}
#hogares <- c("1","2","3","4","5")
personas_h <- c('01')
a<-familias_integrantes(ingresos,personas_h)
head(a)
## criterio 1
#claves<-c("P001","P002","P003","P010","P011","P012","P013","P014","P015", #"P016","P017","P018","P020","P021","P026","P027","P035","P040","P041","P042","P044","P045")
## criterio 2 flexibilida de los ingresos y criterio 3
claves<-c("P001","P002","P003","P010","P011","P012","P013","P014","P015", "P016","P017","P018","P020","P021","P022","P023","P024","P025","P026","P027","P028","P035","P036","P037","P040","P041","P042","P044","P045")
ingresos_e98<-ingresos_acu(a,claves)
ingresos_e98<-ingresos_e98%>%
select(FOLIO,NUM_REN,claves_a,ing_men_p,ling_men_p)%>%
rename(
folio = FOLIO,
num_ren = NUM_REN
)
head(ingresos_e98)
ingresos_e98<-ingresos_e98%>%
mutate(
region = ifelse(substr(folio,5,6) %in% c("02","26","08","05","19","28"),1,
ifelse(substr(folio,5,6) %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(substr(folio,5,6) %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
rango percentil 98
#IN<-(100/110.907)
IN<-(100/93.6)
ingresos_e98$ling_men_pd<-ingresos_e98$ling_men_p + log(IN)
rp_e98 <- rank(ingresos_e98$ling_men_pd)/length(ingresos_e98$ling_men_pd)
#rp_e98<-percent_rank(ingresos_e98$ling_men_pd)
ingresos_e981 <- data.frame(ling_men_pd=ingresos_e98%>%filter(region==1)%>%pull(ling_men_p) + log(IN))
rp_e981 <- rank(ingresos_e981$ling_men_pd)/length(ingresos_e981$ling_men_pd)
ingresos_e982 <- data.frame(ling_men_pd=ingresos_e98%>%filter(region==2)%>%pull(ling_men_p) + log(IN))
rp_e982 <- rank(ingresos_e982$ling_men_pd)/length(ingresos_e982$ling_men_pd)
ingresos_e983 <- data.frame(ling_men_pd=ingresos_e98%>%filter(region==3)%>%pull(ling_men_p) + log(IN))
rp_e983 <- rank(ingresos_e983$ling_men_pd)/length(ingresos_e983$ling_men_pd)
ingresos_e984 <- data.frame(ling_men_pd=ingresos_e98%>%filter(region==4)%>%pull(ling_men_p) + log(IN))
rp_e984 <- rank(ingresos_e984$ling_men_pd)/length(ingresos_e984$ling_men_pd)
Base cruzada pobla-ing
enigh_98<-full_join(poblacion_e98c,ingresos_e98)%>%
drop_na()%>%
mutate(
ocupacion = substr(ocupacion,1,2)
)#%>%
# rename(
# EDU=N_INSTR161,
# OCU = CMO121
# )%>%
# mutate(
# EDU = as.character(EDU)
# )
head(enigh_98)
unique(enigh_98$edad)
# ajuste para nivel de ecucación ESRU
#data_padres2005$EDU <- factor(data_padres2005$EDU)
#data_padres2005$OCU <- factor(data_padres2005$OCU)
#unique(data_padres2005$OCU)
sum(is.na(enigh_98))
##### Guardamos base de padres final
saveRDS(enigh_98, file="Datos/enigh_98_cri3.Rda")
enigh_98%>%count(sexo)
Grafica de ingresos y edad
ed_ear<-full_join(poblacion_e98c,ingresos_e98)%>%
select(edad, ing_men_p)%>%drop_na()%>%
group_by(edad)%>%
summarise(
pro_ing = mean(ing_men_p)
)
ed_ear%>%
hchart( "scatter",
hcaes(x = edad, y = pro_ing),
name="ingreso promedio",
regression = TRUE,
regressionSettings = list(
type = "polynomial",
dashStyle = "ShortDash",
color = "skyblue",
order = 2,
lineWidth = 5,
name = "%eq | $r^2$: %r",
hideInLegend = FALSE)
)%>%
hc_add_dependency("plugins/highcharts-regression.js")
Esdística descriptiva 98
summary(enigh_98$edad)
hist(enigh_98$edad)
papas<- enigh_98%>%group_by(edad)%>%summarise(msal = mean(ing_men_p))
plot(papas$edad,papas$msal)
Padres 1996
poblacion eningh 1996
poblacion<-read.dbf(
file="Datos/ENIGH-1996/POBLA96.dbf"
)
poblacion <- poblacion %>%
rename(
parentesco = PARENTESCO,
folio = FOLIO,
num_ren = NUM_REN,
sexo = SEXO,
edad = EDAD,
per_ing=PER_ING,
ed_formal=ED_FORMAL,
ed_tecnica=ED_TECNICA,
ocupacion=OCUPACION
)
poblacion
poblacion_e96<-poblacion%>%
filter(
parentesco == "01",#en el 98 era "01"
between(edad,25,60),
!is.na(ed_formal),
!is.na(ed_tecnica),
!is.na(ocupacion),
N_EMPLEOS==1, # el entrevistado solo proporciona una ocupación
)%>%
select(
folio,
num_ren,
edad,
sexo,
ed_formal,
ed_tecnica,
ocupacion
)%>%
mutate(
ed_formal = as.integer(as.character(ed_formal)),
ed_tecnica= as.integer(as.character(ed_tecnica)),
estado = substr(folio,5,6)
)
#En 1998 para hijos es "04" y "05". En 1996 "4" abarca todos los hijos
#En 1998 se considera edad<=18, en 1996 se considera edad<=14
folios96<-as.character(poblacion%>%filter(parentesco %in% c("04","05"),edad<=16)%>%select(folio)%>%pull())
poblacion_e96<-poblacion_e96%>%filter(folio %in% folios96 )
nrow(poblacion_e96)
head(poblacion_e96$ed_formal)
str(poblacion_e96$ed_formal)#caracter 2 espacios
unique(poblacion_e96$ed_formal)
head(poblacion_e96$ed_tecnica)
str(poblacion_e96$ed_tecnica)#caracter 1 espacio
unique(poblacion_e96$ed_tecnica)
names(poblacion_e96)
str(poblacion_e96$per_ing)
# hacemos la codificación de ENIGH2018 a ESRU
# 1 Preescolar o kínder
# 2 Primaria
# 3 Secundaria técnica
# 4 Secundaria general
# 5 Preparatoria técnica
# 6 Preparatoria general
# 7 Técnica o comercial con secundaria
# 8 Técnica o comercial con preparatoria
# 9 Normal básica (con primaria o secundari
# 10 Normal de licenciatura
# 11 Profesional (licenciatura o ingeniería)
# 12 Postgrado (maestría o doctorado)
#_____________________________________________________
# 96 NS, no aplica porque pedimos la edución del pp como instrumento
comb<-poblacion_e96%>%
mutate( combi = paste(as.character(ed_formal),as.character(ed_tecnica)))%>%
select(ed_formal,ed_tecnica,combi)
comb
sort(unique(comb$combi))
poblacion_e96c<-poblacion_e96%>%
mutate(
edu_a = ifelse(ed_formal==0 & ed_tecnica==0,0, #sin instruccion(1)
ifelse((ed_formal %in% c(2:13)) & (ed_tecnica %in% c(0,2,3)),ed_formal,
ifelse((ed_formal %in% c(7:13)) & (ed_tecnica %in% c(4,5,6,8)),ed_formal+1,
ifelse(ed_formal==14 & (ed_tecnica %in% c(0,2,4,5,6,8)),17,19))))
)
poblacion_e96c<-poblacion_e96c%>%
mutate(
edu_ac = ifelse(edu_a %in% 0:5,"C1",
ifelse(edu_a %in% 6:10 ,"C2",
ifelse(edu_a %in% 11:12,"C3",
ifelse(edu_a %in% 13:14,"C4","C5"))))
)
poblacion_e96c<-poblacion_e96c%>%
mutate(
region = ifelse(estado %in% c("02","26","08","05","19","28"),1,
ifelse(estado %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(estado %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
Ingresos 96
ingresos<-read.dbf(
file="Datos/ENIGH-1996/ingresos.dbf"
)
familias_integrantes <- function(df,nr){
dfn <- df %>%
filter(NUM_REN %in% nr)
return(dfn)
}
ingresos_acu <- function(df,clavs){
dfn <- df %>%
group_by(FOLIO, NUM_REN) %>%
filter(CLAVE %in% clavs)%>%
summarise(
claves_a = paste(CLAVE,collapse = ","),
ing_tri_t = sum(ING_TRI),
ing_men_p = ing_tri_t/3,
ling_men_p = log(ing_men_p)
) %>% ungroup()
return(dfn)
}
#hogares <- c("1","2","3","4","5")
personas_h <- c('01')
a<-familias_integrantes(ingresos,personas_h)
head(a)
#P001 Sueldos, salarios, jornal y horas extras
#P002 Comisiones, propinas y destajo
#P010:P018 de 1998 son las mismas que P006:P014 de 1996
#P020:P021 de 1998 son las mismas que P016:P017 de 1996
#P026 de 1998 es la misma que P022 de 1996, aunque no hay equivalente en 1996 a la P027 de 1998
#P035 de 1998 es la misma que P030 de 1996
#P040:P042 de 1998 son las mismas que P035:P037 de 1996
#P044:P045 de 1998 son las mismas que P039:P040 de 1996
claves<-c("P001","P002","P006","P007","P008","P009","P010","P011", "P012","P013","P014","P016","P017","P022","P030","P035","P036","P037","P039","P040")
ingresos_e96<-ingresos_acu(a,claves)
ingresos_e96<-ingresos_e96%>%
select(FOLIO,NUM_REN,claves_a,ing_men_p,ling_men_p)%>%
rename(
folio = FOLIO,
num_ren = NUM_REN
)
head(ingresos_e96)
ingresos_e96<- ingresos_e96%>%
mutate(
region = ifelse(substr(folio,5,6) %in% c("02","26","08","05","19","28"),1,
ifelse(substr(folio,5,6) %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(substr(folio,5,6) %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
rango percentil 96
#IN<-(100/110.907)
IN<-(100/93.6)
ingresos_e96$ling_men_pd<-ingresos_e96$ling_men_p + log(IN)
rp_e96 <- rank(ingresos_e96$ling_men_pd)/length(ingresos_e96$ling_men_pd)
#rp_e96<-percent_rank(ingresos_e96$ling_men_pd)
Base cruzada pobla-ing 96
enigh_96<-full_join(poblacion_e96c,ingresos_e96)%>%
drop_na()%>%
mutate(
ocupacion = substr(ocupacion,1,2)
)#%>%
# rename(
# EDU=N_INSTR161,
# OCU = CMO121
# )%>%
# mutate(
# EDU = as.character(EDU)
# )
head(enigh_96)
unique(enigh_96$edad)
# ajuste para nivel de ecucación ESRU
#data_padres2005$EDU <- factor(data_padres2005$EDU)
#data_padres2005$OCU <- factor(data_padres2005$OCU)
#unique(data_padres2005$OCU)
sum(is.na(enigh_96))
names(enigh_96)
##### Guardamos base de padres final
saveRDS(enigh_96, file="Datos/enigh_96_cri3.Rda")
Esdística descriptiva 96
summary(enigh_96$edad)
hist(enigh_96$edad)
papas<- enigh_96%>%group_by(edad)%>%summarise(msal = mean(ing_men_p))
plot(papas$edad,papas$msal)
Padres 1994
poblacion enigh 1994
poblacion<-read.dbf(
file="Datos/ENIGH-Historica/1994/POBLA94.dbf"
)
poblacion <- poblacion %>%
rename(
parentesco = PARENTESCO,
folio = FOLIO,
num_ren = NUM_REN,
sexo = SEXO,
edad = EDAD,
per_ing=PER_ING,
ed_formal=ED_FORMAL,
ed_tecnica=ED_TECNICA,
ocupacion=OCUPACION
)
poblacion
poblacion_e94<-poblacion%>%
filter(
parentesco == "1",#en el 98 era "01"
between(edad,25,60),
!is.na(ed_formal),
!is.na(ed_tecnica),
!is.na(ocupacion),
N_EMPLEOS==1, # el entrevistado solo proporciona una ocupación
)%>%
select(
folio,
num_ren,
edad,
sexo,
ed_formal,
ed_tecnica,
ocupacion
)%>%
mutate(
ed_formal = as.integer(as.character(ed_formal)),
ed_tecnica= as.integer(as.character(ed_tecnica)),
estado = substr(folio,5,6)
)
#En 1998 para hijos es "04" y "05". En 1994 "4" abarca todos los hijos
#En 1998 se considera edad<=18, en 1994 se considera edad<=14
folios94<-as.character(poblacion%>%filter(parentesco %in% c("4"),edad<=13)%>%select(folio)%>%pull())
poblacion_e94<-poblacion_e94%>%filter(folio %in% folios94 )
nrow(poblacion_e94)
head(poblacion_e94$ed_formal)
str(poblacion_e94$ed_formal)#caracter 2 espacios
unique(poblacion_e94$ed_formal)
head(poblacion_e94$ed_tecnica)
str(poblacion_e94$ed_tecnica)#caracter 1 espacio
unique(poblacion_e94$ed_tecnica)
names(poblacion_e94)
str(poblacion_e94$per_ing)
# hacemos la codificación de ENIGH2018 a ESRU
# 1 Preescolar o kínder
# 2 Primaria
# 3 Secundaria técnica
# 4 Secundaria general
# 5 Preparatoria técnica
# 6 Preparatoria general
# 7 Técnica o comercial con secundaria
# 8 Técnica o comercial con preparatoria
# 9 Normal básica (con primaria o secundari
# 10 Normal de licenciatura
# 11 Profesional (licenciatura o ingeniería)
# 12 Postgrado (maestría o doctorado)
#_____________________________________________________
# 94 NS, no aplica porque pedimos la edución del pp como instrumento
comb<-poblacion_e94%>%
mutate( combi = paste(as.character(ed_formal),as.character(ed_tecnica)))%>%
select(ed_formal,ed_tecnica,combi)
comb
sort(unique(comb$combi))
poblacion_e94c<-poblacion_e94%>%
mutate(
edu_a = ifelse(ed_formal==0 & ed_tecnica==0,0, #sin instruccion(1)
ifelse(ed_formal==1 & (ed_tecnica %in% c(0,1)),3,
ifelse(ed_formal==1 & ed_tecnica==2,4,
ifelse(ed_formal==2 & (ed_tecnica %in% c(0,1)),6,
ifelse(ed_formal==2 & (ed_tecnica %in% c(2,3)),7,
ifelse(ed_formal==3 & (ed_tecnica %in% c(0,1)),7,
ifelse(ed_formal==3 & (ed_tecnica %in% c(2,3)),8,
ifelse(ed_formal==4 & ed_tecnica==0,9,
ifelse(ed_formal==4 & ed_tecnica==2,10,
ifelse(ed_formal==4 & (ed_tecnica %in% c(4,5)),11,
ifelse(ed_formal==4 & ed_tecnica==6,13,
ifelse(ed_formal==5 & ed_tecnica==0,11,
ifelse(ed_formal==5 & (ed_tecnica %in% c(4,5)),13,
ifelse(ed_formal==5 & ed_tecnica==6,14,
ifelse(ed_formal==6 & ed_tecnica==0,12,
ifelse(ed_formal==6 & ed_tecnica==2,13,
ifelse(ed_formal==6 & (ed_tecnica %in% c(4,5)),14,
ifelse(ed_formal==6 & (ed_tecnica %in% c(6,7,8)),15,
ifelse(ed_formal==7 & (ed_tecnica %in% c(0,1)),15,
ifelse(ed_formal==7 & (ed_tecnica %in% c(2,3)),16,
ifelse(ed_formal==7 & (ed_tecnica %in% c(4,5,6,8)),17,
ifelse(ed_formal==8 & ed_tecnica==0,17,
ifelse(ed_formal==8 & (ed_tecnica %in% c(2,4,5,6,8)),18,19)))))))))))))))))))))))
)
poblacion_e94c<-poblacion_e94c%>%
mutate(
edu_ac = ifelse(edu_a %in% 0:5,"C1",
ifelse(edu_a %in% 6:10 ,"C2",
ifelse(edu_a %in% 11:12,"C3",
ifelse(edu_a %in% 13:14,"C4","C5"))))
)
poblacion_e94c<-poblacion_e94c%>%
mutate(
region = ifelse(estado %in% c("02","26","08","05","19","28"),1,
ifelse(estado %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(estado %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
Ingresos engih 94
ingresos<-read.dbf(
file="Datos/ENIGH-Historica/1994/ingresos.dbf"
)
familias_integrantes <- function(df,nr){
dfn <- df %>%
filter(NUM_REN %in% nr)
return(dfn)
}
ingresos_acu <- function(df,clavs){
dfn <- df %>%
group_by(FOLIO, NUM_REN) %>%
filter(CLAVE %in% clavs)%>%
summarise(
claves_a = paste(CLAVE,collapse = ","),
ing_tri_t = sum(ING_TRI),
ing_men_p = ing_tri_t/3,
ling_men_p = log(ing_men_p)
) %>% ungroup()
return(dfn)
}
#hogares <- c("1","2","3","4","5")
personas_h <- c('01')
a<-familias_integrantes(ingresos,personas_h)
head(a)
#P001 Sueldos, salarios, jornal y horas extras
#P002 Comisiones, propinas y destajo
#P010:P018 de 1998 son las mismas que P006:P014 de 1994
#P020:P021 de 1998 son las mismas que P016:P017 de 1994
#P026 de 1998 es la misma que P022 de 1994, aunque no hay equivalente en 1994 a la P027 de 1998
#P035 de 1998 es la misma que P029 de 1994
#P040:P042 de 1998 son las mismas que P034:P036 de 1994
#P044:P045 de 1998 son las mismas que P038:P039 de 1994
claves<-c("P001","P002","P006","P007","P008","P009","P010","P011", "P012","P013","P014","P016","P017","P022","P029","P034","P035","P036","P038","P039")
ingresos_e94<-ingresos_acu(a,claves)
ingresos_e94<-ingresos_e94%>%
select(FOLIO,NUM_REN,claves_a,ing_men_p,ling_men_p)%>%
rename(
folio = FOLIO,
num_ren = NUM_REN
)
head(ingresos_e94)
ingresos_e94<- ingresos_e94%>%
mutate(
region = ifelse(substr(folio,5,6) %in% c("02","26","08","05","19","28"),1,
ifelse(substr(folio,5,6) %in% c("12","20","07","30","27","04","31","23"),4,
ifelse(substr(folio,5,6) %in% c("03","25","18","10","32","16","06","14","01","24"),2,3)))
)
rango percentil 94
#IN<-(100/110.907)
IN<-(100/93.6)
ingresos_e94$ling_men_pd<-ingresos_e94$ling_men_p + log(IN)
rp_e94 <- rank(ingresos_e94$ling_men_pd)/length(ingresos_e94$ling_men_pd)
#rp_e94<- percent_rank(ingresos_e94$ling_men_pd)
Bae cruzada pobla-ingre 94
enigh_94<-full_join(poblacion_e94c,ingresos_e94)%>%
drop_na()%>%
mutate(
ocupacion = substr(ocupacion,1,2)
)#%>%
# rename(
# EDU=N_INSTR161,
# OCU = CMO121
# )%>%
# mutate(
# EDU = as.character(EDU)
# )
head(enigh_94)
unique(enigh_94$edad)
# ajuste para nivel de ecucación ESRU
#data_padres2005$EDU <- factor(data_padres2005$EDU)
#data_padres2005$OCU <- factor(data_padres2005$OCU)
#unique(data_padres2005$OCU)
sum(is.na(enigh_94))
names(enigh_94)
##### Guardamos base de padres final
saveRDS(enigh_94, file="Datos/enigh_94_cri3.Rda")
Esdística descriptiva 94
summary(enigh_94$edad)
hist(enigh_94$edad)
papas<- enigh_94%>%group_by(edad)%>%summarise(msal = mean(ing_men_p))
plot(papas$edad,papas$msal)
Eslaticidad integeneracional de ingresos
base_logsing <- list(ingresos_e94,ingresos_e96,ingresos_e98)
base_rp <- list(rp_e94,rp_e96,rp_e98)
Deflactamos ingresos
INPC Feb 2021 = 110.907 Consulta
enigh_94 <- readRDS(file = "Datos/enigh_94_cri3.Rda")
enigh_96 <- readRDS(file = "Datos/enigh_96_cri3.Rda")
enigh_98 <- readRDS(file = "Datos/enigh_98_cri3.Rda")
#dfh_c <- readRDS(file = "Datos/dfh_c_sin_re.Rda")
#dfh_c <- readRDS(file = "Datos/dfh_c_sin_re_ch.Rda")
#dfh_c <- readRDS(file = "Datos/dfh_c_re.Rda")
#dfh_c <- readRDS(file = "Datos/dfh_c_re_ch_cri3.Rda")
dfh_c <- readRDS(file = "Datos/dfh_c_combinada_ch_cri3.Rda")
#dfh_c <- readRDS(file = "Datos/dfh_c_combinada_p1.Rda")
enigh_94<-enigh_94%>%mutate(
edad_c = ifelse(25<=edad & edad<=29,"Edad1",
ifelse(30<=edad & edad<=34,"Edad2",
ifelse(35<=edad & edad<=39,"Edad3",
ifelse(40<=edad & edad<=44,"Edad4",
ifelse(45<=edad & edad<=49,"Edad5",
ifelse(50<=edad & edad<=54,"Edad6","Edad7"))))))
)
enigh_96<-enigh_96%>%mutate(
edad_c = ifelse(25<=edad & edad<=29,"Edad1",
ifelse(30<=edad & edad<=34,"Edad2",
ifelse(35<=edad & edad<=39,"Edad3",
ifelse(40<=edad & edad<=44,"Edad4",
ifelse(45<=edad & edad<=49,"Edad5",
ifelse(50<=edad & edad<=54,"Edad6","Edad7"))))))
)
enigh_98<-enigh_98%>%mutate(
edad_c = ifelse(25<=edad & edad<=29,"Edad1",
ifelse(30<=edad & edad<=34,"Edad2",
ifelse(35<=edad & edad<=39,"Edad3",
ifelse(40<=edad & edad<=44,"Edad4",
ifelse(45<=edad & edad<=49,"Edad5",
ifelse(50<=edad & edad<=54,"Edad6","Edad7"))))))
)
dfh_c <- dfh_c %>%mutate(
pp_edad_c = ifelse( pp_edad<=29,"Edad1",
ifelse(30<=pp_edad & pp_edad<=34,"Edad2",
ifelse(35<=pp_edad & pp_edad<=39,"Edad3",
ifelse(40<=pp_edad & pp_edad<=44,"Edad4",
ifelse(45<=pp_edad & pp_edad<=49,"Edad5",
ifelse(50<=pp_edad & pp_edad<=54,"Edad6","Edad7"))))))
)
dfh_c<-dfh_c%>%
mutate(
region= as.integer(region),
pp_estado = as.integer(pp_estado),
pp_region = ifelse(pp_estado %in% as.integer(c("02","26","08","05","19","28")),1,
ifelse(pp_estado %in% as.integer(c("12","20","07","30","27","04","31","23")),4,
ifelse(pp_estado %in% as.integer(c("03","25","18","10","32","16","06","14","01","24")),2,3)))
)
#IN<-(100/110.907)
IN<-(100/93.6)# enero 2017
enigh_94<-enigh_94%>%
mutate(
ling_men_p=ling_men_p+log(IN)
)
enigh_96<-enigh_96%>%
mutate(
ling_men_p=ling_men_p+log(IN)
)
enigh_98<-enigh_98%>%
mutate(
ling_men_p=ling_men_p+log(IN)
)
unique(dfh_c$region)
unique(dfh_c$pp_region)
#id_c_re<-dfh_c$id_hijo
#id_c_combinada<-dfh_c$id_ho
#sum(id_c_re %in% id_c_combinada)
nrow(dfh_c)
provi<-dfh_c%>%filter((pp_ocup %in% enigh_94$ocupacion) &
(pp_ocup %in% enigh_96$ocupacion) &
(pp_ocup %in% enigh_98$ocupacion))
nrow(provi)
Por la porgramación, para los hijos, se hace dentro del sigueinte programa
# considerando la migracion
dfh_c<- dfh_c %>%
filter(pp_region==region)
nrow(dfh_c)
dfh_cna<-dfh_c%>%drop_na(pp_ocup)%>%drop_na(pp_edad)
nrow(dfh_cna)
Criterio 1 - por region, solo los que no migran 1025 - por region y cohort de ingreso, solo los que no migran 1009 - con ocupacion y por region los ingresos, solo los que no migran 603 - con ocupacion y por region y por cohort de los ingresos, solo los que no migran 405
Criterio 2 - por region y cohort de ingreso, solo los que no migran 1012
criterio 3
- por region y cohort de ingreso 1527
- con ocupacion y por region y por cohort de los ingresos, solo los que no migran 630
Combinada
- no migran 1464 ## Estimación
eii<-function(i,fp,fhp,code=0,reg=0){
#enigh_98 <- readRDS(file = "Datos/enigh_98.Rda")
#dfh_c <- readRDS(file = "Datos/dfh_c.Rda")
#fp = ling_men_p ~ edu_ac + ocupacion + edad + I(edad*edad)
#fhp = ling_h ~ ling_p + edad_h+ I(edad_h*edad_h)
#reg<-1
#code<-1
#print(reg)
# BOOSTRAP
# Regresión de ingresos de padres
#summary(reg_padres)
# numero de padres sin ocupación reportada de hijos
#p_socu<-sum(is.na(dfh_c$pp_ocup))
regresion_padres<-function(enigh,dfh_cna,code=code,reg=reg){
if(code==1){
# regresion padres por region
enigh<-enigh%>%filter(region==reg)
enigh_r <-enigh[sample(nrow(enigh),nrow(enigh), replace = TRUE),]
reg_padres<-lm(
formula = fp,
data = enigh_r
)
# data frame region
dfh_cna<-dfh_cna%>%filter(pp_ocup %in% enigh_r$ocupacion)
data<- data.frame(
edu_ac= dfh_cna$pp_educ_ac,
ocupacion= dfh_cna$pp_ocup,
sexo = dfh_cna$pp_sexo,
#edad_c = "Edad4"
edad = 0#dfh_cna$pp_edad
)
}
else{
# regresion padres completa
enigh_r <-enigh[sample(nrow(enigh),nrow(enigh), replace = TRUE),]
reg_padres<-lm(
formula = fp,
data = enigh_r
)
# data frame completo
dfh_cna<-dfh_cna%>%filter(pp_ocup %in% enigh_r$ocupacion)
data<- data.frame(
edu_ac= dfh_cna$pp_educ_ac,
ocupacion= dfh_cna$pp_ocup,
sexo = dfh_cna$pp_sexo,
#edad_c = "Edad4"
edad = 0#dfh_cna$pp_edad
)
}
return(list(reg_padres,data,dfh_cna))
}
if(code==1){
dfh_cna <- dfh_cna%>%filter(region==reg)
}
p94<-regresion_padres(enigh_94,dfh_cna,code,reg)
p96<-regresion_padres(enigh_96,dfh_cna,code,reg)
p98<-regresion_padres(enigh_98,dfh_cna,code,reg)
reg_p94<-p94[[1]]
data_94<-p94[[2]]
#enigr_p4<-p94[[3]]
dfh_94<-p94[[3]]
reg_p96<-p96[[1]]
data_96<-p96[[2]]
#enigr_p6<-p96[[3]]
dfh_96<-p96[[3]]
reg_p98<-p98[[1]]
data_98<-p98[[2]]
#enigr_p8<-p98[[3]]
dfh_98<-p98[[3]]
dfh_cna <- dfh_cna%>%filter((pp_ocup %in% dfh_94$pp_ocup) &
(pp_ocup %in% dfh_96$pp_ocup) &
(pp_ocup %in% dfh_98$pp_ocup) )
data_94<- data_94%>%filter(ocupacion %in% dfh_cna$pp_ocup)
data_96<- data_96%>%filter(ocupacion %in% dfh_cna$pp_ocup)
data_98<- data_98%>%filter(ocupacion %in% dfh_cna$pp_ocup)
#print(nrow(dfh_cna))
# BOOSTRAP ingreso HIJOS
# calculamos el ingreso de los hijos con los gemelos
# re-sampleados, ademas codificamos la ocupación del hijo a dos caracteres
auxs<-function(k){
sample(k,size=length(k),replace=TRUE)
}
aux_hrr<-function(ing){
#error_e<- abs(ingresos_e16a$ling_men_pd - ing)
error_e<- abs(ingre1618$ling_men_pd - ing)
indice_e<-match(min(error_e),error_e)
indice_e<-indice_e[1]
#return(rp_e16[indice_e16]*100)
return(rp_e1618[indice_e]*100)
}
dfh_cna <- dfh_cna %>%
mutate(
ocu_hc= substring(ocu_h,1,2),
ing_h=unlist(lapply(
lapply(ing_h,auxs),
mean
)
),
ling_h = log(ing_h)+log(IN),
pling_h = unlist(lapply(ling_h,aux_hrr))
)
#dfh_f<-dfh_cna%>%
# mutate(cohort_e = ifelse(ing_h<=2400,1,
# ifelse(ing_h<=4800,2,
# ifelse(ing_h<=7200,3,
# ifelse(ing_h<=12000,4,ifelse(ing_h<=24000,5,6))))),
# cohort_dif=cohort-cohort_e)
#dfh_cna
#dfh_cna$ocu_hijo
#dfh_cna$ling_h
#str(substr(dfh_cna$ocu_h,1,2))
# estimación ingreso padres
# inputamos al hijo correspondiente
estimacion_padres<-function(reg_padres,data,num_base){
aux_prr<-function(ing,num_base){
error_e<- abs(base_logsing[[num_base]]$ling_men_pd - ing)
indice_e<-match(min(error_e),error_e)
indice_e<-indice_e[1]
return(base_rp[[num_base]][indice_e]*100)
}
ling_pf <- predict(
object = reg_padres,
newdata = data
)
pling_pf <- unlist(lapply(ling_pf,aux_prr,num_base))
return(list(ling_pf,pling_pf))
}
est1 <- estimacion_padres(reg_p94,data_94,1)
est2 <- estimacion_padres(reg_p96,data_96,2)
est3 <- estimacion_padres(reg_p98,data_98,3)
mling<-(est1[[1]] + est2[[1]] + est3[[1]])/3
#mling1<-est1[[1]]
#mling2<-est2[[1]]
#mling3<-est3[[1]]
mpling<-(est1[[2]] + est2[[2]]+ est3[[2]])/3
#print("----")
#print(length(est1[[1]]))
#print(length(est2[[1]]))
#print(length(est3[[1]]))
dfhpf<- dfh_cna%>%
mutate(
ling_p = mling,
pling_p = mpling
)
# Boostrap hijos
dfhpf<-dfhpf[sample(nrow(dfhpf),nrow(dfhpf), replace = TRUE),]
reg_hp <- lm(
formula =fhp ,#+ ocu_hc,
data = dfhpf
)
#print(dfhpf$pling_h)
#print(dfhpf$pling_p)
#data.frame(dfhpf$pling_h,dfhpf$pling_p)
reg_hpr <- lm(
formula = pling_h ~ pling_p,
data = dfhpf
)
# plot(dfhpf$pling_p,dfhpf$pling_h,
# xlim=c(0, 100))
#lines(1:100,1:100)
#summary(reg_hp)
beta0<- reg_hp$coefficients[1]
beta <- reg_hp$coefficients[2]
sexoh<- reg_hp$coefficients[3]
edadh<- reg_hp$coefficients[4]
edad2h<-reg_hp$coefficients[5]
betar <- reg_hpr$coefficients[2]
alfar <- reg_hpr$coefficients[1]
nhijos<-nrow(dfh_cna)
# cohort_dif<-as.integer(dfhpf%>%count(cohort_dif)%>%
# filter(cohort_dif==0)%>%
# select(n))
return(data.frame()%>%
summarise(
#cohort_dif=list(dfh_f$cohort_dif),
beta0 = beta0,
beta = beta,
sexoh = sexoh,
edadh = edadh,
edad2h = edad2h,
betar = betar,
alfar = alfar,
nhijos = nhijos,
coeficiente = list(reg_hp$coefficients),
coeficienter = list(reg_hpr$coefficients),
#p_socu = p_socu,
regresionp94 = list(reg_p94),
regresionp96 = list(reg_p96),
regresionp98 = list(reg_p98),
regresion = list(reg_hp),
regresionr = list(reg_hpr)
)
)
}
Estimaciòn individual
eiii<-function(i,fp,fhp,eni,code=0,reg=0){
#enigh_98 <- readRDS(file = "Datos/enigh_98.Rda")
#dfh_c <- readRDS(file = "Datos/dfh_c.Rda")
#fp = ling_men_p ~ edu_ac + ocupacion + edad + I(edad*edad)
#fhp = ling_h ~ ling_p + edad_h+ I(edad_h*edad_h)
#reg<-1
#code<-1
#print(reg)
# BOOSTRAP
# Regresión de ingresos de padres
#summary(reg_padres)
# numero de padres sin ocupación reportada de hijos
#p_socu<-sum(is.na(dfh_c$pp_ocup))
regresion_padres<-function(enigh,dfh_cna,code=code,reg=reg){
if(code==1){
# regresion padres por region
enigh<-enigh%>%filter(region==reg)
enigh_r <-enigh[sample(nrow(enigh),nrow(enigh), replace = TRUE),]
reg_padres<-lm(
formula = fp,
data = enigh_r
)
# data frame region
dfh_cna<-dfh_cna%>%filter(pp_ocup %in% enigh_r$ocupacion)
data<- data.frame(
edu_ac= dfh_cna$pp_educ_ac,
ocupacion= dfh_cna$pp_ocup,
sexo = dfh_cna$pp_sexo,
edad = dfh_cna$pp_edad
)
}
else{
# regresion padres completa
enigh_r <-enigh[sample(nrow(enigh),nrow(enigh), replace = TRUE),]
reg_padres<-lm(
formula = fp,
data = enigh_r
)
# data grame completo
dfh_cna<-dfh_cna%>%filter(pp_ocup %in% enigh_r$ocupacion)
data<- data.frame(
edu_ac= dfh_cna$pp_educ_ac,
ocupacion= dfh_cna$pp_ocup,
sexo = dfh_cna$pp_sexo,
edad = dfh_cna$pp_edad
)
}
return(list(reg_padres,data,dfh_cna))
}
if(code==1){
dfh_cna <- dfh_cna%>%filter(region==reg)
}
if(eni==94){
enigh <- enigh_94
num_base <- 1
}
if(eni==96){
enigh <- enigh_96
num_base <- 2
}
if(eni==98){
enigh <- enigh_98
num_base <- 3
}
p<-regresion_padres(enigh,dfh_cna,code,reg)
reg_p<-p[[1]]
data<-p[[2]]
dfh_cna<-p[[3]]
auxs<-function(k){
sample(k,size=length(k),replace=TRUE)
}
aux_hrr<-function(ing){
#error_e<- abs(ingresos_e16a$ling_men_pd - ing)
error_e<- abs(ingre1618$ling_men_pd - ing)
indice_e<-match(min(error_e),error_e)
indice_e<-indice_e[1]
#return(rp_e16[indice_e]*100)
return(rp_e1618[indice_e]*100)
}
# BOOSTRAP ingreso HIJOS
# calculamos el ingreso de los hijos con los gemelos
# re-sampleados, ademas codificamos la ocupación del hijo a dos caracteres
dfh_cna <- dfh_cna %>%
mutate(
ocu_hc= substring(ocu_h,1,2),
ing_h=unlist(lapply(
lapply(ing_h,auxs),
mean
)
),
ling_h = log(ing_h)+log(IN),
pling_h = unlist(lapply(ling_h,aux_hrr))
)
#dfh_f<-dfh_cna%>%
# mutate(cohort_e = ifelse(ing_h<=2400,1,
# ifelse(ing_h<=4800,2,
# ifelse(ing_h<=7200,3,
# ifelse(ing_h<=12000,4,ifelse(ing_h<=24000,5,6))))),
# cohort_dif=cohort-cohort_e)
#dfh_cna
#dfh_cna$ocu_hijo
#dfh_cna$ling_h
#str(substr(dfh_cna$ocu_h,1,2))
# estimación ingreso padres
# inputamos al hijo correspondiente
estimacion_padres<-function(reg_padres,data,num_base){
aux_prr<-function(ing,num_base){
error_e<- abs(base_logsing[[num_base]]$ling_men_pd - ing)
indice_e<-match(min(error_e),error_e)
indice_e<-indice_e[1]
return(base_rp[[num_base]][indice_e]*100)
}
ling_pf <- predict(
object = reg_padres,
newdata = data
)
pling_pf <- unlist(lapply(ling_pf,aux_prr,num_base))
return(list(ling_pf,pling_pf))
}
est <- estimacion_padres(reg_p,data,num_base)
mling<-est[[1]]
mpling<-est[[2]]
dfhpf<- dfh_cna%>%
mutate(
ling_p = mling,
pling_p = mpling
)
# Boostrap hijos
dfhpf<-dfhpf[sample(nrow(dfhpf),nrow(dfhpf), replace = TRUE),]
reg_hp <- lm(
formula =fhp ,#+ ocu_hc,
data = dfhpf
)
#print(dfhpf$pling_h)
#print(dfhpf$pling_p)
#data.frame(dfhpf$pling_h,dfhpf$pling_p)
reg_hpr <- lm(
formula = pling_h ~ pling_p,
data = dfhpf
)
# plot(dfhpf$pling_p,dfhpf$pling_h,
# xlim=c(0, 100))
# lines(1:100,1:100)
#summary(reg_hp)
beta <- reg_hp$coefficients[2]
betar <- reg_hpr$coefficients[2]
alfar <- reg_hpr$coefficients[1]
# cohort_dif<-as.integer(dfhpf%>%count(cohort_dif)%>%
# filter(cohort_dif==0)%>%
# select(n))
return(data.frame()%>%
summarise(
#cohort_dif=list(dfh_f$cohort_dif),
beta=beta,
betar = betar,
alfar = alfar,
coeficiente = list(reg_hp$coefficients),
coeficienter = list(reg_hpr$coefficients),
#p_socu = p_socu,
regresionp = list(reg_p),
regresionhp = list(reg_hp),
regresionhpr = list(reg_hpr)
)
)
}
Funciones ara regresion
regre_completa<-function(boot=1000){
fp <- ling_men_p ~ edu_ac + ocupacion + sexo + edad + I(edad*edad)
fhp<- ling_h ~ ling_p + sexo_h #+ edad_h + I(edad_h*edad_h)-1
set.seed(123)
a<-lapply(1:boot,eii,fp,fhp,code=0)
resul<-bind_rows(a[1:length(a)])
print("beta cero media")
print(mean(resul$beta0))
print("beta cero sd")
print(sd(resul$beta0))
print("beta media")
print(mean(resul$beta))
print("beta sd")
print(sd(resul$beta))
print("sexo media")
print(mean(resul$sexoh))
print("sexo sd")
print(sd(resul$sexoh))
print("edad media")
print(mean(resul$edadh))
print("edad sd")
print(sd(resul$edadh))
print("edad-2 media")
print(mean(resul$edad2h))
print("edad-2 sd")
print(sd(resul$edad2h))
print("betar media")
print(mean(resul$betar))
print("betar sd")
print(sd(resul$betar))
print("alfar media")
print(mean(resul$alfar))
print("alfar sd")
print(sd(resul$alfar))
hist(resul$beta)
hist(resul$betar)
return(resul)
}
regre_completa_ind<-function(eni,boot=1000){
fp <- ling_men_p ~ edu_ac + ocupacion + sexo + edad + I(edad*edad)
fhp<- ling_h ~ ling_p + sexo_h #+ edad_h +I(edad_h*edad_h)
set.seed(123)
a<-lapply(1:boot,eiii,fp,fhp,eni,code=0)
resul<-bind_rows(a[1:length(a)])
print("beta media")
print(mean(resul$beta))
print("beta sd")
print(sd(resul$beta))
print("betar media")
print(mean(resul$betar))
print("betar sd")
print(sd(resul$betar))
print("alfar media")
print(mean(resul$alfar))
print("alfar sd")
print(sd(resul$alfar))
hist(resul$beta)
hist(resul$betar)
return(resul)
}
regre_region<-function(r, boot = 1000){
fpr <- ling_men_p ~ edu_ac + ocupacion + sexo + edad + I(edad*edad)
fhpr<- ling_h ~ ling_p + sexo_h + edad_h #+ I(edad_h*edad_h)
set.seed(123)
a<-lapply(1:boot,eii,fpr,fhpr,code=1, reg=r)
resul<-bind_rows(a[1:length(a)])
print("beta media")
print(mean(resul$beta))
print("beta sd")
print(sd(resul$beta))
print("betar media")
print(mean(resul$betar))
print("betar sd")
print(sd(resul$betar))
print("alfar media")
print(mean(resul$alfar))
print("alfar sd")
print(sd(resul$alfar))
hist(resul$beta)
hist(resul$betar)
return(resul)
}
regre_region_ind<-function(r,eni, boot = 1000){
fpr <- ling_men_p ~ edu_ac + ocupacion + sexo + edad + I(edad*edad)
fhpr<- ling_h ~ ling_p + sexo_h #+ edad_h + I(edad_h*edad_h)
set.seed(123)
a<-lapply(1:boot,eiii,fpr,fhpr,eni,code=1, reg=r)
resul<-bind_rows(a[1:length(a)])
print("beta media")
print(mean(resul$beta))
print("beta sd")
print(sd(resul$beta))
print("betar media")
print(mean(resul$betar))
print("betar sd")
print(sd(resul$betar))
print("alfar media")
print(mean(resul$alfar))
print("alfar sd")
print(sd(resul$alfar))
hist(resul$beta)
hist(resul$betar)
return(resul)
}
regre_region_rel<-function(regi=0,boot = 1000){
fpr <- ling_men_p ~ edu_ac + ocupacion + sexo + poly((edad-30),2)-1
fhpr<- ling_h ~ ling_p + poly((edad_h-25),2)
set.seed(123)
a<-lapply(1:boot,eii,fpr,fhpr,code=1, reg=regi, rel=1)
resul<-bind_rows(a[1:length(a)])
print("beta media")
print(mean(resul$beta))
print("beta sd")
print(sd(resul$beta))
print("betar media")
print(mean(resul$betar))
print("betar sd")
print(sd(resul$betar))
hist(resul$beta)
hist(resul$betar)
return(resul)
}
# Rango percentil: el porcentaje de puntuaciones en una distribución de puntuación especificada que están por debajo de una puntuación determinada.
# https://www.math.fsu.edu/~wooland/hm2ed/Part3Module1/prVsNth.html
Criterios
Total promedio, criterio principal
reg_cp_100 <- regre_completa(20)
saveRDS(reg_cp_100, file="Datos/Regresiones/reg_cp_100.Rda")
Total promedio, criterio dos
reg_cd_100 <- regre_completa(100)
#reg_cd_100p <- regre_completa(100)
saveRDS(reg_cd_100, file="Datos/Regresiones/reg_cd_100.Rda")
Total individual, criterio principal
reg_cp_98100<-regre_completa_ind(98,100)
saveRDS(reg_cp_94100, file="Datos/Regresiones/reg_cp100_94.Rda")
saveRDS(reg_cp_96100, file="Datos/Regresiones/reg_cp100_96.Rda")
saveRDS(reg_cp_98100, file="Datos/Regresiones/reg_cp100_98.Rda")
#obtener los datoso de los modelos ya establecidos
z<-reg_cp_96$regresionhpr[1][[1]]
class(z)
augment(z)
Total individual, criterio Dos
reg_cd_94100<-regre_completa_ind(100)
reg_cd_96100<-regre_completa_ind(96,100)
reg_cd_98100<-regre_completa_ind(100)
saveRDS(reg_cd_94100, file="Datos/Regresiones/reg_cd100_94.Rda")
saveRDS(reg_cd_96100, file="Datos/Regresiones/reg_cd100_96.Rda")
saveRDS(reg_cd_98100, file="Datos/Regresiones/reg_cd100_98.Rda")
#obtener los datoso de los modelos ya establecidos
z<-reg_cp_96$regresionhpr[1][[1]]
class(z)
augment(z)
Region promedio, criterio principal
reg_reg1_cp_100<-regre_region(1,100)
reg_reg2_cp_100<-regre_region(2,100)
reg_reg3_cp_100<-regre_region(3,100)
reg_reg4_cp_100<-regre_region(4,100)
#summary(reg_reg1_combinada_sexo_cri3_r1617$regresion[[10]])# regresionp[[10]])
saveRDS(reg_reg1_cp_100, file="Datos/Regresiones/reg_reg1_cp_100.Rda")
saveRDS(reg_reg2_cp_100, file="Datos/Regresiones/reg_reg2_cp_100.Rda")
saveRDS(reg_reg3_cp_100, file="Datos/Regresiones/reg_reg3_cp_100.Rda")
saveRDS(reg_reg4_cp_100, file="Datos/Regresiones/reg_reg4_cp_100.Rda")
df<-reg_reg1_cp_100
r1<- data.frame(Norte=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg2_cp_100
r2<- data.frame(Norte_Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg3_cp_100
r3<- data.frame(Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg4_cp_100
r4<- data.frame(Sur=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
regionesdf<-bind_cols(r1,r2,r3,r4)
stargazer(regionesdf,summary = FALSE, digits = 3)
Region promedio, criterio dos
reg_reg1_cdp_100<-regre_region(1,100)
reg_reg2_cdp_100<-regre_region(2,100)
reg_reg3_cdp_100<-regre_region(3,100)
reg_reg4_cdp_100<-regre_region(4,100)
#summary(reg_reg1_combinada_sexo_cri3_r1617$regresion[[10]])# regresionp[[10]])
saveRDS(reg_reg1_cdp_100, file="Datos/Regresiones/reg_reg1_cdp_100.Rda")
saveRDS(reg_reg2_cdp_100, file="Datos/Regresiones/reg_reg2_cdp_100.Rda")
saveRDS(reg_reg3_cdp_100, file="Datos/Regresiones/reg_reg3_cdp_100.Rda")
saveRDS(reg_reg4_cdp_100, file="Datos/Regresiones/reg_reg4_cdp_100.Rda")
df<-reg_reg1_cd_100
r1<- data.frame(Norte=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg2_cd_100
r2<- data.frame(Norte_Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg3_cd_100
r3<- data.frame(Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg4_cd_100
r4<- data.frame(Sur=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
regionesdf<-bind_cols(r1,r2,r3,r4)
stargazer(regionesdf,summary = FALSE, digits = 3)
Region individual, criterio principal
reg_reg1_cp_98100<-regre_region_ind(1,98,100)
reg_reg2_cp_98100<-regre_region_ind(2,98,100)
reg_reg3_cp_98100<-regre_region_ind(3,98,100)
reg_reg4_cp_98100<-regre_region_ind(4,98,100)
#summary(reg_reg1_combinada_sexo_cri3_r1617$regresion[[10]])# regresionp[[10]])
saveRDS(reg_reg1_cp_98100, file="Datos/Regresiones/reg_reg1_cp_98100.Rda")
saveRDS(reg_reg2_cp_98100, file="Datos/Regresiones/reg_reg2_cp_98100.Rda")
saveRDS(reg_reg3_cp_98100, file="Datos/Regresiones/reg_reg3_cp_98100.Rda")
saveRDS(reg_reg4_cp_98100, file="Datos/Regresiones/reg_reg4_cp_98100.Rda")
df<-reg_reg1_cp_98100
r1<- data.frame(Norte=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg2_cp_98100
r2<- data.frame(Norte_Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg3_cp_98100
r3<- data.frame(Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg4_cp_98100
r4<- data.frame(Sur=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
regionesdf<-bind_cols(r1,r2,r3,r4)
stargazer(regionesdf,summary = FALSE, digits = 3)
resul %>%
ggplot(aes(x=beta)) +
geom_histogram(aes(y=..density.. ), bins=25, alpha=0.6,color="blue")+
geom_density() + theme_gray()
Region individual, criterio dos
reg_reg1_cd_98100<-regre_region_ind(1,100)
reg_reg2_cd_98100<-regre_region_ind(2,100)
reg_reg3_cd_98100<-regre_region_ind(3,100)
reg_reg4_cd_98100<-regre_region_ind(4,100)
#summary(reg_reg1_combinada_sexo_cri3_r1617$regresion[[10]])# regresionp[[10]])
saveRDS(reg_reg1_cd_98100, file="Datos/Regresiones/reg_reg1_cd_98100.Rda")
saveRDS(reg_reg2_cd_98100, file="Datos/Regresiones/reg_reg2_cd_98100.Rda")
saveRDS(reg_reg3_cd_98100, file="Datos/Regresiones/reg_reg3_cd_98100.Rda")
saveRDS(reg_reg4_cd_98100, file="Datos/Regresiones/reg_reg4_cd_98100.Rda")
df<-reg_reg1_cd_98100
r1<- data.frame(Norte=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg2_cd_98100
r2<- data.frame(Norte_Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg3_cd_98100
r3<- data.frame(Centro=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
df<-reg_reg4_cd_98100
r4<- data.frame(Sur=c("",
substr(as.character(mean(df$beta)),1,5),
paste("(",substr(as.character(sd(df$beta)),1,5),")",sep="",collapse= ","),
"",
substr(as.character(mean(df$betar)),1,5),
paste("(",substr(as.character(sd(df$betar)),1,5),")",sep="",collapse = ","),
"",
substr(as.character(mean(df$alfar)),1,6),
paste("(",substr(as.character(sd(df$alfar)),1,5),")",sep="",collapse = ","),
""
),
row.names=c(" ",
"beta_r",
"sd br",
" ",
"hat rho_r$",
"sd rho",
" ",
"alpha_r",
"sd alphar",
" "
)
)
regionesdf<-bind_cols(r1,r2,r3,r4)
stargazer(regionesdf,summary = FALSE, digits = 3)
#Graficas
a<- readRDS("Datos/Regresiones/reg_reg1_cp_98100.Rda")
#grafica rango rango regional
graficarr<-function(df,a = "", region= "")
{
la<-df%>%pull(regresionhpr)
la1<-lapply(la[1:length(la)],function(x) x$model)
la1<-lapply(la1[1:length(la1)],function(x){row.names(x)<-NULL; x } )
la2<-bind_rows(la1[1:length(la1)])
print(nrow(la2))
print(sum(is.na(la2)))
la2$pling_p<-la2%>%pull(pling_p)%>%as.integer()
la3<-la2%>%group_by(pling_p)%>%summarise(pling_pm=mean(pling_h))
alfar <- mean(df$alfar)
betar <- mean(df$betar)
ggplot(la3,aes(x=pling_p, y = pling_pm)) +
geom_point(col="gray")+
labs(title = paste(region," ",a),
subtitle = "Rango percentil intergeneracional") +
xlab("Rango pasado") +
ylab("Rango actual") +
xlim(0,100) +
ylim(0,100) +
theme_bw() +
theme(plot.title = element_text(size = 20),
plot.subtitle = element_text(size = 15),
axis.title = element_text(size = 15),
axis.text = element_text(size = 10),
legend.position="top",
legend.title = element_text(size=8, face="bold"),
legend.text = element_text(size=6, face="bold")) +
geom_function(fun = function(x)+ alfar + betar*x,
colour = "red") +
annotate("text",
x=70,
y=25,
label = paste(substr(as.character(alfar),1,6),
" + ",substr(as.character(betar),1,5)
,"x"),
colour = "red",
size = 5)
#parse = TRUE)
}
graficarr(a, "2017 - 1998", "Región Norte:")
grafica rango rango
graficarr_promedio<-function(df,region= "",a = "")
{
la<-df%>%pull(regresionr)
la1<-lapply(la[1:length(la)],function(x) x$model)
la1<-lapply(la1[1:length(la1)],function(x){row.names(x)<-NULL; x } )
la2<-bind_rows(la1[1:length(la1)])
#print(nrow(la2))
#print(sum(is.na(la2)))
la3<-la2%>%mutate(cohortp = cut(pling_p,breaks=seq(0,100,2)))
la3<-la3%>%group_by(cohortp)%>%summarise(pling_pm=mean(pling_p),
pling_hm=mean(pling_h))
alfar <- mean(df$alfar)
betar <- mean(df$betar)
g<-ggplot(la3,aes(x=pling_pm, y = pling_hm)) +
geom_point(col="gray")+
labs(title = paste(region," ",a))+
# subtitle = "Rango percentil intergeneracional") +
xlab("Rango percentil pseudo PP") +
ylab("Rango percentil actual") +
xlim(0,100) +
ylim(0,100) +
# theme_classic() +
theme(
plot.title = element_text(size = 15),
plot.subtitle = element_text(size = 15),
axis.title = element_text(size = 15),
axis.text = element_text(size = 15),
legend.position="top",
legend.title = element_text(size=8, face="bold"),
legend.text = element_text(size=6, face="bold")) +
geom_function(fun = function(x)+ alfar + betar*x,
colour = "red") +
geom_function(fun = function(x) x,colour = "blue")+
theme_update(plot.title = element_text(hjust = 0.5))#+
# annotate("text",
# x=70,
# y=25,
# label = paste("R(y^a)=",substr(as.character(alfar),1,6),
# " + ",substr(as.character(betar),1,5)
# ,"R(y^p)"),
# colour = "red",
# size = 5, parser=TRUE)
#
#parse = TRUE)
return(g)
}
r1<-graficarr_promedio(reg_reg1_cd_100,"Norte (región 1):","Relación de estimaciones de rango percentil")
r2<-graficarr_promedio(reg_reg2_cd_100,"Centro-Norte (región 2):","Relación de estimaciones de rango percentil")
r3<-graficarr_promedio(reg_reg3_cd_100,"Centro (región 3):","Relación de estimaciones de rango percentil")
r4<-graficarr_promedio(reg_reg4_cd_100,"Sur (región 4):","Relación de estimaciones de rango percentil")
r4
regiones conjuntas
alfar1 <- mean(reg_reg1_cd_100$alfar)
betar1 <- mean(reg_reg1_cd_100$betar)
alfar2 <- mean(reg_reg2_cd_100$alfar)
betar2 <- mean(reg_reg2_cd_100$betar)
alfar3 <- mean(reg_reg3_cd_100$alfar)
betar3 <- mean(reg_reg3_cd_100$betar)
alfar4 <- mean(reg_reg4_cd_100$alfar)
betar4 <- mean(reg_reg4_cd_100$betar)
ggplot() +
labs(title = "AIR estimado por regiones")+
xlab("Rango percentil pseudo PP") +
ylab("Rango percentil actual") +
xlim(0,100) +
ylim(0,100) +
# theme_classic() +
theme(
plot.title = element_text(size = 15),
plot.subtitle = element_text(size = 15),
axis.title = element_text(size = 15),
axis.text = element_text(size = 15),
legend.position="top",
legend.title = element_text(size=8, face="bold"),
legend.text = element_text(size=6, face="bold")) +
geom_function(fun = function(x)+ alfar1 + betar1*x,aes(linetype="1"),
colour = "red", alpha=1) +
geom_function(fun = function(x)+ alfar2 + betar2*x,aes(linetype="2"),
colour = "red", alpha=0.8) +
geom_function(fun = function(x)+ alfar3 + betar3*x,aes(linetype="5"),
colour = "red", alpha=0.6) +
geom_function(fun = function(x)+ alfar4 + betar4*x,aes(linetype="6"),
colour = "red", alpha=1) +
scale_linetype_discrete("Región", breaks=c("1", "2","5", "6"), labels=c("Norte", "Centro-Norte","Centro","Sur"))+
geom_function(fun = function(x) x,colour = "blue")+
theme_update(plot.title = element_text(hjust = 0.5))#+
Matriz de transición
transicion<-function(df,region= "",a = "")
{
la<-df%>%pull(regresionr)
la1<-lapply(la[1:length(la)],function(x) x$model)
la1<-lapply(la1[1:length(la1)],function(x){row.names(x)<-NULL; x } )
la2<-bind_rows(la1[1:length(la1)])
#print(nrow(la2))
#print(sum(is.na(la2)))
la3<-la2%>%mutate(cohortp = cut(pling_p,breaks=seq(0,100,20),labels=c("Q1","Q2","Q3","Q4","Q5")),
cohorth = cut(pling_h,breaks=seq(0,100,20),labels=c("q1","q2","q3","q4","q5")))
la3<-la3%>%group_by(cohortp,cohorth)%>%
count()%>%ungroup()
la3<-la3%>%group_by(cohortp)%>%
summarise(p1=n*100/sum(n),
cohortp=factor(cohortp, levels=c("Q1","Q2","Q3","Q4","Q5")),
cohorth=factor(cohorth, levels=c("q5","q4","q3","q2","q1")))%>%ungroup()
la3<-la3%>%arrange(cohortp)#,decreasing = TRUE)
#print(la3%>%group_by(cohortp)%>%summarise(sum(p1)))
la3<-la3%>% pivot_wider(names_from = cohorth, values_from = p1)
return(la3)
}
tranreg1<-transicion(reg_cd_100)
#row.names(tranreg1)<-tranreg1$cohortp
stargazer(as.data.frame(tranreg1),rownames= FALSE, summary = FALSE, digits= 1)
# bar_order <- list(
# "(0,20]" = 4,
# "(20,40]" = 3,
# "(40,60]" = 2,
# "(60,80]" = 1,
# "(80,100]" = 0
# )
# bar_order_v <- as.numeric(bar_order)
tranreg1 %>%
hchart(
'column', hcaes(x = cohortp, y = p1, group = cohorth),
stacking = "normal"
# explicit_order = c("q5","q2","q3","q4","q1")
)
ggsave("region1rr.png", plot = r1, path = "imagenes/")
ggsave("region2rr.png", plot = r2, path = "imagenes/")
ggsave("region3rr.png", plot = r3, path = "imagenes/")
ggsave("region4rr.png", plot = r4, path = "imagenes/")
Graficas EII
graficareii_promedio<-function(df,nl=FALSE,region= "",a = "")
{
la<-df%>%pull(regresion)
la1<-lapply(la[1:length(la)],function(x) x$model)
la1<-lapply(la1[1:length(la1)],function(x){row.names(x)<-NULL; x } )
la2<-bind_rows(la1[1:length(la1)])
#print(nrow(la2))
#print(sum(is.na(la2)))
la2<-la2%>%drop_na()
if(nl==TRUE){
la2<-la2%>%mutate(ingh = exp(ling_h),
ingp = exp(ling_p)
)%>%select(ingh,ingp)
#head(la2)
la2<-la2%>%mutate(peringp=rank(ingp)/length(ingp))
la2<-la2%>%mutate(cohop = cut(peringp, breaks = seq(0,1,0.01), include.lowest=TRUE))
la3<-la2%>%group_by(cohop)%>%summarise(ing_hm=mean(ingh),
ing_pm=mean(ingp))
}else{
la2<-la2%>%mutate(peringp=rank(ling_p)/length(ling_p))
la2 <-la2 %>% mutate(cohop = cut(peringp, breaks = seq(0,1,0.02), include.lowest=TRUE))
la3<-la2%>%group_by(cohop)%>%summarise(ing_hm=mean(ling_h),
ing_pm=mean(ling_p))
}
beta0 <- mean(df$beta0)
beta <- mean(df$beta)
sex<- mean(df$sexoh)
g<-ggplot(la3,aes(x=ing_pm, y = ing_hm)) +
geom_point(col="gray")+
labs(title = paste(region," ",a))+
# subtitle = "Estimación lineal") +
xlab("Log ingreso pseudo PP") +
#xlab("Ingreso pseudo PP") +
ylab("Log ingreso actual") +
#ylab("Ingreso actual") +
#xlim(0,max(la3$ing_pm)) +
#ylim(0,max(la3$ing_hm)) +
xlim(min(la3$ing_pm),max(la3$ing_pm)) +
ylim(6,max(la3$ing_hm)) +
theme_classic() +
theme(
plot.title = element_text(size = 15),
plot.subtitle = element_text(size = 10),
axis.title = element_text(size = 15),
axis.text = element_text(size = 10),
legend.position="top",
legend.title = element_text(size=8, face="bold"),
legend.text = element_text(size=6, face="bold")) +
geom_function(fun = function(x) beta0 + x*beta, colour = "red") +
#geom_function(fun = function(x) exp(beta0) * x**beta, colour = "red") +
geom_function(fun = function(x) beta0 + x*beta + sex, colour = "orange")+
#geom_function(fun = function(x) exp(beta0) * x**beta *exp(sex), colour = "orange")+
#geom_function(fun = function(x) x,colour = "blue")+
theme_update(plot.title = element_text(hjust = 0.5))
# annotate("text",
# x=70,
# y=25,
# label = paste(substr(as.character(alfar),1,6),
# " + ",substr(as.character(betar),1,5)
# ,"x"),
# colour = "red",
# size = 5)
#
#parse = TRUE)
}
#graficareii_promedio<-function(df,nl=FALSE,a = "", region= "")
#region<-"Relación de estimaciones: ingresos actuales vs ingresos pseudo PP"
a<-"log ingresos actuales vs log ingresos pseudo PP"
r1<-graficareii_promedio(reg_reg1_cd_100,nl=FALSE,"Norte (region 1):",a)
r2<-graficareii_promedio(reg_reg2_cd_100,nl=FALSE,"Centro-Norte (region 2):",a)
#r3<-graficareii_promedio(reg_reg3_cd_100,nl=FALSE,"Centro (region 3):",a)
#r4<-graficareii_promedio(reg_reg4_cd_100,nl=FALSE,"Sur (region 4):",a)
r1
r2
r3
r4
ggsave("region1eeil.png", plot = r1, path = "imagenes/")
ggsave("region2eeil.png", plot = r2, path = "imagenes/")
ggsave("region3eeil.png", plot = r3, path = "imagenes/")
ggsave("region4eeil.png", plot = r4, path = "imagenes/")
graficarr_promedio(reg_cp_500,"Actual-Pasado promedio","México, Base A:")
Estad des A
resu<-dfh_c%>%summarise(Sexo_Masculino = filter(dfh_c,sexo_h==1)%>%count()%>%pull(),
Sexo_Femenino = filter(dfh_c,sexo_h==2)%>%count()%>%pull(),
Promedio_Edad_Entrevistado = mean(edad_h),
Sexo_Masculino_PP = filter(dfh_c,pp_sexo==1)%>%count()%>%pull(),
Sexo_Femenino_PP = filter(dfh_c,pp_sexo==2)%>%count()%>%pull(),
Edad_Mínima_PP = min(pp_edad),
Edad_Máxima_PP = max(pp_edad),
Promedio_Edad_PP_2017 = mean(pp_edad)+22)
stargazer(resu,summary = FALSE, digits = 1, flip = TRUE)
Esta des B
resu<-dfh_c%>%summarise(Sexo_Masculino = filter(dfh_c,sexo_h==1)%>%count()%>%pull(),
Sexo_Femenino = filter(dfh_c,sexo_h==2)%>%count()%>%pull(),
Promedio_Edad_Entrevistado = mean(edad_h),
Sexo_Masculino_PP = filter(dfh_c,pp_sexo==1)%>%count()%>%pull(),
Sexo_Femenino_PP = filter(dfh_c,pp_sexo==2)%>%count()%>%pull(),
Edad_Mínima_PP = min(pp_edad),
Edad_Máxima_PP = max(pp_edad),
Promedio_Edad_PP_2017 = mean(pp_edad)+22)
stargazer(resu,summary = FALSE, digits = 1, flip = TRUE)
Esta des bases ENIGH
resuen<- data.frame()%>%summarise(
Tamano_de_muestra = c(nrow(enigh_94),nrow(enigh_96),nrow(enigh_98)),
Hombres = c(nrow(enigh_94%>%filter(sexo==1)),nrow(enigh_96%>%filter(sexo==1)),
nrow(enigh_98%>%filter(sexo==1))),
Mujeres = c(nrow(enigh_94%>%filter(sexo==2)),nrow(enigh_96%>%filter(sexo==2)),
nrow(enigh_98%>%filter(sexo==2))),
Promedio_Ingresos = c(enigh_94%>%select(ing_men_p)%>%pull()%>%mean()*IN,
enigh_96%>%select(ing_men_p)%>%pull()%>%mean()*IN,
enigh_98%>%select(ing_men_p)%>%pull()%>%mean()*IN),
Promedio_logIngresos = log(Promedio_Ingresos)
)
row.names(resuen) = c("E94","E96","E98")
resuen
stargazer(resuen,summary = FALSE)
promedio de ingreso por edad
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
ingreso_edad<-function(df){
df %>%
group_by(edad)%>%
arrange(edad)%>%
summarise(
pro_ing = mean(ing_men_p)*IN
)%>%
hchart( "scatter",
hcaes(x = edad, y = pro_ing),
name="Ingreso promedio",
regression = TRUE,
regressionSettings = list(
type = "polynomial",
dashStyle = "ShortDash",
color = "skyblue",
order = 2,
lineWidth = 5,
name = "%eq | $r^2$: %r",
hideInLegend = FALSE)
)%>%
hc_add_dependency("plugins/highcharts-regression.js")%>%
hc_yAxis(title = list(text = "Promedio de ingreso por edad"))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Promedio de ingreso por edad E98"
) %>%
hc_xAxis(title=list(text="Edad")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
}
ingreso_edad(enigh_98)
histo ingreso
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
histo_ingreso<-function(df){
a<-sort(df$ling_men_pd)
#a<-a[1:(length(a)-5)]
#a<-a[5:(length(a))]
hchart(a, name= "Frecuencia")%>%
hc_yAxis(title = list(text ="Número de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Distribución de ingreso E98"
) %>%
hc_xAxis(title=list(text="Logaritmo del Ingreso (deflactado)")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
}
histo_ingreso(enigh_98)
revisión rango percentil
d<- enigh_98p$ling_men_pd
rd<-rank(d)
nd<-length(d)
rangop<- rd/nd
min(rangop)
max(rangop)
d1<- ingresos_e98$ling_men_p
d1
d2<- ingresos_e98$ling_men_pd
d2
dfe<-data.frame(d,d1,d2)
tail(dfe)
aux_prr<-function(ing,num_base){
error_e<- abs(base_logsing[[num_base]]$ling_men_pd - ing)
#print(error_e)
indice_e<-match(min(error_e),error_e)
print(indice_e)
indice_e<-indice_e[1]
return(base_rp[[num_base]][indice_e]*100)
}
aux_prr(7,3)
base_logsing[[3]]$ling_men_pd[4167]
f<-base_logsing[[3]]$ling_men_pd - 7
f[4167]
dfe[4167,]
d[4167]
rangop[4167]
densidad ingre selecionados
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
a1<-sort(enigh_94$ling_men_pd)
a2<-sort(enigh_96$ling_men_pd)
a3<-sort(enigh_98$ling_men_pd)
hchart(
density(a1),
type = "area",
name = "E94"
)%>%
hc_add_series(
density(a2), type = "area",
name = "E96"
)%>%
hc_add_series(
density(a3), type = "area",
name = "E98"
)%>%
hc_yAxis(title = list(text ="Proporción de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Densidad de ingreso E94, E96, y E98"
) %>%
hc_xAxis(title=list(text="Logaritmo del Ingreso (deflactado)")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
densidad ingre total viejas
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
a1<-sort(ingresos_e94$ling_men_pd)
a2<-sort(ingresos_e96$ling_men_pd)
a3<-sort(ingresos_e98$ling_men_pd)
hchart(
density(a1),
type = "area",
name = "E94"
)%>%
hc_add_series(
density(a2), type = "area",
name = "E96"
)%>%
hc_add_series(
density(a3), type = "area",
name = "E98"
)%>%
hc_yAxis(title = list(text ="Proporción de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Densidad de ingreso E94, E96, y E98"
) %>%
hc_xAxis(title=list(text="Logaritmo del Ingreso (deflactado)")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
densidad ingre total viejas
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
a1<-sort(ingresos_e16a$ling_men_pd)
a2<-sort(ingresos_e18a$ling_men_pd)
hchart(
density(a1),
type = "area",
name = "E16"
)%>%
hc_add_series(
density(a2), type = "area",
name = "E18"
)%>%
hc_yAxis(title = list(text ="Proporción de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Densidad de ingreso E16 y E18"
) %>%
hc_xAxis(title=list(text="Logaritmo del Ingreso (deflactado)")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
densidad ingre conjuay total viejas
ingre1618_gra<-bind_rows(ingresos_e16a,ingresos_e18a)
nrow(ingre1618_gra)
ingre949698_gra<-bind_rows(ingresos_e94,ingresos_e96,ingresos_e98)
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
a1<-sort(ingre1618_gra$ling_men_pd)
hchart(
density(a1),
type = "area",
name = "E16-E18"
)%>%
hc_yAxis(title = list(text ="Proporción de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Densidad de ingreso union E16-E18"
) %>%
hc_xAxis(title=list(text="Logaritmo del Ingreso (deflactado)")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
Total viejeas y nuevas
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
a2<-exp(ingre1618_gra%>%select(ling_men_pd)%>%pull())
a1<-exp(ingre949698_gra%>%select(ling_men_pd)%>%pull())
x <- hist(a1, plot = FALSE)
y <- hist(a2, plot = FALSE)
a2p<-percent_rank(a2)
a1p<-percent_rank(a1)
#a1<-percent_rank(a1)*100
#a2<-percent_rank(a2)*100
hchart(
a2/length(a2),
breaks = 5000,
#type = "area",
name = "E94-E96-E98"
)%>%
hc_add_series(
density(a1),
breaks = 20,
#type = "area",
name = "E16-E18"
)%>%
hc_yAxis(title = list(text ="Proporción de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Densidad de ingreso union, E94-E96-E98, E16-E18"
) %>%
hc_xAxis(title=list(text="Logaritmo del Ingreso (deflactado)"),#)%>%
min = 0,
max = 30000) %>%
hc_xAxis(plotLines = list(list(value=median(a1),color="red",width=2 ),
list(value = median(a2),color="blue",width=2)))%>%
#hc_xAxis(plotLines = list(list(value=median(a2),color = "red" )))%>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
total hisotgrama completo
a2<-ingre1618_gra%>%select(ling_men_pd)%>%pull()
a1<-ingre949698_gra%>%select(ling_men_pd)%>%pull()
dats <- rbind(data.frame(pred = a1, Encuesta = 'E94-E96-E98'),
data.frame(pred = a2, Encuesta = 'E16-E18'))
# here the plot
ggplot(dats, aes(pred, fill = Encuesta)) +
#geom_density(alpha = 0.5, position = "identity", bins = 60)+
geom_density(alpha = 0.5, position = "identity")+
#xlim(0,30000)+
geom_vline(xintercept=median(a1),color = "blue") +
geom_vline(xintercept=median(a2),color = "red")+
labs(title = "Densidad de ingreso")+
xlab("Logaritmo Ingresos") +
ylab("Densidad")
reginales nuevas y viejas
highchart(type = "chart")%>%
hc_yAxis_multiples(
create_yaxis(4, height = c(5,5,5,5), sep=0.1, offset=0.5, turnopposite = FALSE,
title = list(text = rep("Número de casos confirmados",4)))
) %>%
hc_add_series(name="región 1 E94-E96-E98",density(ingre949698_gra%>%
filter(region==1)%>%
select(ling_men_pd)%>%
pull()),
yAxis=0)%>%
hc_add_series(name="región 1 E16-E18",density(ingre1618_gra%>%
filter(region==1)%>%
select(ling_men_pd)%>%
pull()),
yAxis=0)%>%
hc_add_series(name="región 2 E94-E96-E98",density(ingre949698_gra%>%
filter(region==2)%>%
select(ling_men_pd)%>%
pull()),
yAxis=1)%>%
hc_add_series(name="región 2 E16-E18",density(ingre1618_gra%>%
filter(region==2)%>%
select(ling_men_pd)%>%
pull()),
yAxis=1)%>%
hc_add_series(name="región 3 E94-E96-E98",density(ingre949698_gra%>%
filter(region==3)%>%
select(ling_men_pd)%>%
pull()),
yAxis=2)%>%
hc_add_series(name="región 3 E16-E18",density(ingre1618_gra%>%
filter(region==3)%>%
select(ling_men_pd)%>%
pull()),
yAxis=2)%>%
hc_add_series(name="región 4 E94-E96-E98",density(ingre949698_gra%>%
filter(region==4)%>%
select(ling_men_pd)%>%
pull()),
yAxis=3)%>%
hc_add_series(name="región 4 E16-E18",density(ingre1618_gra%>%
filter(region==4)%>%
select(ling_men_pd)%>%
pull()),
yAxis=3)%>%
#hc_yAxis(title = list(text ="Proporción de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(text = "Densidad por región E94-E96-E98, E16-E18 ")%>%
#margin = 20, align = "left",
#style = list(color = "#90ed7d", useHTML = TRUE)) %>%
# hc_subtitle(text = "Utilice la herramienta de zoom en la
# parte inferior")%>%
# hc_tooltip(crosshairs = TRUE, backgroundColor = "#FCFFC5",
# shared = TRUE, borderWidth = 5) %>%
#hc_yAxis(title = list(text = rep("Número de casos confirmados",4))%>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
densidad por región
den_region<-function(df){
a1<-df%>%filter(region==1)%>%select(ling_men_pd)%>%pull()
a2<-df%>%filter(region==2)%>%select(ling_men_pd)%>%pull()
a3<-df%>%filter(region==3)%>%select(ling_men_pd)%>%pull()
a4<- df%>%filter(region==4)%>%select(ling_men_pd)%>%pull()
hchart(
density(a1),
type = "area",
name = "región 1"
)%>%
hc_add_series(
density(a2), type = "area",
name = "región 2"
)%>%
hc_add_series(
density(a3), type = "area",
name = "región 3"
)%>%
hc_add_series(
density(a4), type = "area",
name = "región 4"
)%>%
hc_yAxis(title = list(text ="Proporción de seleccionados" ))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Densidad de ingreso por región, E16-E18"
) %>%
hc_xAxis(title=list(text="Logaritmo del Ingreso (deflactado)")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
}
den_region(ingre1618_gra)
edad region ingreso
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
ingreso_edad_region<-function(df){
df %>%
group_by(region,edad)%>%
summarise(
pro_ing = mean(ing_men_p)*IN
)%>%
hchart( "line",
hcaes(x = edad, y = pro_ing, group = region ))%>%
hc_yAxis(title = list(text = "Promedio de ingreso"))%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_title(
text = "Promedio de ingreso por edad y región E98") %>%
hc_xAxis(title=list(text="Edad")) %>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
}
ingreso_edad_region(enigh_98)
Mapa regional
myMenuItems <- c("downloadPNG", "downloadJPEG", "downloadPDF", 'downloadSVG', 'printChart')
mapdata <- get_data_from_map(download_map_data("countries/mx/mx-all"))
mapdata
mapa<-mapdata %>%
select(code = `woe-name`) %>%
arrange(code)%>%
mutate(tz = ifelse(code %in% c("Baja California", "Chihuahua", "Coahuila", "Nuevo León", "Sonora", "Tamaulipas"),"región 1",
ifelse(code %in% c("Aguascalientes","Baja California Sur", "Colima", "Durango", "Jalisco", "Michoacán", "Nayarit", "San Luis Potosí", "Sinaloa", "Zacatecas"),"región 2",
ifelse(code %in% c("Campeche", "Chiapas", "Guerrero", "Oaxaca", "Quintana Roo", "Tabasco", "Veracruz","Yucatán"),"región 4", "región 3")
) ),
value = as.integer(factor(tz)))
dta_clss <- mapa %>%
group_by(tz) %>%
summarise(value = unique(value)) %>%
arrange(value) %>%
rename(name = tz, from = value) %>%
mutate(to = from + 1) %>%
list_parse()
hcmap("countries/mx/mx-all", data = mapa, value = "value",
joinBy = c("woe-name","code"), name = "Estado",
tooltip = list(pointFormat = "{point.name} {point.tz}"))%>%
hc_title(
text = "Regiones de México"
)%>%
hc_add_theme(hc_theme_ggplot2())%>%
hc_colorAxis(dataClassColor = "category",
dataClasses=dta_clss)%>%
hc_exporting(enabled = TRUE,
filename = "datos",
buttons = list(contextButton = list(menuItems = myMenuItems)))
data <- tibble(
country =
c("PT", "IE", "GB", "IS",
"NO", "SE", "DK", "DE", "NL", "BE", "LU", "ES", "FR", "PL", "CZ", "AT",
"CH", "LI", "SK", "HU", "SI", "IT", "SM", "HR", "BA", "YF", "ME", "AL", "MK",
"FI", "EE", "LV", "LT", "BY", "UA", "MD", "RO", "BG", "GR", "TR", "CY",
"RU"),
tz = c(rep("UTC", 4), rep("UTC + 1",25), rep("UCT + 2",12), "UTC + 3")
)
data <- data %>%
mutate(value = cumsum(!duplicated(tz)))
individuos region
nrow(dfh_c%>%filter(region==4))
caluclo de bcero
promedio_beta0<-function(df,i){
return(df$regresion[[i]]$coefficients[3])
}
mean(unlist(lapply(1:100,promedio_beta0,df=reg_cd_100)))
sd(unlist(lapply(1:100,promedio_beta0,df=reg_cd_100)))
promedio_papas<-function(df,i){
return(df$regresionp98[[i]]$coefficients[27])
}
mean(unlist(lapply(1:10,promedio_papas,df=reg_cd_100)))
sd(unlist(lapply(1:10,promedio_papas,df=reg_cd_100)))
percentilerank<-function(x){
rx<-rle(sort(x))
smaller<-cumsum(c(0, rx$lengths))[seq(length(rx$lengths))]
larger<-rev(cumsum(c(0, rev(rx$lengths))))[-1]
rxpr<-smaller/(smaller+larger)
rxpr[match(x, rx$values)]
}
a<-c(0,2,3,4,5,1,1,1)
rank(a)/length(a)
percentilerank(a)
percent_rank(a)
LS0tCnRpdGxlOiAiRXN0aWFtY2lvbiIKYXV0aG9yOiAiUmFmYWVsIE1hcnTDrW5leiBNYXJ0w61uZXoiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93Ci0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgZXZhbCA9IEZBTFNFKQpgYGAKCgpgYGB7ciBjYXJnYXJfYmlsaW90ZWNhc30KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoaGF2ZW4pICMgaW1wb3J0YSwgZW50cmUgb3Ryb3Mgc29mdHdhcmUsIGRlIFN0YXRhCmxpYnJhcnkoc2psYWJlbGxlZCkgIyBtYW5lamFyIGxhYmVscyBkZSBsYXMgdmFyaWFibGVzIApsaWJyYXJ5KG9wZW54bHN4KSAjIGxlZXIgYXJjaGl2b3MgZGUgZXhjZWwKbGlicmFyeShEVCkgIyB2aXN1YWxpemFyIGEgdGFibGFzCmxpYnJhcnkoZGF0YS50YWJsZSkgIyBjb252ZXJ0aXIgYSB0YWJsYXMKbGlicmFyeShoaWdoY2hhcnRlcikgIyBncsOhZmljYXMgaW50ZXJhY3RpdmFzCmxpYnJhcnkoZm9yZWlnbikKbGlicmFyeShzdGFyZ2F6ZXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShzdXJ2aXZhbCkKbGlicmFyeShicm9vbSkKbGlicmFyeShncmlkRXh0cmEpCmBgYAoKCiMgRnVuY2lvbmVzIGRlIGNhcmdhCgpgYGB7ciBmdW5fY2FyZ19FU1JVfQoKY2FyZ2FyX2VzcnU8LSBmdW5jdGlvbigpewoKcmV0dXJuKHJlYWRfc3RhdGEoCiAgICAgICAgICAgICAgICAgICAgIHBhdGggPSAiRGF0b3MvRVNSVS1FTU9WSS0yMDE3L0VTUlUtRU1PVkktMjAxNy1FbnRyZXZpc3RhZG8uZHRhIiwKICAgICAgICAgICAgICAgICAgICAgYXRvbWljLnRvLmZhYyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgIGVuYyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICkpCn0KYGBgCgoKYGBge3IgY2FyYWdhcl9lbmlnaH0KY2FyZ2FyX2VuaWdoPC0gZnVuY3Rpb24oZG9jdSl7CgpyZXR1cm4ocmVhZF9zdGF0YSgKICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhc3RlKCJEYXRvcy9FTklHSC0yMDE2LyIsZG9jdSwiLmR0YSIsc2VwPSIiKSwKICAgICAgICAgICAgICAgICAgICAgYXRvbWljLnRvLmZhYyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgIGVuYyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICkpCn0KCmNhcmdhcl9lbmlnaF9zYXY8LSBmdW5jdGlvbihkb2N1KXsKCnJldHVybihyZWFkX3Nwc3MoCiAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXN0ZSgiRGF0b3MvRU5JR0gtMjAxNi8iLGRvY3UsIi5zYXYiLHNlcD0iIiksCiAgICAgICAgICAgICAgICAgICAgIGF0b21pYy50by5mYWMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICBlbmMgPSBOVUxMLAogICAgICAgICAgICAgICAgICAgICApKQp9CmBgYAoKCgpgYGB7ciBjYXJhZ2FyX2VuaWdoXzE4fQpjYXJnYXJfZW5pZ2hfMTg8LSBmdW5jdGlvbihkb2N1KXsKCnJldHVybihyZWFkX3N0YXRhKAogICAgICAgICAgICAgICAgICAgICBwYXRoID0gcGFzdGUoIkRhdG9zL0VOSUdILTIwMTgvIixkb2N1LCIuZHRhIixzZXA9IiIpLAogICAgICAgICAgICAgICAgICAgICBhdG9taWMudG8uZmFjID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgZW5jID0gTlVMTCwKICAgICAgICAgICAgICAgICAgICAgKSkKfQoKY2FyZ2FyX2VuaWdoX3Nhdl8xODwtIGZ1bmN0aW9uKGRvY3UpewoKcmV0dXJuKHJlYWRfc3BzcygKICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IHBhc3RlKCJEYXRvcy9FTklHSC0yMDE4LyIsZG9jdSwiLnNhdiIsc2VwPSIiKSwKICAgICAgICAgICAgICAgICAgICAgYXRvbWljLnRvLmZhYyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgIGVuYyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICkpCn0KYGBgCgoKCiMgRmlsdHJhciBoaWpvcyBFU1JVCgojIyBDcmVhbW9zICBwZXIgbW92aWxpZGFkCgpgYGB7ciBjYXJnYV9lc3J1X2NyZWFfbW92fSAKCmRhdGFfZW1vdmkyMDE3PC1jYXJnYXJfZXNydSgpCgpkYXRhX2Vtb3ZpMjAxNzwtZGF0YV9lbW92aTIwMTclPiUKICBtdXRhdGUobW92ID0gaWZlbHNlKHAxNDc+cDE0OCwibWVqb3IiLAogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHAxNDc8cDE0OCwicGVvciIsImlndWFsIikpLAogICAgICAgICBpZF9obyA9IGFzLmludGVnZXIocm93Lm5hbWVzKGRhdGFfZW1vdmkyMDE3KSkpCmRhdGFfZW1vdmkyMDE3JG1vdjwtc2V0X2xhYmVscygKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX2Vtb3ZpMjAxNyRtb3YsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygibWVqb3IiID0gIm1lam9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwZW9yIiA9ICJwZW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpZ3VhbCIgPSAiaWd1YWwiKSkKCmBgYAoKCgoKIyMgc2VsZWNjaW9uIGRlIGhpam9zCgpDcml0ZXJpb3MgZGUgZmlsdHJhZG8KLSBwcmVndW50YSBwMiwgY29tcGFydGVuIGVsIG1pbXNvIGdhc3RvIHBhcmEgY29tZXI6IDEgKSBTaSAyICkgTm8KLSBwcmVndW50YSA1IEVkYWRlcyBlbnRyZSAyNSB5IDQ1IGHDsW9zCi0gcHJlZ3VudGEgcDA4LCBlcyBlbCBqZWZlIGRlbCBob2dhcjogMSApIGplZmUgMikgY8Ozbnl1Z2UgTk8gSU1QTEVNRU5UQURPCi0gcHJlZ3VudGEgcDEyLCBhY3R1YWxtZW50ZSBlc3R1ZGlhLCAxKVNpIDIpTm8KLSBwMjYgSGFiw61hIHVuIGplZmUgZGUgaG9nYXIgZW4gbGEgaW5mYW5jaWEgKDEgcGFkcmUgMiBtYWRyZSkKLSBwNDMgeSBwNDNtIFJlcG9ydGEgZWR1Y2FjacOzbiBkZWwgcGFkcmUgbyBtYWRyZSBwcmljaWFwbAotIHA2OCwgUGVyc29uYXMgcXVlIHRyYWJhamFuLCAxLiBTaSwgMi4gTm8KLSBwNjkgc2kgdHJhYmFqYSBwZXJvIGxhIHNlbWFuYSBwYXNhZGEgbm8gCi0gcDEzMiBudW1lcm8gZGUgcGVyc29uYXMgcXVlIGFwb3J0YW4gaW5ncmVzbwotIHAxMzMgY29ob3J0IGRlIHRvZGFzIGxhcyBwZXJzb25hcyB5IHRvZG9zIGxvcyBpbmdyZXNvcyAoMSBpbmdyZXNvKQoKClZhcmlhYmxlcyBkZSBzZWxlY2Npw7NuIHBhcmEgZXN0aW1hciBpbmdyZXNvCgotIEVzdGFkbwoKLSBwcmVndW50YSA1LCBlZGFkCgotIHByZWd1bnRhIDYsIHNleG8KCi0gUHJlZ3VudGEgMTMsIG5pdmVsIGRlIGVzY3VlbGEKCi0gcDc2IG9jdXBhY2nDs24KLS1TSU5DTzMgY29kaWZpY2FjacOzbiBvY3VwYWNpw7NuIGVudHJldmlzdGFkbwoKLSBwMTMzIGNvaG9ydCBkZSB0b2RhcyBsYXMgcGVyc29uYXMgeSB0b2RvcyBsb3MgaW5ncmVzb3MKCgpgYGB7ciBoaWpvc19zZWxfZXNydX0KIyBwZW5zYW1vcyBxdWUgbG9zIGRhdG9zIHNlIGxlZWVuIGNvbW8gZmFjdG9yZXMgY2FuZG8gY29ycmVzcG9uZGEsIHNpIHNlIGxlZW4gY29tbyBlbnRlcm9zIG5vIGRlYmUgaGFjZXJzZSBlbCBjYXN0aW5nCiNkYXRhX2Vtb3ZpMjAxNzwtZGF0b3NfZQpoaWpvcyA8LSBkYXRhX2Vtb3ZpMjAxNyAlPiUKICBmaWx0ZXIocDAyID09IDEpICAlPiUgI2NvbXBhcnRpciBnYXNvdCBwYXJhIGNvbWVyCiAgZmlsdGVyKGJldHdlZW4ocDA1LDI1LDUwKSkgJT4lICMgZWRhZCwgY3JpdGVyaW8gMSBkZSAyNSBhIDQwLGNyaXRlcmlvMiBhdW1lbnRhbW9zIGxvcyBpbmdyZW9zLCBjcml0ZXJpbyAzIGRlIDI1IGEgNTAKICAjZmlsdGVyKHAwOCA9PSAxKSAgJT4lIAogIGZpbHRlcihwMTIgPT0gMikgICU+JSAjIHlhIG5vIGVzdHVkaWEKICBmaWx0ZXIocDI2ID09IDEgfCBwMjY9PTIgKSAlPiUgIyBzb3N0ZW4gcHJpbmNpcGFsIHBhcGEsIG1hbWEsIAogICBmaWx0ZXIoKCFpcy5uYShwNDMpICYgcDQzIT05OCAmIHAyNiA9PSAxICYgY21vMV8yIT0iLiIgJiAhaXMubmEocDM4XzExKSkgfAogICAgICAgICAgICAoIWlzLm5hKHA0M20pICYgcDQzbSE9OTggICYgcDI2ID09IDIgJiBjbW8yXzIhPSIuIiAmICFpcy5uYShwMzhtXzExKSApKSAlPiUgIyByZXBvcnRhIGVkdWNhY2nDs24gZGUgcHAKICAgZmlsdGVyKCFpcy5uYShwMTMpKSU+JSAjICByZXBvcnRhIGVkdWNhY2nDs24KICBmaWx0ZXIoU0lOQ08zICE9IiIpICU+JSMgcmVwb3J0YSBvZmljaW8gYWN0dWFsCiAgIGZpbHRlcihwNjggPT0gMSB8IHA2OSA9PSAxKSAgJT4lICMgc2kgdHJhYmFqYQogICBmaWx0ZXIocDEzMiAlaW4lIGMoMSkpICU+JSMgcGVyc29uYSBxdWUgYXBvcnRhbiBpbmdyZXNvCiAgZmlsdGVyKCFwMTMzICVpbiUgYyg4LDksTkEpICkgIyByZXBvcnRhIGluZ3Jlc29zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBubyBlc3RhbiBsb3MgaW5ncmVzb3MgIGhvZ2FyIGFpc2xhZG9zLiAKCiNlZGFkX3Byb21lZGlvX3BhZHJlcyA8LSBtZWFuKGhpam9zJHAzOF8xMSwgbmEucm0gPSBUUlVFKQojZWRhZF9wcm9tZWRpb19wYWRyZXMtMjEKCnVuaXF1ZShoaWpvcyRyZWdpb24pCgp1bmlxdWUoaGlqb3MkcDQzKQpucm93KGhpam9zKQpgYGAKIyMgaGlqb3Mgc2VsZWNjaW9uYWRvcwoKSGFjZW1vcyB1biBjb2hvcnQgZGVsIDEgeSBlbCAyIAoKYGBge3IgaGlqb3Nfc2VsX2VzcnVfbW9kfQp2YXI8LWMoIkVzdGFkbyIsInAwNSIsInAwNiIsInAxMyIsIlNJTkNPMyIsInAxMzMiLCJtb3YiLCJpZF9obyIsInJlZ2lvbiIpCmhpam9zX3BhcmFfc2FsPC1oaWpvcyU+JQogIHNlbGVjdCh2YXIpIyU+JQogICNtdXRhdGUocDEzMyA9IGlmZWxzZShwMTMzPT0xLDIscDEzMyktMSkjIGp1bnRhbW9zIGVsIGNvaG9ydCAxIHkgMiAKCmhpam9zX3BhcmFfc2FsIDwtIGhpam9zX3BhcmFfc2FsJT4lCiAgICAgICAgICAgIG11dGF0ZShlc3RyYXRvID0gaWZlbHNlKHAxMzMgJWluJSBjKDEsMiksMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHAxMzMgJWluJSBjKDMpLDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzMyAlaW4lIGMoNCw1KSwzLDQpKSkKICAgICAgICAgICAgICAgICAgICkKCmBgYAoKCiMjIGFqdXN0YW1vcyByZWdpb24KCmBgYHtyIGhpam9zX3NlbF9lc3J1X21vZF8xfQojIGFqc3V0YWpvcyBhIDQgcmVnaW9uZXMKCmhpam9zX3BhcmFfc2FsIDwtIGhpam9zX3BhcmFfc2FsJT4lCiAgICAgICAgICBtdXRhdGUoCiAgICAgICAgICAgIHJlZ2lvbiA9IGlmZWxzZShFc3RhZG8gJWluJSBhcy5pbnRlZ2VyKGMoIjAyIiwiMjYiLCIwOCIsIjA1IiwiMTkiLCIyOCIpKSwxLAogICAgICAgICAgICAgICAgaWZlbHNlKEVzdGFkbyAlaW4lYXMuaW50ZWdlcihjKCIxMiIsIjIwIiwiMDciLCIzMCIsIjI3IiwiMDQiLCIzMSIsIjIzIikpLDQsCiAgICAgICAgICBpZmVsc2UoRXN0YWRvICVpbiUgYXMuaW50ZWdlcihjKCIwMyIsIjI1IiwiMTgiLCIxMCIsIjMyIiwiMTYiLCIwNiIsIjE0IiwiMDEiLCIyNCIpKSwyLDMpKSkKICAgICAgICAgICkKICAgICAgICAgIAoKCiNzdW0oaGlqb3NfcGFyYV9zYWwkcDEzMz09MSkKdW5pcXVlKGhpam9zX3BhcmFfc2FsJHJlZ2lvbikKbnJvdyhoaWpvc19wYXJhX3NhbCkKYGBgCiMjIEhpam9zIGZpam9zCgpgYGB7cn0KYmFzZV9oaWpvc19maWphIDwtIGhpam9zX3BhcmFfc2FsJT4lZmlsdGVyKHAxMzM9PTIpCgpgYGAKCmBgYHtyfQojaW5ncmVzb19oaWpvX2UxOF9lbW92aQoKYmFzZV9oaWpvc19maWphX2Y8LWJhc2VfaGlqb3NfZmlqYSU+JQogICAgc3VtbWFyaXNlKAogICAgIGlkX2hpam8gPSAiZmlqbyIsCiAgICAgaWRfaG8gPSBpZF9obywKICAgICBtb3Y9IG1vdiwKICAgICByZWdpb25oID0gcmVnaW9uLAogICAgIGVkYWQgPSBwMDUsCiAgICAgY29ob3J0ID0gMTAwLCMgcGFhIHF1ZSBzZXB1ZWRhIGhhY2VyIGxhIHJlc3RhIHBlcm8gbm8gc2lnbmlmaWNhIG5hZGEKICAgIGluZ19tZW5fcF9oID0gbGlzdCgyNDAwKSwKICAgICBlc3RyYXRvID0gZXN0cmF0bywKICAgIGVzdGFkbyA9IEVzdGFkbywKICAgIHNleG8gPSBwMDYKICAgICApCgpiYXNlX2hpam9zX2ZpamFfZgpgYGAKCmBgYHtyfQpzYXZlUkRTKGJhc2VfaGlqb3NfZmlqYV9mLCBmaWxlPSJEYXRvcy9iYXNlX2hpam9zX2ZpamFfZl9jcmkzLlJkYSIpCmBgYAoKCiMjIEhpam9zIHBhcmEgZXN0aW1hcgoKYGBge3IgaGlqb3Nfc2VsX2VzcnVfbW9kX2VzdGltYXJ9Cmhpam9zX3BhcmFfc2FsXzE8LWhpam9zX3BhcmFfc2FsJT4lCiAgICAgICBtdXRhdGUocDEzMyA9IGlmZWxzZShwMTMzPT0xLDIscDEzMyktMSkjIHRyYW5zZm9ybWFtb3MKCnVuaXF1ZShoaWpvc19wYXJhX3NhbF8xJHAxMzMpCmBgYAoKCmBgYHtyIGhpam9zX3NlbF9lc3J1X21vZF9ndWFyfQpzYXZlUkRTKGhpam9zX3BhcmFfc2FsXzEsIGZpbGU9IkRhdG9zL2hpam9zX2Vtb3ZpMjAxN19wMS5SZGEiKQp1bmlxdWUoaGlqb3NfcGFyYV9zYWxfMSRwMTMzKQoKYGBgCgoKIyBIaWpvcyBjb25zdHJ1Y2Npw7NuIGluZ3Jlc29zIDE2CgoKIyMgcG9ibGFjaW9uIGVuaWdoIDE2CmBgYHtyIHBvYmxhY2lvbl9lMTZ9CnBvYmxhY2lvbl9lMTY8LWNhcmdhcl9lbmlnaF9zYXYoInBvYmxhY2lvbiIpIApwb2JsYWNpb25fZTE2ZjwtIHBvYmxhY2lvbl9lMTYlPiUKICAjZmlsdGVyKGFzaXNfZXNjID09ICIyIiklPiUgIyB5YSBubyBhc2lzdGUgYSBsYSBlc2N1ZWxhCiAgc2VsZWN0KGZvbGlvdml2LGZvbGlvaG9nLG51bXJlbixzZXhvLGVkYWQsbml2ZWxhcHJvYiklPiUKICBmaWx0ZXIoYmV0d2Vlbihhcy5pbnRlZ2VyKGVkYWQpLDIzLDUyKSkjY3JpdGVyaW8gMSBlbnRyZSAyNS00MCwgY3JpdGVyaW8gMyBlbnRyZSAyNS01MAojIG5vIGZpbHRyYW1vcyBwb3IgamVmZSBkZSBob2dhcgoKbnJvdyhwb2JsYWNpb25fZTE2ZikKc3VtKGlzLm5hKHBvYmxhY2lvbl9lMTZmKSkKYGBgCgojIyBjcmVhbW9zIHJlZ2lvbiAxNgpgYGB7ciBwb2JsYWNpb25fcmVnaW9uX2UxNn0KCgpwb2JsYWNpb25fZTE2ZjwtIHBvYmxhY2lvbl9lMTZmJT4lCiAgICAgICAgICBtdXRhdGUoCiAgICAgICAgICAgIHJlZ2lvbiA9IGlmZWxzZShzdWJzdHIoZm9saW92aXYsMSwyKSAlaW4lIGMoIjAyIiwiMjYiLCIwOCIsIjA1IiwiMTkiLCIyOCIpLDEsCiAgICAgICAgICAgICAgICBpZmVsc2Uoc3Vic3RyKGZvbGlvdml2LDEsMikgJWluJSBjKCIxMiIsIjIwIiwiMDciLCIzMCIsIjI3IiwiMDQiLCIzMSIsIjIzIiksNCwKICAgICAgICAgICAgaWZlbHNlKHN1YnN0cihmb2xpb3ZpdiwxLDIpICVpbiUgYygiMDMiLCIyNSIsIjE4IiwiMTAiLCIzMiIsIjE2IiwiMDYiLCIxNCIsIjAxIiwiMjQiKSwyLDMpKSkKICAgICAgICAgICkKdW5pcXVlKHBvYmxhY2lvbl9lMTZmJHJlZ2lvbikKbnJvdyhwb2JsYWNpb25fZTE2ZikKc3VtKGlzLm5hKHBvYmxhY2lvbl9lMTZmKSkKYGBgCgojIyB0cmFiYWpvcyBlbmlnaCAxNgoKRmlsdHJhbXMgbG9zIHRyYWJham9zCgpgYGB7ciB0cmFiYWpvc19lMTZ9CnRyYWJham9zX2UxNjwtY2FyZ2FyX2VuaWdoX3NhdigidHJhYmFqb3MiKQp0cmFiYWpvc19lMTZmPC10cmFiYWpvc19lMTYlPiUKc2VsZWN0KGZvbGlvdml2LGZvbGlvaG9nLG51bXJlbixzaW5jbyklPiUKIGZpbHRlcighaXMubmEoc2luY28pKQpOUk9XKHRyYWJham9zX2UxNmYpCiNOUk9XKHRyYWJham9zKQpzdW0oaXMubmEodHJhYmFqb3NfZTE2ZikpCgpgYGAKCiMjIEluZ3Jlc29zIGVuaWdoIDIwMTYKCmBgYHtyIGluZ3Jlc29zX2UxNn0KaW5ncmVzb3NfZTE2PC1jYXJnYXJfZW5pZ2hfc2F2KCJpbmdyZXNvcyIpCmZhbWlsaWFzX2ludGVncmFudGVzX2UxNiA8LSBmdW5jdGlvbihkZixmb2xob2csbnIpewogIGRmbiA8LSBkZiAlPiUKICAgIGZpbHRlcihmb2xpb2hvZyAlaW4lIGZvbGhvZyklPiUKICAgIGZpbHRlcihudW1yZW4gJWluJSBucikKICByZXR1cm4oZGZuKQp9IAoKCgppbmdyZXNvc19hY3VfZTE2IDwtIGZ1bmN0aW9uKGRmLGNsYXZzPWdldF9sYWJlbHMoaW5ncmVzb3NfZTE2JGNsYXZlKSl7CiBkZm4gPC0gZGYgJT4lCiAgIGdyb3VwX2J5KGZvbGlvdml2LCBmb2xpb2hvZywgbnVtcmVuKSAlPiUKICAgZmlsdGVyKGNsYXZlICVpbiUgY2xhdnMpJT4lCiAgIHN1bW1hcmlzZSgKICAgY2xhdmVzX2EgPSBwYXN0ZShjbGF2ZSxjb2xsYXBzZSA9ICIsIiksCiAgaW5nX3RyaV90ID0gc3VtKGluZ190cmkpLAogIGluZ19tZW5fcCA9IGluZ190cmlfdC8zLAogIGxpbmdfbWVuX3AgPSBsb2coaW5nX21lbl9wKQogICkgJT4lIHVuZ3JvdXAoKQogCiAKIHJldHVybihkZm4pCn0KCmhvZ2FyZXMgPC0gYygiMSIsIjIiLCIzIiwiNCIsIjUiKQpwZXJzb25hc19oIDwtIGMoJzAxJywnMDInLCcwMycsJzA0JywnMDUnKQoKYTwtZmFtaWxpYXNfaW50ZWdyYW50ZXNfZTE2KGluZ3Jlc29zX2UxNixob2dhcmVzLHBlcnNvbmFzX2gpCmhlYWQoYSkKCiMjIyBjcml0ZXJpbyAxIGFsZ3Vub3MgaW5ncmVzb3Mgbm8gdG9kb3MgbG9zIGRlIGFiYWpvCiNjbGF2ZXM8LWMoIlAwMDEiLCJQMDAyIiwiUDAwMyIsIlAwMTAiLCJQMDExIiwiUDAxMiIsIlAwMTMiLCJQMDE0IiwiUDAxNSIsICJQMDE2IiwiUDAxNyIsIlAwMTgiLCJQMDIwIiwiUDAyMSIsIlAwMjYiLCJQMDI3IiwiUDAzNSIsIlAwNDAiLCJQMDQxIiwiUDA0MiIsIlAwNDQiLCJQMDQ1IikKCiMjIGNyaXRlcmlvIDIgZmxleGliaWxpZGFkIGVuIGxvcyBpbmdyZXNvcywgY3JpdGVyaW8gMwpjbGF2ZXM8LWMoIlAwMDEiLCJQMDAyIiwiUDAwMyIsIlAwMTEiLCJQMTMiLCJQMDIzIiwiUDAyNCIsIlAwMjUiLCJQMDI2IiwiUDAyNyIsIlAwMjgiLCJQMDI5IiwiUDAzMCIsIlAwMzEiLCJQMDMyIiwiUDAzMyIsIlAwNTQiLCJQMDU1IiwiUDA1NiIsICJQMDU5IiwiUDA2MCIsIlAwNjEiLCJQMDYyIiwiUDA2MyIsIlAwNjgiLCJQMDY5IiwiUDA3MCIsIlAwNzEiLCJQMDcyIiwiUDA3MyIsIlAwNzQiLCJQMDc1IiwiUDA3NiIsIlAwNzciLCJQMDc4IiwiUDA3OSIsIlAwODAiKQoKaW5ncmVzb3NfZTE2YTwtaW5ncmVzb3NfYWN1X2UxNihhLGNsYXZlcykgCmluZ3Jlc29zX2UxNmE8LSBpbmdyZXNvc19lMTZhJT4lCiAgICAgICAgICBtdXRhdGUoY29oX2luZyA9IGlmZWxzZShpbmdfbWVuX3A8PTI0MDAsMSwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaW5nX21lbl9wPD00ODAwLDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGluZ19tZW5fcDw9NzIwMCwzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShpbmdfbWVuX3A8PTEyMDAwLDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGluZ19tZW5fcDw9MjQwMDAsNSw2KSkpKSkpCgppbmdyZXNvc19lMTZhPC0gaW5ncmVzb3NfZTE2YSU+JW11dGF0ZSgKICAgcmVnaW9uID0gaWZlbHNlKHN1YnN0cihmb2xpb3ZpdiwxLDIpICVpbiUgYygiMDIiLCIyNiIsIjA4IiwiMDUiLCIxOSIsIjI4IiksMSwKICAgICAgICAgICAgICAgIGlmZWxzZShzdWJzdHIoZm9saW92aXYsMSwyKSAlaW4lIGMoIjEyIiwiMjAiLCIwNyIsIjMwIiwiMjciLCIwNCIsIjMxIiwiMjMiKSw0LAogICAgICAgICAgICBpZmVsc2Uoc3Vic3RyKGZvbGlvdml2LDEsMikgJWluJSBjKCIwMyIsIjI1IiwiMTgiLCIxMCIsIjMyIiwiMTYiLCIwNiIsIjE0IiwiMDEiLCIyNCIpLDIsMykpKQopCgppbmdyZXNvc19lMTZmYzwtaW5ncmVzb3NfZTE2YSU+JSAKIAogIHNlbGVjdChmb2xpb3Zpdixmb2xpb2hvZyxudW1yZW4sY29oX2luZykKYGBgCgoKYGBge3J9CnNvcnQodW5pcXVlKGFzLmNoYXJhY3RlcihpbmdyZXNvc19lMTYkY2xhdmUpKSlbXQpgYGAKCgoKIyMgcmFuZ28gcGVyY2VudGlsIDE2CgpgYGB7cn0KI0lOPC0oMTAwLzExMC45MDcpCklOPC0oMTAwLzkzLjYpCmluZ3Jlc29zX2UxNmEkbGluZ19tZW5fcGQgPC0gaW5ncmVzb3NfZTE2YSRsaW5nX21lbl9wICsgbG9nKElOKQpycF9lMTYgPC0gcmFuayhpbmdyZXNvc19lMTZhJGxpbmdfbWVuX3BkKS9sZW5ndGgoaW5ncmVzb3NfZTE2YSRsaW5nX21lbl9wZCkKYGBgCgoKCmBgYHtyfQppbmdyZXNvc19lMTZhMSA8LSBkYXRhLmZyYW1lKGxpbmdfbWVuX3BkPWluZ3Jlc29zX2UxNmElPiVmaWx0ZXIocmVnaW9uPT0xKSU+JXB1bGwobGluZ19tZW5fcCkgKyBsb2coSU4pKQpycF9lMTYxIDwtIHJhbmsoaW5ncmVzb3NfZTE2YTEkbGluZ19tZW5fcGQpL2xlbmd0aChpbmdyZXNvc19lMTZhMSRsaW5nX21lbl9wZCkKYGBgCgpgYGB7cn0KaW5ncmVzb3NfZTE2YTIgPC0gZGF0YS5mcmFtZShsaW5nX21lbl9wZD1pbmdyZXNvc19lMTZhJT4lZmlsdGVyKHJlZ2lvbj09MiklPiVwdWxsKGxpbmdfbWVuX3ApICsgbG9nKElOKSkKcnBfZTE2MiA8LSByYW5rKGluZ3Jlc29zX2UxNmEyJGxpbmdfbWVuX3BkKS9sZW5ndGgoaW5ncmVzb3NfZTE2YTIkbGluZ19tZW5fcGQpCmBgYAoKCmBgYHtyfQppbmdyZXNvc19lMTZhMyA8LSBkYXRhLmZyYW1lKGxpbmdfbWVuX3BkPWluZ3Jlc29zX2UxNmElPiVmaWx0ZXIocmVnaW9uPT0zKSU+JXB1bGwobGluZ19tZW5fcCkgKyBsb2coSU4pKQpycF9lMTYzIDwtIHJhbmsoaW5ncmVzb3NfZTE2YTMkbGluZ19tZW5fcGQpL2xlbmd0aChpbmdyZXNvc19lMTZhMyRsaW5nX21lbl9wZCkKYGBgCgpgYGB7cn0KaW5ncmVzb3NfZTE2YTQgPC0gZGF0YS5mcmFtZShsaW5nX21lbl9wZD1pbmdyZXNvc19lMTZhJT4lZmlsdGVyKHJlZ2lvbj09NCklPiVwdWxsKGxpbmdfbWVuX3ApICsgbG9nKElOKSkKcnBfZTE2NCA8LSByYW5rKGluZ3Jlc29zX2UxNmE0JGxpbmdfbWVuX3BkKS9sZW5ndGgoaW5ncmVzb3NfZTE2YTQkbGluZ19tZW5fcGQpCmBgYAoKCgoKYGBge3J9Cmhpc3QocnBfZTE2KQpgYGAKCgojIyBCYXNlIGNydXphZGEgcG9iLXRyYSAxNgoKYGBge3IgYmFzZV9jcnV6YWRhfQplbmlnaF8xNjwtIGZ1bGxfam9pbihwb2JsYWNpb25fZTE2Zix0cmFiYWpvc19lMTZmKSU+JQogICBkcm9wX25hKCkKI2VuaWdoPC1mdWxsX2pvaW4oZW5pZ2gsY29uY2VudHJhZG8pJT4lCiAjIGRyb3BfbmEoKQpucm93KGVuaWdoXzE2KQpzdW0oaXMubmEoZW5pZ2hfMTYpKQpgYGAKCiMjIENhbWJpbyBldGlxdWV0YWRvIGVkdWNhY2lvbiAxNgpQYXNhbW9zIGxhcyBldGlxZXV0ZWFzIGRlIGVkdWNhY2nDs24gZGUgZW1vdmkgYSAKCmBgYHtyIGNhbWJpYV9lX2VzcnVfb2N1fQoKaGlqb3NfZW1vdmkgPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9oaWpvc19lbW92aTIwMTdfcDEuUmRhIikjY3JpdGVyaW8gMSB5IDMKaGlqb3NfZW1vdmk8LSBoaWpvc19lbW92aSAlPiUKICBtdXRhdGUocDEzX20gPSBpZmVsc2UocDEzICVpbiUgYygxKSwiMSIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoIHAxMyA9PSAyLCIyIiwKICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwMTMgJWluJSBjKDMsNCksIjMiLAogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCBwMTMgJWluJSBjKDUsNiksIjQiLAogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHAxMyAlaW4lIGMoNyw4KSwiNiIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzICVpbiUgYyg5LDEwKSwiNSIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzPT0xMSwiNyIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzPT0xMiwiOCIsIjAiKSkpKSkpKSkpCnVuaXF1ZShoaWpvc19lbW92aSRwMTNfbSkKCmVuaWdoXzE2PC1lbmlnaF8xNiU+JQogIG11dGF0ZShuaXZlbGFwcm9iPWlmZWxzZShuaXZlbGFwcm9iPT0iOSIsIjgiLG5pdmVsYXByb2IpKQoKdW5pcXVlKGVuaWdoXzE2JG5pdmVsYXByb2IpCgplbmlnaF8xNmY8LWVuaWdoXzE2JT4lCiAgZmlsdGVyKG5pdmVsYXByb2IgJWluJSB1bmlxdWUoaGlqb3NfZW1vdmkkcDEzX20pKQoKbnJvdyhlbmlnaF8xNmYpCmBgYAoKCiMjIEJ1c2NhciBmb2xpb3MgY29uIGNhcmFjdGVyaXN0aWNhcyAxNgoKYGBge3IgYnVzY2FfZm9saW9zX2UxNn0KYnVzY2E8LWZ1bmN0aW9uKGkpewpyZXR1cm4oZW5pZ2hfMTZmJT4lCiAgZmlsdGVyKAogICAgI2FzLmludGVnZXIoc3Vic3RyKGZvbGlvdml2LDEsMikpPT1oaWpvc19lbW92aVtpLF0kRXN0YWRvICYKICAgIHJlZ2lvbiA9PSBoaWpvc19lbW92aVtpLF0kcmVnaW9uICYKICAgIHNleG8gPT0gaGlqb3NfZW1vdmlbaSxdJHAwNiAmCiAgICAoKGVkYWQtMikgPD0gaGlqb3NfZW1vdmlbaSxdJHAwNSkgJgogICAgKGhpam9zX2Vtb3ZpW2ksXSRwMDUgPD0gKGVkYWQrMikpICYKICAgICNhcy5jaGFyYWN0ZXIoc2luY28pID09IGhpam9zX2Vtb3ZpW2ksXSRTSU5DTzMgJgogICAgc3Vic3RyKGFzLmNoYXJhY3RlcihzaW5jbyksMSwxKT09IHN1YnN0cihoaWpvc19lbW92aVtpLF0kU0lOQ08zLDEsMSkmCiAgICBuaXZlbGFwcm9iID09IGhpam9zX2Vtb3ZpW2ksXSRwMTNfbSklPiUKICAgIAogIHNlbGVjdChmb2xpb3Zpdixmb2xpb2hvZykpCn0KCiAgCmE8LWxhcHBseSgxOm5yb3coaGlqb3NfZW1vdmkpLCBidXNjYSkKCmNvbnRhZG9yPC0wCmZvcihpIGluIDE6bnJvdyhoaWpvc19lbW92aSkpCntpZihucm93KGFbW2ldXSk+MCkKICBjb250YWRvcjwtY29udGFkb3IgKzEKfQpjb250YWRvcgoKI3NhdmVSRFMoYSwgZmlsZT0iRGF0b3MvZm9saGlqb3NfZW5pZ2gxNl9lbW92aV9yZV9jaC5SZGEiKQojc2F2ZVJEUyhhLCBmaWxlPSJEYXRvcy9mb2xoaWpvc19lbmlnaDE2X2Vtb3ZpX3JlX2NoX2NyaTMuUmRhIikKc2F2ZVJEUyhhLCBmaWxlPSJEYXRvcy9mb2xoaWpvc19lbmlnaDE2X2Vtb3ZpX3Npbm0xX3JlX3AxLlJkYSIpCiNzYXZlUkRTKGEsIGZpbGU9IkRhdG9zL2ZvbGhpam9zX2VuaWdoMTZfZW1vdmlfZXN0X2NoX2NyaTMuUmRhIikKCmBgYAoKLSBDb24gb2N1cGFjaW9uIHkgcmVnaW9uIGRlbCB0b3RhbCwgNjY4IHBlcnNvbmFzIHRpZW5lbiBnZW1lbG9zCi0gQ29uIHJlZ2lvbiwgCgpDcml0ZXJpbyAzCi0gb2N1cGFjaW9uIHkgcmVnaW9uIHksIDk3OQotIGVzdGFkbywgbWFzIGFsIHJhdG8gY29ob3J0IGVuIGVsIGluZ3Jlc28KIyMjIGZpbHRhbW9zIHNvbG8gbG9zIGhpam9zIGVuY29udHJhZG9zIDE2CgoKYGBge3IgZXRpcXVlX2hpam9zX2VuY199IAojIGV0aXF1ZXRhbW9zIHBhcmEgbm8gcGVyZGVyIGxhIG51bWVyYWNpb24gcmVzcGVjdG8gYSBsb3MgaGlqb3Mgb3JpZ2luYWxlcwpmb2xoaWpvc19lMTZfZW1vdmkgPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9mb2xoaWpvc19lbmlnaDE2X2Vtb3ZpX3Npbm0xX3JlX3AxLlJkYSIpCm5hbWVzKGZvbGhpam9zX2UxNl9lbW92aSkgPC0gYXMuY2hhcmFjdGVyKDE6bnJvdyhoaWpvc19lbW92aSkpCmxlbmd0aChmb2xoaWpvc19lMTZfZW1vdmkpCmBgYAoKYGBge3IgZmlsdHJhX2hpam9zX2VuY29ufQpMIDwtIGMoKQpmb3IoaSBpbiAxOmxlbmd0aChmb2xoaWpvc19lMTZfZW1vdmkpKXsKICBpZighKG5yb3coZm9saGlqb3NfZTE2X2Vtb3ZpW1tpXV0pPjApKXsKICAgIEw8LWMoTCxpKX0KfQojIFNvbG8gaGlqb3MgcXVlIHNlIGxlcyBwdWRvIGVuY29udHJhciBlbiBlbmlnaC0yMDE2IDEwNzcvMTEzMQpmb2xoaWpvc19lMTZfZW1vdmlmPC1mb2xoaWpvc19lMTZfZW1vdmlbLUxdCiAgICAKCmxlbmd0aChmb2xoaWpvc19lMTZfZW1vdmlmKQoKI25hbWVzKGZvbGhpam9zX2Vtb3ZpZikKI25hbWVzKGZvbGhpam9zX2Vtb3ZpKQpgYGAKCiMjIyBVbmljb3MgZm9saW9zLCBkaWZlcmVudGVzIHRyYWJham9zIDE2CgoKCmBgYHtyIGZpbHRyYV9maWxfaGlqX3VuaX0KdW5pY29zX2ZvbGlvczwtZnVuY3Rpb24oaSl7CmZvbGhpam9zX2UxNl9lbW92aWZbW2ldXSU+JQogIGRpc3RpbmN0KCkKfQoKIyBmaWx0cmFtb3MgdW5pY29zIGZvbGlvcyBwb3IgZGlmZXJlbnRlcyB0cmFiYWpvcyBkZSBsYSBtaXNtYSBwZXJzb25hCmE8LWxhcHBseSgxOmxlbmd0aChmb2xoaWpvc19lMTZfZW1vdmlmKSwgdW5pY29zX2ZvbGlvcykKbmFtZXMoYSk8LW5hbWVzKGZvbGhpam9zX2UxNl9lbW92aWYpCmxlbmd0aChhKQoKZm9saGlqb3NfZTE2X2Vtb3ZpZjwtYQpgYGAKCgojIyMgT2JzZXJ2YW1vcyBsYXMgZWRhZGVzIGRlIGxvcyBlbmNvbnRyYWRvcyAxNgoKYGBge3IgZ3JhX2VkYWRlc19oX2VuY30KCm15TWVudUl0ZW1zIDwtIGMoImRvd25sb2FkUE5HIiwgImRvd25sb2FkSlBFRyIsICJkb3dubG9hZFBERiIsICdkb3dubG9hZFNWRycsICdwcmludENoYXJ0JykKCmhpam9zX2Vtb3ZpJT4lCiAgc2xpY2UoYXMuaW50ZWdlcihuYW1lcyhmb2xoaWpvc19lMTZfZW1vdmlmKSkpJT4lCiAgc2VsZWN0KHAwNSklPiUKICBjb3VudChwMDUpJT4lCiAgICBoY2hhcnQoJ2NvbHVtbicsCiAgICAgICAgIGhjYWVzKCB5ID0gJ24nKSklPiUKICBoY19hZGRfdGhlbWUoaGNfdGhlbWVfZmZ4KCkpJT4lCiAgaGNfdGl0bGUoCiAgICB0ZXh0ID0gIiIKICApICU+JQogICNoY19zdWJ0aXRsZSh0ZXh0ID0gIkxhcyBlZGFkZXMgZXN0w6FuIGFncnVwYWRhcyBlbiBpbnRlcnZhbG9zIAogICAjICAgICAgICAgICBkZSAxMCBhw7FvcyAoZGEgY2xpYyBzb2JyZSBGIG8gTSkiKSAlPiUKICAjIGhjX2NyZWRpdHMoCiAgIyAgZW5hYmxlZCA9IFRSVUUsIHRleHQgPSAiU291cmNlOiBTU1MiLAogICMgIHN0eWxlID0gbGlzdChmb250U2l6ZSA9ICIxMnB4IikpJT4lCiAgaGNfeUF4aXModGl0bGUgPSBsaXN0KHRleHQgPSAiTsO6bWVybyBkZSBwYXJ0aWNpcGFudGVzIikpJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJOw7ptZXJvIGRlIHBlcnNvbmFzIiksCiAgICAgICAgICAgY2F0ZWdvcmllcyA9IGFzLmNoYXJhY3RlcigyNTo1MCkpICU+JQogICAgaGNfZXhwb3J0aW5nKGVuYWJsZWQgPSBUUlVFLAogICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJkYXRvcyIsCiAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KGNvbnRleHRCdXR0b24gPSBsaXN0KG1lbnVJdGVtcyA9IG15TWVudUl0ZW1zKSkpCgoKYGBgCgojIyMgT2JzZXJ2YW1vcyBsYXMgZXN0YWRvcyBkZSBsb3MgZW5jb250cmFkb3MgMTYKCmBgYHtyIGdyYV9lc3RhZG9zX2hfZTE2fQpoaWpvc19lbW92aSU+JQogIHNsaWNlKGFzLmludGVnZXIobmFtZXMoZm9saGlqb3NfZTE2X2Vtb3ZpZikpKSU+JQogIGNvdW50KEVzdGFkbyklPiUKICAgIGhjaGFydCgnY29sdW1uJywKICAgICAgICAgaGNhZXMoIHkgPSAnbicpKSU+JQogIGhjX2FkZF90aGVtZShoY190aGVtZV9mZngoKSklPiUKICBoY190aXRsZSgKICAgIHRleHQgPSAiIgogICkgJT4lCiAgI2hjX3N1YnRpdGxlKHRleHQgPSAiTGFzIGVkYWRlcyBlc3TDoW4gYWdydXBhZGFzIGVuIGludGVydmFsb3MgCiAgICMgICAgICAgICAgIGRlIDEwIGHDsW9zIChkYSBjbGljIHNvYnJlIEYgbyBNKSIpICU+JQogICMgaGNfY3JlZGl0cygKICAjICBlbmFibGVkID0gVFJVRSwgdGV4dCA9ICJTb3VyY2U6IFNTUyIsCiAgIyAgc3R5bGUgPSBsaXN0KGZvbnRTaXplID0gIjEycHgiKSklPiUKICBoY195QXhpcyh0aXRsZSA9IGxpc3QodGV4dCA9ICJOw7ptZXJvIGRlIHBhcnRpY2lwYW50ZXMiKSklPiUKICBoY194QXhpcyh0aXRsZT1saXN0KHRleHQ9Ik7Dum1lcm8gZGUgcGVyc29uYXMiKSwKICAgICAgICAgICBjYXRlZ29yaWVzID0gZ2V0X2xhYmVscyhoaWpvc19lbW92aSRFc3RhZG8pKSAlPiUKICAgIGhjX2V4cG9ydGluZyhlbmFibGVkID0gVFJVRSwKICAgICAgICAgICAgICAgZmlsZW5hbWUgPSAiZGF0b3MiLAogICAgICAgICAgICAgICBidXR0b25zID0gbGlzdChjb250ZXh0QnV0dG9uID0gbGlzdChtZW51SXRlbXMgPSBteU1lbnVJdGVtcykpKQoKYGBgCgoKIyMgSW5ncmVzbyBoaWpvIGVuaWdoXzE2IC0gZW1vdmkKCmBgYHtyIGluZ3JlX2hpam9fZTE2X2Vtb3ZpfQoKaW5ncmVzb19oaWpvX2UxNl9lbW92aTwtZnVuY3Rpb24oaSl7CiAgaW5ncmVzb3NfZTE2YSU+JQogIGZpbHRlcihmb2xpb3ZpdiAlaW4lIGZvbGhpam9zX2UxNl9lbW92aWZbW2ldXSRmb2xpb3ZpdiAmCiAgICBmb2xpb2hvZyAlaW4lIGZvbGhpam9zX2UxNl9lbW92aWZbW2ldXSRmb2xpb2hvZyklPiUKICAgI2ZpbHRlcihjb2hfaW5nPT1oaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxNl9lbW92aWZbaV0pKSwicDEzMyJdKSU+JQogICAgc3VtbWFyaXNlKAogICAgIGlkX2hpam8gPSBuYW1lcyhmb2xoaWpvc19lMTZfZW1vdmlmW2ldKSwKICAgICBpZF9obyA9IGhpam9zX2Vtb3ZpW2FzLmludGVnZXIobmFtZXMoZm9saGlqb3NfZTE2X2Vtb3ZpZltpXSkpLCJpZF9obyJdLAogICAgIG1vdj0gaGlqb3NfZW1vdmlbYXMuaW50ZWdlcihuYW1lcyhmb2xoaWpvc19lMTZfZW1vdmlmW2ldKSksIm1vdiJdLAogICAgIHJlZ2lvbmggPSBoaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxNl9lbW92aWZbaV0pKSwicmVnaW9uIl0sCiAgICAgZWRhZCA9IGhpam9zX2Vtb3ZpW2FzLmludGVnZXIobmFtZXMoZm9saGlqb3NfZTE2X2Vtb3ZpZltpXSkpLCJwMDUiXSwKICAgICBjb2hvcnQgPSBoaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxNl9lbW92aWZbaV0pKSwicDEzMyJdLAogICAgaW5nX21lbl9wX2ggPWxpc3QoaW5nX21lbl9wKSwKICAgICBlc3RyYXRvID0gaGlqb3NfZW1vdmlbYXMuaW50ZWdlcihuYW1lcyhmb2xoaWpvc19lMTZfZW1vdmlmW2ldKSksImVzdHJhdG8iXSwKICAgIGVzdGFkbyA9IGhpam9zX2Vtb3ZpW2FzLmludGVnZXIobmFtZXMoZm9saGlqb3NfZTE2X2Vtb3ZpZltpXSkpLCJFc3RhZG8iXSwKICAgIHNleG8gPSBoaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxNl9lbW92aWZbaV0pKSwicDA2Il0KICAgICApCn0KIzI3MywzMzIgc29uIHZhY2lvcwojIGluZ3Jlc28gaGlqbyBwZXJvIHVhbGd1bm9zIG5vIHBvZHJpYW4gZXN0YXIgcG9yIG5vIHRlbmVyIHJlZ2lzdHJvIGRlIHNhbGFyaW8KCmE8LWxhcHBseSgxOmxlbmd0aChmb2xoaWpvc19lMTZfZW1vdmlmKSwgaW5ncmVzb19oaWpvX2UxNl9lbW92aSkKaW5ncmVzb19oaWpvZ19lMTZfZW1vdmk8LWEKbGVuZ3RoKGluZ3Jlc29faGlqb2dfZTE2X2Vtb3ZpKQojaW5ncmVzb19oaWpvZ19lMTZfZW1vdmlbWzMzMl1dCiN4PC1pbmdyZXNvX2hpam9nX2UxNl9lbW92aVtbMzMyXV0kaW5nX21lbl9wX2hbMV0KI3N1bShpbmdyZXNvX2hpam9nX2UxNl9lbW92aVtbMzMyXV0kaW5nX21lbl9wX2hbWzFdXSxuYS5ybSA9IFRSVUUpCgoKYGBgCiMjIEZpbHRyYW1vcyBzb2JyZSBpbmdyZXNvcyBlbmNvbnRyYWRvcyAxNgoKYGBge3IgZmlsX2luZ3JlX2VuY19lMTZfZW1vdml9CgpMIDwtIGMoKQpmb3IoaSBpbiAxOmxlbmd0aChpbmdyZXNvX2hpam9nX2UxNl9lbW92aSkpewogIGlmKHN1bShpbmdyZXNvX2hpam9nX2UxNl9lbW92aVtbaV1dJGluZ19tZW5fcF9oW1sxXV0sbmEucm0gPSBUUlVFKT09MCl7CiAgICBMPC1jKEwsaSl9Cn0KbGVuZ3RoKEwpCgppbmdyZXNvX2hpam9nX2UxNl9lbW92aTwtaW5ncmVzb19oaWpvZ19lMTZfZW1vdmlbLUxdCgpsZW5ndGgoaW5ncmVzb19oaWpvZ19lMTZfZW1vdmkpCmluZ3Jlc29faGlqb2dfZTE2X2Vtb3ZpWzFdCmluZ3Jlc29faGlqb2dfZTE2X2Vtb3ZpWzJdCgoKaW5ncmVzb19oaWpvZ19lMTZfZW1vdmlmPC1iaW5kX3Jvd3MoaW5ncmVzb19oaWpvZ19lMTZfZW1vdmlbMTpsZW5ndGgoaW5ncmVzb19oaWpvZ19lMTZfZW1vdmkpXSkKCgpucm93KGluZ3Jlc29faGlqb2dfZTE2X2Vtb3ZpZikKCnNhdmVSRFMoaW5ncmVzb19oaWpvZ19lMTZfZW1vdmlmLCBmaWxlPSJEYXRvcy9pbmdyZXNvX2hpal9mX2Vtb3ZpX3Npbm0xX3JlX3AxLlJkYSIpCgpnZW1lbG9zPC1jKCkKZm9yKCBpIGluIDE6bnJvdyhpbmdyZXNvX2hpam9nX2UxNl9lbW92aWYpKXsKZ2VtZWxvczwtYyhnZW1lbG9zLGxlbmd0aChpbmdyZXNvX2hpam9nX2UxNl9lbW92aWYkaW5nX21lbl9wX2hbW2ldXSkpCn0KI2dlbWVsb3MKI21pbihpbmdyZXNvX2hpam9nX2UxNl9lbW92aWYkaW5nX21lbl9wX2hbWzQ1OV1dKQojbWF4KGluZ3Jlc29faGlqb2dfZTE2X2Vtb3ZpZiRpbmdfbWVuX3BfaFtbNDU5XV0pCgppbmdyZXNvX2hpam9nX2UxNl9lbW92aWYlPiVzZWxlY3QoaWRfaG8pCmBgYApQcm9tZWRpbyBkZSBnZW1lbG9zIHBvciBpbmRpdmlkdW8KCmBgYHtyfQoKbGVuPC0wCmZvcihpIGluIDE6bnJvdyhpbmdyZXNvX2hpam9nX2UxNl9lbW92aWYpKXsKbGVuPC0gbGVuICsgbGVuZ3RoKGluZ3Jlc29faGlqb2dfZTE2X2Vtb3ZpZiRpbmdfbWVuX3BfaFtbaV1dKQp9CgpsZW4vbnJvdyhpbmdyZXNvX2hpam9nX2UxNl9lbW92aWYpCmBgYAoKCkNSSVRFUklPIDEKLSBjb24gIHJlZ2lvbiAxMTE3IHRpZW5lbiBzYWxhcmlvCi0gY29uIHJlZ2lvbiB5IGVuIGNvaG9ydCBkZSBpbmdyZXNvIHRpZW5lbiBzYWxhcmlvIDExMDAKLSBjb24gb2N1cGFjaW9uIHkgcmVnaW9uIDY1OSB0aWVuZW4gc2FsYXJpbwotIGNvbiBvY3VwYWNpb24geSByZWdpb24geSBjb2hvcnQgZGUgaW5ncmVzbyA0MzYgdGllbmVuIHNhbGFyaW8KCgpDUklURVJJTyAyIChpbmdyZXNvc28gYXVtZW50YW1vcyBsYXMgY2xhdmVzKQotIGNvbiByZWdpb24geSBlbiBjb2hvcnQgZGUgaW5ncmVzbyB0aWVuZW4gc2FsYXJpbyAxMTAzCgpDUklURVJJTyAzIChpbmdyZXNvc28gYXVtZW50YW1vcyBsYXMgY2xhdmVzLCB5IGxvcyByYW5nb3MgZGUgZWRhZCkKLSBjb24gcmVnaW9uIHkgZW4gY29ob3J0IGRlIGluZ3Jlc28gdGllbmVuIHNhbGFyaW8gMTY1OAotIGNvbiByZWdpb24sIG9jdXBhY2nDs24geSBlbiBlbCBjb2hvcnQgZGUgaW5ncmVzbyB0aWVuZW4gNjgzCi0gY29uZSBlc3RhZG8sIGNvaG9ydCBlbiBlbCBpbmdyZXNvLCAxNDczCgoKCgojIEhpam9zIGNvbnN0cnVjY2nDs24gaW5ncmVzb3MgMTgKCgojIyBwb2JsYWNpb24gZW5pZ2ggMTgKYGBge3IgcG9ibGFjaW9uX2UxOH0KcG9ibGFjaW9uX2UxODwtY2FyZ2FyX2VuaWdoX3Nhdl8xOCgicG9ibGFjaW9uIikgCnBvYmxhY2lvbl9lMThmPC0gcG9ibGFjaW9uX2UxOCU+JQogICNmaWx0ZXIoYXNpc19lc2MgPT0gIjIiKSU+JSAjIHlhIG5vIGFzaXN0ZSBhIGxhIGVzY3VlbGEKICBzZWxlY3QoZm9saW92aXYsZm9saW9ob2csbnVtcmVuLHNleG8sZWRhZCxuaXZlbGFwcm9iKSU+JQogIGZpbHRlcihiZXR3ZWVuKGFzLmludGVnZXIoZWRhZCksMjMsNTIpKSNjcml0ZXJpbyAxIGVudHJlIDI1LTQwLCBjcml0ZXJpbyAzIGVudHJlIDI1LTUwCiMgbm8gZmlsdHJhbW9zIHBvciBqZWZlIGRlIGhvZ2FyCgpucm93KHBvYmxhY2lvbl9lMThmKQpzdW0oaXMubmEocG9ibGFjaW9uX2UxOGYpKQpgYGAKCgojIyBjcmVhbW9zIHJlZ2lvbiAxOApgYGB7ciBwb2JsYWNpb25fcmVnaW9uX2UxOH0KCgpwb2JsYWNpb25fZTE4ZjwtIHBvYmxhY2lvbl9lMThmJT4lCiAgICAgICAgICBtdXRhdGUoCiAgICAgICAgICAgIHJlZ2lvbiA9IGlmZWxzZShzdWJzdHIoZm9saW92aXYsMSwyKSAlaW4lIGMoIjAyIiwiMjYiLCIwOCIsIjA1IiwiMTkiLCIyOCIpLDEsCiAgICAgICAgICAgICAgICBpZmVsc2Uoc3Vic3RyKGZvbGlvdml2LDEsMikgJWluJSBjKCIxMiIsIjIwIiwiMDciLCIzMCIsIjI3IiwiMDQiLCIzMSIsIjIzIiksNCwKICAgICAgICAgICAgaWZlbHNlKHN1YnN0cihmb2xpb3ZpdiwxLDIpICVpbiUgYygiMDMiLCIyNSIsIjE4IiwiMTAiLCIzMiIsIjE2IiwiMDYiLCIxNCIsIjAxIiwiMjQiKSwyLDMpKSkKICAgICAgICAgICkKdW5pcXVlKHBvYmxhY2lvbl9lMThmJHJlZ2lvbikKbnJvdyhwb2JsYWNpb25fZTE4ZikKc3VtKGlzLm5hKHBvYmxhY2lvbl9lMThmKSkKYGBgCgojIyB0cmFiYWpvcyBlbmlnaCAxOAoKRmlsdHJhbXMgbG9zIHRyYWJham9zCgpgYGB7ciB0cmFiYWpvc19lMTh9CnRyYWJham9zX2UxODwtY2FyZ2FyX2VuaWdoX3Nhdl8xOCgidHJhYmFqb3MiKQp0cmFiYWpvc19lMThmPC10cmFiYWpvc19lMTglPiUKc2VsZWN0KGZvbGlvdml2LGZvbGlvaG9nLG51bXJlbixzaW5jbyklPiUKIGZpbHRlcighaXMubmEoc2luY28pKQpOUk9XKHRyYWJham9zX2UxOGYpCiNOUk9XKHRyYWJham9zKQpzdW0oaXMubmEodHJhYmFqb3NfZTE4ZikpCgpgYGAKIyMgSW5ncmVzb3MgZW5pZ2ggMjAxOAoKYGBge3IgaW5ncmVzb3NfZTE4fQppbmdyZXNvc19lMTg8LWNhcmdhcl9lbmlnaF9zYXZfMTgoImluZ3Jlc29zIikKZmFtaWxpYXNfaW50ZWdyYW50ZXNfZTE4IDwtIGZ1bmN0aW9uKGRmLGZvbGhvZyxucil7CiAgZGZuIDwtIGRmICU+JQogICAgZmlsdGVyKGZvbGlvaG9nICVpbiUgZm9saG9nKSU+JQogICAgZmlsdGVyKG51bXJlbiAlaW4lIG5yKQogIHJldHVybihkZm4pCn0gCgoKCmluZ3Jlc29zX2FjdV9lMTggPC0gZnVuY3Rpb24oZGYsY2xhdnM9Z2V0X2xhYmVscyhpbmdyZXNvc19lMTgkY2xhdmUpKXsKIGRmbiA8LSBkZiAlPiUKICAgZ3JvdXBfYnkoZm9saW92aXYsIGZvbGlvaG9nLCBudW1yZW4pICU+JQogICBmaWx0ZXIoY2xhdmUgJWluJSBjbGF2cyklPiUKICAgc3VtbWFyaXNlKAogICBjbGF2ZXNfYSA9IHBhc3RlKGNsYXZlLGNvbGxhcHNlID0gIiwiKSwKICBpbmdfdHJpX3QgPSBzdW0oaW5nX3RyaSksCiAgaW5nX21lbl9wID0gaW5nX3RyaV90LzMsCiAgbGluZ19tZW5fcCA9IGxvZyhpbmdfbWVuX3ApCiAgKSAlPiUgdW5ncm91cCgpCiAKIAogcmV0dXJuKGRmbikKfQoKaG9nYXJlcyA8LSBjKCIxIiwiMiIsIjMiLCI0IiwiNSIpCnBlcnNvbmFzX2ggPC0gYygnMDEnLCcwMicsJzAzJywnMDQnLCcwNScpCgphPC1mYW1pbGlhc19pbnRlZ3JhbnRlc19lMTgoaW5ncmVzb3NfZTE4LGhvZ2FyZXMscGVyc29uYXNfaCkKaGVhZChhKQoKIyMjIGNyaXRlcmlvIDEgYWxndW5vcyBpbmdyZXNvcyBubyB0b2RvcyBsb3MgZGUgYWJham8KI2NsYXZlczwtYygiUDAwMSIsIlAwMDIiLCJQMDAzIiwiUDAxMCIsIlAwMTEiLCJQMDEyIiwiUDAxMyIsIlAwMTQiLCJQMDE1IiwgIlAwMTYiLCJQMDE3IiwiUDAxOCIsIlAwMjAiLCJQMDIxIiwiUDAyNiIsIlAwMjciLCJQMDM1IiwiUDA0MCIsIlAwNDEiLCJQMDQyIiwiUDA0NCIsIlAwNDUiKQoKIyMgY3JpdGVyaW8gMiBmbGV4aWJpbGlkYWQgZW4gbG9zIGluZ3Jlc29zLCBjcml0ZXJpbyAzCmNsYXZlczwtYygiUDAwMSIsIlAwMDIiLCJQMDAzIiwiUDAxMSIsIlAxMyIsIlAwMjMiLCJQMDI0IiwiUDAyNSIsIlAwMjYiLCJQMDI3IiwiUDAyOCIsIlAwMjkiLCJQMDMwIiwiUDAzMSIsIlAwMzIiLCJQMDMzIiwiUDA1NCIsIlAwNTUiLCJQMDU2IiwgIlAwNTkiLCJQMDYwIiwiUDA2MSIsIlAwNjIiLCJQMDYzIiwiUDA2OCIsIlAwNjkiLCJQMDcwIiwiUDA3MSIsIlAwNzIiLCJQMDczIiwiUDA3NCIsIlAwNzUiLCJQMDc2IiwiUDA3NyIsIlAwNzgiLCJQMDc5IiwiUDA4MCIpCgppbmdyZXNvc19lMThhPC1pbmdyZXNvc19hY3VfZTE4KGEsY2xhdmVzKSAKaW5ncmVzb3NfZTE4YTwtIGluZ3Jlc29zX2UxOGElPiUKICAgICAgICAgIG11dGF0ZShjb2hfaW5nID0gaWZlbHNlKGluZ19tZW5fcDw9MjQwMCwxLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShpbmdfbWVuX3A8PTQ4MDAsMiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaW5nX21lbl9wPD03MjAwLDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGluZ19tZW5fcDw9MTIwMDAsNCwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaW5nX21lbl9wPD0yNDAwMCw1LDYpKSkpKSkKCmluZ3Jlc29zX2UxOGEKaW5ncmVzb3NfZTE4ZmM8LWluZ3Jlc29zX2UxOGElPiUKICBzZWxlY3QoZm9saW92aXYsZm9saW9ob2csbnVtcmVuLGNvaF9pbmcpCmBgYAoKIyMgcmFuZ28gcGVyY2VudGlsIDE4CgpgYGB7cn0KI0lOPC0oMTAwLzExMC45MDcpCklOPC0oMTAwLzkzLjYpCmluZ3Jlc29zX2UxOGEkbGluZ19tZW5fcGQgPC0gaW5ncmVzb3NfZTE4YSRsaW5nX21lbl9wICsgbG9nKElOKQpycF9lMTggPC0gcmFuayhpbmdyZXNvc19lMThhJGxpbmdfbWVuX3BkKS9sZW5ndGgoaW5ncmVzb3NfZTE4YSRsaW5nX21lbl9wZCkKYGBgCgoKCmBgYHtyfQpoaXN0KHJwX2UxOCkKYGBgCgoKCgojIyBCYXNlIGNydXphZGEgcG9iLXRyYSAxOAoKYGBge3IgYmFzZV9jcnV6YWRhXzE4fQplbmlnaF8xODwtIGZ1bGxfam9pbihwb2JsYWNpb25fZTE4Zix0cmFiYWpvc19lMThmKSU+JQogICBkcm9wX25hKCkKI2VuaWdoPC1mdWxsX2pvaW4oZW5pZ2gsY29uY2VudHJhZG8pJT4lCiAjIGRyb3BfbmEoKQpucm93KGVuaWdoXzE4KQpzdW0oaXMubmEoZW5pZ2hfMTgpKQpgYGAKCiMjIENhbWJpbyBldGlxdWV0YWRvIGVkdWNhY2lvbiAxOApQYXNhbW9zIGxhcyBldGlxZXV0ZWFzIGRlIGVkdWNhY2nDs24gZGUgZW1vdmkgYSAKCmBgYHtyIGNhbWJpYV9lX2VzcnVfb2N1XzE4fQoKaGlqb3NfZW1vdmkgPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9oaWpvc19lbW92aTIwMTdfcDEuUmRhIikjY3JpdGVyaW8gMSB5IDMKaGlqb3NfZW1vdmk8LSBoaWpvc19lbW92aSAlPiUKICBtdXRhdGUocDEzX20gPSBpZmVsc2UocDEzICVpbiUgYygxKSwiMSIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoIHAxMyA9PSAyLCIyIiwKICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwMTMgJWluJSBjKDMsNCksIjMiLAogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCBwMTMgJWluJSBjKDUsNiksIjQiLAogICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHAxMyAlaW4lIGMoNyw4KSwiNiIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzICVpbiUgYyg5LDEwKSwiNSIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzPT0xMSwiNyIsCiAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzPT0xMiwiOCIsIjAiKSkpKSkpKSkpCnVuaXF1ZShoaWpvc19lbW92aSRwMTNfbSkKCmVuaWdoXzE4PC1lbmlnaF8xOCU+JQogIG11dGF0ZShuaXZlbGFwcm9iPWlmZWxzZShuaXZlbGFwcm9iPT0iOSIsIjgiLG5pdmVsYXByb2IpKQoKdW5pcXVlKGVuaWdoXzE4JG5pdmVsYXByb2IpCgplbmlnaF8xOGY8LWVuaWdoXzE4JT4lCiAgZmlsdGVyKG5pdmVsYXByb2IgJWluJSB1bmlxdWUoaGlqb3NfZW1vdmkkcDEzX20pKQoKbnJvdyhlbmlnaF8xOGYpCmBgYAoKIyMgQnVzY2FyIGZvbGlvcyBjb24gY2FyYWN0ZXJpc3RpY2FzIDE4CgpgYGB7ciBidXNjYV9mb2xpb3NfZTE4fQpidXNjYTwtZnVuY3Rpb24oaSl7CnJldHVybihlbmlnaF8xOGYlPiUKICBmaWx0ZXIoCiAgICAjYXMuaW50ZWdlcihzdWJzdHIoZm9saW92aXYsMSwyKSk9PWhpam9zX2Vtb3ZpW2ksXSRFc3RhZG8gJgogICAgcmVnaW9uID09IGhpam9zX2Vtb3ZpW2ksXSRyZWdpb24gJgogICAgc2V4byA9PSBoaWpvc19lbW92aVtpLF0kcDA2ICYKICAgICgoZWRhZC0yKSA8PSBoaWpvc19lbW92aVtpLF0kcDA1KSAmCiAgICAoaGlqb3NfZW1vdmlbaSxdJHAwNSA8PSAoZWRhZCsyKSkgJgogICAgI2FzLmNoYXJhY3RlcihzaW5jbykgPT0gaGlqb3NfZW1vdmlbaSxdJFNJTkNPMyAmCiAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKHNpbmNvKSwxLDEpID09IHN1YnN0cihoaWpvc19lbW92aVtpLF0kU0lOQ08zLDEsMSkmCiAgICBuaXZlbGFwcm9iID09IGhpam9zX2Vtb3ZpW2ksXSRwMTNfbSklPiUKICAgIAogIHNlbGVjdChmb2xpb3Zpdixmb2xpb2hvZykpCn0KCiAgCmE8LWxhcHBseSgxOm5yb3coaGlqb3NfZW1vdmkpLCBidXNjYSkKCmNvbnRhZG9yPC0wCmZvcihpIGluIDE6bnJvdyhoaWpvc19lbW92aSkpCntpZihucm93KGFbW2ldXSk+MCkKICBjb250YWRvcjwtY29udGFkb3IgKzEKfQpjb250YWRvcgoKc2F2ZVJEUyhhLCBmaWxlPSJEYXRvcy9mb2xoaWpvc19lbmlnaDE4X2Vtb3ZpX3Npbm0xX3JlX3AxLlJkYSIpCgpgYGAKIyMjIGZpbHRhbW9zIHNvbG8gbG9zIGhpam9zIGVuY29udHJhZG9zIDE4CgpgYGB7ciBldGlxdWVfaGlqb3NfZW5jXzE4fSAKIyBldGlxdWV0YW1vcyBwYXJhIG5vIHBlcmRlciBsYSBudW1lcmFjaW9uIHJlc3BlY3RvIGEgbG9zIGhpam9zIG9yaWdpbmFsZXMKZm9saGlqb3NfZTE4X2Vtb3ZpIDwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvZm9saGlqb3NfZW5pZ2gxOF9lbW92aV9zaW5tMV9yZV9wMS5SZGEiKQpuYW1lcyhmb2xoaWpvc19lMThfZW1vdmkpIDwtIGFzLmNoYXJhY3RlcigxOm5yb3coaGlqb3NfZW1vdmkpKQpsZW5ndGgoZm9saGlqb3NfZTE4X2Vtb3ZpKQpgYGAKCmBgYHtyIGZpbHRyYV9oaWpvc19lbmNvbl8xOH0KTCA8LSBjKCkKZm9yKGkgaW4gMTpsZW5ndGgoZm9saGlqb3NfZTE4X2Vtb3ZpKSl7CiAgaWYoIShucm93KGZvbGhpam9zX2UxOF9lbW92aVtbaV1dKT4wKSl7CiAgICBMPC1jKEwsaSl9Cn0KIyBTb2xvIGhpam9zIHF1ZSBzZSBsZXMgcHVkbyBlbmNvbnRyYXIgZW4gZW5pZ2gtMjAxNiAxMDc3LzExMzEKZm9saGlqb3NfZTE4X2Vtb3ZpZjwtZm9saGlqb3NfZTE4X2Vtb3ZpWy1MXQogICAgCgpsZW5ndGgoZm9saGlqb3NfZTE4X2Vtb3ZpZikKCiNuYW1lcyhmb2xoaWpvc19lbW92aWYpCiNuYW1lcyhmb2xoaWpvc19lbW92aSkKYGBgCgojIyMgVW5pY29zIGZvbGlvcywgZGlmZXJlbnRlcyB0cmFiYWpvcyAxOAoKCgpgYGB7ciBmaWx0cmFfZmlsX2hpal91bmlfMTh9CnVuaWNvc19mb2xpb3M8LWZ1bmN0aW9uKGkpewpmb2xoaWpvc19lMThfZW1vdmlmW1tpXV0lPiUKICBkaXN0aW5jdCgpCn0KCiMgZmlsdHJhbW9zIHVuaWNvcyBmb2xpb3MgcG9yIGRpZmVyZW50ZXMgdHJhYmFqb3MgZGUgbGEgbWlzbWEgcGVyc29uYQphPC1sYXBwbHkoMTpsZW5ndGgoZm9saGlqb3NfZTE4X2Vtb3ZpZiksIHVuaWNvc19mb2xpb3MpCm5hbWVzKGEpPC1uYW1lcyhmb2xoaWpvc19lMThfZW1vdmlmKQpsZW5ndGgoYSkKCmZvbGhpam9zX2UxOF9lbW92aWY8LWEKYGBgCgojIyMgT2JzZXJ2YW1vcyBsYXMgZWRhZGVzIGRlIGxvcyBlbmNvbnRyYWRvcyAxOAoKYGBge3IgZ3JhX2VkYWRlc19oX2VuY18xOH0KCm15TWVudUl0ZW1zIDwtIGMoImRvd25sb2FkUE5HIiwgImRvd25sb2FkSlBFRyIsICJkb3dubG9hZFBERiIsICdkb3dubG9hZFNWRycsICdwcmludENoYXJ0JykKCmhpam9zX2Vtb3ZpJT4lCiAgc2xpY2UoYXMuaW50ZWdlcihuYW1lcyhmb2xoaWpvc19lMThfZW1vdmlmKSkpJT4lCiAgc2VsZWN0KHAwNSklPiUKICBjb3VudChwMDUpJT4lCiAgICBoY2hhcnQoJ2NvbHVtbicsCiAgICAgICAgIGhjYWVzKCB5ID0gJ24nKSklPiUKICBoY19hZGRfdGhlbWUoaGNfdGhlbWVfZmZ4KCkpJT4lCiAgaGNfdGl0bGUoCiAgICB0ZXh0ID0gIiIKICApICU+JQogICNoY19zdWJ0aXRsZSh0ZXh0ID0gIkxhcyBlZGFkZXMgZXN0w6FuIGFncnVwYWRhcyBlbiBpbnRlcnZhbG9zIAogICAjICAgICAgICAgICBkZSAxMCBhw7FvcyAoZGEgY2xpYyBzb2JyZSBGIG8gTSkiKSAlPiUKICAjIGhjX2NyZWRpdHMoCiAgIyAgZW5hYmxlZCA9IFRSVUUsIHRleHQgPSAiU291cmNlOiBTU1MiLAogICMgIHN0eWxlID0gbGlzdChmb250U2l6ZSA9ICIxMnB4IikpJT4lCiAgaGNfeUF4aXModGl0bGUgPSBsaXN0KHRleHQgPSAiTsO6bWVybyBkZSBwYXJ0aWNpcGFudGVzIikpJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJOw7ptZXJvIGRlIHBlcnNvbmFzIiksCiAgICAgICAgICAgY2F0ZWdvcmllcyA9IGFzLmNoYXJhY3RlcigyNTo1MCkpICU+JQogICAgaGNfZXhwb3J0aW5nKGVuYWJsZWQgPSBUUlVFLAogICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJkYXRvcyIsCiAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KGNvbnRleHRCdXR0b24gPSBsaXN0KG1lbnVJdGVtcyA9IG15TWVudUl0ZW1zKSkpCgoKYGBgCgoKIyMjIE9ic2VydmFtb3MgbGFzIGVzdGFkb3MgZGUgbG9zIGVuY29udHJhZG9zIDE4CgpgYGB7ciBncmFfZXN0YWRvc19oX2UxOH0KaGlqb3NfZW1vdmklPiUKICBzbGljZShhcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxOF9lbW92aWYpKSklPiUKICBjb3VudChFc3RhZG8pJT4lCiAgICBoY2hhcnQoJ2NvbHVtbicsCiAgICAgICAgIGhjYWVzKCB5ID0gJ24nKSklPiUKICBoY19hZGRfdGhlbWUoaGNfdGhlbWVfZmZ4KCkpJT4lCiAgaGNfdGl0bGUoCiAgICB0ZXh0ID0gIiIKICApICU+JQogICNoY19zdWJ0aXRsZSh0ZXh0ID0gIkxhcyBlZGFkZXMgZXN0w6FuIGFncnVwYWRhcyBlbiBpbnRlcnZhbG9zIAogICAjICAgICAgICAgICBkZSAxMCBhw7FvcyAoZGEgY2xpYyBzb2JyZSBGIG8gTSkiKSAlPiUKICAjIGhjX2NyZWRpdHMoCiAgIyAgZW5hYmxlZCA9IFRSVUUsIHRleHQgPSAiU291cmNlOiBTU1MiLAogICMgIHN0eWxlID0gbGlzdChmb250U2l6ZSA9ICIxMnB4IikpJT4lCiAgaGNfeUF4aXModGl0bGUgPSBsaXN0KHRleHQgPSAiTsO6bWVybyBkZSBwYXJ0aWNpcGFudGVzIikpJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJOw7ptZXJvIGRlIHBlcnNvbmFzIiksCiAgICAgICAgICAgY2F0ZWdvcmllcyA9IGdldF9sYWJlbHMoaGlqb3NfZW1vdmkkRXN0YWRvKSkgJT4lCiAgICBoY19leHBvcnRpbmcoZW5hYmxlZCA9IFRSVUUsCiAgICAgICAgICAgICAgIGZpbGVuYW1lID0gImRhdG9zIiwKICAgICAgICAgICAgICAgYnV0dG9ucyA9IGxpc3QoY29udGV4dEJ1dHRvbiA9IGxpc3QobWVudUl0ZW1zID0gbXlNZW51SXRlbXMpKSkKCmBgYAoKIyMgSW5ncmVzbyBoaWpvIGVuaWdoIDE4IC0gZW1vdmkKCmBgYHtyIGluZ3JlX2hpam9fZTE4X2Vtb3ZpfQoKaW5ncmVzb19oaWpvX2UxOF9lbW92aTwtZnVuY3Rpb24oaSl7CiAgaW5ncmVzb3NfZTE4YSU+JQogIGZpbHRlcihmb2xpb3ZpdiAlaW4lIGZvbGhpam9zX2UxOF9lbW92aWZbW2ldXSRmb2xpb3ZpdiAmCiAgICBmb2xpb2hvZyAlaW4lIGZvbGhpam9zX2UxOF9lbW92aWZbW2ldXSRmb2xpb2hvZyklPiUKICAjIGZpbHRlcihjb2hfaW5nPT1oaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxOF9lbW92aWZbaV0pKSwicDEzMyJdKSU+JQogICAgc3VtbWFyaXNlKAogICAgIGlkX2hpam8gPSBuYW1lcyhmb2xoaWpvc19lMThfZW1vdmlmW2ldKSwKICAgICBpZF9obyA9IGhpam9zX2Vtb3ZpW2FzLmludGVnZXIobmFtZXMoZm9saGlqb3NfZTE4X2Vtb3ZpZltpXSkpLCJpZF9obyJdLAogICAgIG1vdj0gaGlqb3NfZW1vdmlbYXMuaW50ZWdlcihuYW1lcyhmb2xoaWpvc19lMThfZW1vdmlmW2ldKSksIm1vdiJdLAogICAgIHJlZ2lvbmggPSBoaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxOF9lbW92aWZbaV0pKSwicmVnaW9uIl0sCiAgICAgZWRhZCA9IGhpam9zX2Vtb3ZpW2FzLmludGVnZXIobmFtZXMoZm9saGlqb3NfZTE4X2Vtb3ZpZltpXSkpLCJwMDUiXSwKICAgICBjb2hvcnQgPSBoaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxOF9lbW92aWZbaV0pKSwicDEzMyJdLAogICAgaW5nX21lbl9wX2ggPWxpc3QoaW5nX21lbl9wKSwKICAgICBlc3RyYXRvID0gaGlqb3NfZW1vdmlbYXMuaW50ZWdlcihuYW1lcyhmb2xoaWpvc19lMThfZW1vdmlmW2ldKSksImVzdHJhdG8iXSwKICAgIGVzdGFkbyA9IGhpam9zX2Vtb3ZpW2FzLmludGVnZXIobmFtZXMoZm9saGlqb3NfZTE4X2Vtb3ZpZltpXSkpLCJFc3RhZG8iXSwKICAgIHNleG8gPSBoaWpvc19lbW92aVthcy5pbnRlZ2VyKG5hbWVzKGZvbGhpam9zX2UxOF9lbW92aWZbaV0pKSwicDA2Il0KICAgICApCn0KIzI3MywzMzIgc29uIHZhY2lvcwojIGluZ3Jlc28gaGlqbyBwZXJvIHVhbGd1bm9zIG5vIHBvZHJpYW4gZXN0YXIgcG9yIG5vIHRlbmVyIHJlZ2lzdHJvIGRlIHNhbGFyaW8KCmE8LWxhcHBseSgxOmxlbmd0aChmb2xoaWpvc19lMThfZW1vdmlmKSwgaW5ncmVzb19oaWpvX2UxOF9lbW92aSkKaW5ncmVzb19oaWpvZ19lMThfZW1vdmk8LWEKbGVuZ3RoKGluZ3Jlc29faGlqb2dfZTE4X2Vtb3ZpKQojaW5ncmVzb19oaWpvZ19lMTZfZW1vdmlbWzMzMl1dCiN4PC1pbmdyZXNvX2hpam9nX2UxNl9lbW92aVtbMzMyXV0kaW5nX21lbl9wX2hbMV0KI3N1bShpbmdyZXNvX2hpam9nX2UxNl9lbW92aVtbMzMyXV0kaW5nX21lbl9wX2hbWzFdXSxuYS5ybSA9IFRSVUUpCgoKYGBgCiMjIEZpbHRyYW1vcyBzb2JyZSBpbmdyZXNvcyBlbmNvbnRyYWRvcyAxOAoKYGBge3IgZmlsX2luZ3JlX2VuY19lMThfZW1vdml9CgpMIDwtIGMoKQpmb3IoaSBpbiAxOmxlbmd0aChpbmdyZXNvX2hpam9nX2UxOF9lbW92aSkpewogIGlmKHN1bShpbmdyZXNvX2hpam9nX2UxOF9lbW92aVtbaV1dJGluZ19tZW5fcF9oW1sxXV0sbmEucm0gPSBUUlVFKT09MCl7CiAgICBMPC1jKEwsaSl9Cn0KbGVuZ3RoKEwpCgppbmdyZXNvX2hpam9nX2UxOF9lbW92aTwtaW5ncmVzb19oaWpvZ19lMThfZW1vdmlbLUxdCgpsZW5ndGgoaW5ncmVzb19oaWpvZ19lMThfZW1vdmkpCmluZ3Jlc29faGlqb2dfZTE4X2Vtb3ZpWzFdCmluZ3Jlc29faGlqb2dfZTE4X2Vtb3ZpWzJdCgoKaW5ncmVzb19oaWpvZ19lMThfZW1vdmlmPC1iaW5kX3Jvd3MoaW5ncmVzb19oaWpvZ19lMThfZW1vdmlbMTpsZW5ndGgoaW5ncmVzb19oaWpvZ19lMThfZW1vdmkpXSkKCgpucm93KGluZ3Jlc29faGlqb2dfZTE4X2Vtb3ZpZikKCnNhdmVSRFMoaW5ncmVzb19oaWpvZ19lMThfZW1vdmlmLCBmaWxlPSJEYXRvcy9pbmdyZXNvMThfaGlqX2ZfZW1vdmlfc2lubTFfcmVfcDEuUmRhIikKCmdlbWVsb3M8LWMoKQpmb3IoIGkgaW4gMTpucm93KGluZ3Jlc29faGlqb2dfZTE4X2Vtb3ZpZikpewpnZW1lbG9zPC1jKGdlbWVsb3MsbGVuZ3RoKGluZ3Jlc29faGlqb2dfZTE4X2Vtb3ZpZiRpbmdfbWVuX3BfaFtbaV1dKSkKfQojZ2VtZWxvcwojbWluKGluZ3Jlc29faGlqb2dfZTE2X2Vtb3ZpZiRpbmdfbWVuX3BfaFtbNDU5XV0pCiNtYXgoaW5ncmVzb19oaWpvZ19lMTZfZW1vdmlmJGluZ19tZW5fcF9oW1s0NTldXSkKCgpgYGAKCgoKCgpDUklURVJJTyAzIChpbmdyZXNvc28gYXVtZW50YW1vcyBsYXMgY2xhdmVzLCB5IGxvcyByYW5nb3MgZGUgZWRhZCkKLSBjb24gcmVnaW9uLCBvY3VwYWNpw7NuIHkgZW4gZWwgY29ob3J0IGRlIGluZ3Jlc28gdGllbmVuIDcxNwoKCmBgYHtyfQppbmdyZXNvX2hpam9nX2UxOF9lbW92aWYlPiVzZWxlY3QoaWRfaGlqbyxpZF9obykKYGBgCgoKCmBgYHtyfQoKbGVuPC0wCmZvcihpIGluIDE6bnJvdyhpbmdyZXNvX2hpam9nX2UxOF9lbW92aWYpKXsKbGVuPC0gbGVuICsgbGVuZ3RoKGluZ3Jlc29faGlqb2dfZTE4X2Vtb3ZpZiRpbmdfbWVuX3BfaFtbaV1dKQp9CgpsZW4vbnJvdyhpbmdyZXNvX2hpam9nX2UxOF9lbW92aWYpCmBgYAoKCiMgQmFzZSBkZSBpbmdyZXNvcyBoaWpvcyBmaW5hbAoKYGBge3J9CmJhc2UxPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9pbmdyZXNvX2hpal9mX2Vtb3ZpX3Npbl9yZV9wMS5SZGEiKQpucm93KGJhc2UxKSMxMTQ4ICs4OSA9IDEyMzcKYmFzZTI8LSByZWFkUkRTKGZpbGU9IkRhdG9zL2luZ3Jlc28xOF9oaWpfZl9lbW92aV9zaW5fcmVfcDEuUmRhIikKbnJvdyhiYXNlMikjMTE0OCArIDg5ID0gMTIzNwoKI2Jhc2UxJT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlMiRpZF9obykpCgpiYXNlcDwtYmFzZTIlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2UxJGlkX2hvKSkKbnJvdyhiYXNlcCkKCmJhc2VwMjwtZnVsbF9qb2luKGJhc2UxLCBiYXNlcCkKbnJvdyhiYXNlcDIpICMgMTIzNyArIDYyID0gMTI5OQoKI19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpiYXNlMzwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzbzE4X2hpal9mX2Vtb3ZpX3Npbm0zX3JlX3AxLlJkYSIpCm5yb3coYmFzZTMpICMgMTI2NiArIDMzID0gMTI5OQoKI2Jhc2VwMiU+JWZpbHRlcighKGlkX2hvICVpbiUgYmFzZTMkaWRfaG8pKQpiYXNlcDM8LSBiYXNlMyU+JWZpbHRlcighKGlkX2hvICVpbiUgYmFzZXAyJGlkX2hvKSkgCm5yb3coYmFzZXAzKSAgCgpiYXNlcDQ8LSBmdWxsX2pvaW4oYmFzZXAzLGJhc2VwMikKbnJvdyhiYXNlcDQpIyAxMjk5CgojX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KYmFzZTQ8LSByZWFkUkRTKGZpbGU9IkRhdG9zL2luZ3Jlc28xOF9oaWpfZl9lbW92aV9zaW5tMl9yZV9wMS5SZGEiKQpucm93KGJhc2U0KSAjIDEzNDYKCiNiYXNlcDQlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2U0JGlkX2hvKSkKCmJhc2VwNTwtYmFzZTQlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2VwNCRpZF9obykpCm5yb3coYmFzZXA1KSM1OQoKYmFzZXA2PC1mdWxsX2pvaW4oYmFzZXA1LGJhc2VwNCkKbnJvdyhiYXNlcDYpIyAxMzU4CgoKI19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpiYXNlNTwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzbzE4X2hpal9mX2Vtb3ZpX3Npbm0xX3JlX3AxLlJkYSIpCm5yb3coYmFzZTUpIyAxNDczCgojYmFzZXA2JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlNSRpZF9obykpCgpiYXNlcDc8LWJhc2U1JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlcDYkaWRfaG8pKQpucm93KGJhc2VwNykjIDExOQoKYmFzZXA4PC1mdWxsX2pvaW4oYmFzZXA3LGJhc2VwNikKbnJvdyhiYXNlcDgpIyAxNDc3CgojX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpiYXNlNjwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9zaW5tM19yZV9wMS5SZGEiKQpucm93KGJhc2U2KSMxMjcwCgojYmFzZXA4JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlNiRpZF9obykpCgpiYXNlcDk8LWJhc2U2JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlcDgkaWRfaG8pKQpucm93KGJhc2VwOSkjIDEKCmJhc2VwMTA8LWZ1bGxfam9pbihiYXNlcDksYmFzZXA4KQpucm93KGJhc2VwMTApICMgMTQ3OCAKCiNfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KYmFzZTc8LSByZWFkUkRTKGZpbGU9IkRhdG9zL2luZ3Jlc29faGlqX2ZfZW1vdmlfc2lubTJfcmVfcDEuUmRhIikKbnJvdyhiYXNlNykjMTM0MgoKI2Jhc2VwMTAlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2U3JGlkX2hvKSkKCmJhc2VwMTE8LWJhc2U3JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlcDEwJGlkX2hvKSkKbnJvdyhiYXNlcDExKSMgMgoKYmFzZXAxMjwtZnVsbF9qb2luKGJhc2VwMTEsYmFzZXAxMCkKbnJvdyhiYXNlcDEyKSMgMTQ4MAoKI19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpiYXNlODwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9zaW5tMV9yZV9wMS5SZGEiKQpucm93KGJhc2U4KSAjIDE0NzYKCiNiYXNlcDEyJT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlOCRpZF9obykpCgpiYXNlcDEzPC1iYXNlOCU+JWZpbHRlcighKGlkX2hvICVpbiUgYmFzZXAxMiRpZF9obykpCm5yb3coYmFzZXAxMykgIyA2CgoKYmFzZXAxNDwtZnVsbF9qb2luKGJhc2VwMTMsYmFzZXAxMikKbnJvdyhiYXNlcDE0KSMgMTQ4NgoKYmFzZV9jZjwtYmFzZXAxNAoKCmBgYAoKCmBgYHtyfQpzYXZlUkRTKGJhc2VfY2YsZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9jb21iaW5hZGFfcDEuUmRhIikKCmBgYAoKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwoKYGBge3J9CmJhc2UxPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9pbmdyZXNvX2hpal9mX2Vtb3ZpX3Npbl9yZV9jaF9jcmkzLlJkYSIpCm5yb3coYmFzZTEpICMgNTA0ICsgMTU4ID0gNjYyCmJhc2UyPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9pbmdyZXNvMThfaGlqX2ZfZW1vdmlfc2luX3JlX2NoX2NyaTMuUmRhIikKbnJvdyhiYXNlMikgIyA1MjYgKyAxMzYgPSAgNjYyCgojYmFzZTElPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2UyJGlkX2hvKSkKCmJhc2VwPC1iYXNlMiU+JWZpbHRlcighKGlkX2hvICVpbiUgYmFzZTEkaWRfaG8pKQoKYmFzZXAyPC1mdWxsX2pvaW4oYmFzZTEsIGJhc2VwKQpucm93KGJhc2VwMikgIyA2NjIgKyAxMDYgPSAgNzY4CgojX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmJhc2UzPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9pbmdyZXNvX2hpal9mX2Vtb3ZpX3Npbm0zX3JlX2NoX2NyaTMuUmRhIikKbnJvdyhiYXNlMykgIyA2NDggKyAxMjAgPSAgNzY4CgojYmFzZXAyJT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlMyRpZF9obykpCmJhc2VwMzwtIGJhc2UzJT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlcDIkaWRfaG8pKSAKbnJvdyhiYXNlcDMpICAKCmJhc2VwNDwtIGZ1bGxfam9pbihiYXNlcDMsYmFzZXAyKQpucm93KGJhc2VwNCkjIDc2OCArIDQ4ID0gODE2CgoKI19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmJhc2U0PC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9pbmdyZXNvMThfaGlqX2ZfZW1vdmlfc2lubTNfcmVfY2hfY3JpMy5SZGEiKQpucm93KGJhc2U0KSMgNjcxICsgMTQ1ID0gODE2CgojYmFzZXA0JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlNCRpZF9obykpCgpiYXNlcDU8LWJhc2U0JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlcDQkaWRfaG8pKQpucm93KGJhc2VwNSkjIDQ4CgpiYXNlcDY8LWZ1bGxfam9pbihiYXNlcDUsYmFzZXA0KQpucm93KGJhc2VwNikjIDgxNiArIDExMSA9IDkyNwoKI19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpiYXNlNTwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9zaW5tMl9yZV9jaF9jcmkzLlJkYSIpCm5yb3coYmFzZTUpIyA4NDAgKyA4NyA9ICA5MjcKCiNiYXNlcDYlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2U1JGlkX2hvKSkKCmJhc2VwNzwtYmFzZTUlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2VwNiRpZF9obykpCm5yb3coYmFzZXA3KSMgMTExIAoKYmFzZXA4PC1mdWxsX2pvaW4oYmFzZXA3LGJhc2VwNikKbnJvdyhiYXNlcDgpIyA5MjcgKyA0NiA9IDk3MwoKI19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KYmFzZTY8LSByZWFkUkRTKGZpbGU9IkRhdG9zL2luZ3Jlc28xOF9oaWpfZl9lbW92aV9zaW5tMl9yZV9jaF9jcmkzLlJkYSIpCm5yb3coYmFzZTYpIyA4NDEgKyAxMzIgPSA5NzMKCiNiYXNlcDglPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2U2JGlkX2hvKSkKCmJhc2VwOTwtYmFzZTYlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2VwOCRpZF9obykpCm5yb3coYmFzZXA5KSMgNDYKCmJhc2VwMTA8LWZ1bGxfam9pbihiYXNlcDksYmFzZXA4KQpucm93KGJhc2VwMTApICMgOTczICsgMTk3ID0gMTE3MAoKI19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpiYXNlNzwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9zaW5tMV9yZV9jaF9jcmkzLlJkYSIpCm5yb3coYmFzZTcpIyAxMTI3ICsgNDMgID0gMTE3MAoKI2Jhc2VwMTAlPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2U3JGlkX2hvKSkKCmJhc2VwMTE8LWJhc2U3JT4lZmlsdGVyKCEoaWRfaG8gJWluJSBiYXNlcDEwJGlkX2hvKSkKbnJvdyhiYXNlcDExKSMgMTk3CgpiYXNlcDEyPC1mdWxsX2pvaW4oYmFzZXAxMSxiYXNlcDEwKQpucm93KGJhc2VwMTIpIyAxMTcwICsgNDEgPSAxMjExCgojX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpiYXNlODwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzbzE4X2hpal9mX2Vtb3ZpX3Npbm0xX3JlX2NoX2NyaTMuUmRhIikKbnJvdyhiYXNlOCkgIyAxMTQwICsgNzEgPSAxMjExCgojYmFzZXAxMiU+JWZpbHRlcighKGlkX2hvICVpbiUgYmFzZTgkaWRfaG8pKQoKYmFzZXAxMzwtYmFzZTglPiVmaWx0ZXIoIShpZF9obyAlaW4lIGJhc2VwMTIkaWRfaG8pKQpucm93KGJhc2VwMTMpICMgNDEKCgpiYXNlcDE0PC1mdWxsX2pvaW4oYmFzZXAxMyxiYXNlcDEyKQpucm93KGJhc2VwMTQpIyAxMjExCgpiYXNlX2NmPC1mdWxsX2pvaW4oYmFzZV9oaWpvc19maWphX2YsIGJhc2VwMTQpCnN0cih1bmlxdWUoYmFzZV9jZiRpZF9obykpCmBgYAoKCgoKIyMgSW5ncmVzbyBoaWpvcyBkaXJlY3RvIAoKCmBgYHtyfQpoaWpvc19wYXJhX3NhbF8yIDwtIGhpam9zX3BhcmFfc2FsJT4lZmlsdGVyKCEoaWRfaG8gJWluJWJhc2VfY2YkaWRfaG8gKSkKbnJvdyhoaWpvc19wYXJhX3NhbF8yKQpoaWpvc19wYXJhX3NhbF8yJT4lY291bnQocDEzMykKYGBgCiAKaGFjZW1vcyBzdSBpbnRlcnZhbG8KCmBgYHtyfQoKCgoKCmhpam9zX3BhcmFfc2FsXzI8LWhpam9zX3BhcmFfc2FsXzIlPiVtdXRhdGUoCiAgbG93PWlmZWxzZShwMTMzPT0xLDAsCiAgICAgICAgICAgICBpZmVsc2UocDEzMz09MywgMjQwMS4wLCAKICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzMz09NCw0ODAxLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwMTMzPT01LDcyMDEuMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwMTMzPT02LDEyMDAxLjAsMjQwMDEpKSkgKSksCiAgCiAgdXBwZXIgPSBpZmVsc2UocDEzMz09MSwyMzk5LjAsCiAgICAgICAgICAgICBpZmVsc2UocDEzMz09MywgNDgwMC4wLCAKICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzMz09NCw3MjAwLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwMTMzPT01LDEyMDAwLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocDEzMz09NiwyNDAwMCw0MDAwMCkpKSApKQogICN0eXBlID0gaWZlbHNlKHAxMzMhPTcsImludGVydmFsIiwibGVmdCIpLAogICNldmVudCA9IGlmZWxzZShwMTMzIT03LDMsMikKICAKICApCgoKaGluZ3M8LWhpam9zX3BhcmFfc2FsXzIlPiVtdXRhdGUocDA1Mj1wMDUqcDA1KQoKWiA8LXdpdGgoaGluZ3MsIFN1cnYobG93LAogICAgICAgICAgICAgICAgICAgICB1cHBlciwKICAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSByZXAoMyxucm93KGhpbmdzKSksCiAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSAiaW50ZXJ2YWwiKSkgCgptb2RlbG88LXN1cnZyZWcoWn4gIGZhY3RvcihwMTMzKSArIHAwNSArIHAwNTIgKyBwMDYgICsgcDEzICsgZmFjdG9yKHN1YnN0cihTSU5DTzMsMSwxKSktMSwgZGF0YT1oaW5ncywKICAgICAgICAgICAgICAgIGRpc3QgPSAiZ2F1c3NpYW4iKQoKc3VtbWFyeShtb2RlbG8pCgpuZXdkPC0gZGF0YS5mcmFtZSgjcmVnaW9uID0gZmFjdG9yKGhpbmdzJHJlZ2lvbiksCiAgICAgICAgICAgICAgICAgIHAxMzMgPSBmYWN0b3IoaGluZ3MkcDEzMyksCiAgICAgICAgICAgICAgICAgIHAwNT1oaW5ncyRwMDUsCiAgICAgICAgICAgICAgICAgIHAwNTI9aGluZ3MkcDA1MiwKICAgICAgICAgICAgICAgICAgcDA2PWhpbmdzJHAwNiwKICAgICAgICAgICAgICAgICAgcDEzPWhpbmdzJHAxMywKICAgICAgICAgICAgICAgICAgU0lOQ08zPWZhY3RvcihzdWJzdHIoaGluZ3MkU0lOQ08zLDEsMSkpKQoKaGluZ3MkaW5ncmVzczwtcHJlZGljdChtb2RlbG8sbmV3ZCwgdHlwZT0icmVzcG9uc2UiKQoKaGluZ3MlPiVzZWxlY3QoLWluZ3Jlc28pCnBybzwtZnVsbF9qb2luKGhpbmdzLGhpam9zX3BhcmFfc2FsMiU+JXNlbGVjdCgtaW5ncmVzbykpCnBybyU+JW11dGF0ZShpbmdyZXNzPWlmZWxzZShwMTMzPT0yLDI0MDAsaW5ncmVzcykpJT4lCiAgbXV0YXRlKGNvaG9ydF9oID0gaWZlbHNlKGluZ3Jlc3M8PTI0MDAsMSwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoaW5ncmVzczw9NDgwMCwyLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShpbmdyZXNzPD03MjAwLDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGluZ3Jlc3M8PTEyMDAwLDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGluZ3Jlc3M8PTI0MDAwLDUsNikpKSkpLAogICAgICAgICBjb2hvcnRfZGlmPSBhcy5pbnRlZ2VyKHAxMzMpLWNvaG9ydF9oKSU+JWZpbHRlcihwMTMzPT0yKSU+JW5yb3coKQpgYGAKCgoKCgpgYGB7cn0Kc2F2ZVJEUyhiYXNlX2NmLGZpbGU9IkRhdG9zL2luZ3Jlc29faGlqX2ZfZW1vdmlfY29tYmluYWRhX2NyaTMuUmRhIikKCmBgYAoKCiMjIHJhbmdvIHBlcmNlbnRpbCAxNi0xOAoKYGBge3J9CiNJTjwtKDEwMC8xMTAuOTA3KQpJTjwtKDEwMC85My42KQojCmluZ3JlMTYxODwtYmluZF9yb3dzKGluZ3Jlc29zX2UxNmElPiVzZWxlY3QobGluZ19tZW5fcGQpLGluZ3Jlc29zX2UxOGElPiVzZWxlY3QobGluZ19tZW5fcGQpKQpycF9lMTYxOCA8LSByYW5rKGluZ3JlMTYxOCRsaW5nX21lbl9wZCkvbGVuZ3RoKGluZ3JlMTYxOCRsaW5nX21lbl9wZCkKI3JwX2UxNjE4PC1wZXJjZW50X3JhbmsoaW5ncmUxNjE4JGxpbmdfbWVuX3BkKQpgYGAKCgpgYGB7cn0KaGlzdChycF9lMTYxOCkKYGBgCgoKIyBIaWpvcyBjb24gaW5ncmVzbwoKYGBge3IgZmlsdHJvX2hpam9zX3lhX2luZ3Jlc299Cmhpam9zX2Vtb3ZpX2hwIDwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9jb21iaW5hZGFfcDEuUmRhIikKCiNoaWpvc19lbW92aV9ocCA8LSByZWFkUkRTKGZpbGU9IkRhdG9zL2luZ3Jlc29faGlqX2ZfZW1vdmlfY29tYmluYWRhX2NyaTMuUmRhIikKI2hpam9zX2Vtb3ZpX2hwIDwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9zaW5fcmVfY2hfY3JpMy5SZGEiKQojaGlqb3NfZW1vdmlfaHAgPC0gcmVhZFJEUyhmaWxlPSJEYXRvcy9pbmdyZXNvX2hpal9mX2Vtb3ZpX3JlX2NoX2NyaTMuUmRhIikKI2hpam9zX2Vtb3ZpX2hwIDwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9yZV9jaF9jcmkyLlJkYSIpCiNoaWpvc19lbW92aV9ocCA8LSByZWFkUkRTKGZpbGU9IkRhdG9zL2luZ3Jlc29faGlqX2ZfZW1vdmlfcmUuUmRhIikKI2hpam9zX2Vtb3ZpX2hwIDwtIHJlYWRSRFMoZmlsZT0iRGF0b3MvaW5ncmVzb19oaWpfZl9lbW92aV9zaW5fcmVfY2guUmRhIikKCm5yb3coaGlqb3NfZW1vdmlfaHApCmhpam9zX2Vtb3ZpX2hwIAojIHAwNSBlZGFkIGFjdAojIHAwNiBzZXhvIGFjdAojIHAxMyBlZHVjIGhpam8KIyBTSU5DTzMsIG9jdXBhY2nDs24gaGlqbwojIHAyMyBlbiBxZXUgZXN0YWRvIHZpdmlhIGEgbG9zIDE0CiMgcDI2IHByaW5jaXBhbCBzb3N0ZW4gZWPDs21pY28KIyBwMzhfMTEgZWRhZCBwYWRyZSAyMDE2CiMgcDM4bV8xMSBlZGFkIG1hZHJlIDIwMTYKIyBwNDMgbml2ZWwgZWR1Y2F0aXZvIHBhZHJlCiNwNDNtIG5pdmVsIGVkdWNhdGl2byBtYWRyZQojIGNtbzFfMiBvY3VwYWNpb24gZGVsIHBhZHJlCiMgY21vMl8yIG9jdXBhY2lvbiBkZSBsYSBtYWRyZSAKCgp2YXJwPC1jKCJFc3RhZG8iLCJwMDUiLCJwMDYiLCJwMTMiLCJTSU5DTzMiLCJwMjMiLCJwMjYiLCJwMzhfMTEiLCJwMzhtXzExIiwicDQzIiwicDQ0IiwKICAgICAgICAicDQzbSIsInA0NG0iLCJjbW8xXzIiLCJjbW8yXzIiLCJtb3YiLAogICAgICAgICJyZWdpb24iLCJwMTMzIiwiaWRfaG8iKQpwYWRyZXNfaDwtZGF0YV9lbW92aTIwMTclPiUKIyAjICAgIGZpbHRlcihwMDIgPT0gMSkgICU+JSAjY29tcGFydGlyIGdhc290IHBhcmEgY29tZXIKIyAgIGZpbHRlcihiZXR3ZWVuKHAwNSwyNSw1MCkpICU+JSAjIGVkYWQgPC0tLS0tLS0tLS0tLS0tLS0tY3JpdGVyaW8gMSB5IDMKIyAgICNmaWx0ZXIocDA4ID09IDEpICAlPiUgCiMgICBmaWx0ZXIocDEyID09IDIpICAlPiUjIHlhIG5vIGVzdHVkaWEKIyAgIGZpbHRlcihwMjYgPT0gMSB8IHAyNj09MiApICU+JSAjIHNvc3RlbiBwcmluY2lwYWwgcGFwYSwgbWFtYSwgCiMgICAgZmlsdGVyKCghaXMubmEocDQzKSAmIHA0MyE9OTggJiBwMjYgPT0gMSAmIGNtbzFfMiE9Ii4iICYgIWlzLm5hKHAzOF8xMSkpfCM8LS0tLS0tLS0tLW9qbyBvY3VwYWNpb24gbnMKIyAgICAgICAgICAgICAoIWlzLm5hKHA0M20pICYgcDQzbSE9OTggICYgcDI2ID09IDIgJiBjbW8yXzIhPSIuIiAmICFpcy5uYShwMzhtXzExKSkpICU+JSAjIHJlcG9ydGEgZWR1Y2FjacOzbiBkZSBwcAojICAgIGZpbHRlcighaXMubmEocDEzKSklPiUgIyAgcmVwb3J0YSBlZHVjYWNpw7NuCiMgICBmaWx0ZXIoU0lOQ08zICE9IiIpICU+JSMgcmVwb3J0YSBvZmljaW8gYWN0dWFsCiMgICAgZmlsdGVyKHA2OCA9PSAxIHwgcDY5ID09IDEpICAlPiUgIyBzaSB0cmFiYWphCiMgICAgZmlsdGVyKHAxMzIgJWluJSBjKDEpKSAlPiUjIHBlcnNvbmEgcXVlIGFwb3J0YW4gaW5ncmVzbwojICAgZmlsdGVyKCFwMTMzICVpbiUgYyg4LDksTkEpICklPiUKICAgc2VsZWN0KHZhcnApJT4lCiAgIHNsaWNlKGFzLmludGVnZXIodW5saXN0KGhpam9zX2Vtb3ZpX2hwJT4lc2VsZWN0KGlkX2hvKSkpKSU+JSM8LS0tLS0tLS0tb29qb29vIGVycyBpZF9oaWpvCiMgICBmaWx0ZXIoaWRfaG8gJWluJSBoaWpvc19lbW92aV9ocCRpZF9obyApJT4lCiAgbXV0YXRlKAogICAgICAgICBwcF9pZF9oaWpvID0gaGlqb3NfZW1vdmlfaHAlPiVwdWxsKGlkX2hvKSwjIGVyYSBpZF9oaWpvCiAgICAgICAgIGluZ19oID0gaGlqb3NfZW1vdmlfaHAlPiVwdWxsKGluZ19tZW5fcF9oKSwKICAgICAgICAgY29ob3J0ID0gaWZlbHNlKHAxMzM9PTEsMixwMTMzKS0xLAogICAgICAgICByZWdpb24gPSBoaWpvc19lbW92aV9ocCU+JXB1bGwocmVnaW9uaCkKICAgICAgICAgKSU+JQogIHJlbmFtZSgKICAgICAgICAgIGVkYWRfaCA9IHAwNSwKICAgICAgICAgIHNleG9faCA9IHAwNiwKICAgICAgICAgIGVkdV9oID0gcDEzLAogICAgICAgICAgb2N1X2ggPSBTSU5DTzMsCiAgICAgICAgICBwcF9lc3RhZG8gPSBwMjMsCiAgICAgICAgICBwcCA9IHAyNiwKICAgICAgICAgIHBfZWRhZF8yMDE2PSBwMzhfMTEsCiAgICAgICAgICBtX2VkYWRfMjAxNiA9IHAzOG1fMTEsCiAgICAgICAgICBwX2VkdSA9IHA0MywKICAgICAgICAgIHBfZWR1ZyA9IHA0NCwKICAgICAgICAgIG1fZWR1ID0gcDQzbSwKICAgICAgICAgIG1fZWR1ZyA9IHA0NG0sCiAgICAgICAgICBwX29jdSA9IGNtbzFfMiwKICAgICAgICAgIG1fb2N1ID0gY21vMl8yCiAgICAgICAgICklPiUKICBtdXRhdGUoCiAgICAgICAgcF9lZHUgPSBhcy5pbnRlZ2VyKHBfZWR1KSwKICAgICAgICBtX2VkdSA9IGFzLmludGVnZXIobV9lZHUpCiAgKQogIApsZW5ndGgocGFkcmVzX2gpCiMgbGFzIG9jdXBhY2lvbmVzIG5vIGVuY29udHJhZGFzIGxhcyBzdXN0aXR1aW1vcyBwb3IgdW4gTkEKcGFkcmVzX2g8LXBhZHJlc19oJT4lCiAgbXV0YXRlKHBfb2N1ID0gaWZlbHNlKHBfb2N1PT0iLiIsTkEscF9vY3UpLAogICAgICAgICBtX29jdSA9IGlmZWxzZShtX29jdT09Ii4iLE5BLG1fb2N1KSkKCnVuaXF1ZShwYWRyZXNfaCRwX29jdSkKdW5pcXVlKHBhZHJlc19oJG1fb2N1KQpoZWFkKHBhZHJlc19oKQpgYGAKCiMjIENyZWFyIGJhc2UgbGltcGlhCgpgYGB7ciBiYXNlX2xpbV9oX2luZ30KCgpmaWx0cm9fcHBfYzwtZnVuY3Rpb24oZGZfMSxnZW5lcmFsID0gMCkKewogICNyZWNpYmUgdW4gaGlqbyBkZSB1biBkYXRhZnJhbWUsIHBhcmEgcG9saW1vcmZpc21vCiAgIyBnZW5lcmFsID0gMHkgcmVncmVzYSB1biBkYXRhIGZyYW1lIGNvbiBsb3MgZGF0b3MKICAjIG9yZGVuYWRvcyBkZWwgaGlqbwogIGlmKGRmXzFbInBwIl09PTEpCiAgewogICAgZGZuIDwtIGRmXzElPiUKICAgICAgICAgIGZpbHRlcihwcD09MSklPiUKICAgICAgICAgIHNlbGVjdChzdGFydHNfd2l0aChjKCJwcCIsInBfIikpLAogICAgICAgICAgICAgaW5nX2gsZWR1X2gsb2N1X2gsZWRhZF9oLHBfZWRhZF8yMDE2LAogICAgICAgICAgICAgcmVnaW9uLGNvaG9ydCxzZXhvX2gpJT4lCiAgICAgICAgICBtdXRhdGUocHBfZWRhZDIwMTYgPSBwX2VkYWRfMjAxNiklPiUKICAgICAgICAgIHJlbmFtZSgKICAgICAgICAgICAgaWRfaG8gPSBwcF9pZF9oaWpvLAogICAgICAgICAgICBwcF9zZXhvID0gcHAsCiAgICAgICAgICAgIHBwX2VkYWQgPSBwX2VkYWRfMjAxNiwKICAgICAgICAgICAgcHBfZWR1YyA9IHBfZWR1LAogICAgICAgICAgICBwcF9lZHVjZyA9IHBfZWR1ZywKICAgICAgICAgICAgcHBfb2N1cCA9IHBfb2N1CiAgICAgICAgICApJT4lCiAgICAgICAgbXV0YXRlKHBwX2VkYWQgPSBwcF9lZGFkICsgKDE0LWVkYWRfaCkpCiAgfQogIGlmKGRmXzFbInBwIl09PTIpCiAgICB7CiAgICBkZm48LWRmXzElPiUKICAgICAgICBmaWx0ZXIocHA9PTIpJT4lCiAgICAgICAgc2VsZWN0KHN0YXJ0c193aXRoKGMoInBwIiwibV8iKSksaW5nX2gsZWR1X2gsCiAgICAgICAgICAgIG9jdV9oLGVkYWRfaCxtX2VkYWRfMjAxNiwKICAgICAgICAgICAgcmVnaW9uLGNvaG9ydCxzZXhvX2gpJT4lCiAgICAgICBtdXRhdGUocHBfZWRhZDIwMTYgPSBtX2VkYWRfMjAxNiklPiUKICAgICAgICByZW5hbWUoCiAgICAgICAgICBpZF9obyA9IHBwX2lkX2hpam8sCiAgICAgICAgICBwcF9zZXhvID0gcHAsCiAgICAgICAgICBwcF9lZGFkID0gbV9lZGFkXzIwMTYsCiAgICAgICAgICBwcF9lZHVjID0gbV9lZHUsCiAgICAgICAgICBwcF9lZHVjZyA9IG1fZWR1ZywKICAgICAgICAgIHBwX29jdXAgPSBtX29jdQogICAgICAgICklPiUKICAgICAgICBtdXRhdGUocHBfZWRhZCA9IHBwX2VkYWQgKyAoMTQtZWRhZF9oKSkKICB9CiAgaWYoaXMubmEoZGZuJHBwX2VkYWQpICYgZ2VuZXJhbCl7CiAgICByZXR1cm4oIk5EIikKICB9CiAgcmV0dXJuKGRmbikKfQoKI2NvbXBvcmJhbW9zIHFldSBmdW5jaW9uZSBiaWVuCmZpbHRyb19wcF9jKHBhZHJlc19oWzEsXSkKCgphY29tb2RhX2RmX2M8LWZ1bmN0aW9uKGRmKXsKICAjZGFtb3MgdW4gZGYgZGUgdW5hIGVkYWQsICB5CiAgIyBub3MgcmVncmVzYSB1biBkYXRhIGZyYW1lIGFjb21vZGFkbwogIGF1eDwtZnVuY3Rpb24oaSl7CiAgICByZXR1cm4oZGZbaSxdKQogIH0KICBhPC1sYXBwbHkoMTpucm93KGRmKSxhdXgpCiAgTDwtbGFwcGx5KGEsZmlsdHJvX3BwX2MpCiAgZGZuIDwtYmluZF9yb3dzKExbMTpsZW5ndGgoTCldKQogIHJldHVybihkZm4pCn0KCmRmaDwtYWNvbW9kYV9kZl9jKHBhZHJlc19oKQoKCgpwcm9fZWRhZF9jIDwtIGZ1bmN0aW9uKGRmKXsKICAjbGUgZGFtb3MgZWwgZGYgeSBub3MgcmVncmVzYSBlbCBwcm9tZWRpbyBkZSBsYSBlZGFkZSAgbG9zIHBhZHJlcwogIGRmJT4lc3VtbWFyaXNlKAogICAgcHJvbWVkaV9lZGFkX3BhZHJlcyA9IG1lYW4ocHBfZWRhZDIwMTYsbmEucm09VFJVRSkpCiAgfQoKZWRhZGVzX3BybzwtIHByb19lZGFkX2MoZGZoKQptZWFuKGRmaCRlZGFkX2gpCmVkYWRlc19wcm8KI2VkYWRlcyBkZSBwYWRyZXMgZmFsdGFudGVzCnN1bShpcy5uYShkZmgkcHBfZWRhZDIwMTYpKQojIApoZWFkKGRmaCkKCiMgMjAxNi0yMQpgYGAKIyMgQ29kaWZpY2FjaW9uIGVkdWFjacOzbgoKCmBgYHtyIGNvZF9lZHVfaGlqb30KCmRmaF9jPC0gZGZoJT4lCiAgIG11dGF0ZSgKICAgcHBfZWR1Y19hID0gaWZlbHNlKHBwX2VkdWM9PTEsMSwgICAgI3NpbiBpbnN0cnVjY2lvbigxKQogICAgICAgICAgaWZlbHNlKHBwX2VkdWM9PTIsMStwcF9lZHVjZywKICAgICAgICAgIGlmZWxzZShwcF9lZHVjICVpbiUgYygzLDQpLDcrcHBfZWR1Y2csCiAgICAgICAgICBpZmVsc2UocHBfZWR1YyAlaW4lIGMoNSw2LDcsOCw5KSwxMCtwcF9lZHVjZywKICAgICAgICAgIGlmZWxzZShwcF9lZHVjICVpbiUgYygxMCwxMSksMTMrcHBfZWR1Y2csMTcrcHBfZWR1Y2cpKSkpKQogICkKCiAgCgp1bmlxdWUoZGZoX2MkcHBfZWR1Y19hKQoKZGZoX2M8LWRmaF9jJT4lCiAgbXV0YXRlKAogICBwcF9lZHVjX2FjID0gaWZlbHNlKHBwX2VkdWNfYSAlaW4lIDA6NSwiQzEiLCAgICAKICAgICAgICAgIGlmZWxzZShwcF9lZHVjX2EgJWluJSA2OjEwICwiQzIiLAogICAgICAgICAgaWZlbHNlKHBwX2VkdWNfYSAlaW4lIDExOjEyLCJDMyIsCiAgICAgICAgICBpZmVsc2UocHBfZWR1Y19hICVpbiUgMTM6MTQsIkM0IiwiQzUiKSkpKQogICkKCiMjIyBHdWFyZGFtb3MgYmFzZSBkZSBkYXRvcyBkZSBoaWpvcyBmaW5hbAoKc2F2ZVJEUyhkZmhfYywgZmlsZT0iRGF0b3MvZGZoX2NfY29tYmluYWRhX3AxLlJkYSIpCgoKI3NhdmVSRFMoZGZoX2MsIGZpbGU9IkRhdG9zL2RmaF9jX3Npbl9yZV9jaF9jcmkzLlJkYSIpCgojc2F2ZVJEUyhkZmhfYywgZmlsZT0iRGF0b3MvZGZoX2NfcmVfY2hfY3JpMy5SZGEiKQoKI3NhdmVSRFMoZGZoX2MsIGZpbGU9IkRhdG9zL2RmaF9jX3JlX2NoX2NyaTIuUmRhIikKCiNzYXZlUkRTKGRmaF9jLCBmaWxlPSJEYXRvcy9kZmhfY19zaW5fcmVfY2guUmRhIikKCgoKCmBgYAoKIyBQYWRyZXMgMTk5OAoKY3JpdGVyaW8gMSwKU2VsZWNjaW9uYW1vcyBkZSBsYSBFTklHSCAxOTk3LCBubyBoYXkgZW50b25jZXMgMTk5OAoKY3JpdGVyaW8gMgpOTyB0ZW5lbW9zIGVuaWdoIDkzIGFnYXJyYW1vcyBlbmlnaCA5NCAoY3VhbmRvIGxhIHRlbmdhbW9zKQoKIyMgUG9ibGFjaW9uIGVuaWdoIDk4CgpgYGB7ciBwb2JsYWNpb25fZTk4fQoKcG9ibGFjaW9uPC1yZWFkLmRiZigKICAgICAgICAgICAgICBmaWxlPSJEYXRvcy9FTklHSC1IaXN0b3JpY2EvMTk5OC9QT0JMQTk4LmRiZiIKICAgICAgICAgICAgICApCgoKCnBvYmxhY2lvbl9lOTg8LXBvYmxhY2lvbiU+JQogIGZpbHRlcigKICAgIHBhcmVudGVzY28gPT0gIjAxIiwKICAgIGJldHdlZW4oZWRhZCwyNSw2MCksIzwtLS0tLS0tLS0tLS0tLS0tLS0gY3JpdGVyaW8gMSB5IDMgY2FtYmlhciAKICAgICFpcy5uYShlZF9mb3JtYWwpLAogICAgIWlzLm5hKGVkX3RlY25pY2EpLAogICAgIWlzLm5hKG9jdXBhY2lvbiksCiAgICBuX2VtcGxlb3M9PTEsICMgZWwgZW50cmV2aXN0YWRvIHNvbG8gcHJvcG9yY2lvbmEgdW5hIG9jdXBhY2nDs24KICApJT4lCiAgc2VsZWN0KAogICAgZm9saW8sCiAgICBudW1fcmVuLAogICAgZWRhZCwKICAgIHNleG8sCiAgICBlZF9mb3JtYWwsCiAgICBlZF90ZWNuaWNhLAogICAgb2N1cGFjaW9uCiAgKSU+JQogbXV0YXRlKAogIGVkX2Zvcm1hbCA9IGFzLmludGVnZXIoYXMuY2hhcmFjdGVyKGVkX2Zvcm1hbCkpLAogICBlZF90ZWNuaWNhPSBhcy5pbnRlZ2VyKGFzLmNoYXJhY3RlcihlZF90ZWNuaWNhKSksCiAgZXN0YWRvID0gc3Vic3RyKGZvbGlvLDUsNikKICkKCiN1bmlxdWUocG9ibGFfZW5pZ2gxOTk4JGVkX2Zvcm1hbCkKI3BvYmxhX2VuaWdoMTk5OCRlZF9mb3JtYWwKbnJvdyhwb2JsYWNpb25fZTk4KQpoZWFkKHBvYmxhY2lvbl9lOTgkZWRfZm9ybWFsKQpzdHIocG9ibGFjaW9uX2U5OCRlZF9mb3JtYWwpI2NhcmFjdGVyIDIgZXNwYWNpb3MKdW5pcXVlKHBvYmxhY2lvbl9lOTgkZWRfZm9ybWFsKQojcG9ibGFfZW5pZ2gxOTk4JGVkX2Zvcm1hbD09IjAzIgpoZWFkKHBvYmxhY2lvbl9lOTgkZWRfdGVjbmljYSkKc3RyKHBvYmxhY2lvbl9lOTgkZWRfdGVjbmljYSkjY2FyYWN0ZXIgMSBlc3BhY2lvCnVuaXF1ZShwb2JsYWNpb25fZTk4JGVkX3RlY25pY2EpCiNwb2JsYV9lbmlnaDE5OTglPiVjb3VudChuX2VtcGxlb3MpLCBzZSBleHBsb3JvIHBhcmEgcXVpdGFyIHVuYSBvY3VwYWNpb24KbmFtZXMocG9ibGFjaW9uKQpzdHIocG9ibGFjaW9uJHBlcl9pbmcpCnVuaXF1ZShwb2JsYWNpb25fZTk4JGVzdGFkbykKYGBgCmZvbGlvcyBkZSBnZW50ZSBjb24gaGlqb3MgbWVub3JlcyBkZSAxNCBhw7FvcwpgYGB7cn0KZm9saW9zOTg8LWFzLmNoYXJhY3Rlcihwb2JsYWNpb24lPiVmaWx0ZXIocGFyZW50ZXNjbyAlaW4lIGMoIjA0IiwiMDUiKSxlZGFkPD0xOCklPiVzZWxlY3QoZm9saW8pJT4lcHVsbCgpKQpwb2JsYWNpb25fZTk4PC1wb2JsYWNpb25fZTk4JT4lZmlsdGVyKGZvbGlvICVpbiUgIGZvbGlvczk4ICkKYGBgCgoKCiMjIyBDb2RpZmljYWNpw7NuIGVkdWNhY2nDs24gZW5pZ2ggMTk5OAoKYGBge3IgY29kX2VkX2U5OH0KIyBoYWNlbW9zIGxhIGNvZGlmaWNhY2nDs24gZGUgRU5JR0gyMDE4IGEgRVNSVQojMQlQcmVlc2NvbGFyIG8ga8OtbmRlcgojIDIJUHJpbWFyaWEKIyAzCVNlY3VuZGFyaWEgdMOpY25pY2EKIyA0CVNlY3VuZGFyaWEgZ2VuZXJhbAojIDUJUHJlcGFyYXRvcmlhIHTDqWNuaWNhCiMgNglQcmVwYXJhdG9yaWEgZ2VuZXJhbAojIDcJVMOpY25pY2EgbyBjb21lcmNpYWwgY29uIHNlY3VuZGFyaWEKIyA4CVTDqWNuaWNhIG8gY29tZXJjaWFsIGNvbiBwcmVwYXJhdG9yaWEKIyA5CU5vcm1hbCBiw6FzaWNhIChjb24gcHJpbWFyaWEgbyBzZWN1bmRhcmkKIyAxMCBOb3JtYWwgZGUgbGljZW5jaWF0dXJhCiMgMTEgUHJvZmVzaW9uYWwgKGxpY2VuY2lhdHVyYSBvIGluZ2VuaWVyw61hKQojIDEyIFBvc3RncmFkbyAobWFlc3Ryw61hIG8gZG9jdG9yYWRvKQojX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KIyA5OCBOUywgbm8gYXBsaWNhIHBvcnF1ZSBwZWRpbW9zIGxhIGVkdWNpw7NuIGRlbCBwcCBjb21vIGluc3RydW1lbnRvCgoKIyB2ZW1zbyBsYXMgY29tYmluYWNpb25lcyBkZSBlZHVjYWNpw7NuIHBhcmEgY29kaWZpY2FyCgpjb21iPC1wb2JsYWNpb25fZTk4JT4lCiAgIG11dGF0ZSggY29tYmkgPSBwYXN0ZShhcy5jaGFyYWN0ZXIoZWRfZm9ybWFsKSxhcy5jaGFyYWN0ZXIoZWRfdGVjbmljYSkpKSU+JQogIHNlbGVjdChlZF9mb3JtYWwsZWRfdGVjbmljYSxjb21iaSkKCiAgCnNvcnQodW5pcXVlKGNvbWIkY29tYmkpKQojIFsxXSAiMDEgMSIgIjAyIDEiICIwMyAxIiAiMDMgMiIgIjA0IDEiICIwNSAxIiAiMDYgMSIgIjA3IDEiICIwNyAyIiAiMDggMSIKIyBbMTFdICIwOCAyIiAiMDggMyIgIjA4IDQiICIwOCA1IiAiMDkgMSIgIjA5IDQiICIwOSA1IiAiMTAgMSIgIjEwIDIiICIxMCA0IgojIFsyMV0gIjEwIDUiICIxMSAxIiAiMTEgMyIgIjExIDQiICIxMSA1IiAiMTEgNiIgIjExIDciICIxMiAxIiAiMTIgMyIgIjEyIDUiCiMgWzMxXSAiMTIgNiIgIjEyIDciICIxMyAxIiAiMTMgNSIgIjEzIDYiICIxMyA3IiAiMTMgOCIgIjEzIDkiICIxNCAxIiAiMTQgMyIKIyBbNDFdICIxNCA1IiAiMTQgNiIgIjE0IDciICIxNCA5IiAiMTUgMSIgIjE1IDMiICIxNSA0IiAiMTUgNSIgIjE1IDYiICIxNSA3IgojIFs1MV0gIjE1IDkiICIxNiAxIiAiMTYgNSIgIjE2IDciICIxNiA5IgoKCgoKIyAiMTYgMSIgIjE2IDUiICIxNiA3IiAiMTYgOSIKCiNjb2RpZmljYW1vcyBhIGEgYcOxb3MgZGUgZWR1Y2FjacOzbgpwb2JsYWNpb25fZTk4YzwtcG9ibGFjaW9uX2U5OCU+JQogICBtdXRhdGUoCiAgIGVkdV9hID0gaWZlbHNlKGVkX2Zvcm1hbD09MSAmIGVkX3RlY25pY2E9PTEsMCwgICAgI3NpbiBpbnN0cnVjY2lvbigxKQogICAgICAgICAgaWZlbHNlKChlZF9mb3JtYWwgJWluJSBjKDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMykpCiAgICAgICAgICAgICAgICAgJiAoZWRfdGVjbmljYSAlaW4lIGMoMSwyKSksZWRfZm9ybWFsLTEsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT04ICYgKGVkX3RlY25pY2EgJWluJSBjKDMsNCw1KSksOSwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTkgJiAoZWRfdGVjbmljYSAlaW4lIGMoNCw1KSksMTAsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT0xMCAmIChlZF90ZWNuaWNhICVpbiUgYygyLDQsNSkpLDExLAogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09MTEgJiAoZWRfdGVjbmljYSAlaW4lIGMoMyw0LDUsNSw3KSksMTIsCiAgICAgICAgICBpZmVsc2UoKGVkX2Zvcm1hbCAlaW4lYygxMikpICYgKGVkX3RlY25pY2EgJWluJSBjKDMsNSw2LDcpKSwxMiwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTEzICYgKGVkX3RlY25pY2EgJWluJSBjKDUsNiw3LDgsOSkpLDEzLAogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09MTQgJiAoZWRfdGVjbmljYSAlaW4lIGMoMSwzLDUsNiw3LDkpKSwxNCwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTE1ICYgKGVkX3RlY25pY2EgJWluJSBjKDEsMyw0LDUsNiw3LDkpKSwxNywxOSkpKSkpKSkpKSkKICApCgp1bmlxdWUocG9ibGFjaW9uX2U5OGMkZWR1X2EpCgojY29kaWZpY2Ftb3MgYSBjb2dob3J0IGRlIGVkdWNhY2nDs24KCnBvYmxhY2lvbl9lOThjPC1wb2JsYWNpb25fZTk4YyU+JQogICBtdXRhdGUoCiAgIGVkdV9hYyA9IGlmZWxzZShlZHVfYSAlaW4lIDA6NSwiQzEiLCAgICAKICAgICAgICAgIGlmZWxzZShlZHVfYSAlaW4lIDY6MTAgLCJDMiIsCiAgICAgICAgICBpZmVsc2UoZWR1X2EgJWluJSAxMToxMiwiQzMiLAogICAgICAgICAgaWZlbHNlKGVkdV9hICVpbiUgMTM6MTQsIkM0IiwiQzUiKSkpKQogICkKCnVuaXF1ZShwb2JsYWNpb25fZTk4YyRlZHVfYWMgKQoKCmBgYAoKIyMjIENyZWFjaW9uIGRlIHJlZ2lvbgpgYGB7ciBjcmVhX3JlZ2lvbl9lOTh9Cgpwb2JsYWNpb25fZTk4YzwtcG9ibGFjaW9uX2U5OGMlPiUKICAgICAgICAgIG11dGF0ZSgKICAgICAgICAgICAgcmVnaW9uID0gaWZlbHNlKGVzdGFkbyAlaW4lIGMoIjAyIiwiMjYiLCIwOCIsIjA1IiwiMTkiLCIyOCIpLDEsCiAgICAgICAgICAgICAgICBpZmVsc2UoZXN0YWRvICVpbiUgYygiMTIiLCIyMCIsIjA3IiwiMzAiLCIyNyIsIjA0IiwiMzEiLCIyMyIpLDQsCiAgICAgICAgICAgICAgICBpZmVsc2UoZXN0YWRvICVpbiUgYygiMDMiLCIyNSIsIjE4IiwiMTAiLCIzMiIsIjE2IiwiMDYiLCIxNCIsIjAxIiwiMjQiKSwyLDMpKSkKICAgICAgICAgICkKCmBgYAoKCiMjIEluZ3Jlc29zIGVuaWdoIDk4CgoKYGBge3IgaW5ncmVzb3NfZTk4fQppbmdyZXNvczwtcmVhZC5kYmYoCiAgICAgICAgICAgICAgZmlsZT0iRGF0b3MvRU5JR0gtSGlzdG9yaWNhLzE5OTgvaW5ncmVzb3MuZGJmIgogICAgICAgICAgICAgICkKCmZhbWlsaWFzX2ludGVncmFudGVzIDwtIGZ1bmN0aW9uKGRmLG5yKXsKICBkZm4gPC0gZGYgJT4lCiAgICBmaWx0ZXIoTlVNX1JFTiAlaW4lIG5yKQogIHJldHVybihkZm4pCn0gCgoKCmluZ3Jlc29zX2FjdSA8LSBmdW5jdGlvbihkZixjbGF2cyl7CiBkZm4gPC0gZGYgJT4lCiAgIGdyb3VwX2J5KEZPTElPLCBOVU1fUkVOKSAlPiUKICAgZmlsdGVyKENMQVZFICVpbiUgY2xhdnMpJT4lCiAgIHN1bW1hcmlzZSgKICAgY2xhdmVzX2EgPSBwYXN0ZShDTEFWRSxjb2xsYXBzZSA9ICIsIiksCiAgaW5nX3RyaV90ID0gc3VtKElOR19UUkkpLAogIGluZ19tZW5fcCA9IGluZ190cmlfdC8zLAogIGxpbmdfbWVuX3AgPSBsb2coaW5nX21lbl9wKQogICkgJT4lIHVuZ3JvdXAoKQogCiAKIHJldHVybihkZm4pCn0KCiNob2dhcmVzIDwtIGMoIjEiLCIyIiwiMyIsIjQiLCI1IikKcGVyc29uYXNfaCA8LSBjKCcwMScpCgphPC1mYW1pbGlhc19pbnRlZ3JhbnRlcyhpbmdyZXNvcyxwZXJzb25hc19oKQpoZWFkKGEpCiMjIGNyaXRlcmlvIDEKI2NsYXZlczwtYygiUDAwMSIsIlAwMDIiLCJQMDAzIiwiUDAxMCIsIlAwMTEiLCJQMDEyIiwiUDAxMyIsIlAwMTQiLCJQMDE1IiwgIyJQMDE2IiwiUDAxNyIsIlAwMTgiLCJQMDIwIiwiUDAyMSIsIlAwMjYiLCJQMDI3IiwiUDAzNSIsIlAwNDAiLCJQMDQxIiwiUDA0MiIsIlAwNDQiLCJQMDQ1IikKCiMjIGNyaXRlcmlvIDIgZmxleGliaWxpZGEgZGUgbG9zIGluZ3Jlc29zIHkgY3JpdGVyaW8gMwpjbGF2ZXM8LWMoIlAwMDEiLCJQMDAyIiwiUDAwMyIsIlAwMTAiLCJQMDExIiwiUDAxMiIsIlAwMTMiLCJQMDE0IiwiUDAxNSIsICJQMDE2IiwiUDAxNyIsIlAwMTgiLCJQMDIwIiwiUDAyMSIsIlAwMjIiLCJQMDIzIiwiUDAyNCIsIlAwMjUiLCJQMDI2IiwiUDAyNyIsIlAwMjgiLCJQMDM1IiwiUDAzNiIsIlAwMzciLCJQMDQwIiwiUDA0MSIsIlAwNDIiLCJQMDQ0IiwiUDA0NSIpCgoKaW5ncmVzb3NfZTk4PC1pbmdyZXNvc19hY3UoYSxjbGF2ZXMpIAppbmdyZXNvc19lOTg8LWluZ3Jlc29zX2U5OCU+JQogIHNlbGVjdChGT0xJTyxOVU1fUkVOLGNsYXZlc19hLGluZ19tZW5fcCxsaW5nX21lbl9wKSU+JQogIHJlbmFtZSgKICAgIGZvbGlvID0gRk9MSU8sCiAgICBudW1fcmVuID0gTlVNX1JFTgogICkKaGVhZChpbmdyZXNvc19lOTgpCgppbmdyZXNvc19lOTg8LWluZ3Jlc29zX2U5OCU+JQogIG11dGF0ZSgKICAgICByZWdpb24gPSBpZmVsc2Uoc3Vic3RyKGZvbGlvLDUsNikgJWluJSBjKCIwMiIsIjI2IiwiMDgiLCIwNSIsIjE5IiwiMjgiKSwxLAogICAgICAgICAgICAgICAgaWZlbHNlKHN1YnN0cihmb2xpbyw1LDYpICVpbiUgYygiMTIiLCIyMCIsIjA3IiwiMzAiLCIyNyIsIjA0IiwiMzEiLCIyMyIpLDQsCiAgICAgICAgICAgICAgICBpZmVsc2Uoc3Vic3RyKGZvbGlvLDUsNikgJWluJSBjKCIwMyIsIjI1IiwiMTgiLCIxMCIsIjMyIiwiMTYiLCIwNiIsIjE0IiwiMDEiLCIyNCIpLDIsMykpKQogICkKCmBgYAoKIyMgcmFuZ28gcGVyY2VudGlsIDk4CgpgYGB7cn0KI0lOPC0oMTAwLzExMC45MDcpCklOPC0oMTAwLzkzLjYpCmluZ3Jlc29zX2U5OCRsaW5nX21lbl9wZDwtaW5ncmVzb3NfZTk4JGxpbmdfbWVuX3AgKyBsb2coSU4pCnJwX2U5OCA8LSByYW5rKGluZ3Jlc29zX2U5OCRsaW5nX21lbl9wZCkvbGVuZ3RoKGluZ3Jlc29zX2U5OCRsaW5nX21lbl9wZCkKI3JwX2U5ODwtcGVyY2VudF9yYW5rKGluZ3Jlc29zX2U5OCRsaW5nX21lbl9wZCkKYGBgCgoKCmBgYHtyfQppbmdyZXNvc19lOTgxIDwtIGRhdGEuZnJhbWUobGluZ19tZW5fcGQ9aW5ncmVzb3NfZTk4JT4lZmlsdGVyKHJlZ2lvbj09MSklPiVwdWxsKGxpbmdfbWVuX3ApICsgbG9nKElOKSkKcnBfZTk4MSA8LSByYW5rKGluZ3Jlc29zX2U5ODEkbGluZ19tZW5fcGQpL2xlbmd0aChpbmdyZXNvc19lOTgxJGxpbmdfbWVuX3BkKQpgYGAKCgpgYGB7cn0KaW5ncmVzb3NfZTk4MiA8LSBkYXRhLmZyYW1lKGxpbmdfbWVuX3BkPWluZ3Jlc29zX2U5OCU+JWZpbHRlcihyZWdpb249PTIpJT4lcHVsbChsaW5nX21lbl9wKSArIGxvZyhJTikpCnJwX2U5ODIgPC0gcmFuayhpbmdyZXNvc19lOTgyJGxpbmdfbWVuX3BkKS9sZW5ndGgoaW5ncmVzb3NfZTk4MiRsaW5nX21lbl9wZCkKYGBgCgoKYGBge3J9CmluZ3Jlc29zX2U5ODMgPC0gZGF0YS5mcmFtZShsaW5nX21lbl9wZD1pbmdyZXNvc19lOTglPiVmaWx0ZXIocmVnaW9uPT0zKSU+JXB1bGwobGluZ19tZW5fcCkgKyBsb2coSU4pKQpycF9lOTgzIDwtIHJhbmsoaW5ncmVzb3NfZTk4MyRsaW5nX21lbl9wZCkvbGVuZ3RoKGluZ3Jlc29zX2U5ODMkbGluZ19tZW5fcGQpCmBgYAoKYGBge3J9CmluZ3Jlc29zX2U5ODQgPC0gZGF0YS5mcmFtZShsaW5nX21lbl9wZD1pbmdyZXNvc19lOTglPiVmaWx0ZXIocmVnaW9uPT00KSU+JXB1bGwobGluZ19tZW5fcCkgKyBsb2coSU4pKQpycF9lOTg0IDwtIHJhbmsoaW5ncmVzb3NfZTk4NCRsaW5nX21lbl9wZCkvbGVuZ3RoKGluZ3Jlc29zX2U5ODQkbGluZ19tZW5fcGQpCmBgYAoKCiMjIEJhc2UgY3J1emFkYSBwb2JsYS1pbmcKCmBgYHtyIGJhc2VfY3J1el9lOTh9CmVuaWdoXzk4PC1mdWxsX2pvaW4ocG9ibGFjaW9uX2U5OGMsaW5ncmVzb3NfZTk4KSU+JQogIGRyb3BfbmEoKSU+JQogICBtdXRhdGUoCiAgICAgb2N1cGFjaW9uID0gc3Vic3RyKG9jdXBhY2lvbiwxLDIpCiAgICkjJT4lCiAgIyByZW5hbWUoCiAgIyAgIEVEVT1OX0lOU1RSMTYxLAogICMgICBPQ1UgPSBDTU8xMjEKICAjICklPiUKICAjIG11dGF0ZSgKICAjICAgRURVID0gYXMuY2hhcmFjdGVyKEVEVSkKICAjICkKaGVhZChlbmlnaF85OCkKCnVuaXF1ZShlbmlnaF85OCRlZGFkKQoKIyBhanVzdGUgcGFyYSBuaXZlbCBkZSBlY3VjYWNpw7NuIEVTUlUKCiNkYXRhX3BhZHJlczIwMDUkRURVIDwtIGZhY3RvcihkYXRhX3BhZHJlczIwMDUkRURVKQojZGF0YV9wYWRyZXMyMDA1JE9DVSA8LSBmYWN0b3IoZGF0YV9wYWRyZXMyMDA1JE9DVSkKCiN1bmlxdWUoZGF0YV9wYWRyZXMyMDA1JE9DVSkKc3VtKGlzLm5hKGVuaWdoXzk4KSkKYGBgCgoKCmBgYHtyIGJhc2VfY3J1el9lOTggZ3VhcmRhfQojIyMjIyBHdWFyZGFtb3MgYmFzZSBkZSBwYWRyZXMgZmluYWwKc2F2ZVJEUyhlbmlnaF85OCwgZmlsZT0iRGF0b3MvZW5pZ2hfOThfY3JpMy5SZGEiKQplbmlnaF85OCU+JWNvdW50KHNleG8pCmBgYAoKCiMjIEdyYWZpY2EgZGUgaW5ncmVzb3MgeSBlZGFkCgpgYGB7cn0KZWRfZWFyPC1mdWxsX2pvaW4ocG9ibGFjaW9uX2U5OGMsaW5ncmVzb3NfZTk4KSU+JQogIHNlbGVjdChlZGFkLCBpbmdfbWVuX3ApJT4lZHJvcF9uYSgpJT4lCiAgZ3JvdXBfYnkoZWRhZCklPiUKICBzdW1tYXJpc2UoCiAgIHByb19pbmcgPSBtZWFuKGluZ19tZW5fcCkKICApCgplZF9lYXIlPiUKaGNoYXJ0KCAic2NhdHRlciIsIAogICAgICAgIGhjYWVzKHggPSBlZGFkLCB5ID0gcHJvX2luZyksCiAgICAgICAgbmFtZT0iaW5ncmVzbyBwcm9tZWRpbyIsCiAgICAgICAgcmVncmVzc2lvbiA9IFRSVUUsCiAgICAgICAgICByZWdyZXNzaW9uU2V0dGluZ3MgPSBsaXN0KAogICAgdHlwZSA9ICJwb2x5bm9taWFsIiwKICAgIGRhc2hTdHlsZSA9ICJTaG9ydERhc2giLAogICAgY29sb3IgPSAic2t5Ymx1ZSIsCiAgICBvcmRlciA9IDIsCiAgICBsaW5lV2lkdGggPSA1LAogICAgbmFtZSA9ICIlZXEgfCAkcl4yJDogJXIiLAogICAgaGlkZUluTGVnZW5kID0gRkFMU0UpCiAgICAgICAgKSU+JQogIGhjX2FkZF9kZXBlbmRlbmN5KCJwbHVnaW5zL2hpZ2hjaGFydHMtcmVncmVzc2lvbi5qcyIpCiAgCgogIApgYGAKCgoKCiMjIEVzZMOtc3RpY2EgZGVzY3JpcHRpdmEgOTgKCmBgYHtyfQpzdW1tYXJ5KGVuaWdoXzk4JGVkYWQpCmhpc3QoZW5pZ2hfOTgkZWRhZCkKcGFwYXM8LSBlbmlnaF85OCU+JWdyb3VwX2J5KGVkYWQpJT4lc3VtbWFyaXNlKG1zYWwgPSBtZWFuKGluZ19tZW5fcCkpCnBsb3QocGFwYXMkZWRhZCxwYXBhcyRtc2FsKQpgYGAKCgojIFBhZHJlcyAgMTk5NgoKIyMgcG9ibGFjaW9uIGVuaW5naCAxOTk2CgpgYGB7cn0KcG9ibGFjaW9uPC1yZWFkLmRiZigKICAgICAgICAgICAgICBmaWxlPSJEYXRvcy9FTklHSC0xOTk2L1BPQkxBOTYuZGJmIgogICAgICAgICAgICAgICkKcG9ibGFjaW9uIDwtIHBvYmxhY2lvbiAlPiUgCiAgICAgICAgICAgICAgICByZW5hbWUoCiAgICAgICAgICAgICAgICAgIHBhcmVudGVzY28gPSBQQVJFTlRFU0NPLAogICAgICAgICAgICAgICAgICBmb2xpbyA9IEZPTElPLAogICAgICAgICAgICAgICAgICBudW1fcmVuID0gTlVNX1JFTiwKICAgICAgICAgICAgICAgICAgc2V4byA9IFNFWE8sCiAgICAgICAgICAgICAgICAgIGVkYWQgPSBFREFELAogICAgICAgICAgICAgICAgICBwZXJfaW5nPVBFUl9JTkcsCiAgICAgICAgICAgICAgICAgIGVkX2Zvcm1hbD1FRF9GT1JNQUwsCiAgICAgICAgICAgICAgICAgIGVkX3RlY25pY2E9RURfVEVDTklDQSwKICAgICAgICAgICAgICAgICAgb2N1cGFjaW9uPU9DVVBBQ0lPTgogICAgICAgICAgICAgICAgICApCnBvYmxhY2lvbgpgYGAKCgpgYGB7cn0KcG9ibGFjaW9uX2U5NjwtcG9ibGFjaW9uJT4lCiAgZmlsdGVyKAogICAgcGFyZW50ZXNjbyA9PSAiMDEiLCNlbiBlbCA5OCBlcmEgIjAxIgogICAgYmV0d2VlbihlZGFkLDI1LDYwKSwKICAgICFpcy5uYShlZF9mb3JtYWwpLAogICAgIWlzLm5hKGVkX3RlY25pY2EpLAogICAgIWlzLm5hKG9jdXBhY2lvbiksCiAgICBOX0VNUExFT1M9PTEsICMgZWwgZW50cmV2aXN0YWRvIHNvbG8gcHJvcG9yY2lvbmEgdW5hIG9jdXBhY2nDs24KICApJT4lCiAgc2VsZWN0KAogICAgZm9saW8sCiAgICBudW1fcmVuLAogICAgZWRhZCwKICAgIHNleG8sCiAgICBlZF9mb3JtYWwsCiAgICBlZF90ZWNuaWNhLAogICAgb2N1cGFjaW9uCiAgKSU+JQogbXV0YXRlKAogIGVkX2Zvcm1hbCA9IGFzLmludGVnZXIoYXMuY2hhcmFjdGVyKGVkX2Zvcm1hbCkpLAogICBlZF90ZWNuaWNhPSBhcy5pbnRlZ2VyKGFzLmNoYXJhY3RlcihlZF90ZWNuaWNhKSksCiAgZXN0YWRvID0gc3Vic3RyKGZvbGlvLDUsNikKICkKYGBgCgoKYGBge3J9CiNFbiAxOTk4IHBhcmEgaGlqb3MgZXMgIjA0IiB5ICIwNSIuIEVuIDE5OTYgIjQiIGFiYXJjYSB0b2RvcyBsb3MgaGlqb3MKI0VuIDE5OTggc2UgY29uc2lkZXJhIGVkYWQ8PTE4LCBlbiAxOTk2IHNlIGNvbnNpZGVyYSBlZGFkPD0xNApmb2xpb3M5NjwtYXMuY2hhcmFjdGVyKHBvYmxhY2lvbiU+JWZpbHRlcihwYXJlbnRlc2NvICVpbiUgYygiMDQiLCIwNSIpLGVkYWQ8PTE2KSU+JXNlbGVjdChmb2xpbyklPiVwdWxsKCkpCnBvYmxhY2lvbl9lOTY8LXBvYmxhY2lvbl9lOTYlPiVmaWx0ZXIoZm9saW8gJWluJSAgZm9saW9zOTYgKQpgYGAKCmBgYHtyfQpucm93KHBvYmxhY2lvbl9lOTYpCmhlYWQocG9ibGFjaW9uX2U5NiRlZF9mb3JtYWwpCnN0cihwb2JsYWNpb25fZTk2JGVkX2Zvcm1hbCkjY2FyYWN0ZXIgMiBlc3BhY2lvcwp1bmlxdWUocG9ibGFjaW9uX2U5NiRlZF9mb3JtYWwpCmBgYAoKYGBge3J9CmhlYWQocG9ibGFjaW9uX2U5NiRlZF90ZWNuaWNhKQpzdHIocG9ibGFjaW9uX2U5NiRlZF90ZWNuaWNhKSNjYXJhY3RlciAxIGVzcGFjaW8KdW5pcXVlKHBvYmxhY2lvbl9lOTYkZWRfdGVjbmljYSkKCm5hbWVzKHBvYmxhY2lvbl9lOTYpCnN0cihwb2JsYWNpb25fZTk2JHBlcl9pbmcpCmBgYAoKYGBge3J9CiMgaGFjZW1vcyBsYSBjb2RpZmljYWNpw7NuIGRlIEVOSUdIMjAxOCBhIEVTUlUKIyAxCVByZWVzY29sYXIgbyBrw61uZGVyCiMgMglQcmltYXJpYQojIDMJU2VjdW5kYXJpYSB0w6ljbmljYQojIDQJU2VjdW5kYXJpYSBnZW5lcmFsCiMgNQlQcmVwYXJhdG9yaWEgdMOpY25pY2EKIyA2CVByZXBhcmF0b3JpYSBnZW5lcmFsCiMgNwlUw6ljbmljYSBvIGNvbWVyY2lhbCBjb24gc2VjdW5kYXJpYQojIDgJVMOpY25pY2EgbyBjb21lcmNpYWwgY29uIHByZXBhcmF0b3JpYQojIDkJTm9ybWFsIGLDoXNpY2EgKGNvbiBwcmltYXJpYSBvIHNlY3VuZGFyaQojIDEwIE5vcm1hbCBkZSBsaWNlbmNpYXR1cmEKIyAxMSBQcm9mZXNpb25hbCAobGljZW5jaWF0dXJhIG8gaW5nZW5pZXLDrWEpCiMgMTIgUG9zdGdyYWRvIChtYWVzdHLDrWEgbyBkb2N0b3JhZG8pCiNfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwojIDk2IE5TLCBubyBhcGxpY2EgcG9ycXVlIHBlZGltb3MgbGEgZWR1Y2nDs24gZGVsIHBwIGNvbW8gaW5zdHJ1bWVudG8KY29tYjwtcG9ibGFjaW9uX2U5NiU+JQogICBtdXRhdGUoIGNvbWJpID0gcGFzdGUoYXMuY2hhcmFjdGVyKGVkX2Zvcm1hbCksYXMuY2hhcmFjdGVyKGVkX3RlY25pY2EpKSklPiUKICBzZWxlY3QoZWRfZm9ybWFsLGVkX3RlY25pY2EsY29tYmkpCmNvbWIKc29ydCh1bmlxdWUoY29tYiRjb21iaSkpCmBgYAoKYGBge3J9CnBvYmxhY2lvbl9lOTZjPC1wb2JsYWNpb25fZTk2JT4lCiAgIG11dGF0ZSgKICAgZWR1X2EgPSBpZmVsc2UoZWRfZm9ybWFsPT0wICYgZWRfdGVjbmljYT09MCwwLCAgICAjc2luIGluc3RydWNjaW9uKDEpCiAgICAgICAgICBpZmVsc2UoKGVkX2Zvcm1hbCAlaW4lIGMoMjoxMykpICYgKGVkX3RlY25pY2EgJWluJSBjKDAsMiwzKSksZWRfZm9ybWFsLAogICAgICAgICAgaWZlbHNlKChlZF9mb3JtYWwgJWluJSBjKDc6MTMpKSAmIChlZF90ZWNuaWNhICVpbiUgYyg0LDUsNiw4KSksZWRfZm9ybWFsKzEsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT0xNCAmIChlZF90ZWNuaWNhICVpbiUgYygwLDIsNCw1LDYsOCkpLDE3LDE5KSkpKQopCmBgYAoKYGBge3J9CnBvYmxhY2lvbl9lOTZjPC1wb2JsYWNpb25fZTk2YyU+JQogICBtdXRhdGUoCiAgIGVkdV9hYyA9IGlmZWxzZShlZHVfYSAlaW4lIDA6NSwiQzEiLCAgICAKICAgICAgICAgIGlmZWxzZShlZHVfYSAlaW4lIDY6MTAgLCJDMiIsCiAgICAgICAgICBpZmVsc2UoZWR1X2EgJWluJSAxMToxMiwiQzMiLAogICAgICAgICAgaWZlbHNlKGVkdV9hICVpbiUgMTM6MTQsIkM0IiwiQzUiKSkpKQogICkKYGBgCgoKYGBge3J9CnBvYmxhY2lvbl9lOTZjPC1wb2JsYWNpb25fZTk2YyU+JQogICAgICAgICAgbXV0YXRlKAogICAgICAgICAgICByZWdpb24gPSBpZmVsc2UoZXN0YWRvICVpbiUgYygiMDIiLCIyNiIsIjA4IiwiMDUiLCIxOSIsIjI4IiksMSwKICAgICAgICAgICAgICAgIGlmZWxzZShlc3RhZG8gJWluJSBjKCIxMiIsIjIwIiwiMDciLCIzMCIsIjI3IiwiMDQiLCIzMSIsIjIzIiksNCwKICAgICAgICAgICAgICAgIGlmZWxzZShlc3RhZG8gJWluJSBjKCIwMyIsIjI1IiwiMTgiLCIxMCIsIjMyIiwiMTYiLCIwNiIsIjE0IiwiMDEiLCIyNCIpLDIsMykpKQogICAgICAgICAgKQpgYGAKCgojIyBJbmdyZXNvcyA5NgoKYGBge3J9CmluZ3Jlc29zPC1yZWFkLmRiZigKICAgICAgICAgICAgICBmaWxlPSJEYXRvcy9FTklHSC0xOTk2L2luZ3Jlc29zLmRiZiIKICAgICAgICAgICAgICApCgpgYGAKCmBgYHtyfQpmYW1pbGlhc19pbnRlZ3JhbnRlcyA8LSBmdW5jdGlvbihkZixucil7CiAgZGZuIDwtIGRmICU+JQogICAgZmlsdGVyKE5VTV9SRU4gJWluJSBucikKICByZXR1cm4oZGZuKQp9CmBgYAoKYGBge3J9CmluZ3Jlc29zX2FjdSA8LSBmdW5jdGlvbihkZixjbGF2cyl7CiBkZm4gPC0gZGYgJT4lCiAgIGdyb3VwX2J5KEZPTElPLCBOVU1fUkVOKSAlPiUKICAgZmlsdGVyKENMQVZFICVpbiUgY2xhdnMpJT4lCiAgIHN1bW1hcmlzZSgKICAgY2xhdmVzX2EgPSBwYXN0ZShDTEFWRSxjb2xsYXBzZSA9ICIsIiksCiAgaW5nX3RyaV90ID0gc3VtKElOR19UUkkpLAogIGluZ19tZW5fcCA9IGluZ190cmlfdC8zLAogIGxpbmdfbWVuX3AgPSBsb2coaW5nX21lbl9wKQogICkgJT4lIHVuZ3JvdXAoKQogCiAKIHJldHVybihkZm4pCn0KYGBgCgpgYGB7cn0KI2hvZ2FyZXMgPC0gYygiMSIsIjIiLCIzIiwiNCIsIjUiKQpwZXJzb25hc19oIDwtIGMoJzAxJykKCmE8LWZhbWlsaWFzX2ludGVncmFudGVzKGluZ3Jlc29zLHBlcnNvbmFzX2gpCmhlYWQoYSkKI1AwMDEgU3VlbGRvcywgc2FsYXJpb3MsIGpvcm5hbCB5IGhvcmFzIGV4dHJhcyAKI1AwMDIgQ29taXNpb25lcywgcHJvcGluYXMgeSBkZXN0YWpvIAojUDAxMDpQMDE4IGRlIDE5OTggc29uIGxhcyBtaXNtYXMgcXVlIFAwMDY6UDAxNCBkZSAxOTk2CiNQMDIwOlAwMjEgZGUgMTk5OCBzb24gbGFzIG1pc21hcyBxdWUgUDAxNjpQMDE3IGRlIDE5OTYKI1AwMjYgZGUgMTk5OCBlcyBsYSBtaXNtYSBxdWUgUDAyMiBkZSAxOTk2LCBhdW5xdWUgbm8gaGF5IGVxdWl2YWxlbnRlIGVuIDE5OTYgYSBsYSBQMDI3IGRlIDE5OTgKI1AwMzUgZGUgMTk5OCBlcyBsYSBtaXNtYSBxdWUgUDAzMCBkZSAxOTk2CiNQMDQwOlAwNDIgZGUgMTk5OCBzb24gbGFzIG1pc21hcyBxdWUgUDAzNTpQMDM3IGRlIDE5OTYKI1AwNDQ6UDA0NSBkZSAxOTk4IHNvbiBsYXMgbWlzbWFzIHF1ZSBQMDM5OlAwNDAgZGUgMTk5NgpjbGF2ZXM8LWMoIlAwMDEiLCJQMDAyIiwiUDAwNiIsIlAwMDciLCJQMDA4IiwiUDAwOSIsIlAwMTAiLCJQMDExIiwgIlAwMTIiLCJQMDEzIiwiUDAxNCIsIlAwMTYiLCJQMDE3IiwiUDAyMiIsIlAwMzAiLCJQMDM1IiwiUDAzNiIsIlAwMzciLCJQMDM5IiwiUDA0MCIpCmluZ3Jlc29zX2U5NjwtaW5ncmVzb3NfYWN1KGEsY2xhdmVzKSAKaW5ncmVzb3NfZTk2PC1pbmdyZXNvc19lOTYlPiUKICBzZWxlY3QoRk9MSU8sTlVNX1JFTixjbGF2ZXNfYSxpbmdfbWVuX3AsbGluZ19tZW5fcCklPiUKICByZW5hbWUoCiAgICBmb2xpbyA9IEZPTElPLAogICAgbnVtX3JlbiA9IE5VTV9SRU4KICApCmhlYWQoaW5ncmVzb3NfZTk2KQoKaW5ncmVzb3NfZTk2PC0gaW5ncmVzb3NfZTk2JT4lCiAgbXV0YXRlKAogICAgIHJlZ2lvbiA9IGlmZWxzZShzdWJzdHIoZm9saW8sNSw2KSAlaW4lIGMoIjAyIiwiMjYiLCIwOCIsIjA1IiwiMTkiLCIyOCIpLDEsCiAgICAgICAgICAgICAgICBpZmVsc2Uoc3Vic3RyKGZvbGlvLDUsNikgJWluJSBjKCIxMiIsIjIwIiwiMDciLCIzMCIsIjI3IiwiMDQiLCIzMSIsIjIzIiksNCwKICAgICAgICAgICAgICAgIGlmZWxzZShzdWJzdHIoZm9saW8sNSw2KSAlaW4lIGMoIjAzIiwiMjUiLCIxOCIsIjEwIiwiMzIiLCIxNiIsIjA2IiwiMTQiLCIwMSIsIjI0IiksMiwzKSkpCiAgKQoKYGBgCgojIyByYW5nbyBwZXJjZW50aWwgOTYKCmBgYHtyfQojSU48LSgxMDAvMTEwLjkwNykKSU48LSgxMDAvOTMuNikKaW5ncmVzb3NfZTk2JGxpbmdfbWVuX3BkPC1pbmdyZXNvc19lOTYkbGluZ19tZW5fcCArIGxvZyhJTikKcnBfZTk2IDwtIHJhbmsoaW5ncmVzb3NfZTk2JGxpbmdfbWVuX3BkKS9sZW5ndGgoaW5ncmVzb3NfZTk2JGxpbmdfbWVuX3BkKQojcnBfZTk2PC1wZXJjZW50X3JhbmsoaW5ncmVzb3NfZTk2JGxpbmdfbWVuX3BkKQpgYGAKCgoKIyMgQmFzZSBjcnV6YWRhIHBvYmxhLWluZyA5NgoKYGBge3IgYmFzZV9jcnV6X2U5Nn0KZW5pZ2hfOTY8LWZ1bGxfam9pbihwb2JsYWNpb25fZTk2YyxpbmdyZXNvc19lOTYpJT4lCiAgZHJvcF9uYSgpJT4lCiAgIG11dGF0ZSgKICAgICBvY3VwYWNpb24gPSBzdWJzdHIob2N1cGFjaW9uLDEsMikKICAgKSMlPiUKICAjIHJlbmFtZSgKICAjICAgRURVPU5fSU5TVFIxNjEsCiAgIyAgIE9DVSA9IENNTzEyMQogICMgKSU+JQogICMgbXV0YXRlKAogICMgICBFRFUgPSBhcy5jaGFyYWN0ZXIoRURVKQogICMgKQpoZWFkKGVuaWdoXzk2KQoKdW5pcXVlKGVuaWdoXzk2JGVkYWQpCgojIGFqdXN0ZSBwYXJhIG5pdmVsIGRlIGVjdWNhY2nDs24gRVNSVQoKI2RhdGFfcGFkcmVzMjAwNSRFRFUgPC0gZmFjdG9yKGRhdGFfcGFkcmVzMjAwNSRFRFUpCiNkYXRhX3BhZHJlczIwMDUkT0NVIDwtIGZhY3RvcihkYXRhX3BhZHJlczIwMDUkT0NVKQoKI3VuaXF1ZShkYXRhX3BhZHJlczIwMDUkT0NVKQpzdW0oaXMubmEoZW5pZ2hfOTYpKQpuYW1lcyhlbmlnaF85NikKYGBgCgoKYGBge3IgYmFzZV9jcnV6X2U5NiBndWFyZGF9CiMjIyMjIEd1YXJkYW1vcyBiYXNlIGRlIHBhZHJlcyBmaW5hbApzYXZlUkRTKGVuaWdoXzk2LCBmaWxlPSJEYXRvcy9lbmlnaF85Nl9jcmkzLlJkYSIpCgpgYGAKCiMjIEVzZMOtc3RpY2EgZGVzY3JpcHRpdmEgOTYKCmBgYHtyfQpzdW1tYXJ5KGVuaWdoXzk2JGVkYWQpCmhpc3QoZW5pZ2hfOTYkZWRhZCkKcGFwYXM8LSBlbmlnaF85NiU+JWdyb3VwX2J5KGVkYWQpJT4lc3VtbWFyaXNlKG1zYWwgPSBtZWFuKGluZ19tZW5fcCkpCnBsb3QocGFwYXMkZWRhZCxwYXBhcyRtc2FsKQpgYGAKCgoKCgojIFBhZHJlcyAxOTk0CgojIyBwb2JsYWNpb24gZW5pZ2ggMTk5NAoKYGBge3J9CnBvYmxhY2lvbjwtcmVhZC5kYmYoCiAgICAgICAgICAgICAgZmlsZT0iRGF0b3MvRU5JR0gtSGlzdG9yaWNhLzE5OTQvUE9CTEE5NC5kYmYiCiAgICAgICAgICAgICAgKQpwb2JsYWNpb24gPC0gcG9ibGFjaW9uICU+JSAKICAgICAgICAgICAgICAgIHJlbmFtZSgKICAgICAgICAgICAgICAgICAgcGFyZW50ZXNjbyA9IFBBUkVOVEVTQ08sCiAgICAgICAgICAgICAgICAgIGZvbGlvID0gRk9MSU8sCiAgICAgICAgICAgICAgICAgIG51bV9yZW4gPSBOVU1fUkVOLAogICAgICAgICAgICAgICAgICBzZXhvID0gU0VYTywKICAgICAgICAgICAgICAgICAgZWRhZCA9IEVEQUQsCiAgICAgICAgICAgICAgICAgIHBlcl9pbmc9UEVSX0lORywKICAgICAgICAgICAgICAgICAgZWRfZm9ybWFsPUVEX0ZPUk1BTCwKICAgICAgICAgICAgICAgICAgZWRfdGVjbmljYT1FRF9URUNOSUNBLAogICAgICAgICAgICAgICAgICBvY3VwYWNpb249T0NVUEFDSU9OCiAgICAgICAgICAgICAgICAgICkKcG9ibGFjaW9uCmBgYAoKYGBge3J9CnBvYmxhY2lvbl9lOTQ8LXBvYmxhY2lvbiU+JQogIGZpbHRlcigKICAgIHBhcmVudGVzY28gPT0gIjEiLCNlbiBlbCA5OCBlcmEgIjAxIgogICAgYmV0d2VlbihlZGFkLDI1LDYwKSwKICAgICFpcy5uYShlZF9mb3JtYWwpLAogICAgIWlzLm5hKGVkX3RlY25pY2EpLAogICAgIWlzLm5hKG9jdXBhY2lvbiksCiAgICBOX0VNUExFT1M9PTEsICMgZWwgZW50cmV2aXN0YWRvIHNvbG8gcHJvcG9yY2lvbmEgdW5hIG9jdXBhY2nDs24KICApJT4lCiAgc2VsZWN0KAogICAgZm9saW8sCiAgICBudW1fcmVuLAogICAgZWRhZCwKICAgIHNleG8sCiAgICBlZF9mb3JtYWwsCiAgICBlZF90ZWNuaWNhLAogICAgb2N1cGFjaW9uCiAgKSU+JQogbXV0YXRlKAogIGVkX2Zvcm1hbCA9IGFzLmludGVnZXIoYXMuY2hhcmFjdGVyKGVkX2Zvcm1hbCkpLAogICBlZF90ZWNuaWNhPSBhcy5pbnRlZ2VyKGFzLmNoYXJhY3RlcihlZF90ZWNuaWNhKSksCiAgZXN0YWRvID0gc3Vic3RyKGZvbGlvLDUsNikKICkKYGBgCgoKYGBge3J9CiNFbiAxOTk4IHBhcmEgaGlqb3MgZXMgIjA0IiB5ICIwNSIuIEVuIDE5OTQgIjQiIGFiYXJjYSB0b2RvcyBsb3MgaGlqb3MKI0VuIDE5OTggc2UgY29uc2lkZXJhIGVkYWQ8PTE4LCBlbiAxOTk0IHNlIGNvbnNpZGVyYSBlZGFkPD0xNApmb2xpb3M5NDwtYXMuY2hhcmFjdGVyKHBvYmxhY2lvbiU+JWZpbHRlcihwYXJlbnRlc2NvICVpbiUgYygiNCIpLGVkYWQ8PTEzKSU+JXNlbGVjdChmb2xpbyklPiVwdWxsKCkpCnBvYmxhY2lvbl9lOTQ8LXBvYmxhY2lvbl9lOTQlPiVmaWx0ZXIoZm9saW8gJWluJSAgZm9saW9zOTQgKQpgYGAKCmBgYHtyfQpucm93KHBvYmxhY2lvbl9lOTQpCmhlYWQocG9ibGFjaW9uX2U5NCRlZF9mb3JtYWwpCnN0cihwb2JsYWNpb25fZTk0JGVkX2Zvcm1hbCkjY2FyYWN0ZXIgMiBlc3BhY2lvcwp1bmlxdWUocG9ibGFjaW9uX2U5NCRlZF9mb3JtYWwpCmBgYApgYGB7cn0KaGVhZChwb2JsYWNpb25fZTk0JGVkX3RlY25pY2EpCnN0cihwb2JsYWNpb25fZTk0JGVkX3RlY25pY2EpI2NhcmFjdGVyIDEgZXNwYWNpbwp1bmlxdWUocG9ibGFjaW9uX2U5NCRlZF90ZWNuaWNhKQoKbmFtZXMocG9ibGFjaW9uX2U5NCkKc3RyKHBvYmxhY2lvbl9lOTQkcGVyX2luZykKYGBgCmBgYHtyfQojIGhhY2Vtb3MgbGEgY29kaWZpY2FjacOzbiBkZSBFTklHSDIwMTggYSBFU1JVCiMgMQlQcmVlc2NvbGFyIG8ga8OtbmRlcgojIDIJUHJpbWFyaWEKIyAzCVNlY3VuZGFyaWEgdMOpY25pY2EKIyA0CVNlY3VuZGFyaWEgZ2VuZXJhbAojIDUJUHJlcGFyYXRvcmlhIHTDqWNuaWNhCiMgNglQcmVwYXJhdG9yaWEgZ2VuZXJhbAojIDcJVMOpY25pY2EgbyBjb21lcmNpYWwgY29uIHNlY3VuZGFyaWEKIyA4CVTDqWNuaWNhIG8gY29tZXJjaWFsIGNvbiBwcmVwYXJhdG9yaWEKIyA5CU5vcm1hbCBiw6FzaWNhIChjb24gcHJpbWFyaWEgbyBzZWN1bmRhcmkKIyAxMCBOb3JtYWwgZGUgbGljZW5jaWF0dXJhCiMgMTEgUHJvZmVzaW9uYWwgKGxpY2VuY2lhdHVyYSBvIGluZ2VuaWVyw61hKQojIDEyIFBvc3RncmFkbyAobWFlc3Ryw61hIG8gZG9jdG9yYWRvKQojX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KIyA5NCBOUywgbm8gYXBsaWNhIHBvcnF1ZSBwZWRpbW9zIGxhIGVkdWNpw7NuIGRlbCBwcCBjb21vIGluc3RydW1lbnRvCmNvbWI8LXBvYmxhY2lvbl9lOTQlPiUKICAgbXV0YXRlKCBjb21iaSA9IHBhc3RlKGFzLmNoYXJhY3RlcihlZF9mb3JtYWwpLGFzLmNoYXJhY3RlcihlZF90ZWNuaWNhKSkpJT4lCiAgc2VsZWN0KGVkX2Zvcm1hbCxlZF90ZWNuaWNhLGNvbWJpKQpjb21iCnNvcnQodW5pcXVlKGNvbWIkY29tYmkpKQpgYGAKCmBgYHtyfQpwb2JsYWNpb25fZTk0YzwtcG9ibGFjaW9uX2U5NCU+JQogICBtdXRhdGUoCiAgIGVkdV9hID0gaWZlbHNlKGVkX2Zvcm1hbD09MCAmIGVkX3RlY25pY2E9PTAsMCwgICAgI3NpbiBpbnN0cnVjY2lvbigxKQogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09MSAmIChlZF90ZWNuaWNhICVpbiUgYygwLDEpKSwzLAogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09MSAmIGVkX3RlY25pY2E9PTIsNCwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTIgJiAoZWRfdGVjbmljYSAlaW4lIGMoMCwxKSksNiwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTIgJiAoZWRfdGVjbmljYSAlaW4lIGMoMiwzKSksNywKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTMgJiAoZWRfdGVjbmljYSAlaW4lIGMoMCwxKSksNywKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTMgJiAoZWRfdGVjbmljYSAlaW4lIGMoMiwzKSksOCwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTQgJiBlZF90ZWNuaWNhPT0wLDksCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT00ICYgZWRfdGVjbmljYT09MiwxMCwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTQgJiAoZWRfdGVjbmljYSAlaW4lIGMoNCw1KSksMTEsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT00ICYgZWRfdGVjbmljYT09NiwxMywKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTUgJiBlZF90ZWNuaWNhPT0wLDExLAogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09NSAmIChlZF90ZWNuaWNhICVpbiUgYyg0LDUpKSwxMywKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTUgJiBlZF90ZWNuaWNhPT02LDE0LAogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09NiAmIGVkX3RlY25pY2E9PTAsMTIsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT02ICYgZWRfdGVjbmljYT09MiwxMywKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTYgJiAoZWRfdGVjbmljYSAlaW4lIGMoNCw1KSksMTQsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT02ICYgKGVkX3RlY25pY2EgJWluJSBjKDYsNyw4KSksMTUsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT03ICYgKGVkX3RlY25pY2EgJWluJSBjKDAsMSkpLDE1LAogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09NyAmIChlZF90ZWNuaWNhICVpbiUgYygyLDMpKSwxNiwKICAgICAgICAgIGlmZWxzZShlZF9mb3JtYWw9PTcgJiAoZWRfdGVjbmljYSAlaW4lIGMoNCw1LDYsOCkpLDE3LAogICAgICAgICAgaWZlbHNlKGVkX2Zvcm1hbD09OCAmIGVkX3RlY25pY2E9PTAsMTcsCiAgICAgICAgICBpZmVsc2UoZWRfZm9ybWFsPT04ICYgKGVkX3RlY25pY2EgJWluJSBjKDIsNCw1LDYsOCkpLDE4LDE5KSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkKICApCmBgYAoKYGBge3J9CnBvYmxhY2lvbl9lOTRjPC1wb2JsYWNpb25fZTk0YyU+JQogICBtdXRhdGUoCiAgIGVkdV9hYyA9IGlmZWxzZShlZHVfYSAlaW4lIDA6NSwiQzEiLCAgICAKICAgICAgICAgIGlmZWxzZShlZHVfYSAlaW4lIDY6MTAgLCJDMiIsCiAgICAgICAgICBpZmVsc2UoZWR1X2EgJWluJSAxMToxMiwiQzMiLAogICAgICAgICAgaWZlbHNlKGVkdV9hICVpbiUgMTM6MTQsIkM0IiwiQzUiKSkpKQogICkKYGBgCgoKYGBge3J9CnBvYmxhY2lvbl9lOTRjPC1wb2JsYWNpb25fZTk0YyU+JQogICAgICAgICAgbXV0YXRlKAogICAgICAgICAgICByZWdpb24gPSBpZmVsc2UoZXN0YWRvICVpbiUgYygiMDIiLCIyNiIsIjA4IiwiMDUiLCIxOSIsIjI4IiksMSwKICAgICAgICAgICAgICAgIGlmZWxzZShlc3RhZG8gJWluJSBjKCIxMiIsIjIwIiwiMDciLCIzMCIsIjI3IiwiMDQiLCIzMSIsIjIzIiksNCwKICAgICAgICAgICAgICAgIGlmZWxzZShlc3RhZG8gJWluJSBjKCIwMyIsIjI1IiwiMTgiLCIxMCIsIjMyIiwiMTYiLCIwNiIsIjE0IiwiMDEiLCIyNCIpLDIsMykpKQogICAgICAgICAgKQpgYGAKCgojIyBJbmdyZXNvcyBlbmdpaCA5NAoKYGBge3J9CmluZ3Jlc29zPC1yZWFkLmRiZigKICAgICAgICAgICAgICBmaWxlPSJEYXRvcy9FTklHSC1IaXN0b3JpY2EvMTk5NC9pbmdyZXNvcy5kYmYiCiAgICAgICAgICAgICAgKQoKYGBgCgpgYGB7cn0KZmFtaWxpYXNfaW50ZWdyYW50ZXMgPC0gZnVuY3Rpb24oZGYsbnIpewogIGRmbiA8LSBkZiAlPiUKICAgIGZpbHRlcihOVU1fUkVOICVpbiUgbnIpCiAgcmV0dXJuKGRmbikKfQpgYGAKCmBgYHtyfQppbmdyZXNvc19hY3UgPC0gZnVuY3Rpb24oZGYsY2xhdnMpewogZGZuIDwtIGRmICU+JQogICBncm91cF9ieShGT0xJTywgTlVNX1JFTikgJT4lCiAgIGZpbHRlcihDTEFWRSAlaW4lIGNsYXZzKSU+JQogICBzdW1tYXJpc2UoCiAgIGNsYXZlc19hID0gcGFzdGUoQ0xBVkUsY29sbGFwc2UgPSAiLCIpLAogIGluZ190cmlfdCA9IHN1bShJTkdfVFJJKSwKICBpbmdfbWVuX3AgPSBpbmdfdHJpX3QvMywKICBsaW5nX21lbl9wID0gbG9nKGluZ19tZW5fcCkKICApICU+JSB1bmdyb3VwKCkKIAogCiByZXR1cm4oZGZuKQp9CmBgYAoKYGBge3J9CiNob2dhcmVzIDwtIGMoIjEiLCIyIiwiMyIsIjQiLCI1IikKcGVyc29uYXNfaCA8LSBjKCcwMScpCgphPC1mYW1pbGlhc19pbnRlZ3JhbnRlcyhpbmdyZXNvcyxwZXJzb25hc19oKQpoZWFkKGEpCiNQMDAxIFN1ZWxkb3MsIHNhbGFyaW9zLCBqb3JuYWwgeSBob3JhcyBleHRyYXMgCiNQMDAyIENvbWlzaW9uZXMsIHByb3BpbmFzIHkgZGVzdGFqbyAKI1AwMTA6UDAxOCBkZSAxOTk4IHNvbiBsYXMgbWlzbWFzIHF1ZSBQMDA2OlAwMTQgZGUgMTk5NAojUDAyMDpQMDIxIGRlIDE5OTggc29uIGxhcyBtaXNtYXMgcXVlIFAwMTY6UDAxNyBkZSAxOTk0CiNQMDI2IGRlIDE5OTggZXMgbGEgbWlzbWEgcXVlIFAwMjIgZGUgMTk5NCwgYXVucXVlIG5vIGhheSBlcXVpdmFsZW50ZSBlbiAxOTk0IGEgbGEgUDAyNyBkZSAxOTk4CiNQMDM1IGRlIDE5OTggZXMgbGEgbWlzbWEgcXVlIFAwMjkgZGUgMTk5NAojUDA0MDpQMDQyIGRlIDE5OTggc29uIGxhcyBtaXNtYXMgcXVlIFAwMzQ6UDAzNiBkZSAxOTk0CiNQMDQ0OlAwNDUgZGUgMTk5OCBzb24gbGFzIG1pc21hcyBxdWUgUDAzODpQMDM5IGRlIDE5OTQKY2xhdmVzPC1jKCJQMDAxIiwiUDAwMiIsIlAwMDYiLCJQMDA3IiwiUDAwOCIsIlAwMDkiLCJQMDEwIiwiUDAxMSIsICJQMDEyIiwiUDAxMyIsIlAwMTQiLCJQMDE2IiwiUDAxNyIsIlAwMjIiLCJQMDI5IiwiUDAzNCIsIlAwMzUiLCJQMDM2IiwiUDAzOCIsIlAwMzkiKQppbmdyZXNvc19lOTQ8LWluZ3Jlc29zX2FjdShhLGNsYXZlcykgCmluZ3Jlc29zX2U5NDwtaW5ncmVzb3NfZTk0JT4lCiAgc2VsZWN0KEZPTElPLE5VTV9SRU4sY2xhdmVzX2EsaW5nX21lbl9wLGxpbmdfbWVuX3ApJT4lCiAgcmVuYW1lKAogICAgZm9saW8gPSBGT0xJTywKICAgIG51bV9yZW4gPSBOVU1fUkVOCiAgKQpoZWFkKGluZ3Jlc29zX2U5NCkKCgppbmdyZXNvc19lOTQ8LSBpbmdyZXNvc19lOTQlPiUKICBtdXRhdGUoCiAgICAgcmVnaW9uID0gaWZlbHNlKHN1YnN0cihmb2xpbyw1LDYpICVpbiUgYygiMDIiLCIyNiIsIjA4IiwiMDUiLCIxOSIsIjI4IiksMSwKICAgICAgICAgICAgICAgIGlmZWxzZShzdWJzdHIoZm9saW8sNSw2KSAlaW4lIGMoIjEyIiwiMjAiLCIwNyIsIjMwIiwiMjciLCIwNCIsIjMxIiwiMjMiKSw0LAogICAgICAgICAgICAgICAgaWZlbHNlKHN1YnN0cihmb2xpbyw1LDYpICVpbiUgYygiMDMiLCIyNSIsIjE4IiwiMTAiLCIzMiIsIjE2IiwiMDYiLCIxNCIsIjAxIiwiMjQiKSwyLDMpKSkKICApCgoKYGBgCgojIyByYW5nbyBwZXJjZW50aWwgOTQKCmBgYHtyfQojSU48LSgxMDAvMTEwLjkwNykKSU48LSgxMDAvOTMuNikKaW5ncmVzb3NfZTk0JGxpbmdfbWVuX3BkPC1pbmdyZXNvc19lOTQkbGluZ19tZW5fcCArIGxvZyhJTikKcnBfZTk0IDwtIHJhbmsoaW5ncmVzb3NfZTk0JGxpbmdfbWVuX3BkKS9sZW5ndGgoaW5ncmVzb3NfZTk0JGxpbmdfbWVuX3BkKQojcnBfZTk0PC0gcGVyY2VudF9yYW5rKGluZ3Jlc29zX2U5NCRsaW5nX21lbl9wZCkKYGBgCgoKCiMjIEJhZSBjcnV6YWRhIHBvYmxhLWluZ3JlIDk0CgpgYGB7ciBiYXNlX2NydXpfZTk0fQplbmlnaF85NDwtZnVsbF9qb2luKHBvYmxhY2lvbl9lOTRjLGluZ3Jlc29zX2U5NCklPiUKICBkcm9wX25hKCklPiUKICAgbXV0YXRlKAogICAgIG9jdXBhY2lvbiA9IHN1YnN0cihvY3VwYWNpb24sMSwyKQogICApIyU+JQogICMgcmVuYW1lKAogICMgICBFRFU9Tl9JTlNUUjE2MSwKICAjICAgT0NVID0gQ01PMTIxCiAgIyApJT4lCiAgIyBtdXRhdGUoCiAgIyAgIEVEVSA9IGFzLmNoYXJhY3RlcihFRFUpCiAgIyApCmhlYWQoZW5pZ2hfOTQpCgp1bmlxdWUoZW5pZ2hfOTQkZWRhZCkKCiMgYWp1c3RlIHBhcmEgbml2ZWwgZGUgZWN1Y2FjacOzbiBFU1JVCgojZGF0YV9wYWRyZXMyMDA1JEVEVSA8LSBmYWN0b3IoZGF0YV9wYWRyZXMyMDA1JEVEVSkKI2RhdGFfcGFkcmVzMjAwNSRPQ1UgPC0gZmFjdG9yKGRhdGFfcGFkcmVzMjAwNSRPQ1UpCgojdW5pcXVlKGRhdGFfcGFkcmVzMjAwNSRPQ1UpCnN1bShpcy5uYShlbmlnaF85NCkpCm5hbWVzKGVuaWdoXzk0KQpgYGAKCgpgYGB7ciBiYXNlX2NydXpfZTk0IGd1YXJkYX0KIyMjIyMgR3VhcmRhbW9zIGJhc2UgZGUgcGFkcmVzIGZpbmFsCnNhdmVSRFMoZW5pZ2hfOTQsIGZpbGU9IkRhdG9zL2VuaWdoXzk0X2NyaTMuUmRhIikKCmBgYAoKIyMgRXNkw61zdGljYSBkZXNjcmlwdGl2YSA5NAoKYGBge3J9CnN1bW1hcnkoZW5pZ2hfOTQkZWRhZCkKaGlzdChlbmlnaF85NCRlZGFkKQpwYXBhczwtIGVuaWdoXzk0JT4lZ3JvdXBfYnkoZWRhZCklPiVzdW1tYXJpc2UobXNhbCA9IG1lYW4oaW5nX21lbl9wKSkKcGxvdChwYXBhcyRlZGFkLHBhcGFzJG1zYWwpCmBgYAoKCgoKCgoKIyBFc2xhdGljaWRhZCBpbnRlZ2VuZXJhY2lvbmFsIGRlIGluZ3Jlc29zCgoKYGBge3J9CmJhc2VfbG9nc2luZyA8LSBsaXN0KGluZ3Jlc29zX2U5NCxpbmdyZXNvc19lOTYsaW5ncmVzb3NfZTk4KQpiYXNlX3JwIDwtIGxpc3QocnBfZTk0LHJwX2U5NixycF9lOTgpCmBgYAoKCgojIyBEZWZsYWN0YW1vcyBpbmdyZXNvcwoKSU5QQyBGZWIgMjAyMSA9IDExMC45MDcgW0NvbnN1bHRhXVtdCgoKCgoKCgoKCmBgYHtyfQplbmlnaF85NCA8LSByZWFkUkRTKGZpbGUgPSAiRGF0b3MvZW5pZ2hfOTRfY3JpMy5SZGEiKQplbmlnaF85NiA8LSByZWFkUkRTKGZpbGUgPSAiRGF0b3MvZW5pZ2hfOTZfY3JpMy5SZGEiKQplbmlnaF85OCA8LSByZWFkUkRTKGZpbGUgPSAiRGF0b3MvZW5pZ2hfOThfY3JpMy5SZGEiKQoKI2RmaF9jIDwtIHJlYWRSRFMoZmlsZSA9ICJEYXRvcy9kZmhfY19zaW5fcmUuUmRhIikKI2RmaF9jIDwtIHJlYWRSRFMoZmlsZSA9ICJEYXRvcy9kZmhfY19zaW5fcmVfY2guUmRhIikKI2RmaF9jIDwtIHJlYWRSRFMoZmlsZSA9ICJEYXRvcy9kZmhfY19yZS5SZGEiKQojZGZoX2MgPC0gcmVhZFJEUyhmaWxlID0gIkRhdG9zL2RmaF9jX3JlX2NoX2NyaTMuUmRhIikKZGZoX2MgPC0gcmVhZFJEUyhmaWxlID0gIkRhdG9zL2RmaF9jX2NvbWJpbmFkYV9jaF9jcmkzLlJkYSIpCiNkZmhfYyA8LSByZWFkUkRTKGZpbGUgPSAiRGF0b3MvZGZoX2NfY29tYmluYWRhX3AxLlJkYSIpCgoKZW5pZ2hfOTQ8LWVuaWdoXzk0JT4lbXV0YXRlKAogIGVkYWRfYyA9IGlmZWxzZSgyNTw9ZWRhZCAmIGVkYWQ8PTI5LCJFZGFkMSIsCiAgICAgICAgICAgICAgICAgIGlmZWxzZSgzMDw9ZWRhZCAmIGVkYWQ8PTM0LCJFZGFkMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoMzU8PWVkYWQgJiBlZGFkPD0zOSwiRWRhZDMiLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoNDA8PWVkYWQgJiBlZGFkPD00NCwiRWRhZDQiLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoNDU8PWVkYWQgJiBlZGFkPD00OSwiRWRhZDUiLAogICAgICAgICAgICAgIGlmZWxzZSg1MDw9ZWRhZCAmIGVkYWQ8PTU0LCJFZGFkNiIsIkVkYWQ3IikpKSkpKQopCgplbmlnaF85NjwtZW5pZ2hfOTYlPiVtdXRhdGUoCiAgZWRhZF9jID0gaWZlbHNlKDI1PD1lZGFkICYgZWRhZDw9MjksIkVkYWQxIiwKICAgICAgICAgICAgICAgICAgaWZlbHNlKDMwPD1lZGFkICYgZWRhZDw9MzQsIkVkYWQyIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSgzNTw9ZWRhZCAmIGVkYWQ8PTM5LCJFZGFkMyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSg0MDw9ZWRhZCAmIGVkYWQ8PTQ0LCJFZGFkNCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSg0NTw9ZWRhZCAmIGVkYWQ8PTQ5LCJFZGFkNSIsCiAgICAgICAgICAgICAgaWZlbHNlKDUwPD1lZGFkICYgZWRhZDw9NTQsIkVkYWQ2IiwiRWRhZDciKSkpKSkpCikKCmVuaWdoXzk4PC1lbmlnaF85OCU+JW11dGF0ZSgKICBlZGFkX2MgPSBpZmVsc2UoMjU8PWVkYWQgJiBlZGFkPD0yOSwiRWRhZDEiLAogICAgICAgICAgICAgICAgICBpZmVsc2UoMzA8PWVkYWQgJiBlZGFkPD0zNCwiRWRhZDIiLAogICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKDM1PD1lZGFkICYgZWRhZDw9MzksIkVkYWQzIiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKDQwPD1lZGFkICYgZWRhZDw9NDQsIkVkYWQ0IiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKDQ1PD1lZGFkICYgZWRhZDw9NDksIkVkYWQ1IiwKICAgICAgICAgICAgICBpZmVsc2UoNTA8PWVkYWQgJiBlZGFkPD01NCwiRWRhZDYiLCJFZGFkNyIpKSkpKSkKKQoKZGZoX2MgPC0gZGZoX2MgJT4lbXV0YXRlKAogIHBwX2VkYWRfYyA9IGlmZWxzZSggcHBfZWRhZDw9MjksIkVkYWQxIiwKICAgICAgICAgICAgICAgICAgaWZlbHNlKDMwPD1wcF9lZGFkICYgcHBfZWRhZDw9MzQsIkVkYWQyIiwKICAgICAgICAgICAgICAgIGlmZWxzZSgzNTw9cHBfZWRhZCAmIHBwX2VkYWQ8PTM5LCJFZGFkMyIsCiAgICAgICAgICAgICAgICBpZmVsc2UoNDA8PXBwX2VkYWQgJiBwcF9lZGFkPD00NCwiRWRhZDQiLAogICAgICAgICAgICAgICAgaWZlbHNlKDQ1PD1wcF9lZGFkICYgcHBfZWRhZDw9NDksIkVkYWQ1IiwKICAgICAgICAgIGlmZWxzZSg1MDw9cHBfZWRhZCAmIHBwX2VkYWQ8PTU0LCJFZGFkNiIsIkVkYWQ3IikpKSkpKQopCgpkZmhfYzwtZGZoX2MlPiUKICAgICAgICAgIG11dGF0ZSgKICAgICAgICAgICAgcmVnaW9uPSBhcy5pbnRlZ2VyKHJlZ2lvbiksCiAgICAgICAgICAgIHBwX2VzdGFkbyA9IGFzLmludGVnZXIocHBfZXN0YWRvKSwKICAgICAgICAgICAgcHBfcmVnaW9uID0gaWZlbHNlKHBwX2VzdGFkbyAlaW4lIGFzLmludGVnZXIoYygiMDIiLCIyNiIsIjA4IiwiMDUiLCIxOSIsIjI4IikpLDEsCiAgICAgICAgICAgICAgICBpZmVsc2UocHBfZXN0YWRvICVpbiUgYXMuaW50ZWdlcihjKCIxMiIsIjIwIiwiMDciLCIzMCIsIjI3IiwiMDQiLCIzMSIsIjIzIikpLDQsCiAgICAgICAgICAgICAgICBpZmVsc2UocHBfZXN0YWRvICVpbiUgYXMuaW50ZWdlcihjKCIwMyIsIjI1IiwiMTgiLCIxMCIsIjMyIiwiMTYiLCIwNiIsIjE0IiwiMDEiLCIyNCIpKSwyLDMpKSkKICAgICAgICAgICkKCiNJTjwtKDEwMC8xMTAuOTA3KQpJTjwtKDEwMC85My42KSMgZW5lcm8gMjAxNwoKZW5pZ2hfOTQ8LWVuaWdoXzk0JT4lCiAgbXV0YXRlKAogIGxpbmdfbWVuX3A9bGluZ19tZW5fcCtsb2coSU4pCiAgKQoKZW5pZ2hfOTY8LWVuaWdoXzk2JT4lCiAgbXV0YXRlKAogIGxpbmdfbWVuX3A9bGluZ19tZW5fcCtsb2coSU4pCiAgKQoKZW5pZ2hfOTg8LWVuaWdoXzk4JT4lCiAgbXV0YXRlKAogIGxpbmdfbWVuX3A9bGluZ19tZW5fcCtsb2coSU4pCiAgKQoKCnVuaXF1ZShkZmhfYyRyZWdpb24pCnVuaXF1ZShkZmhfYyRwcF9yZWdpb24pCgoKI2lkX2NfcmU8LWRmaF9jJGlkX2hpam8KI2lkX2NfY29tYmluYWRhPC1kZmhfYyRpZF9obwoKI3N1bShpZF9jX3JlICVpbiUgaWRfY19jb21iaW5hZGEpCm5yb3coZGZoX2MpCmBgYAoKCmBgYHtyfQpwcm92aTwtZGZoX2MlPiVmaWx0ZXIoKHBwX29jdXAgJWluJSBlbmlnaF85NCRvY3VwYWNpb24pICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBwX29jdXAgJWluJSBlbmlnaF85NiRvY3VwYWNpb24pICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBwX29jdXAgJWluJSBlbmlnaF85OCRvY3VwYWNpb24pKQpucm93KHByb3ZpKQpgYGAKCgpQb3IgbGEgcG9yZ3JhbWFjacOzbiwgcGFyYSBsb3MgaGlqb3MsIHNlIGhhY2UgZGVudHJvIGRlbCBzaWd1ZWludGUgcHJvZ3JhbWEgCgogIFtDb25zdWx0YV06IGh0dHBzOi8vd3d3LmJhbnhpY28ub3JnLm14L1NpZUludGVybmV0L2NvbnN1bHRhckRpcmVjdG9yaW9JbnRlcm5ldEFjdGlvbi5kbz9hY2Npb249Y29uc3VsdGFyQ3VhZHJvJmlkQ3VhZHJvPUNQMTU0JmxvY2FsZT1lcwoKCgoKCgpgYGB7ciBtaWdyYX0KIyBjb25zaWRlcmFuZG8gbGEgbWlncmFjaW9uCgpkZmhfYzwtIGRmaF9jICU+JQogIGZpbHRlcihwcF9yZWdpb249PXJlZ2lvbikKCm5yb3coZGZoX2MpCmBgYAoKYGBge3J9CmRmaF9jbmE8LWRmaF9jJT4lZHJvcF9uYShwcF9vY3VwKSU+JWRyb3BfbmEocHBfZWRhZCkKbnJvdyhkZmhfY25hKQpgYGAKCgoKQ3JpdGVyaW8gMQotIHBvciByZWdpb24sIHNvbG8gbG9zIHF1ZSBubyBtaWdyYW4gMTAyNQotICBwb3IgcmVnaW9uIHkgY29ob3J0IGRlIGluZ3Jlc28sIHNvbG8gbG9zIHF1ZSBubyBtaWdyYW4gMTAwOQotIGNvbiBvY3VwYWNpb24geSBwb3IgcmVnaW9uIGxvcyBpbmdyZXNvcywgc29sbyBsb3MgcXVlIG5vIG1pZ3JhbiA2MDMKLSBjb24gb2N1cGFjaW9uIHkgcG9yIHJlZ2lvbiB5IHBvciBjb2hvcnQgZGUgbG9zIGluZ3Jlc29zLCBzb2xvIGxvcyBxdWUgbm8gbWlncmFuIDQwNQoKQ3JpdGVyaW8gMgotICBwb3IgcmVnaW9uIHkgY29ob3J0IGRlIGluZ3Jlc28sIHNvbG8gbG9zIHF1ZSBubyBtaWdyYW4gMTAxMgoKCmNyaXRlcmlvIDMKCi0gcG9yIHJlZ2lvbiB5IGNvaG9ydCBkZSBpbmdyZXNvIDE1MjcKLSBjb24gb2N1cGFjaW9uIHkgcG9yIHJlZ2lvbiB5IHBvciBjb2hvcnQgZGUgbG9zIGluZ3Jlc29zLCBzb2xvIGxvcyBxdWUgbm8gbWlncmFuIDYzMAoKQ29tYmluYWRhCgotIG5vIG1pZ3JhbiAxNDY0CiMjIEVzdGltYWNpw7NuCgpgYGB7ciBmdW5fcHJpbl9laWl9CmVpaTwtZnVuY3Rpb24oaSxmcCxmaHAsY29kZT0wLHJlZz0wKXsKI2VuaWdoXzk4IDwtIHJlYWRSRFMoZmlsZSA9ICJEYXRvcy9lbmlnaF85OC5SZGEiKQojZGZoX2MgPC0gcmVhZFJEUyhmaWxlID0gIkRhdG9zL2RmaF9jLlJkYSIpCiNmcCA9IGxpbmdfbWVuX3AgfiBlZHVfYWMgKyBvY3VwYWNpb24gKyBlZGFkICsgSShlZGFkKmVkYWQpCiNmaHAgPSBsaW5nX2ggfiBsaW5nX3AgKyBlZGFkX2grIEkoZWRhZF9oKmVkYWRfaCkKI3JlZzwtMQojY29kZTwtMQojcHJpbnQocmVnKQojIEJPT1NUUkFQICAKIyBSZWdyZXNpw7NuIGRlIGluZ3Jlc29zIGRlIHBhZHJlcyAgCiNzdW1tYXJ5KHJlZ19wYWRyZXMpCgojIG51bWVybyBkZSBwYWRyZXMgc2luIG9jdXBhY2nDs24gcmVwb3J0YWRhIGRlIGhpam9zCiNwX3NvY3U8LXN1bShpcy5uYShkZmhfYyRwcF9vY3VwKSkKCnJlZ3Jlc2lvbl9wYWRyZXM8LWZ1bmN0aW9uKGVuaWdoLGRmaF9jbmEsY29kZT1jb2RlLHJlZz1yZWcpewogIGlmKGNvZGU9PTEpewoKICAgICMgcmVncmVzaW9uIHBhZHJlcyAgcG9yIHJlZ2lvbgogIAogICAgZW5pZ2g8LWVuaWdoJT4lZmlsdGVyKHJlZ2lvbj09cmVnKQogICAgZW5pZ2hfciA8LWVuaWdoW3NhbXBsZShucm93KGVuaWdoKSxucm93KGVuaWdoKSwgcmVwbGFjZSA9IFRSVUUpLF0KCiAgICByZWdfcGFkcmVzPC1sbSgKICAgIGZvcm11bGEgPSBmcCwKICAgIGRhdGEgPSBlbmlnaF9yCiAgICApCiAgICAKICAgICMgZGF0YSBmcmFtZSByZWdpb24KICAgIAogICAgZGZoX2NuYTwtZGZoX2NuYSU+JWZpbHRlcihwcF9vY3VwICVpbiUgZW5pZ2hfciRvY3VwYWNpb24pCiAgCiAgICBkYXRhPC0gZGF0YS5mcmFtZSgKICAgICAgICAgIGVkdV9hYz0gZGZoX2NuYSRwcF9lZHVjX2FjLAogICAgICAgICAgb2N1cGFjaW9uPSBkZmhfY25hJHBwX29jdXAsCiAgICAgICAgICBzZXhvID0gZGZoX2NuYSRwcF9zZXhvLAogICAgICAgICAgI2VkYWRfYyA9ICJFZGFkNCIKICAgICAgICAgIGVkYWQgPSAwI2RmaF9jbmEkcHBfZWRhZAogICAgICAgICkKICB9CiAgZWxzZXsKICAKICAgICMgcmVncmVzaW9uIHBhZHJlcyBjb21wbGV0YQogIAogICAgZW5pZ2hfciA8LWVuaWdoW3NhbXBsZShucm93KGVuaWdoKSxucm93KGVuaWdoKSwgcmVwbGFjZSA9IFRSVUUpLF0KICAKICAgIHJlZ19wYWRyZXM8LWxtKAogICAgZm9ybXVsYSA9IGZwLAogICAgZGF0YSA9IGVuaWdoX3IKICAgICkKICAgIAogICAgIyBkYXRhIGZyYW1lIGNvbXBsZXRvCiAgICAKICAgIGRmaF9jbmE8LWRmaF9jbmElPiVmaWx0ZXIocHBfb2N1cCAlaW4lIGVuaWdoX3Ikb2N1cGFjaW9uKQogIAogICAgZGF0YTwtIGRhdGEuZnJhbWUoCiAgICAgICAgICBlZHVfYWM9IGRmaF9jbmEkcHBfZWR1Y19hYywKICAgICAgICAgIG9jdXBhY2lvbj0gZGZoX2NuYSRwcF9vY3VwLAogICAgICAgICAgc2V4byA9IGRmaF9jbmEkcHBfc2V4bywKICAgICAgICAgICNlZGFkX2MgPSAiRWRhZDQiCiAgICAgICAgICBlZGFkID0gMCNkZmhfY25hJHBwX2VkYWQKICAgICAgICApCiAgfQoKICByZXR1cm4obGlzdChyZWdfcGFkcmVzLGRhdGEsZGZoX2NuYSkpCiAgCn0KCmlmKGNvZGU9PTEpewpkZmhfY25hIDwtIGRmaF9jbmElPiVmaWx0ZXIocmVnaW9uPT1yZWcpCn0KCgoKcDk0PC1yZWdyZXNpb25fcGFkcmVzKGVuaWdoXzk0LGRmaF9jbmEsY29kZSxyZWcpCnA5NjwtcmVncmVzaW9uX3BhZHJlcyhlbmlnaF85NixkZmhfY25hLGNvZGUscmVnKQpwOTg8LXJlZ3Jlc2lvbl9wYWRyZXMoZW5pZ2hfOTgsZGZoX2NuYSxjb2RlLHJlZykKCnJlZ19wOTQ8LXA5NFtbMV1dCmRhdGFfOTQ8LXA5NFtbMl1dCiNlbmlncl9wNDwtcDk0W1szXV0KZGZoXzk0PC1wOTRbWzNdXQoKcmVnX3A5NjwtcDk2W1sxXV0KZGF0YV85NjwtcDk2W1syXV0KI2VuaWdyX3A2PC1wOTZbWzNdXQpkZmhfOTY8LXA5NltbM11dCgpyZWdfcDk4PC1wOThbWzFdXQpkYXRhXzk4PC1wOThbWzJdXQojZW5pZ3JfcDg8LXA5OFtbM11dCmRmaF85ODwtcDk4W1szXV0KCmRmaF9jbmEgPC0gZGZoX2NuYSU+JWZpbHRlcigocHBfb2N1cCAlaW4lIGRmaF85NCRwcF9vY3VwKSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwcF9vY3VwICVpbiUgZGZoXzk2JHBwX29jdXApICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBwX29jdXAgJWluJSBkZmhfOTgkcHBfb2N1cCkgKQoKCmRhdGFfOTQ8LSBkYXRhXzk0JT4lZmlsdGVyKG9jdXBhY2lvbiAlaW4lIGRmaF9jbmEkcHBfb2N1cCkKZGF0YV85NjwtIGRhdGFfOTYlPiVmaWx0ZXIob2N1cGFjaW9uICVpbiUgZGZoX2NuYSRwcF9vY3VwKQpkYXRhXzk4PC0gZGF0YV85OCU+JWZpbHRlcihvY3VwYWNpb24gJWluJSBkZmhfY25hJHBwX29jdXApCgojcHJpbnQobnJvdyhkZmhfY25hKSkKCiMgQk9PU1RSQVAgaW5ncmVzbyBISUpPUwoKIyBjYWxjdWxhbW9zIGVsIGluZ3Jlc28gZGUgbG9zIGhpam9zIGNvbiBsb3MgZ2VtZWxvcwojIHJlLXNhbXBsZWFkb3MsIGFkZW1hcyBjb2RpZmljYW1vcyBsYSBvY3VwYWNpw7NuIGRlbCBoaWpvIGEgZG9zIGNhcmFjdGVyZXMKCmF1eHM8LWZ1bmN0aW9uKGspewogIHNhbXBsZShrLHNpemU9bGVuZ3RoKGspLHJlcGxhY2U9VFJVRSkKfQoKCgphdXhfaHJyPC1mdW5jdGlvbihpbmcpewogICNlcnJvcl9lPC0gYWJzKGluZ3Jlc29zX2UxNmEkbGluZ19tZW5fcGQgLSBpbmcpCiAgZXJyb3JfZTwtIGFicyhpbmdyZTE2MTgkbGluZ19tZW5fcGQgLSBpbmcpCiAgaW5kaWNlX2U8LW1hdGNoKG1pbihlcnJvcl9lKSxlcnJvcl9lKQogIGluZGljZV9lPC1pbmRpY2VfZVsxXQogICNyZXR1cm4ocnBfZTE2W2luZGljZV9lMTZdKjEwMCkKICByZXR1cm4ocnBfZTE2MThbaW5kaWNlX2VdKjEwMCkKfQoKCgpkZmhfY25hIDwtIGRmaF9jbmEgJT4lCiAgbXV0YXRlKAogICBvY3VfaGM9IHN1YnN0cmluZyhvY3VfaCwxLDIpLAogICBpbmdfaD11bmxpc3QobGFwcGx5KAogICAgICAgICAgICAgICAgICAgICAgbGFwcGx5KGluZ19oLGF1eHMpLAogICAgICAgICAgICAgICAgICAgICAgbWVhbgogICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKSwKICAgbGluZ19oID0gbG9nKGluZ19oKStsb2coSU4pLAogICBwbGluZ19oID0gdW5saXN0KGxhcHBseShsaW5nX2gsYXV4X2hycikpCiAgKQoKCiAgICAgI2RmaF9mPC1kZmhfY25hJT4lCiAgICAgICMgIG11dGF0ZShjb2hvcnRfZSA9IGlmZWxzZShpbmdfaDw9MjQwMCwxLAogICAgICAgICAjICAgICAgICAgICAgICAgICAgaWZlbHNlKGluZ19oPD00ODAwLDIsCiAgICAgICAgICMgICAgICAgICAgICAgICAgICBpZmVsc2UoaW5nX2g8PTcyMDAsMywKICAgICAgICAgIyAgICAgICAgICAgICAgICAgIGlmZWxzZShpbmdfaDw9MTIwMDAsNCxpZmVsc2UoaW5nX2g8PTI0MDAwLDUsNikpKSkpLAogICAgICAgICAjIGNvaG9ydF9kaWY9Y29ob3J0LWNvaG9ydF9lKQoKICAKICAgICAgI2RmaF9jbmEgICAKICAgICAjZGZoX2NuYSRvY3VfaGlqbyAKICAgICAgI2RmaF9jbmEkbGluZ19oCgogICAgICAjc3RyKHN1YnN0cihkZmhfY25hJG9jdV9oLDEsMikpCgogICAgICAjIGVzdGltYWNpw7NuIGluZ3Jlc28gcGFkcmVzCiAgICAgICMgaW5wdXRhbW9zIGFsIGhpam8gY29ycmVzcG9uZGllbnRlCgoKZXN0aW1hY2lvbl9wYWRyZXM8LWZ1bmN0aW9uKHJlZ19wYWRyZXMsZGF0YSxudW1fYmFzZSl7CgogIGF1eF9wcnI8LWZ1bmN0aW9uKGluZyxudW1fYmFzZSl7CiAgICBlcnJvcl9lPC0gYWJzKGJhc2VfbG9nc2luZ1tbbnVtX2Jhc2VdXSRsaW5nX21lbl9wZCAtIGluZykKICAgIGluZGljZV9lPC1tYXRjaChtaW4oZXJyb3JfZSksZXJyb3JfZSkKICAgIGluZGljZV9lPC1pbmRpY2VfZVsxXQogICAgcmV0dXJuKGJhc2VfcnBbW251bV9iYXNlXV1baW5kaWNlX2VdKjEwMCkKICB9CiAgCiAgbGluZ19wZiA8LSBwcmVkaWN0KAogICAgICAgICAgICBvYmplY3QgPSByZWdfcGFkcmVzLCAgIAogICAgICAgICAgICBuZXdkYXRhID0gZGF0YQogICAgICAgICAgKQogIAogIHBsaW5nX3BmIDwtIHVubGlzdChsYXBwbHkobGluZ19wZixhdXhfcHJyLG51bV9iYXNlKSkKICAKICByZXR1cm4obGlzdChsaW5nX3BmLHBsaW5nX3BmKSkKfQoKZXN0MSA8LSBlc3RpbWFjaW9uX3BhZHJlcyhyZWdfcDk0LGRhdGFfOTQsMSkKZXN0MiA8LSBlc3RpbWFjaW9uX3BhZHJlcyhyZWdfcDk2LGRhdGFfOTYsMikKZXN0MyA8LSBlc3RpbWFjaW9uX3BhZHJlcyhyZWdfcDk4LGRhdGFfOTgsMykKCgptbGluZzwtKGVzdDFbWzFdXSArIGVzdDJbWzFdXSArIGVzdDNbWzFdXSkvMwojbWxpbmcxPC1lc3QxW1sxXV0KI21saW5nMjwtZXN0MltbMV1dCiNtbGluZzM8LWVzdDNbWzFdXQogIAptcGxpbmc8LShlc3QxW1syXV0gKyBlc3QyW1syXV0rIGVzdDNbWzJdXSkvMwoKI3ByaW50KCItLS0tIikKI3ByaW50KGxlbmd0aChlc3QxW1sxXV0pKQojcHJpbnQobGVuZ3RoKGVzdDJbWzFdXSkpCiNwcmludChsZW5ndGgoZXN0M1tbMV1dKSkKCmRmaHBmPC0gZGZoX2NuYSU+JQogICAgICAgIG11dGF0ZSgKICAgICAgICAgIGxpbmdfcCA9IG1saW5nLAogICAgICAgICAgcGxpbmdfcCA9IG1wbGluZwogICAgICAgICkKCgojIEJvb3N0cmFwIGhpam9zCmRmaHBmPC1kZmhwZltzYW1wbGUobnJvdyhkZmhwZiksbnJvdyhkZmhwZiksIHJlcGxhY2UgPSBUUlVFKSxdCiAgCiAgCnJlZ19ocCA8LSBsbSgKICAgICAgICAgICAgZm9ybXVsYSA9ZmhwICwjKyBvY3VfaGMsCiAgICAgICAgICAgIGRhdGEgPSBkZmhwZgogICAgICAgICAgKSAKICAgICAgICAgICAgICAgICNwcmludChkZmhwZiRwbGluZ19oKQogICAgICAgICAgICAgICAgI3ByaW50KGRmaHBmJHBsaW5nX3ApCiAgICAgICAgICAgICAgICAjZGF0YS5mcmFtZShkZmhwZiRwbGluZ19oLGRmaHBmJHBsaW5nX3ApCiAKcmVnX2hwciA8LSBsbSgKICAgICAgICAgICAgZm9ybXVsYSA9IHBsaW5nX2ggfiBwbGluZ19wLAogICAgICAgICAgICBkYXRhID0gZGZocGYKICAgICAgICAgICkKICAgICAgICAgICAgICAgIyBwbG90KGRmaHBmJHBsaW5nX3AsZGZocGYkcGxpbmdfaCwKICAgICAgICAgICAgICAgICMgICAgIHhsaW09YygwLCAxMDApKSAKICAgICAgICAgICAgICAgICNsaW5lcygxOjEwMCwxOjEwMCkKCgoKICAgICAgICAgICAgICAgICNzdW1tYXJ5KHJlZ19ocCkKYmV0YTA8LSByZWdfaHAkY29lZmZpY2llbnRzWzFdCmJldGEgPC0gcmVnX2hwJGNvZWZmaWNpZW50c1syXQpzZXhvaDwtIHJlZ19ocCRjb2VmZmljaWVudHNbM10KZWRhZGg8LSByZWdfaHAkY29lZmZpY2llbnRzWzRdCmVkYWQyaDwtcmVnX2hwJGNvZWZmaWNpZW50c1s1XQpiZXRhciA8LSByZWdfaHByJGNvZWZmaWNpZW50c1syXQphbGZhciA8LSByZWdfaHByJGNvZWZmaWNpZW50c1sxXQpuaGlqb3M8LW5yb3coZGZoX2NuYSkKICAgICAgICAgICMgY29ob3J0X2RpZjwtYXMuaW50ZWdlcihkZmhwZiU+JWNvdW50KGNvaG9ydF9kaWYpJT4lCiAgICAgICAgICAjICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjb2hvcnRfZGlmPT0wKSU+JQogICAgICAgICAgIyAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobikpCgoKcmV0dXJuKGRhdGEuZnJhbWUoKSU+JQogICAgICAgICBzdW1tYXJpc2UoCiAgICAgICAgICAgICNjb2hvcnRfZGlmPWxpc3QoZGZoX2YkY29ob3J0X2RpZiksCiAgICAgICAgICAgIGJldGEwID0gYmV0YTAsCiAgICAgICAgICAgIGJldGEgPSBiZXRhLAogICAgICAgICAgICBzZXhvaCA9IHNleG9oLAogICAgICAgICAgICBlZGFkaCA9IGVkYWRoLAogICAgICAgICAgICBlZGFkMmggPSBlZGFkMmgsCiAgICAgICAgICAgIGJldGFyID0gYmV0YXIsCiAgICAgICAgICAgIGFsZmFyID0gYWxmYXIsCiAgICAgICAgICAgIG5oaWpvcyA9IG5oaWpvcywKICAgICAgICAgICAgY29lZmljaWVudGUgPSBsaXN0KHJlZ19ocCRjb2VmZmljaWVudHMpLAogICAgICAgICAgICBjb2VmaWNpZW50ZXIgPSBsaXN0KHJlZ19ocHIkY29lZmZpY2llbnRzKSwKICAgICAgICAgICAgI3Bfc29jdSA9IHBfc29jdSwKICAgICAgICAgICAgcmVncmVzaW9ucDk0ID0gbGlzdChyZWdfcDk0KSwKICAgICAgICAgICAgcmVncmVzaW9ucDk2ID0gbGlzdChyZWdfcDk2KSwKICAgICAgICAgICAgcmVncmVzaW9ucDk4ID0gbGlzdChyZWdfcDk4KSwKICAgICAgICAgICAgcmVncmVzaW9uID0gbGlzdChyZWdfaHApLAogICAgICAgICAgICByZWdyZXNpb25yID0gbGlzdChyZWdfaHByKQogICAgICAgICkKICAgICAgKQoKfQoKCmBgYAoKCgojIyBFc3RpbWFjacOybiBpbmRpdmlkdWFsCgpgYGB7ciBmdW5fcHJpbl9laWlpfQplaWlpPC1mdW5jdGlvbihpLGZwLGZocCxlbmksY29kZT0wLHJlZz0wKXsKI2VuaWdoXzk4IDwtIHJlYWRSRFMoZmlsZSA9ICJEYXRvcy9lbmlnaF85OC5SZGEiKQojZGZoX2MgPC0gcmVhZFJEUyhmaWxlID0gIkRhdG9zL2RmaF9jLlJkYSIpCiNmcCA9IGxpbmdfbWVuX3AgfiBlZHVfYWMgKyBvY3VwYWNpb24gKyBlZGFkICsgSShlZGFkKmVkYWQpCiNmaHAgPSBsaW5nX2ggfiBsaW5nX3AgKyBlZGFkX2grIEkoZWRhZF9oKmVkYWRfaCkKI3JlZzwtMQojY29kZTwtMQojcHJpbnQocmVnKQojIEJPT1NUUkFQICAKIyBSZWdyZXNpw7NuIGRlIGluZ3Jlc29zIGRlIHBhZHJlcyAgCiNzdW1tYXJ5KHJlZ19wYWRyZXMpCgojIG51bWVybyBkZSBwYWRyZXMgc2luIG9jdXBhY2nDs24gcmVwb3J0YWRhIGRlIGhpam9zCiNwX3NvY3U8LXN1bShpcy5uYShkZmhfYyRwcF9vY3VwKSkKCnJlZ3Jlc2lvbl9wYWRyZXM8LWZ1bmN0aW9uKGVuaWdoLGRmaF9jbmEsY29kZT1jb2RlLHJlZz1yZWcpewogIGlmKGNvZGU9PTEpewoKICAgICMgcmVncmVzaW9uIHBhZHJlcyAgcG9yIHJlZ2lvbgogIAogICAgZW5pZ2g8LWVuaWdoJT4lZmlsdGVyKHJlZ2lvbj09cmVnKQogICAgZW5pZ2hfciA8LWVuaWdoW3NhbXBsZShucm93KGVuaWdoKSxucm93KGVuaWdoKSwgcmVwbGFjZSA9IFRSVUUpLF0KCiAgICByZWdfcGFkcmVzPC1sbSgKICAgIGZvcm11bGEgPSBmcCwKICAgIGRhdGEgPSBlbmlnaF9yCiAgICApCiAgICAKICAgICMgZGF0YSBmcmFtZSByZWdpb24KICAgIAogICAgZGZoX2NuYTwtZGZoX2NuYSU+JWZpbHRlcihwcF9vY3VwICVpbiUgZW5pZ2hfciRvY3VwYWNpb24pCiAgCiAgICBkYXRhPC0gZGF0YS5mcmFtZSgKICAgICAgICAgIGVkdV9hYz0gZGZoX2NuYSRwcF9lZHVjX2FjLAogICAgICAgICAgb2N1cGFjaW9uPSBkZmhfY25hJHBwX29jdXAsCiAgICAgICAgICBzZXhvID0gZGZoX2NuYSRwcF9zZXhvLAogICAgICAgICAgZWRhZCA9IGRmaF9jbmEkcHBfZWRhZCAKICAgICAgICApCiAgfQogIGVsc2V7CiAgCiAgICAjIHJlZ3Jlc2lvbiBwYWRyZXMgY29tcGxldGEKICAKICAgIGVuaWdoX3IgPC1lbmlnaFtzYW1wbGUobnJvdyhlbmlnaCksbnJvdyhlbmlnaCksIHJlcGxhY2UgPSBUUlVFKSxdCiAgCiAgICByZWdfcGFkcmVzPC1sbSgKICAgIGZvcm11bGEgPSBmcCwKICAgIGRhdGEgPSBlbmlnaF9yCiAgICApCiAgICAKICAgICMgZGF0YSBncmFtZSBjb21wbGV0bwogICAgCiAgICBkZmhfY25hPC1kZmhfY25hJT4lZmlsdGVyKHBwX29jdXAgJWluJSBlbmlnaF9yJG9jdXBhY2lvbikKICAKICAgIGRhdGE8LSBkYXRhLmZyYW1lKAogICAgICAgICAgZWR1X2FjPSBkZmhfY25hJHBwX2VkdWNfYWMsCiAgICAgICAgICBvY3VwYWNpb249IGRmaF9jbmEkcHBfb2N1cCwKICAgICAgICAgIHNleG8gPSBkZmhfY25hJHBwX3NleG8sCiAgICAgICAgICBlZGFkID0gZGZoX2NuYSRwcF9lZGFkIAogICAgICAgICkKICB9CgogIHJldHVybihsaXN0KHJlZ19wYWRyZXMsZGF0YSxkZmhfY25hKSkKICAKfQoKaWYoY29kZT09MSl7CmRmaF9jbmEgPC0gZGZoX2NuYSU+JWZpbHRlcihyZWdpb249PXJlZykKfQoKCmlmKGVuaT09OTQpewplbmlnaCA8LSBlbmlnaF85NApudW1fYmFzZSA8LSAxCn0KCmlmKGVuaT09OTYpewplbmlnaCA8LSBlbmlnaF85NgpudW1fYmFzZSA8LSAyCn0KCmlmKGVuaT09OTgpewplbmlnaCA8LSBlbmlnaF85OApudW1fYmFzZSA8LSAzCn0KCiAgCnA8LXJlZ3Jlc2lvbl9wYWRyZXMoZW5pZ2gsZGZoX2NuYSxjb2RlLHJlZykKCnJlZ19wPC1wW1sxXV0KZGF0YTwtcFtbMl1dCmRmaF9jbmE8LXBbWzNdXQoKCmF1eHM8LWZ1bmN0aW9uKGspewogIHNhbXBsZShrLHNpemU9bGVuZ3RoKGspLHJlcGxhY2U9VFJVRSkKfQoKCgphdXhfaHJyPC1mdW5jdGlvbihpbmcpewogICNlcnJvcl9lPC0gYWJzKGluZ3Jlc29zX2UxNmEkbGluZ19tZW5fcGQgLSBpbmcpCiAgZXJyb3JfZTwtIGFicyhpbmdyZTE2MTgkbGluZ19tZW5fcGQgLSBpbmcpCiAgaW5kaWNlX2U8LW1hdGNoKG1pbihlcnJvcl9lKSxlcnJvcl9lKQogIGluZGljZV9lPC1pbmRpY2VfZVsxXQogICNyZXR1cm4ocnBfZTE2W2luZGljZV9lXSoxMDApCiAgcmV0dXJuKHJwX2UxNjE4W2luZGljZV9lXSoxMDApCn0KCgojIEJPT1NUUkFQIGluZ3Jlc28gSElKT1MKCiMgY2FsY3VsYW1vcyBlbCBpbmdyZXNvIGRlIGxvcyBoaWpvcyBjb24gbG9zIGdlbWVsb3MKIyByZS1zYW1wbGVhZG9zLCBhZGVtYXMgY29kaWZpY2Ftb3MgbGEgb2N1cGFjacOzbiBkZWwgaGlqbyBhIGRvcyBjYXJhY3RlcmVzCgpkZmhfY25hIDwtIGRmaF9jbmEgJT4lCiAgbXV0YXRlKAogICBvY3VfaGM9IHN1YnN0cmluZyhvY3VfaCwxLDIpLAogICBpbmdfaD11bmxpc3QobGFwcGx5KAogICAgICAgICAgICAgICAgICAgICAgbGFwcGx5KGluZ19oLGF1eHMpLAogICAgICAgICAgICAgICAgICAgICAgbWVhbgogICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKSwKICAgbGluZ19oID0gbG9nKGluZ19oKStsb2coSU4pLAogICBwbGluZ19oID0gdW5saXN0KGxhcHBseShsaW5nX2gsYXV4X2hycikpCiAgKQoKCiAgICAgI2RmaF9mPC1kZmhfY25hJT4lCiAgICAgICMgIG11dGF0ZShjb2hvcnRfZSA9IGlmZWxzZShpbmdfaDw9MjQwMCwxLAogICAgICAgICAjICAgICAgICAgICAgICAgICAgaWZlbHNlKGluZ19oPD00ODAwLDIsCiAgICAgICAgICMgICAgICAgICAgICAgICAgICBpZmVsc2UoaW5nX2g8PTcyMDAsMywKICAgICAgICAgIyAgICAgICAgICAgICAgICAgIGlmZWxzZShpbmdfaDw9MTIwMDAsNCxpZmVsc2UoaW5nX2g8PTI0MDAwLDUsNikpKSkpLAogICAgICAgICAjIGNvaG9ydF9kaWY9Y29ob3J0LWNvaG9ydF9lKQoKICAKICAgICAgI2RmaF9jbmEgICAKICAgICAjZGZoX2NuYSRvY3VfaGlqbyAKICAgICAgI2RmaF9jbmEkbGluZ19oCgogICAgICAjc3RyKHN1YnN0cihkZmhfY25hJG9jdV9oLDEsMikpCgogICAgICAjIGVzdGltYWNpw7NuIGluZ3Jlc28gcGFkcmVzCiAgICAgICMgaW5wdXRhbW9zIGFsIGhpam8gY29ycmVzcG9uZGllbnRlCgoKZXN0aW1hY2lvbl9wYWRyZXM8LWZ1bmN0aW9uKHJlZ19wYWRyZXMsZGF0YSxudW1fYmFzZSl7CgogIGF1eF9wcnI8LWZ1bmN0aW9uKGluZyxudW1fYmFzZSl7CiAgICBlcnJvcl9lPC0gYWJzKGJhc2VfbG9nc2luZ1tbbnVtX2Jhc2VdXSRsaW5nX21lbl9wZCAtIGluZykKICAgIGluZGljZV9lPC1tYXRjaChtaW4oZXJyb3JfZSksZXJyb3JfZSkKICAgIGluZGljZV9lPC1pbmRpY2VfZVsxXQogICAgcmV0dXJuKGJhc2VfcnBbW251bV9iYXNlXV1baW5kaWNlX2VdKjEwMCkKICB9CiAgCiAgbGluZ19wZiA8LSBwcmVkaWN0KAogICAgICAgICAgICBvYmplY3QgPSByZWdfcGFkcmVzLCAgIAogICAgICAgICAgICBuZXdkYXRhID0gZGF0YQogICAgICAgICAgKQogIAogIHBsaW5nX3BmIDwtIHVubGlzdChsYXBwbHkobGluZ19wZixhdXhfcHJyLG51bV9iYXNlKSkKICAKICByZXR1cm4obGlzdChsaW5nX3BmLHBsaW5nX3BmKSkKfQoKZXN0IDwtIGVzdGltYWNpb25fcGFkcmVzKHJlZ19wLGRhdGEsbnVtX2Jhc2UpCgoKbWxpbmc8LWVzdFtbMV1dCgptcGxpbmc8LWVzdFtbMl1dIAoKCmRmaHBmPC0gZGZoX2NuYSU+JQogICAgICAgIG11dGF0ZSgKICAgICAgICAgIGxpbmdfcCA9IG1saW5nLAogICAgICAgICAgcGxpbmdfcCA9IG1wbGluZwogICAgICAgICkKCgojIEJvb3N0cmFwIGhpam9zCmRmaHBmPC1kZmhwZltzYW1wbGUobnJvdyhkZmhwZiksbnJvdyhkZmhwZiksIHJlcGxhY2UgPSBUUlVFKSxdCiAgCiAgCnJlZ19ocCA8LSBsbSgKICAgICAgICAgICAgZm9ybXVsYSA9ZmhwICwjKyBvY3VfaGMsCiAgICAgICAgICAgIGRhdGEgPSBkZmhwZgogICAgICAgICAgKSAKICAgICAgICAgICAgICAgICNwcmludChkZmhwZiRwbGluZ19oKQogICAgICAgICAgICAgICAgI3ByaW50KGRmaHBmJHBsaW5nX3ApCiAgICAgICAgICAgICAgICAjZGF0YS5mcmFtZShkZmhwZiRwbGluZ19oLGRmaHBmJHBsaW5nX3ApCiAKcmVnX2hwciA8LSBsbSgKICAgICAgICAgICAgZm9ybXVsYSA9IHBsaW5nX2ggfiBwbGluZ19wLAogICAgICAgICAgICBkYXRhID0gZGZocGYKICAgICAgICAgICkKICAgICAgICAgICAgICAgICMgcGxvdChkZmhwZiRwbGluZ19wLGRmaHBmJHBsaW5nX2gsCiAgICAgICAgICAgICAgICAjICAgICAgeGxpbT1jKDAsIDEwMCkpIAogICAgICAgICAgICAgICAgIyAgbGluZXMoMToxMDAsMToxMDApCgoKCiAgICAgICAgICAgICAgICAjc3VtbWFyeShyZWdfaHApCgpiZXRhIDwtIHJlZ19ocCRjb2VmZmljaWVudHNbMl0KYmV0YXIgPC0gcmVnX2hwciRjb2VmZmljaWVudHNbMl0KYWxmYXIgPC0gcmVnX2hwciRjb2VmZmljaWVudHNbMV0KICAgICAgICAgICMgY29ob3J0X2RpZjwtYXMuaW50ZWdlcihkZmhwZiU+JWNvdW50KGNvaG9ydF9kaWYpJT4lCiAgICAgICAgICAjICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjb2hvcnRfZGlmPT0wKSU+JQogICAgICAgICAgIyAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobikpCgoKcmV0dXJuKGRhdGEuZnJhbWUoKSU+JQogICAgICAgICBzdW1tYXJpc2UoCiAgICAgICAgICAgICNjb2hvcnRfZGlmPWxpc3QoZGZoX2YkY29ob3J0X2RpZiksCiAgICAgICAgICAgIGJldGE9YmV0YSwKICAgICAgICAgICAgYmV0YXIgPSBiZXRhciwKICAgICAgICAgICAgYWxmYXIgPSBhbGZhciwKICAgICAgICAgICAgY29lZmljaWVudGUgPSBsaXN0KHJlZ19ocCRjb2VmZmljaWVudHMpLAogICAgICAgICAgICBjb2VmaWNpZW50ZXIgPSBsaXN0KHJlZ19ocHIkY29lZmZpY2llbnRzKSwKICAgICAgICAgICAgI3Bfc29jdSA9IHBfc29jdSwKICAgICAgICAgICAgcmVncmVzaW9ucCA9IGxpc3QocmVnX3ApLAogICAgICAgICAgICByZWdyZXNpb25ocCA9IGxpc3QocmVnX2hwKSwKICAgICAgICAgICAgcmVncmVzaW9uaHByID0gbGlzdChyZWdfaHByKQogICAgICAgICkKICAgICAgKQoKfQoKCmBgYAoKCgojIyBGdW5jaW9uZXMgYXJhIHJlZ3Jlc2lvbgoKYGBge3IgZnVuX3ByaW5fZWlpIGZuY29uZXN9CgpyZWdyZV9jb21wbGV0YTwtZnVuY3Rpb24oYm9vdD0xMDAwKXsKICBmcCA8LSBsaW5nX21lbl9wIH4gZWR1X2FjICsgb2N1cGFjaW9uICsgc2V4byArIGVkYWQgKyBJKGVkYWQqZWRhZCkKICBmaHA8LSBsaW5nX2ggfiBsaW5nX3AgICsgc2V4b19oICAgIysgZWRhZF9oICsgSShlZGFkX2gqZWRhZF9oKS0xCiAgc2V0LnNlZWQoMTIzKQogIGE8LWxhcHBseSgxOmJvb3QsZWlpLGZwLGZocCxjb2RlPTApCiAgcmVzdWw8LWJpbmRfcm93cyhhWzE6bGVuZ3RoKGEpXSkKICAKICBwcmludCgiYmV0YSBjZXJvIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJGJldGEwKSkKICBwcmludCgiYmV0YSBjZXJvIHNkIikKICBwcmludChzZChyZXN1bCRiZXRhMCkpCiAgCiAgcHJpbnQoImJldGEgbWVkaWEiKQogIHByaW50KG1lYW4ocmVzdWwkYmV0YSkpCiAgcHJpbnQoImJldGEgc2QiKQogIHByaW50KHNkKHJlc3VsJGJldGEpKQogIAogIHByaW50KCJzZXhvIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJHNleG9oKSkKICBwcmludCgic2V4byBzZCIpCiAgcHJpbnQoc2QocmVzdWwkc2V4b2gpKQogIAogIHByaW50KCJlZGFkIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJGVkYWRoKSkKICBwcmludCgiZWRhZCBzZCIpCiAgcHJpbnQoc2QocmVzdWwkZWRhZGgpKQogIAogIHByaW50KCJlZGFkLTIgbWVkaWEiKQogIHByaW50KG1lYW4ocmVzdWwkZWRhZDJoKSkKICBwcmludCgiZWRhZC0yIHNkIikKICBwcmludChzZChyZXN1bCRlZGFkMmgpKQogIAogIHByaW50KCJiZXRhciBtZWRpYSIpCiAgcHJpbnQobWVhbihyZXN1bCRiZXRhcikpCiAgcHJpbnQoImJldGFyIHNkIikKICBwcmludChzZChyZXN1bCRiZXRhcikpCiAgCiAgcHJpbnQoImFsZmFyIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJGFsZmFyKSkKICBwcmludCgiYWxmYXIgc2QiKQogIHByaW50KHNkKHJlc3VsJGFsZmFyKSkKICAKICBoaXN0KHJlc3VsJGJldGEpCiAgaGlzdChyZXN1bCRiZXRhcikKICByZXR1cm4ocmVzdWwpCn0KCnJlZ3JlX2NvbXBsZXRhX2luZDwtZnVuY3Rpb24oZW5pLGJvb3Q9MTAwMCl7CiAgZnAgPC0gbGluZ19tZW5fcCB+IGVkdV9hYyArIG9jdXBhY2lvbiArIHNleG8gKyBlZGFkICsgSShlZGFkKmVkYWQpCiAgZmhwPC0gbGluZ19oIH4gbGluZ19wICArIHNleG9faCAjKyBlZGFkX2ggK0koZWRhZF9oKmVkYWRfaCkKICBzZXQuc2VlZCgxMjMpCiAgYTwtbGFwcGx5KDE6Ym9vdCxlaWlpLGZwLGZocCxlbmksY29kZT0wKQogIHJlc3VsPC1iaW5kX3Jvd3MoYVsxOmxlbmd0aChhKV0pCiAgcHJpbnQoImJldGEgbWVkaWEiKQogIHByaW50KG1lYW4ocmVzdWwkYmV0YSkpCiAgcHJpbnQoImJldGEgc2QiKQogIHByaW50KHNkKHJlc3VsJGJldGEpKQogIHByaW50KCJiZXRhciBtZWRpYSIpCiAgcHJpbnQobWVhbihyZXN1bCRiZXRhcikpCiAgcHJpbnQoImJldGFyIHNkIikKICBwcmludChzZChyZXN1bCRiZXRhcikpCiAgcHJpbnQoImFsZmFyIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJGFsZmFyKSkKICBwcmludCgiYWxmYXIgc2QiKQogIHByaW50KHNkKHJlc3VsJGFsZmFyKSkKICBoaXN0KHJlc3VsJGJldGEpCiAgaGlzdChyZXN1bCRiZXRhcikKICByZXR1cm4ocmVzdWwpCn0KCgpyZWdyZV9yZWdpb248LWZ1bmN0aW9uKHIsIGJvb3QgPSAxMDAwKXsKICBmcHIgPC0gbGluZ19tZW5fcCB+IGVkdV9hYyArIG9jdXBhY2lvbiArIHNleG8gICsgZWRhZCArIEkoZWRhZCplZGFkKQogIGZocHI8LSBsaW5nX2ggfiBsaW5nX3AgICArIHNleG9faCArIGVkYWRfaCAjKyBJKGVkYWRfaCplZGFkX2gpCiAgc2V0LnNlZWQoMTIzKQogIGE8LWxhcHBseSgxOmJvb3QsZWlpLGZwcixmaHByLGNvZGU9MSwgcmVnPXIpCiAgcmVzdWw8LWJpbmRfcm93cyhhWzE6bGVuZ3RoKGEpXSkKICBwcmludCgiYmV0YSBtZWRpYSIpCiAgcHJpbnQobWVhbihyZXN1bCRiZXRhKSkKICBwcmludCgiYmV0YSBzZCIpCiAgcHJpbnQoc2QocmVzdWwkYmV0YSkpCiAgcHJpbnQoImJldGFyIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJGJldGFyKSkKICBwcmludCgiYmV0YXIgc2QiKQogIHByaW50KHNkKHJlc3VsJGJldGFyKSkKICBwcmludCgiYWxmYXIgbWVkaWEiKQogIHByaW50KG1lYW4ocmVzdWwkYWxmYXIpKQogIHByaW50KCJhbGZhciBzZCIpCiAgcHJpbnQoc2QocmVzdWwkYWxmYXIpKQoKICBoaXN0KHJlc3VsJGJldGEpCiAgaGlzdChyZXN1bCRiZXRhcikKICByZXR1cm4ocmVzdWwpCn0KCnJlZ3JlX3JlZ2lvbl9pbmQ8LWZ1bmN0aW9uKHIsZW5pLCBib290ID0gMTAwMCl7CiAgZnByIDwtIGxpbmdfbWVuX3AgfiBlZHVfYWMgKyBvY3VwYWNpb24gKyBzZXhvICArIGVkYWQgKyBJKGVkYWQqZWRhZCkKICBmaHByPC0gbGluZ19oIH4gbGluZ19wICAgKyBzZXhvX2ggIysgZWRhZF9oICsgSShlZGFkX2gqZWRhZF9oKQogIHNldC5zZWVkKDEyMykKICBhPC1sYXBwbHkoMTpib290LGVpaWksZnByLGZocHIsZW5pLGNvZGU9MSwgcmVnPXIpCiAgcmVzdWw8LWJpbmRfcm93cyhhWzE6bGVuZ3RoKGEpXSkKICBwcmludCgiYmV0YSBtZWRpYSIpCiAgcHJpbnQobWVhbihyZXN1bCRiZXRhKSkKICBwcmludCgiYmV0YSBzZCIpCiAgcHJpbnQoc2QocmVzdWwkYmV0YSkpCiAgcHJpbnQoImJldGFyIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJGJldGFyKSkKICBwcmludCgiYmV0YXIgc2QiKQogIHByaW50KHNkKHJlc3VsJGJldGFyKSkKICBwcmludCgiYWxmYXIgbWVkaWEiKQogIHByaW50KG1lYW4ocmVzdWwkYWxmYXIpKQogIHByaW50KCJhbGZhciBzZCIpCiAgcHJpbnQoc2QocmVzdWwkYWxmYXIpKQoKICBoaXN0KHJlc3VsJGJldGEpCiAgaGlzdChyZXN1bCRiZXRhcikKICByZXR1cm4ocmVzdWwpCn0KCnJlZ3JlX3JlZ2lvbl9yZWw8LWZ1bmN0aW9uKHJlZ2k9MCxib290ID0gMTAwMCl7CiAgZnByIDwtIGxpbmdfbWVuX3AgfiBlZHVfYWMgKyBvY3VwYWNpb24gKyBzZXhvICsgcG9seSgoZWRhZC0zMCksMiktMQogIGZocHI8LSBsaW5nX2ggfiBsaW5nX3AgICArIHBvbHkoKGVkYWRfaC0yNSksMikKICBzZXQuc2VlZCgxMjMpCiAgYTwtbGFwcGx5KDE6Ym9vdCxlaWksZnByLGZocHIsY29kZT0xLCByZWc9cmVnaSwgcmVsPTEpCiAgcmVzdWw8LWJpbmRfcm93cyhhWzE6bGVuZ3RoKGEpXSkKICBwcmludCgiYmV0YSBtZWRpYSIpCiAgcHJpbnQobWVhbihyZXN1bCRiZXRhKSkKICBwcmludCgiYmV0YSBzZCIpCiAgcHJpbnQoc2QocmVzdWwkYmV0YSkpCiAgcHJpbnQoImJldGFyIG1lZGlhIikKICBwcmludChtZWFuKHJlc3VsJGJldGFyKSkKICBwcmludCgiYmV0YXIgc2QiKQogIHByaW50KHNkKHJlc3VsJGJldGFyKSkKICBoaXN0KHJlc3VsJGJldGEpCiAgaGlzdChyZXN1bCRiZXRhcikKICByZXR1cm4ocmVzdWwpCn0KCiMgUmFuZ28gcGVyY2VudGlsOiBlbCBwb3JjZW50YWplIGRlIHB1bnR1YWNpb25lcyBlbiB1bmEgZGlzdHJpYnVjacOzbiBkZSBwdW50dWFjacOzbiBlc3BlY2lmaWNhZGEgcXVlIGVzdMOhbiBwb3IgZGViYWpvIGRlIHVuYSBwdW50dWFjacOzbiBkZXRlcm1pbmFkYS4KIyBodHRwczovL3d3dy5tYXRoLmZzdS5lZHUvfndvb2xhbmQvaG0yZWQvUGFydDNNb2R1bGUxL3ByVnNOdGguaHRtbAoKCmBgYAoKCgojICBDcml0ZXJpb3MKCiMgVG90YWwgcHJvbWVkaW8sIGNyaXRlcmlvIHByaW5jaXBhbAoKYGBge3J9CnJlZ19jcF8xMDAgPC0gcmVncmVfY29tcGxldGEoMjApCmBgYAoKYGBge3J9CnNhdmVSRFMocmVnX2NwXzEwMCwgZmlsZT0iRGF0b3MvUmVncmVzaW9uZXMvcmVnX2NwXzEwMC5SZGEiKQpgYGAKCgojIFRvdGFsIHByb21lZGlvLCBjcml0ZXJpbyBkb3MKCmBgYHtyfQpyZWdfY2RfMTAwIDwtIHJlZ3JlX2NvbXBsZXRhKDEwMCkKI3JlZ19jZF8xMDBwIDwtIHJlZ3JlX2NvbXBsZXRhKDEwMCkKYGBgCgoKYGBge3J9CnNhdmVSRFMocmVnX2NkXzEwMCwgZmlsZT0iRGF0b3MvUmVncmVzaW9uZXMvcmVnX2NkXzEwMC5SZGEiKQpgYGAKCiMgVG90YWwgaW5kaXZpZHVhbCwgY3JpdGVyaW8gcHJpbmNpcGFsCgoKYGBge3J9CnJlZ19jcF85ODEwMDwtcmVncmVfY29tcGxldGFfaW5kKDk4LDEwMCkKYGBgCgpgYGB7cn0Kc2F2ZVJEUyhyZWdfY3BfOTQxMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19jcDEwMF85NC5SZGEiKQpzYXZlUkRTKHJlZ19jcF85NjEwMCwgZmlsZT0iRGF0b3MvUmVncmVzaW9uZXMvcmVnX2NwMTAwXzk2LlJkYSIpCnNhdmVSRFMocmVnX2NwXzk4MTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfY3AxMDBfOTguUmRhIikKYGBgCgoKYGBge3J9CiNvYnRlbmVyIGxvcyBkYXRvc28gZGUgbG9zIG1vZGVsb3MgeWEgZXN0YWJsZWNpZG9zIAp6PC1yZWdfY3BfOTYkcmVncmVzaW9uaHByWzFdW1sxXV0KY2xhc3MoeikKCmF1Z21lbnQoeikKCmBgYAoKIyBUb3RhbCBpbmRpdmlkdWFsLCBjcml0ZXJpbyBEb3MKCgpgYGB7cn0KcmVnX2NkXzk0MTAwPC1yZWdyZV9jb21wbGV0YV9pbmQoMTAwKQoKcmVnX2NkXzk2MTAwPC1yZWdyZV9jb21wbGV0YV9pbmQoOTYsMTAwKQoKcmVnX2NkXzk4MTAwPC1yZWdyZV9jb21wbGV0YV9pbmQoMTAwKQoKCmBgYAoKYGBge3J9CnNhdmVSRFMocmVnX2NkXzk0MTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfY2QxMDBfOTQuUmRhIikKc2F2ZVJEUyhyZWdfY2RfOTYxMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19jZDEwMF85Ni5SZGEiKQpzYXZlUkRTKHJlZ19jZF85ODEwMCwgZmlsZT0iRGF0b3MvUmVncmVzaW9uZXMvcmVnX2NkMTAwXzk4LlJkYSIpCmBgYAoKCmBgYHtyfQojb2J0ZW5lciBsb3MgZGF0b3NvIGRlIGxvcyBtb2RlbG9zIHlhIGVzdGFibGVjaWRvcyAKejwtcmVnX2NwXzk2JHJlZ3Jlc2lvbmhwclsxXVtbMV1dCmNsYXNzKHopCgphdWdtZW50KHopCgpgYGAKCgojIFJlZ2lvbiBwcm9tZWRpbywgIGNyaXRlcmlvIHByaW5jaXBhbAoKCgpgYGB7cn0KCnJlZ19yZWcxX2NwXzEwMDwtcmVncmVfcmVnaW9uKDEsMTAwKQpyZWdfcmVnMl9jcF8xMDA8LXJlZ3JlX3JlZ2lvbigyLDEwMCkKcmVnX3JlZzNfY3BfMTAwPC1yZWdyZV9yZWdpb24oMywxMDApCnJlZ19yZWc0X2NwXzEwMDwtcmVncmVfcmVnaW9uKDQsMTAwKQoKI3N1bW1hcnkocmVnX3JlZzFfY29tYmluYWRhX3NleG9fY3JpM19yMTYxNyRyZWdyZXNpb25bWzEwXV0pIyByZWdyZXNpb25wW1sxMF1dKQoKCmBgYAoKCgpgYGB7cn0Kc2F2ZVJEUyhyZWdfcmVnMV9jcF8xMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19yZWcxX2NwXzEwMC5SZGEiKQpzYXZlUkRTKHJlZ19yZWcyX2NwXzEwMCwgZmlsZT0iRGF0b3MvUmVncmVzaW9uZXMvcmVnX3JlZzJfY3BfMTAwLlJkYSIpCnNhdmVSRFMocmVnX3JlZzNfY3BfMTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfcmVnM19jcF8xMDAuUmRhIikKc2F2ZVJEUyhyZWdfcmVnNF9jcF8xMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19yZWc0X2NwXzEwMC5SZGEiKQoKYGBgCgoKCmBgYHtyfQpkZjwtcmVnX3JlZzFfY3BfMTAwCnIxPC0gZGF0YS5mcmFtZShOb3J0ZT1jKCIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YSkpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGEpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2U9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YXIpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYWxmYXIpKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRhbGZhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgcm93Lm5hbWVzPWMoIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJldGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYnIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoYXQgcmhvX3IkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCByaG8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYWxwaGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIgogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCgpkZjwtcmVnX3JlZzJfY3BfMTAwCnIyPC0gZGF0YS5mcmFtZShOb3J0ZV9DZW50cm89YygiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGEpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGFyKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGFsZmFyKSksMSw2KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYWxmYXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIgogICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAgICAgICAgIHJvdy5uYW1lcz1jKCIgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZXRhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGJyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaGF0IHJob19yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgcmhvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImFscGhhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGFscGhhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQpkZjwtcmVnX3JlZzNfY3BfMTAwCnIzPC0gZGF0YS5mcmFtZShDZW50cm89YygiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGEpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGFyKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGFsZmFyKSksMSw2KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYWxmYXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIgogICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAgICAgICAgIHJvdy5uYW1lcz1jKCIgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZXRhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGJyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaGF0IHJob19yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgcmhvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImFscGhhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGFscGhhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQoKCmRmPC1yZWdfcmVnNF9jcF8xMDAKcjQ8LSBkYXRhLmZyYW1lKFN1cj1jKCIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YSkpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGEpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2U9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YXIpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYWxmYXIpKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRhbGZhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgcm93Lm5hbWVzPWMoIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJldGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYnIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoYXQgcmhvX3IkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCByaG8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYWxwaGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIgogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCgoKcmVnaW9uZXNkZjwtYmluZF9jb2xzKHIxLHIyLHIzLHI0KQoKc3RhcmdhemVyKHJlZ2lvbmVzZGYsc3VtbWFyeSA9IEZBTFNFLCBkaWdpdHMgPSAzKQoKYGBgCgojIFJlZ2lvbiBwcm9tZWRpbywgIGNyaXRlcmlvIGRvcwoKCgpgYGB7cn0KCnJlZ19yZWcxX2NkcF8xMDA8LXJlZ3JlX3JlZ2lvbigxLDEwMCkKcmVnX3JlZzJfY2RwXzEwMDwtcmVncmVfcmVnaW9uKDIsMTAwKQpyZWdfcmVnM19jZHBfMTAwPC1yZWdyZV9yZWdpb24oMywxMDApCnJlZ19yZWc0X2NkcF8xMDA8LXJlZ3JlX3JlZ2lvbig0LDEwMCkKCiNzdW1tYXJ5KHJlZ19yZWcxX2NvbWJpbmFkYV9zZXhvX2NyaTNfcjE2MTckcmVncmVzaW9uW1sxMF1dKSMgcmVncmVzaW9ucFtbMTBdXSkKCgpgYGAKCgoKYGBge3J9CnNhdmVSRFMocmVnX3JlZzFfY2RwXzEwMCwgZmlsZT0iRGF0b3MvUmVncmVzaW9uZXMvcmVnX3JlZzFfY2RwXzEwMC5SZGEiKQpzYXZlUkRTKHJlZ19yZWcyX2NkcF8xMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19yZWcyX2NkcF8xMDAuUmRhIikKc2F2ZVJEUyhyZWdfcmVnM19jZHBfMTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfcmVnM19jZHBfMTAwLlJkYSIpCnNhdmVSRFMocmVnX3JlZzRfY2RwXzEwMCwgZmlsZT0iRGF0b3MvUmVncmVzaW9uZXMvcmVnX3JlZzRfY2RwXzEwMC5SZGEiKQoKYGBgCgoKCmBgYHtyfQpkZjwtcmVnX3JlZzFfY2RfMTAwCnIxPC0gZGF0YS5mcmFtZShOb3J0ZT1jKCIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YSkpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGEpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2U9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YXIpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYWxmYXIpKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRhbGZhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgcm93Lm5hbWVzPWMoIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJldGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYnIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoYXQgcmhvX3IkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCByaG8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYWxwaGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIgogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCgpkZjwtcmVnX3JlZzJfY2RfMTAwCnIyPC0gZGF0YS5mcmFtZShOb3J0ZV9DZW50cm89YygiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGEpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGFyKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGFsZmFyKSksMSw2KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYWxmYXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIgogICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAgICAgICAgIHJvdy5uYW1lcz1jKCIgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZXRhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGJyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaGF0IHJob19yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgcmhvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImFscGhhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGFscGhhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQpkZjwtcmVnX3JlZzNfY2RfMTAwCnIzPC0gZGF0YS5mcmFtZShDZW50cm89YygiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGEpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGFyKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGFsZmFyKSksMSw2KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYWxmYXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIgogICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAgICAgICAgIHJvdy5uYW1lcz1jKCIgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZXRhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGJyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaGF0IHJob19yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgcmhvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImFscGhhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGFscGhhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQoKCmRmPC1yZWdfcmVnNF9jZF8xMDAKcjQ8LSBkYXRhLmZyYW1lKFN1cj1jKCIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YSkpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGEpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2U9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YXIpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYWxmYXIpKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRhbGZhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgcm93Lm5hbWVzPWMoIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJldGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYnIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoYXQgcmhvX3IkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCByaG8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYWxwaGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIgogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCgoKcmVnaW9uZXNkZjwtYmluZF9jb2xzKHIxLHIyLHIzLHI0KQoKc3RhcmdhemVyKHJlZ2lvbmVzZGYsc3VtbWFyeSA9IEZBTFNFLCBkaWdpdHMgPSAzKQoKYGBgCgojIFJlZ2lvbiBpbmRpdmlkdWFsLCAgY3JpdGVyaW8gcHJpbmNpcGFsCgoKCmBgYHtyfQoKcmVnX3JlZzFfY3BfOTgxMDA8LXJlZ3JlX3JlZ2lvbl9pbmQoMSw5OCwxMDApCnJlZ19yZWcyX2NwXzk4MTAwPC1yZWdyZV9yZWdpb25faW5kKDIsOTgsMTAwKQpyZWdfcmVnM19jcF85ODEwMDwtcmVncmVfcmVnaW9uX2luZCgzLDk4LDEwMCkKcmVnX3JlZzRfY3BfOTgxMDA8LXJlZ3JlX3JlZ2lvbl9pbmQoNCw5OCwxMDApCgojc3VtbWFyeShyZWdfcmVnMV9jb21iaW5hZGFfc2V4b19jcmkzX3IxNjE3JHJlZ3Jlc2lvbltbMTBdXSkjIHJlZ3Jlc2lvbnBbWzEwXV0pCgoKYGBgCgoKCmBgYHtyfQpzYXZlUkRTKHJlZ19yZWcxX2NwXzk4MTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfcmVnMV9jcF85ODEwMC5SZGEiKQpzYXZlUkRTKHJlZ19yZWcyX2NwXzk4MTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfcmVnMl9jcF85ODEwMC5SZGEiKQpzYXZlUkRTKHJlZ19yZWczX2NwXzk4MTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfcmVnM19jcF85ODEwMC5SZGEiKQpzYXZlUkRTKHJlZ19yZWc0X2NwXzk4MTAwLCBmaWxlPSJEYXRvcy9SZWdyZXNpb25lcy9yZWdfcmVnNF9jcF85ODEwMC5SZGEiKQoKYGBgCgoKCmBgYHtyfQpkZjwtcmVnX3JlZzFfY3BfOTgxMDAKcjE8LSBkYXRhLmZyYW1lKE5vcnRlPWMoIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YSkpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZT0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhcikpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRhbGZhcikpLDEsNiksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGFsZmFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIKICAgICAgICAgICAgICAgICAgICAgICAgKSwgCiAgICAgICAgICAgICAgICByb3cubmFtZXM9YygiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmV0YV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBiciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhhdCByaG9fciQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIHJobyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbHBoYV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBhbHBoYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKCmRmPC1yZWdfcmVnMl9jcF85ODEwMApyMjwtIGRhdGEuZnJhbWUoTm9ydGVfQ2VudHJvPWMoIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YSkpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZT0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhcikpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRhbGZhcikpLDEsNiksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGFsZmFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIKICAgICAgICAgICAgICAgICAgICAgICAgKSwgCiAgICAgICAgICAgICAgICByb3cubmFtZXM9YygiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmV0YV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBiciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhhdCByaG9fciQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIHJobyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbHBoYV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBhbHBoYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKZGY8LXJlZ19yZWczX2NwXzk4MTAwCnIzPC0gZGF0YS5mcmFtZShDZW50cm89YygiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGEpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGJldGFyKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyKGFzLmNoYXJhY3RlcihtZWFuKGRmJGFsZmFyKSksMSw2KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYWxmYXIpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2UgPSAiLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAiIgogICAgICAgICAgICAgICAgICAgICAgICApLCAKICAgICAgICAgICAgICAgIHJvdy5uYW1lcz1jKCIgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZXRhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGJyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaGF0IHJob19yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgcmhvIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImFscGhhX3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIGFscGhhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgKQoKCmRmPC1yZWdfcmVnNF9jcF85ODEwMApyNDwtIGRhdGEuZnJhbWUoU3VyPWMoIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YSkpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZT0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhcikpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRhbGZhcikpLDEsNiksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGFsZmFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIKICAgICAgICAgICAgICAgICAgICAgICAgKSwgCiAgICAgICAgICAgICAgICByb3cubmFtZXM9YygiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmV0YV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBiciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhhdCByaG9fciQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIHJobyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbHBoYV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBhbHBoYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKCgpyZWdpb25lc2RmPC1iaW5kX2NvbHMocjEscjIscjMscjQpCgpzdGFyZ2F6ZXIocmVnaW9uZXNkZixzdW1tYXJ5ID0gRkFMU0UsIGRpZ2l0cyA9IDMpCgpgYGAKCgpgYGB7cn0KcmVzdWwgJT4lIAogIGdncGxvdChhZXMoeD1iZXRhKSkgKwogICAgZ2VvbV9oaXN0b2dyYW0oYWVzKHk9Li5kZW5zaXR5Li4gKSwgYmlucz0yNSwgYWxwaGE9MC42LGNvbG9yPSJibHVlIikrCiAgZ2VvbV9kZW5zaXR5KCkgKyB0aGVtZV9ncmF5KCkKYGBgCgoKCiMgUmVnaW9uIGluZGl2aWR1YWwsICBjcml0ZXJpbyBkb3MKCgoKYGBge3J9CgpyZWdfcmVnMV9jZF85ODEwMDwtcmVncmVfcmVnaW9uX2luZCgxLDEwMCkKcmVnX3JlZzJfY2RfOTgxMDA8LXJlZ3JlX3JlZ2lvbl9pbmQoMiwxMDApCnJlZ19yZWczX2NkXzk4MTAwPC1yZWdyZV9yZWdpb25faW5kKDMsMTAwKQpyZWdfcmVnNF9jZF85ODEwMDwtcmVncmVfcmVnaW9uX2luZCg0LDEwMCkKCiNzdW1tYXJ5KHJlZ19yZWcxX2NvbWJpbmFkYV9zZXhvX2NyaTNfcjE2MTckcmVncmVzaW9uW1sxMF1dKSMgcmVncmVzaW9ucFtbMTBdXSkKCgpgYGAKCgoKYGBge3J9CnNhdmVSRFMocmVnX3JlZzFfY2RfOTgxMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19yZWcxX2NkXzk4MTAwLlJkYSIpCnNhdmVSRFMocmVnX3JlZzJfY2RfOTgxMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19yZWcyX2NkXzk4MTAwLlJkYSIpCnNhdmVSRFMocmVnX3JlZzNfY2RfOTgxMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19yZWczX2NkXzk4MTAwLlJkYSIpCnNhdmVSRFMocmVnX3JlZzRfY2RfOTgxMDAsIGZpbGU9IkRhdG9zL1JlZ3Jlc2lvbmVzL3JlZ19yZWc0X2NkXzk4MTAwLlJkYSIpCgpgYGAKCgpgYGB7cn0KZGY8LXJlZ19yZWcxX2NkXzk4MTAwCnIxPC0gZGF0YS5mcmFtZShOb3J0ZT1jKCIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YSkpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGEpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2U9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YXIpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYWxmYXIpKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRhbGZhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgcm93Lm5hbWVzPWMoIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJldGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYnIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoYXQgcmhvX3IkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCByaG8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYWxwaGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIgogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCgpkZjwtcmVnX3JlZzJfY2RfOTgxMDAKcjI8LSBkYXRhLmZyYW1lKE5vcnRlX0NlbnRybz1jKCIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YSkpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGEpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2U9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YXIpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYWxmYXIpKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRhbGZhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgcm93Lm5hbWVzPWMoIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJldGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYnIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoYXQgcmhvX3IkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCByaG8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYWxwaGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIgogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCmRmPC1yZWdfcmVnM19jZF85ODEwMApyMzwtIGRhdGEuZnJhbWUoQ2VudHJvPWMoIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhKSksMSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoIigiLHN1YnN0cihhcy5jaGFyYWN0ZXIoc2QoZGYkYmV0YSkpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZT0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRiZXRhcikpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0cihhcy5jaGFyYWN0ZXIobWVhbihkZiRhbGZhcikpLDEsNiksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGFsZmFyKSksMSw1KSwiKSIsc2VwPSIiLGNvbGxhcHNlID0gIiwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIiIKICAgICAgICAgICAgICAgICAgICAgICAgKSwgCiAgICAgICAgICAgICAgICByb3cubmFtZXM9YygiICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmV0YV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBiciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImhhdCByaG9fciQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNkIHJobyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbHBoYV9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCBhbHBoYXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKCgpkZjwtcmVnX3JlZzRfY2RfOTgxMDAKcjQ8LSBkYXRhLmZyYW1lKFN1cj1jKCIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YSkpLDEsNSksCiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCIoIixzdWJzdHIoYXMuY2hhcmFjdGVyKHNkKGRmJGJldGEpKSwxLDUpLCIpIixzZXA9IiIsY29sbGFwc2U9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYmV0YXIpKSwxLDUpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRiZXRhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICAgICAgICBzdWJzdHIoYXMuY2hhcmFjdGVyKG1lYW4oZGYkYWxmYXIpKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgiKCIsc3Vic3RyKGFzLmNoYXJhY3RlcihzZChkZiRhbGZhcikpLDEsNSksIikiLHNlcD0iIixjb2xsYXBzZSA9ICIsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICIiCiAgICAgICAgICAgICAgICAgICAgICAgICksIAogICAgICAgICAgICAgICAgcm93Lm5hbWVzPWMoIiAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImJldGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYnIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoYXQgcmhvX3IkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZCByaG8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWxwaGFfciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2QgYWxwaGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIgogICAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCgoKcmVnaW9uZXNkZjwtYmluZF9jb2xzKHIxLHIyLHIzLHI0KQoKc3RhcmdhemVyKHJlZ2lvbmVzZGYsc3VtbWFyeSA9IEZBTFNFLCBkaWdpdHMgPSAzKQoKYGBgCgojR3JhZmljYXMKCmBgYHtyfQphPC0gcmVhZFJEUygiRGF0b3MvUmVncmVzaW9uZXMvcmVnX3JlZzFfY3BfOTgxMDAuUmRhIikKCmBgYAoKI2dyYWZpY2EgcmFuZ28gcmFuZ28gIHJlZ2lvbmFsCgpgYGB7cn0KZ3JhZmljYXJyPC1mdW5jdGlvbihkZixhID0gIiIsIHJlZ2lvbj0gIiIpCnsKICBsYTwtZGYlPiVwdWxsKHJlZ3Jlc2lvbmhwcikKCiAgbGExPC1sYXBwbHkobGFbMTpsZW5ndGgobGEpXSxmdW5jdGlvbih4KSB4JG1vZGVsKQoKICBsYTE8LWxhcHBseShsYTFbMTpsZW5ndGgobGExKV0sZnVuY3Rpb24oeCl7cm93Lm5hbWVzKHgpPC1OVUxMOyB4IH0gKQoKICBsYTI8LWJpbmRfcm93cyhsYTFbMTpsZW5ndGgobGExKV0pCiAgcHJpbnQobnJvdyhsYTIpKQogIHByaW50KHN1bShpcy5uYShsYTIpKSkKICAKICBsYTIkcGxpbmdfcDwtbGEyJT4lcHVsbChwbGluZ19wKSU+JWFzLmludGVnZXIoKQoKICBsYTM8LWxhMiU+JWdyb3VwX2J5KHBsaW5nX3ApJT4lc3VtbWFyaXNlKHBsaW5nX3BtPW1lYW4ocGxpbmdfaCkpCiAgCiAgYWxmYXIgPC0gIG1lYW4oZGYkYWxmYXIpCiAgYmV0YXIgPC0gbWVhbihkZiRiZXRhcikKICAKICBnZ3Bsb3QobGEzLGFlcyh4PXBsaW5nX3AsIHkgPSBwbGluZ19wbSkpICsgCiAgICAgICAgZ2VvbV9wb2ludChjb2w9ImdyYXkiKSsgCiAgICAgICAgbGFicyh0aXRsZSA9IHBhc3RlKHJlZ2lvbiwiICIsYSksCiAgICAgICAgICAgICBzdWJ0aXRsZSA9ICAiUmFuZ28gcGVyY2VudGlsIGludGVyZ2VuZXJhY2lvbmFsIikgKwogICAgICAgIHhsYWIoIlJhbmdvIHBhc2FkbyIpICsgCiAgICAgICAgeWxhYigiUmFuZ28gYWN0dWFsIikgKwogICAgICAgIHhsaW0oMCwxMDApICsgCiAgICAgICAgeWxpbSgwLDEwMCkgKwogICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwKICAgICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgICAgICBsZWdlbmQucG9zaXRpb249InRvcCIsCiAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGZhY2U9ImJvbGQiKSwKICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT02LCBmYWNlPSJib2xkIikpICsKICAgICAgICBnZW9tX2Z1bmN0aW9uKGZ1biA9IGZ1bmN0aW9uKHgpKyBhbGZhciArIGJldGFyKngsCiAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAicmVkIikgKwogICAgICAgIGFubm90YXRlKCJ0ZXh0IiwKICAgICAgICAgICAgICAgICB4PTcwLAogICAgICAgICAgICAgICAgIHk9MjUsCiAgICAgICAgICAgICAgICAgbGFiZWwgPSBwYXN0ZShzdWJzdHIoYXMuY2hhcmFjdGVyKGFsZmFyKSwxLDYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiArICIsc3Vic3RyKGFzLmNoYXJhY3RlcihiZXRhciksMSw1KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLCJ4IiksCiAgICAgICAgICAgICAgICAgY29sb3VyID0gInJlZCIsCiAgICAgICAgICAgICAgICAgc2l6ZSA9IDUpCiAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgI3BhcnNlID0gVFJVRSkKfQoKZ3JhZmljYXJyKGEsICIyMDE3IC0gMTk5OCIsICJSZWdpw7NuIE5vcnRlOiIpCgpgYGAKCiMjIGdyYWZpY2EgcmFuZ28gcmFuZ28KCmBgYHtyfQpncmFmaWNhcnJfcHJvbWVkaW88LWZ1bmN0aW9uKGRmLHJlZ2lvbj0gIiIsYSA9ICIiKQp7CiAgbGE8LWRmJT4lcHVsbChyZWdyZXNpb25yKQoKICBsYTE8LWxhcHBseShsYVsxOmxlbmd0aChsYSldLGZ1bmN0aW9uKHgpIHgkbW9kZWwpCgogIGxhMTwtbGFwcGx5KGxhMVsxOmxlbmd0aChsYTEpXSxmdW5jdGlvbih4KXtyb3cubmFtZXMoeCk8LU5VTEw7IHggfSApCgogIGxhMjwtYmluZF9yb3dzKGxhMVsxOmxlbmd0aChsYTEpXSkKICAjcHJpbnQobnJvdyhsYTIpKQogICNwcmludChzdW0oaXMubmEobGEyKSkpCiAgCiAgbGEzPC1sYTIlPiVtdXRhdGUoY29ob3J0cCA9IGN1dChwbGluZ19wLGJyZWFrcz1zZXEoMCwxMDAsMikpKQogIAogIGxhMzwtbGEzJT4lZ3JvdXBfYnkoY29ob3J0cCklPiVzdW1tYXJpc2UocGxpbmdfcG09bWVhbihwbGluZ19wKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsaW5nX2htPW1lYW4ocGxpbmdfaCkpCiAgCiAgYWxmYXIgPC0gIG1lYW4oZGYkYWxmYXIpCiAgYmV0YXIgPC0gbWVhbihkZiRiZXRhcikKICAKICBnPC1nZ3Bsb3QobGEzLGFlcyh4PXBsaW5nX3BtLCB5ID0gcGxpbmdfaG0pKSArIAogICAgICAgIGdlb21fcG9pbnQoY29sPSJncmF5IikrIAogICAgICAgIGxhYnModGl0bGUgPSBwYXN0ZShyZWdpb24sIiAiLGEpKSsKICAgICAgICAgICAgIyBzdWJ0aXRsZSA9ICAiUmFuZ28gcGVyY2VudGlsIGludGVyZ2VuZXJhY2lvbmFsIikgKwogICAgICAgIHhsYWIoIlJhbmdvIHBlcmNlbnRpbCBwc2V1ZG8gUFAiKSArIAogICAgICAgIHlsYWIoIlJhbmdvIHBlcmNlbnRpbCBhY3R1YWwiKSArCiAgICAgICAgeGxpbSgwLDEwMCkgKyAKICAgICAgICB5bGltKDAsMTAwKSArCiAgICAgICAjIHRoZW1lX2NsYXNzaWMoKSArCiAgICAgICAgdGhlbWUoCiAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgICAgICAgICBsZWdlbmQucG9zaXRpb249InRvcCIsCiAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGZhY2U9ImJvbGQiKSwKICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT02LCBmYWNlPSJib2xkIikpICsKICAgICAgICAKICAgIGdlb21fZnVuY3Rpb24oZnVuID0gZnVuY3Rpb24oeCkrIGFsZmFyICsgYmV0YXIqeCwKICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJyZWQiKSArCiAgICAKICAgICAgICBnZW9tX2Z1bmN0aW9uKGZ1biA9IGZ1bmN0aW9uKHgpIHgsY29sb3VyID0gImJsdWUiKSsKICAgICAgICAKICAgICAgdGhlbWVfdXBkYXRlKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSMrCiAgICAgICAgIyBhbm5vdGF0ZSgidGV4dCIsCiAgICAgICAgIyAgICAgICAgICB4PTcwLAogICAgICAgICMgICAgICAgICAgeT0yNSwKICAgICAgICAjICAgICAgICAgIGxhYmVsID0gcGFzdGUoIlIoeV5hKT0iLHN1YnN0cihhcy5jaGFyYWN0ZXIoYWxmYXIpLDEsNiksCiAgICAgICAgIyAgICAgICAgICAgICAgICAgICAgICAgICIgKyAiLHN1YnN0cihhcy5jaGFyYWN0ZXIoYmV0YXIpLDEsNSkKICAgICAgICAjICAgICAgICAgICAgICAgICAgICAgICAgLCJSKHlecCkiKSwKICAgICAgICAjICAgICAgICAgIGNvbG91ciA9ICJyZWQiLAogICAgICAgICMgICAgICAgICAgc2l6ZSA9IDUsIHBhcnNlcj1UUlVFKQogICAgICAgICMgICAgICAgICAgCiAgICAgICAgICAgICAgICAgI3BhcnNlID0gVFJVRSkKICByZXR1cm4oZykKfQoKcjE8LWdyYWZpY2Fycl9wcm9tZWRpbyhyZWdfcmVnMV9jZF8xMDAsIk5vcnRlIChyZWdpw7NuIDEpOiIsIlJlbGFjacOzbiBkZSBlc3RpbWFjaW9uZXMgZGUgcmFuZ28gcGVyY2VudGlsIikKcjI8LWdyYWZpY2Fycl9wcm9tZWRpbyhyZWdfcmVnMl9jZF8xMDAsIkNlbnRyby1Ob3J0ZSAocmVnacOzbiAyKToiLCJSZWxhY2nDs24gZGUgZXN0aW1hY2lvbmVzIGRlIHJhbmdvIHBlcmNlbnRpbCIpCnIzPC1ncmFmaWNhcnJfcHJvbWVkaW8ocmVnX3JlZzNfY2RfMTAwLCJDZW50cm8gKHJlZ2nDs24gMyk6IiwiUmVsYWNpw7NuIGRlIGVzdGltYWNpb25lcyBkZSByYW5nbyBwZXJjZW50aWwiKQpyNDwtZ3JhZmljYXJyX3Byb21lZGlvKHJlZ19yZWc0X2NkXzEwMCwiU3VyIChyZWdpw7NuIDQpOiIsIlJlbGFjacOzbiBkZSBlc3RpbWFjaW9uZXMgZGUgcmFuZ28gcGVyY2VudGlsIikKCnI0CgpgYGAKCiMgcmVnaW9uZXMgY29uanVudGFzCgoKCmBgYHtyfQogYWxmYXIxIDwtICBtZWFuKHJlZ19yZWcxX2NkXzEwMCRhbGZhcikKICBiZXRhcjEgPC0gbWVhbihyZWdfcmVnMV9jZF8xMDAkYmV0YXIpCiAgCiAgIGFsZmFyMiA8LSAgbWVhbihyZWdfcmVnMl9jZF8xMDAkYWxmYXIpCiAgYmV0YXIyIDwtIG1lYW4ocmVnX3JlZzJfY2RfMTAwJGJldGFyKQogIAogICBhbGZhcjMgPC0gIG1lYW4ocmVnX3JlZzNfY2RfMTAwJGFsZmFyKQogIGJldGFyMyA8LSBtZWFuKHJlZ19yZWczX2NkXzEwMCRiZXRhcikKICAKICAgYWxmYXI0IDwtICBtZWFuKHJlZ19yZWc0X2NkXzEwMCRhbGZhcikKICBiZXRhcjQgPC0gbWVhbihyZWdfcmVnNF9jZF8xMDAkYmV0YXIpCiAgCiAgZ2dwbG90KCkgKyAKICAgICAgICAgCiAgICAgICAgbGFicyh0aXRsZSA9ICJBSVIgZXN0aW1hZG8gcG9yIHJlZ2lvbmVzIikrCiAgICAgICAgICAKICAgICAgICB4bGFiKCJSYW5nbyBwZXJjZW50aWwgcHNldWRvIFBQIikgKyAKICAgICAgICB5bGFiKCJSYW5nbyBwZXJjZW50aWwgYWN0dWFsIikgKwogICAgICAgIHhsaW0oMCwxMDApICsgCiAgICAgICAgeWxpbSgwLDEwMCkgKwogICAgICAgIyB0aGVtZV9jbGFzc2ljKCkgKwogICAgICAgIHRoZW1lKAogICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICAgICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLAogICAgICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJ0b3AiLAogICAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT04LCBmYWNlPSJib2xkIiksCiAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9NiwgZmFjZT0iYm9sZCIpKSArCiAgICAgICAgCiAgICBnZW9tX2Z1bmN0aW9uKGZ1biA9IGZ1bmN0aW9uKHgpKyBhbGZhcjEgKyBiZXRhcjEqeCxhZXMobGluZXR5cGU9IjEiKSwKICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJyZWQiLCBhbHBoYT0xKSArCiAgCiAgICBnZW9tX2Z1bmN0aW9uKGZ1biA9IGZ1bmN0aW9uKHgpKyBhbGZhcjIgKyBiZXRhcjIqeCxhZXMobGluZXR5cGU9IjIiKSwKICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9ICJyZWQiLCBhbHBoYT0wLjgpICsKICAgIGdlb21fZnVuY3Rpb24oZnVuID0gZnVuY3Rpb24oeCkrIGFsZmFyMyArIGJldGFyMyp4LGFlcyhsaW5ldHlwZT0iNSIpLAogICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gInJlZCIsIGFscGhhPTAuNikgKyAgIAogICAgZ2VvbV9mdW5jdGlvbihmdW4gPSBmdW5jdGlvbih4KSsgYWxmYXI0ICsgYmV0YXI0KngsYWVzKGxpbmV0eXBlPSI2IiksCiAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSAicmVkIiwgYWxwaGE9MSkgKwpzY2FsZV9saW5ldHlwZV9kaXNjcmV0ZSgiUmVnacOzbiIsIGJyZWFrcz1jKCIxIiwgIjIiLCI1IiwgIjYiKSwgbGFiZWxzPWMoIk5vcnRlIiwgIkNlbnRyby1Ob3J0ZSIsIkNlbnRybyIsIlN1ciIpKSsKICAKICAgICAgICAgICAgZ2VvbV9mdW5jdGlvbihmdW4gPSBmdW5jdGlvbih4KSB4LGNvbG91ciA9ICJibHVlIikrCiAgICAKCiAgICAgICAgCiAgICAgIHRoZW1lX3VwZGF0ZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkjKwpgYGAKCgojIE1hdHJpeiBkZSB0cmFuc2ljacOzbgoKCmBgYHtyfQp0cmFuc2ljaW9uPC1mdW5jdGlvbihkZixyZWdpb249ICIiLGEgPSAiIikKewogIGxhPC1kZiU+JXB1bGwocmVncmVzaW9ucikKCiAgbGExPC1sYXBwbHkobGFbMTpsZW5ndGgobGEpXSxmdW5jdGlvbih4KSB4JG1vZGVsKQoKICBsYTE8LWxhcHBseShsYTFbMTpsZW5ndGgobGExKV0sZnVuY3Rpb24oeCl7cm93Lm5hbWVzKHgpPC1OVUxMOyB4IH0gKQoKICBsYTI8LWJpbmRfcm93cyhsYTFbMTpsZW5ndGgobGExKV0pCiAgI3ByaW50KG5yb3cobGEyKSkKICAjcHJpbnQoc3VtKGlzLm5hKGxhMikpKQogIAogIGxhMzwtbGEyJT4lbXV0YXRlKGNvaG9ydHAgPSBjdXQocGxpbmdfcCxicmVha3M9c2VxKDAsMTAwLDIwKSxsYWJlbHM9YygiUTEiLCJRMiIsIlEzIiwiUTQiLCJRNSIpKSwKICAgICAgICAgICAgICAgICAgICBjb2hvcnRoID0gY3V0KHBsaW5nX2gsYnJlYWtzPXNlcSgwLDEwMCwyMCksbGFiZWxzPWMoInExIiwicTIiLCJxMyIsInE0IiwicTUiKSkpCiAgCiAgbGEzPC1sYTMlPiVncm91cF9ieShjb2hvcnRwLGNvaG9ydGgpJT4lCiAgY291bnQoKSU+JXVuZ3JvdXAoKQogIAogIGxhMzwtbGEzJT4lZ3JvdXBfYnkoY29ob3J0cCklPiUgCiAgICBzdW1tYXJpc2UocDE9bioxMDAvc3VtKG4pLAogICAgICAgICAgICAgIGNvaG9ydHA9ZmFjdG9yKGNvaG9ydHAsIGxldmVscz1jKCJRMSIsIlEyIiwiUTMiLCJRNCIsIlE1IikpLAogICAgICAgICAgICAgIGNvaG9ydGg9ZmFjdG9yKGNvaG9ydGgsIGxldmVscz1jKCJxNSIsInE0IiwicTMiLCJxMiIsInExIikpKSU+JXVuZ3JvdXAoKQogICAKICBsYTM8LWxhMyU+JWFycmFuZ2UoY29ob3J0cCkjLGRlY3JlYXNpbmcgPSBUUlVFKQogICAKICAjcHJpbnQobGEzJT4lZ3JvdXBfYnkoY29ob3J0cCklPiVzdW1tYXJpc2Uoc3VtKHAxKSkpCiAgCiAgIGxhMzwtbGEzJT4lIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBjb2hvcnRoLCB2YWx1ZXNfZnJvbSA9IHAxKQpyZXR1cm4obGEzKQogIAp9Cgp0cmFucmVnMTwtdHJhbnNpY2lvbihyZWdfY2RfMTAwKQojcm93Lm5hbWVzKHRyYW5yZWcxKTwtdHJhbnJlZzEkY29ob3J0cAoKc3RhcmdhemVyKGFzLmRhdGEuZnJhbWUodHJhbnJlZzEpLHJvd25hbWVzPSBGQUxTRSwgc3VtbWFyeSA9IEZBTFNFLCBkaWdpdHM9IDEpCmBgYAoKYGBge3J9CiMgYmFyX29yZGVyIDwtIGxpc3QoCiMgICAiKDAsMjBdIiA9IDQsCiMgICAiKDIwLDQwXSIgPSAzLAojICAgIig0MCw2MF0iID0gMiwKIyAgICIoNjAsODBdIiA9IDEsCiMgICAiKDgwLDEwMF0iID0gMAojICkKIyBiYXJfb3JkZXJfdiA8LSBhcy5udW1lcmljKGJhcl9vcmRlcikKCnRyYW5yZWcxICU+JSAKICBoY2hhcnQoCiAgICAnY29sdW1uJywgaGNhZXMoeCA9IGNvaG9ydHAsIHkgPSBwMSwgZ3JvdXAgPSBjb2hvcnRoKSwKICAgIHN0YWNraW5nID0gIm5vcm1hbCIKICAjICBleHBsaWNpdF9vcmRlciA9IGMoInE1IiwicTIiLCJxMyIsInE0IiwicTEiKQogICAgKSAKYGBgCgoKCgpgYGB7cn0KZ2dzYXZlKCJyZWdpb24xcnIucG5nIiwgcGxvdCA9IHIxLCBwYXRoID0gImltYWdlbmVzLyIpCmdnc2F2ZSgicmVnaW9uMnJyLnBuZyIsIHBsb3QgPSByMiwgcGF0aCA9ICJpbWFnZW5lcy8iKQpnZ3NhdmUoInJlZ2lvbjNyci5wbmciLCBwbG90ID0gcjMsIHBhdGggPSAiaW1hZ2VuZXMvIikKZ2dzYXZlKCJyZWdpb240cnIucG5nIiwgcGxvdCA9IHI0LCBwYXRoID0gImltYWdlbmVzLyIpCgoKCmBgYAoKIyBHcmFmaWNhcyBFSUkKCmBgYHtyfQpncmFmaWNhcmVpaV9wcm9tZWRpbzwtZnVuY3Rpb24oZGYsbmw9RkFMU0UscmVnaW9uPSAiIixhID0gIiIpCnsKICAKICAKICBsYTwtZGYlPiVwdWxsKHJlZ3Jlc2lvbikKCiAgbGExPC1sYXBwbHkobGFbMTpsZW5ndGgobGEpXSxmdW5jdGlvbih4KSB4JG1vZGVsKQoKICBsYTE8LWxhcHBseShsYTFbMTpsZW5ndGgobGExKV0sZnVuY3Rpb24oeCl7cm93Lm5hbWVzKHgpPC1OVUxMOyB4IH0gKQoKICBsYTI8LWJpbmRfcm93cyhsYTFbMTpsZW5ndGgobGExKV0pCiAgI3ByaW50KG5yb3cobGEyKSkKICAjcHJpbnQoc3VtKGlzLm5hKGxhMikpKQogIAogIGxhMjwtbGEyJT4lZHJvcF9uYSgpCiAgCiAgaWYobmw9PVRSVUUpewogIGxhMjwtbGEyJT4lbXV0YXRlKGluZ2ggPSBleHAobGluZ19oKSwKICAgICAgICAgICAgICAgICAgICAgaW5ncCA9IGV4cChsaW5nX3ApCiAgICAgICAgICAgICAgICAgICAgICklPiVzZWxlY3QoaW5naCxpbmdwKQogICNoZWFkKGxhMikKICAgbGEyPC1sYTIlPiVtdXRhdGUocGVyaW5ncD1yYW5rKGluZ3ApL2xlbmd0aChpbmdwKSkKICAgbGEyPC1sYTIlPiVtdXRhdGUoY29ob3AgPSBjdXQocGVyaW5ncCwgYnJlYWtzID0gc2VxKDAsMSwwLjAxKSwgaW5jbHVkZS5sb3dlc3Q9VFJVRSkpCiAgIGxhMzwtbGEyJT4lZ3JvdXBfYnkoY29ob3ApJT4lc3VtbWFyaXNlKGluZ19obT1tZWFuKGluZ2gpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmdfcG09bWVhbihpbmdwKSkKICAgCiAgfWVsc2V7CiAgbGEyPC1sYTIlPiVtdXRhdGUocGVyaW5ncD1yYW5rKGxpbmdfcCkvbGVuZ3RoKGxpbmdfcCkpCiAgbGEyIDwtbGEyICU+JSBtdXRhdGUoY29ob3AgPSBjdXQocGVyaW5ncCwgYnJlYWtzID0gc2VxKDAsMSwwLjAyKSwgaW5jbHVkZS5sb3dlc3Q9VFJVRSkpCiAgbGEzPC1sYTIlPiVncm91cF9ieShjb2hvcCklPiVzdW1tYXJpc2UoaW5nX2htPW1lYW4obGluZ19oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmdfcG09bWVhbihsaW5nX3ApKQogIH0KICAKICAKICAKICAgCiAgCiAgYmV0YTAgPC0gIG1lYW4oZGYkYmV0YTApCiAgYmV0YSA8LSBtZWFuKGRmJGJldGEpCiAgc2V4PC0gbWVhbihkZiRzZXhvaCkKICAKICBnPC1nZ3Bsb3QobGEzLGFlcyh4PWluZ19wbSwgeSA9IGluZ19obSkpICsgCiAgICAgICAgZ2VvbV9wb2ludChjb2w9ImdyYXkiKSsgCiAgICAgICAgbGFicyh0aXRsZSA9IHBhc3RlKHJlZ2lvbiwiICIsYSkpKwogICAgICAgICAgICAjIHN1YnRpdGxlID0gICJFc3RpbWFjacOzbiAgbGluZWFsIikgKwogICAgICAgIHhsYWIoIkxvZyBpbmdyZXNvIHBzZXVkbyBQUCIpICsgCiAgICAgICAgI3hsYWIoIkluZ3Jlc28gcHNldWRvIFBQIikgKwogICAgICAgIAogICAgICAgIHlsYWIoIkxvZyBpbmdyZXNvIGFjdHVhbCIpICsKICAgICAgICAjeWxhYigiSW5ncmVzbyBhY3R1YWwiKSArCiAgICAgICAgCiAgICAgICAgICN4bGltKDAsbWF4KGxhMyRpbmdfcG0pKSArIAogICAgICAgICAjeWxpbSgwLG1heChsYTMkaW5nX2htKSkgKyAgICAKICAgICAgICAKICAgICAgICB4bGltKG1pbihsYTMkaW5nX3BtKSxtYXgobGEzJGluZ19wbSkpICsgCiAgICAgICAgeWxpbSg2LG1heChsYTMkaW5nX2htKSkgKwogICAgICAgIAogICAgICAgIHRoZW1lX2NsYXNzaWMoKSArCiAgICAgICAgdGhlbWUoCiAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwKICAgICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksCiAgICAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLAogICAgICAgICAgICBsZWdlbmQucG9zaXRpb249InRvcCIsCiAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTgsIGZhY2U9ImJvbGQiKSwKICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT02LCBmYWNlPSJib2xkIikpICsKICAgICAgICAKICAgIGdlb21fZnVuY3Rpb24oZnVuID0gZnVuY3Rpb24oeCkgYmV0YTAgKyB4KmJldGEsIGNvbG91ciA9ICJyZWQiKSArCiAgICAjZ2VvbV9mdW5jdGlvbihmdW4gPSBmdW5jdGlvbih4KSBleHAoYmV0YTApICogeCoqYmV0YSwgY29sb3VyID0gInJlZCIpICsKICAgIAogICAgZ2VvbV9mdW5jdGlvbihmdW4gPSBmdW5jdGlvbih4KSBiZXRhMCArIHgqYmV0YSArIHNleCwgY29sb3VyID0gIm9yYW5nZSIpKwogICAgI2dlb21fZnVuY3Rpb24oZnVuID0gZnVuY3Rpb24oeCkgZXhwKGJldGEwKSAqIHgqKmJldGEgKmV4cChzZXgpLCBjb2xvdXIgPSAib3JhbmdlIikrCiAgICAKICAgICNnZW9tX2Z1bmN0aW9uKGZ1biA9IGZ1bmN0aW9uKHgpIHgsY29sb3VyID0gImJsdWUiKSsKICAgICAgICB0aGVtZV91cGRhdGUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCiAgICAgICAgIyBhbm5vdGF0ZSgidGV4dCIsCiAgICAgICAgIyAgICAgICAgICB4PTcwLAogICAgICAgICMgICAgICAgICAgeT0yNSwKICAgICAgICAjICAgICAgICAgIGxhYmVsID0gcGFzdGUoc3Vic3RyKGFzLmNoYXJhY3RlcihhbGZhciksMSw2KSwKICAgICAgICAjICAgICAgICAgICAgICAgICAgICAgICAgIiArICIsc3Vic3RyKGFzLmNoYXJhY3RlcihiZXRhciksMSw1KQogICAgICAgICMgICAgICAgICAgICAgICAgICAgICAgICAsIngiKSwKICAgICAgICAjICAgICAgICAgIGNvbG91ciA9ICJyZWQiLAogICAgICAgICMgICAgICAgICAgc2l6ZSA9IDUpCiAgICAgICAgIyAgICAgICAgICAKICAgICAgICAgICAgICAgICAjcGFyc2UgPSBUUlVFKQp9CgojZ3JhZmljYXJlaWlfcHJvbWVkaW88LWZ1bmN0aW9uKGRmLG5sPUZBTFNFLGEgPSAiIiwgcmVnaW9uPSAiIikKI3JlZ2lvbjwtIlJlbGFjacOzbiBkZSBlc3RpbWFjaW9uZXM6IGluZ3Jlc29zIGFjdHVhbGVzIHZzIGluZ3Jlc29zIHBzZXVkbyBQUCIKCmE8LSJsb2cgaW5ncmVzb3MgYWN0dWFsZXMgdnMgbG9nIGluZ3Jlc29zIHBzZXVkbyBQUCIKcjE8LWdyYWZpY2FyZWlpX3Byb21lZGlvKHJlZ19yZWcxX2NkXzEwMCxubD1GQUxTRSwiTm9ydGUgKHJlZ2lvbiAxKToiLGEpCnIyPC1ncmFmaWNhcmVpaV9wcm9tZWRpbyhyZWdfcmVnMl9jZF8xMDAsbmw9RkFMU0UsIkNlbnRyby1Ob3J0ZSAocmVnaW9uIDIpOiIsYSkKI3IzPC1ncmFmaWNhcmVpaV9wcm9tZWRpbyhyZWdfcmVnM19jZF8xMDAsbmw9RkFMU0UsIkNlbnRybyAocmVnaW9uIDMpOiIsYSkKI3I0PC1ncmFmaWNhcmVpaV9wcm9tZWRpbyhyZWdfcmVnNF9jZF8xMDAsbmw9RkFMU0UsIlN1ciAocmVnaW9uIDQpOiIsYSkKCgpyMQpyMgpyMwpyNApgYGAKCmBgYHtyfQpnZ3NhdmUoInJlZ2lvbjFlZWlsLnBuZyIsIHBsb3QgPSByMSwgcGF0aCA9ICJpbWFnZW5lcy8iKQpnZ3NhdmUoInJlZ2lvbjJlZWlsLnBuZyIsIHBsb3QgPSByMiwgcGF0aCA9ICJpbWFnZW5lcy8iKQpnZ3NhdmUoInJlZ2lvbjNlZWlsLnBuZyIsIHBsb3QgPSByMywgcGF0aCA9ICJpbWFnZW5lcy8iKQpnZ3NhdmUoInJlZ2lvbjRlZWlsLnBuZyIsIHBsb3QgPSByNCwgcGF0aCA9ICJpbWFnZW5lcy8iKQpgYGAKCgoKCgoKCgoKCgpgYGB7cn0KZ3JhZmljYXJyX3Byb21lZGlvKHJlZ19jcF81MDAsIkFjdHVhbC1QYXNhZG8gcHJvbWVkaW8iLCJNw6l4aWNvLCBCYXNlIEE6IikKYGBgCgoKIyBFc3RhZCBkZXMgIEEKCmBgYHtyfQpyZXN1PC1kZmhfYyU+JXN1bW1hcmlzZShTZXhvX01hc2N1bGlubyA9IGZpbHRlcihkZmhfYyxzZXhvX2g9PTEpJT4lY291bnQoKSU+JXB1bGwoKSwKICAgICAgICAgICAgICAgICAgU2V4b19GZW1lbmlubyA9IGZpbHRlcihkZmhfYyxzZXhvX2g9PTIpJT4lY291bnQoKSU+JXB1bGwoKSwKICAgICAgICAgICAgICAgICBQcm9tZWRpb19FZGFkX0VudHJldmlzdGFkbyA9IG1lYW4oZWRhZF9oKSwKICAgICAgICAgICAgICAgICBTZXhvX01hc2N1bGlub19QUCA9IGZpbHRlcihkZmhfYyxwcF9zZXhvPT0xKSU+JWNvdW50KCklPiVwdWxsKCksCiAgICAgICAgICAgICAgICAgU2V4b19GZW1lbmlub19QUCA9IGZpbHRlcihkZmhfYyxwcF9zZXhvPT0yKSU+JWNvdW50KCklPiVwdWxsKCksCiAgICAgICAgICAgICAgICAgRWRhZF9Nw61uaW1hX1BQID0gbWluKHBwX2VkYWQpLAogICAgICAgICAgICAgICAgIEVkYWRfTcOheGltYV9QUCA9IG1heChwcF9lZGFkKSwKICAgICAgICAgICAgICAgICBQcm9tZWRpb19FZGFkX1BQXzIwMTcgPSBtZWFuKHBwX2VkYWQpKzIyKQoKCnN0YXJnYXplcihyZXN1LHN1bW1hcnkgPSBGQUxTRSwgZGlnaXRzID0gMSwgZmxpcCA9IFRSVUUpCmBgYAoKCgoKCiMgRXN0YSBkZXMgQiAKCmBgYHtyfQpyZXN1PC1kZmhfYyU+JXN1bW1hcmlzZShTZXhvX01hc2N1bGlubyA9IGZpbHRlcihkZmhfYyxzZXhvX2g9PTEpJT4lY291bnQoKSU+JXB1bGwoKSwKICAgICAgICAgICAgICAgICAgU2V4b19GZW1lbmlubyA9IGZpbHRlcihkZmhfYyxzZXhvX2g9PTIpJT4lY291bnQoKSU+JXB1bGwoKSwKICAgICAgICAgICAgICAgICBQcm9tZWRpb19FZGFkX0VudHJldmlzdGFkbyA9IG1lYW4oZWRhZF9oKSwKICAgICAgICAgICAgICAgICBTZXhvX01hc2N1bGlub19QUCA9IGZpbHRlcihkZmhfYyxwcF9zZXhvPT0xKSU+JWNvdW50KCklPiVwdWxsKCksCiAgICAgICAgICAgICAgICAgU2V4b19GZW1lbmlub19QUCA9IGZpbHRlcihkZmhfYyxwcF9zZXhvPT0yKSU+JWNvdW50KCklPiVwdWxsKCksCiAgICAgICAgICAgICAgICAgRWRhZF9Nw61uaW1hX1BQID0gbWluKHBwX2VkYWQpLAogICAgICAgICAgICAgICAgIEVkYWRfTcOheGltYV9QUCA9IG1heChwcF9lZGFkKSwKICAgICAgICAgICAgICAgICBQcm9tZWRpb19FZGFkX1BQXzIwMTcgPSBtZWFuKHBwX2VkYWQpKzIyKQoKCnN0YXJnYXplcihyZXN1LHN1bW1hcnkgPSBGQUxTRSwgZGlnaXRzID0gMSwgZmxpcCA9IFRSVUUpCmBgYAojIEVzdGEgZGVzIGJhc2VzIEVOSUdICgpgYGB7cn0KcmVzdWVuPC0gZGF0YS5mcmFtZSgpJT4lc3VtbWFyaXNlKAogIFRhbWFub19kZV9tdWVzdHJhID0gYyhucm93KGVuaWdoXzk0KSxucm93KGVuaWdoXzk2KSxucm93KGVuaWdoXzk4KSksCiAgSG9tYnJlcyA9IGMobnJvdyhlbmlnaF85NCU+JWZpbHRlcihzZXhvPT0xKSksbnJvdyhlbmlnaF85NiU+JWZpbHRlcihzZXhvPT0xKSksCiAgICAgICAgICAgICAgbnJvdyhlbmlnaF85OCU+JWZpbHRlcihzZXhvPT0xKSkpLAogIE11amVyZXMgPSBjKG5yb3coZW5pZ2hfOTQlPiVmaWx0ZXIoc2V4bz09MikpLG5yb3coZW5pZ2hfOTYlPiVmaWx0ZXIoc2V4bz09MikpLAogICAgICAgICAgICAgIG5yb3coZW5pZ2hfOTglPiVmaWx0ZXIoc2V4bz09MikpKSwKICBQcm9tZWRpb19JbmdyZXNvcyA9IGMoZW5pZ2hfOTQlPiVzZWxlY3QoaW5nX21lbl9wKSU+JXB1bGwoKSU+JW1lYW4oKSpJTiwKICAgICAgICAgICAgICAgICAgICAgICAgZW5pZ2hfOTYlPiVzZWxlY3QoaW5nX21lbl9wKSU+JXB1bGwoKSU+JW1lYW4oKSpJTiwKICAgICAgICAgICAgICAgICAgICAgICAgZW5pZ2hfOTglPiVzZWxlY3QoaW5nX21lbl9wKSU+JXB1bGwoKSU+JW1lYW4oKSpJTiksCiAgUHJvbWVkaW9fbG9nSW5ncmVzb3MgPSBsb2coUHJvbWVkaW9fSW5ncmVzb3MpCiAgKQpyb3cubmFtZXMocmVzdWVuKSA9IGMoIkU5NCIsIkU5NiIsIkU5OCIpCnJlc3VlbgoKc3RhcmdhemVyKHJlc3VlbixzdW1tYXJ5ID0gRkFMU0UpCmBgYAoKIyMgcHJvbWVkaW8gZGUgaW5ncmVzbyBwb3IgZWRhZAoKCmBgYHtyfQpteU1lbnVJdGVtcyA8LSBjKCJkb3dubG9hZFBORyIsICJkb3dubG9hZEpQRUciLCAiZG93bmxvYWRQREYiLCAnZG93bmxvYWRTVkcnLCAncHJpbnRDaGFydCcpCmluZ3Jlc29fZWRhZDwtZnVuY3Rpb24oZGYpewpkZiAlPiUKICBncm91cF9ieShlZGFkKSU+JQogICAgYXJyYW5nZShlZGFkKSU+JQogIHN1bW1hcmlzZSgKICAgcHJvX2luZyA9IG1lYW4oaW5nX21lbl9wKSpJTgogICklPiUKaGNoYXJ0KCAic2NhdHRlciIsIAogICAgICAgIGhjYWVzKHggPSBlZGFkLCB5ID0gcHJvX2luZyksCiAgICAgICAgbmFtZT0iSW5ncmVzbyBwcm9tZWRpbyIsCiAgICAgICAgcmVncmVzc2lvbiA9IFRSVUUsCiAgICAgICAgICByZWdyZXNzaW9uU2V0dGluZ3MgPSBsaXN0KAogICAgdHlwZSA9ICJwb2x5bm9taWFsIiwKICAgIGRhc2hTdHlsZSA9ICJTaG9ydERhc2giLAogICAgY29sb3IgPSAic2t5Ymx1ZSIsCiAgICBvcmRlciA9IDIsCiAgICBsaW5lV2lkdGggPSA1LAogICAgbmFtZSA9ICIlZXEgfCAkcl4yJDogJXIiLAogICAgaGlkZUluTGVnZW5kID0gRkFMU0UpCiAgICAgICAgKSU+JQogIGhjX2FkZF9kZXBlbmRlbmN5KCJwbHVnaW5zL2hpZ2hjaGFydHMtcmVncmVzc2lvbi5qcyIpJT4lCiAgaGNfeUF4aXModGl0bGUgPSBsaXN0KHRleHQgPSAiUHJvbWVkaW8gZGUgaW5ncmVzbyBwb3IgZWRhZCIpKSU+JQogICAgaGNfYWRkX3RoZW1lKGhjX3RoZW1lX2dncGxvdDIoKSklPiUKICAgIGhjX3RpdGxlKAogICAgdGV4dCA9ICJQcm9tZWRpbyBkZSBpbmdyZXNvIHBvciBlZGFkIEU5OCIKICApICU+JQogIGhjX3hBeGlzKHRpdGxlPWxpc3QodGV4dD0iRWRhZCIpKSAlPiUKICAgIGhjX2V4cG9ydGluZyhlbmFibGVkID0gVFJVRSwKICAgICAgICAgICAgICAgZmlsZW5hbWUgPSAiZGF0b3MiLAogICAgICAgICAgICAgICBidXR0b25zID0gbGlzdChjb250ZXh0QnV0dG9uID0gbGlzdChtZW51SXRlbXMgPSBteU1lbnVJdGVtcykpKQp9CmluZ3Jlc29fZWRhZChlbmlnaF85OCkKYGBgCgojIyBoaXN0byBpbmdyZXNvCgoKYGBge3J9Cm15TWVudUl0ZW1zIDwtIGMoImRvd25sb2FkUE5HIiwgImRvd25sb2FkSlBFRyIsICJkb3dubG9hZFBERiIsICdkb3dubG9hZFNWRycsICdwcmludENoYXJ0JykKaGlzdG9faW5ncmVzbzwtZnVuY3Rpb24oZGYpewphPC1zb3J0KGRmJGxpbmdfbWVuX3BkKQojYTwtYVsxOihsZW5ndGgoYSktNSldCiNhPC1hWzU6KGxlbmd0aChhKSldCgpoY2hhcnQoYSwgbmFtZT0gIkZyZWN1ZW5jaWEiKSU+JQogIGhjX3lBeGlzKHRpdGxlID0gbGlzdCh0ZXh0ID0iTsO6bWVybyBkZSBzZWxlY2Npb25hZG9zIiApKSU+JQogICAgaGNfYWRkX3RoZW1lKGhjX3RoZW1lX2dncGxvdDIoKSklPiUKICAgIGhjX3RpdGxlKAogICAgdGV4dCA9ICJEaXN0cmlidWNpw7NuIGRlIGluZ3Jlc28gRTk4IgogICkgJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJMb2dhcml0bW8gZGVsIEluZ3Jlc28gKGRlZmxhY3RhZG8pIikpICU+JQogICAgaGNfZXhwb3J0aW5nKGVuYWJsZWQgPSBUUlVFLAogICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJkYXRvcyIsCiAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KGNvbnRleHRCdXR0b24gPSBsaXN0KG1lbnVJdGVtcyA9IG15TWVudUl0ZW1zKSkpCn0KaGlzdG9faW5ncmVzbyhlbmlnaF85OCkKYGBgCgojIyByZXZpc2nDs24gcmFuZ28gcGVyY2VudGlsCgpgYGB7cn0KZDwtIGVuaWdoXzk4cCRsaW5nX21lbl9wZApyZDwtcmFuayhkKQpuZDwtbGVuZ3RoKGQpCnJhbmdvcDwtIHJkL25kCm1pbihyYW5nb3ApCm1heChyYW5nb3ApCgpkMTwtIGluZ3Jlc29zX2U5OCRsaW5nX21lbl9wCmQxCgpkMjwtIGluZ3Jlc29zX2U5OCRsaW5nX21lbl9wZApkMgoKZGZlPC1kYXRhLmZyYW1lKGQsZDEsZDIpCgp0YWlsKGRmZSkKCmF1eF9wcnI8LWZ1bmN0aW9uKGluZyxudW1fYmFzZSl7CiAgICBlcnJvcl9lPC0gYWJzKGJhc2VfbG9nc2luZ1tbbnVtX2Jhc2VdXSRsaW5nX21lbl9wZCAtIGluZykKICAgICNwcmludChlcnJvcl9lKQogICAgaW5kaWNlX2U8LW1hdGNoKG1pbihlcnJvcl9lKSxlcnJvcl9lKQogICAgcHJpbnQoaW5kaWNlX2UpCiAgICBpbmRpY2VfZTwtaW5kaWNlX2VbMV0KICAgIHJldHVybihiYXNlX3JwW1tudW1fYmFzZV1dW2luZGljZV9lXSoxMDApCiAgfQphdXhfcHJyKDcsMykKCmJhc2VfbG9nc2luZ1tbM11dJGxpbmdfbWVuX3BkWzQxNjddCgpmPC1iYXNlX2xvZ3NpbmdbWzNdXSRsaW5nX21lbl9wZCAtIDcKZls0MTY3XQoKZGZlWzQxNjcsXQpkWzQxNjddCnJhbmdvcFs0MTY3XQpgYGAKIyMgZGVuc2lkYWQgaW5ncmUgc2VsZWNpb25hZG9zCgpgYGB7cn0KbXlNZW51SXRlbXMgPC0gYygiZG93bmxvYWRQTkciLCAiZG93bmxvYWRKUEVHIiwgImRvd25sb2FkUERGIiwgJ2Rvd25sb2FkU1ZHJywgJ3ByaW50Q2hhcnQnKQphMTwtc29ydChlbmlnaF85NCRsaW5nX21lbl9wZCkKYTI8LXNvcnQoZW5pZ2hfOTYkbGluZ19tZW5fcGQpCmEzPC1zb3J0KGVuaWdoXzk4JGxpbmdfbWVuX3BkKQoKaGNoYXJ0KAogIGRlbnNpdHkoYTEpLCAKICB0eXBlID0gImFyZWEiLCAKICBuYW1lID0gIkU5NCIKICApJT4lCiAgaGNfYWRkX3NlcmllcygKICAgIGRlbnNpdHkoYTIpLCB0eXBlID0gImFyZWEiLAogICAgbmFtZSA9ICJFOTYiCiAgICApJT4lCiAgaGNfYWRkX3NlcmllcygKICAgIGRlbnNpdHkoYTMpLCB0eXBlID0gImFyZWEiLAogICAgbmFtZSA9ICJFOTgiCiAgICApJT4lCmhjX3lBeGlzKHRpdGxlID0gbGlzdCh0ZXh0ID0iUHJvcG9yY2nDs24gZGUgc2VsZWNjaW9uYWRvcyIgKSklPiUKICAgIGhjX2FkZF90aGVtZShoY190aGVtZV9nZ3Bsb3QyKCkpJT4lCiAgICBoY190aXRsZSgKICAgIHRleHQgPSAiRGVuc2lkYWQgZGUgaW5ncmVzbyBFOTQsIEU5NiwgeSBFOTgiCiAgKSAlPiUKICBoY194QXhpcyh0aXRsZT1saXN0KHRleHQ9IkxvZ2FyaXRtbyBkZWwgSW5ncmVzbyAoZGVmbGFjdGFkbykiKSkgJT4lCiAgICBoY19leHBvcnRpbmcoZW5hYmxlZCA9IFRSVUUsCiAgICAgICAgICAgICAgIGZpbGVuYW1lID0gImRhdG9zIiwKICAgICAgICAgICAgICAgYnV0dG9ucyA9IGxpc3QoY29udGV4dEJ1dHRvbiA9IGxpc3QobWVudUl0ZW1zID0gbXlNZW51SXRlbXMpKSkKYGBgCgojIyBkZW5zaWRhZCBpbmdyZSB0b3RhbCB2aWVqYXMKCmBgYHtyfQpteU1lbnVJdGVtcyA8LSBjKCJkb3dubG9hZFBORyIsICJkb3dubG9hZEpQRUciLCAiZG93bmxvYWRQREYiLCAnZG93bmxvYWRTVkcnLCAncHJpbnRDaGFydCcpCmExPC1zb3J0KGluZ3Jlc29zX2U5NCRsaW5nX21lbl9wZCkKYTI8LXNvcnQoaW5ncmVzb3NfZTk2JGxpbmdfbWVuX3BkKQphMzwtc29ydChpbmdyZXNvc19lOTgkbGluZ19tZW5fcGQpCgpoY2hhcnQoCiAgZGVuc2l0eShhMSksIAogIHR5cGUgPSAiYXJlYSIsIAogIG5hbWUgPSAiRTk0IgogICklPiUKICBoY19hZGRfc2VyaWVzKAogICAgZGVuc2l0eShhMiksIHR5cGUgPSAiYXJlYSIsCiAgICBuYW1lID0gIkU5NiIKICAgICklPiUKICBoY19hZGRfc2VyaWVzKAogICAgZGVuc2l0eShhMyksIHR5cGUgPSAiYXJlYSIsCiAgICBuYW1lID0gIkU5OCIKICAgICklPiUKaGNfeUF4aXModGl0bGUgPSBsaXN0KHRleHQgPSJQcm9wb3JjacOzbiBkZSBzZWxlY2Npb25hZG9zIiApKSU+JQogICAgaGNfYWRkX3RoZW1lKGhjX3RoZW1lX2dncGxvdDIoKSklPiUKICAgIGhjX3RpdGxlKAogICAgdGV4dCA9ICJEZW5zaWRhZCBkZSBpbmdyZXNvIEU5NCwgRTk2LCB5IEU5OCIKICApICU+JQogIGhjX3hBeGlzKHRpdGxlPWxpc3QodGV4dD0iTG9nYXJpdG1vIGRlbCBJbmdyZXNvIChkZWZsYWN0YWRvKSIpKSAlPiUKICAgIGhjX2V4cG9ydGluZyhlbmFibGVkID0gVFJVRSwKICAgICAgICAgICAgICAgZmlsZW5hbWUgPSAiZGF0b3MiLAogICAgICAgICAgICAgICBidXR0b25zID0gbGlzdChjb250ZXh0QnV0dG9uID0gbGlzdChtZW51SXRlbXMgPSBteU1lbnVJdGVtcykpKQpgYGAKIyMgZGVuc2lkYWQgaW5ncmUgdG90YWwgdmllamFzCgpgYGB7cn0KbXlNZW51SXRlbXMgPC0gYygiZG93bmxvYWRQTkciLCAiZG93bmxvYWRKUEVHIiwgImRvd25sb2FkUERGIiwgJ2Rvd25sb2FkU1ZHJywgJ3ByaW50Q2hhcnQnKQphMTwtc29ydChpbmdyZXNvc19lMTZhJGxpbmdfbWVuX3BkKQphMjwtc29ydChpbmdyZXNvc19lMThhJGxpbmdfbWVuX3BkKQoKaGNoYXJ0KAogIGRlbnNpdHkoYTEpLCAKICB0eXBlID0gImFyZWEiLCAKICBuYW1lID0gIkUxNiIKICApJT4lCiAgaGNfYWRkX3NlcmllcygKICAgIGRlbnNpdHkoYTIpLCB0eXBlID0gImFyZWEiLAogICAgbmFtZSA9ICJFMTgiCiAgICApJT4lCgpoY195QXhpcyh0aXRsZSA9IGxpc3QodGV4dCA9IlByb3BvcmNpw7NuIGRlIHNlbGVjY2lvbmFkb3MiICkpJT4lCiAgICBoY19hZGRfdGhlbWUoaGNfdGhlbWVfZ2dwbG90MigpKSU+JQogICAgaGNfdGl0bGUoCiAgICB0ZXh0ID0gIkRlbnNpZGFkIGRlIGluZ3Jlc28gRTE2IHkgRTE4IgogICkgJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJMb2dhcml0bW8gZGVsIEluZ3Jlc28gKGRlZmxhY3RhZG8pIikpICU+JQogICAgaGNfZXhwb3J0aW5nKGVuYWJsZWQgPSBUUlVFLAogICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJkYXRvcyIsCiAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KGNvbnRleHRCdXR0b24gPSBsaXN0KG1lbnVJdGVtcyA9IG15TWVudUl0ZW1zKSkpCmBgYAoKIyMgZGVuc2lkYWQgaW5ncmUgY29uanVheSB0b3RhbCB2aWVqYXMKCmBgYHtyfQppbmdyZTE2MThfZ3JhPC1iaW5kX3Jvd3MoaW5ncmVzb3NfZTE2YSxpbmdyZXNvc19lMThhKQpucm93KGluZ3JlMTYxOF9ncmEpCgppbmdyZTk0OTY5OF9ncmE8LWJpbmRfcm93cyhpbmdyZXNvc19lOTQsaW5ncmVzb3NfZTk2LGluZ3Jlc29zX2U5OCkKYGBgCgoKCmBgYHtyfQpteU1lbnVJdGVtcyA8LSBjKCJkb3dubG9hZFBORyIsICJkb3dubG9hZEpQRUciLCAiZG93bmxvYWRQREYiLCAnZG93bmxvYWRTVkcnLCAncHJpbnRDaGFydCcpCmExPC1zb3J0KGluZ3JlMTYxOF9ncmEkbGluZ19tZW5fcGQpCgpoY2hhcnQoCiAgZGVuc2l0eShhMSksIAogIHR5cGUgPSAiYXJlYSIsIAogIG5hbWUgPSAiRTE2LUUxOCIKICApJT4lCgpoY195QXhpcyh0aXRsZSA9IGxpc3QodGV4dCA9IlByb3BvcmNpw7NuIGRlIHNlbGVjY2lvbmFkb3MiICkpJT4lCiAgICBoY19hZGRfdGhlbWUoaGNfdGhlbWVfZ2dwbG90MigpKSU+JQpoY190aXRsZSgKICAgIHRleHQgPSAiRGVuc2lkYWQgZGUgaW5ncmVzbyB1bmlvbiBFMTYtRTE4IgogICkgJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJMb2dhcml0bW8gZGVsIEluZ3Jlc28gKGRlZmxhY3RhZG8pIikpICU+JQogICAgaGNfZXhwb3J0aW5nKGVuYWJsZWQgPSBUUlVFLAogICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJkYXRvcyIsCiAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KGNvbnRleHRCdXR0b24gPSBsaXN0KG1lbnVJdGVtcyA9IG15TWVudUl0ZW1zKSkpCmBgYAoKIyMgVG90YWwgdmllamVhcyB5IG51ZXZhcyAKCmBgYHtyfQpteU1lbnVJdGVtcyA8LSBjKCJkb3dubG9hZFBORyIsICJkb3dubG9hZEpQRUciLCAiZG93bmxvYWRQREYiLCAnZG93bmxvYWRTVkcnLCAncHJpbnRDaGFydCcpCmEyPC1leHAoaW5ncmUxNjE4X2dyYSU+JXNlbGVjdChsaW5nX21lbl9wZCklPiVwdWxsKCkpCmExPC1leHAoaW5ncmU5NDk2OThfZ3JhJT4lc2VsZWN0KGxpbmdfbWVuX3BkKSU+JXB1bGwoKSkKeCA8LSBoaXN0KGExLCBwbG90ID0gRkFMU0UpCnkgPC0gaGlzdChhMiwgcGxvdCA9IEZBTFNFKQoKYTJwPC1wZXJjZW50X3JhbmsoYTIpCmExcDwtcGVyY2VudF9yYW5rKGExKQojYTE8LXBlcmNlbnRfcmFuayhhMSkqMTAwCiNhMjwtcGVyY2VudF9yYW5rKGEyKSoxMDAKaGNoYXJ0KAogICBhMi9sZW5ndGgoYTIpLAogIGJyZWFrcyA9IDUwMDAsCiAgI3R5cGUgPSAiYXJlYSIsIAogIG5hbWUgPSAiRTk0LUU5Ni1FOTgiCiAgKSU+JQoKaGNfYWRkX3NlcmllcygKICBkZW5zaXR5KGExKSwgCiAgYnJlYWtzID0gMjAsCiAjdHlwZSA9ICJhcmVhIiwgCiAgbmFtZSA9ICJFMTYtRTE4IgogICklPiUKaGNfeUF4aXModGl0bGUgPSBsaXN0KHRleHQgPSJQcm9wb3JjacOzbiBkZSBzZWxlY2Npb25hZG9zIiApKSU+JQogICAgaGNfYWRkX3RoZW1lKGhjX3RoZW1lX2dncGxvdDIoKSklPiUKaGNfdGl0bGUoCiAgICB0ZXh0ID0gIkRlbnNpZGFkIGRlIGluZ3Jlc28gdW5pb24sIEU5NC1FOTYtRTk4LCBFMTYtRTE4IgogICkgJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJMb2dhcml0bW8gZGVsIEluZ3Jlc28gKGRlZmxhY3RhZG8pIiksIyklPiUKICAgICAgICAgIG1pbiA9IDAsCiAgICAgICAgICAgbWF4ID0gMzAwMDApICU+JQogIGhjX3hBeGlzKHBsb3RMaW5lcyA9IGxpc3QobGlzdCh2YWx1ZT1tZWRpYW4oYTEpLGNvbG9yPSJyZWQiLHdpZHRoPTIgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QodmFsdWUgPSBtZWRpYW4oYTIpLGNvbG9yPSJibHVlIix3aWR0aD0yKSkpJT4lCiAgI2hjX3hBeGlzKHBsb3RMaW5lcyA9IGxpc3QobGlzdCh2YWx1ZT1tZWRpYW4oYTIpLGNvbG9yID0gInJlZCIgKSkpJT4lCiAgICBoY19leHBvcnRpbmcoZW5hYmxlZCA9IFRSVUUsCiAgICAgICAgICAgICAgIGZpbGVuYW1lID0gImRhdG9zIiwKICAgICAgICAgICAgICAgYnV0dG9ucyA9IGxpc3QoY29udGV4dEJ1dHRvbiA9IGxpc3QobWVudUl0ZW1zID0gbXlNZW51SXRlbXMpKSkKYGBgCgojIyB0b3RhbCBoaXNvdGdyYW1hIGNvbXBsZXRvCgpgYGB7cn0KYTI8LWluZ3JlMTYxOF9ncmElPiVzZWxlY3QobGluZ19tZW5fcGQpJT4lcHVsbCgpCmExPC1pbmdyZTk0OTY5OF9ncmElPiVzZWxlY3QobGluZ19tZW5fcGQpJT4lcHVsbCgpCgpkYXRzIDwtIHJiaW5kKGRhdGEuZnJhbWUocHJlZCA9IGExLCBFbmN1ZXN0YSA9ICdFOTQtRTk2LUU5OCcpLAogICAgICAgICAgICAgIGRhdGEuZnJhbWUocHJlZCA9IGEyLCBFbmN1ZXN0YSA9ICdFMTYtRTE4JykpCgojIGhlcmUgdGhlIHBsb3QKZ2dwbG90KGRhdHMsIGFlcyhwcmVkLCBmaWxsID0gRW5jdWVzdGEpKSArIAogICNnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjUsIHBvc2l0aW9uID0gImlkZW50aXR5IiwgYmlucyA9IDYwKSsKICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjUsIHBvc2l0aW9uID0gImlkZW50aXR5IikrCiAgICAjeGxpbSgwLDMwMDAwKSsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdD1tZWRpYW4oYTEpLGNvbG9yID0gImJsdWUiKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PW1lZGlhbihhMiksY29sb3IgPSAicmVkIikrCiAgbGFicyh0aXRsZSA9ICJEZW5zaWRhZCBkZSBpbmdyZXNvIikrCiAgICAgICAgICAKICAgICAgICB4bGFiKCJMb2dhcml0bW8gSW5ncmVzb3MiKSAgKwogICAgICAgIHlsYWIoIkRlbnNpZGFkIikgCgoKCgoKYGBgCgoKCiMjIHJlZ2luYWxlcyBudWV2YXMgeSB2aWVqYXMKCmBgYHtyfQpoaWdoY2hhcnQodHlwZSA9ICJjaGFydCIpJT4lCiAgIGhjX3lBeGlzX211bHRpcGxlcygKICAgICBjcmVhdGVfeWF4aXMoNCwgaGVpZ2h0ID0gYyg1LDUsNSw1KSwgc2VwPTAuMSwgb2Zmc2V0PTAuNSwgdHVybm9wcG9zaXRlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgIHRpdGxlID0gbGlzdCh0ZXh0ID0gcmVwKCJOw7ptZXJvIGRlIGNhc29zIGNvbmZpcm1hZG9zIiw0KSkpCiAgICAgCiAgICAgKSAlPiUKICAKICBoY19hZGRfc2VyaWVzKG5hbWU9InJlZ2nDs24gMSBFOTQtRTk2LUU5OCIsZGVuc2l0eShpbmdyZTk0OTY5OF9ncmElPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIocmVnaW9uPT0xKSU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChsaW5nX21lbl9wZCklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWxsKCkpLAogICAgICAgICAgICAgICAgeUF4aXM9MCklPiUKCiAgaGNfYWRkX3NlcmllcyhuYW1lPSJyZWdpw7NuIDEgRTE2LUUxOCIsZGVuc2l0eShpbmdyZTE2MThfZ3JhJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHJlZ2lvbj09MSklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobGluZ19tZW5fcGQpJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbCgpKSwKICAgICAgICAgICAgICAgIHlBeGlzPTApJT4lCiAgaGNfYWRkX3NlcmllcyhuYW1lPSJyZWdpw7NuIDIgRTk0LUU5Ni1FOTgiLGRlbnNpdHkoaW5ncmU5NDk2OThfZ3JhJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHJlZ2lvbj09MiklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobGluZ19tZW5fcGQpJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbCgpKSwKICAgICAgICAgICAgICAgIHlBeGlzPTEpJT4lCiAgaGNfYWRkX3NlcmllcyhuYW1lPSJyZWdpw7NuIDIgRTE2LUUxOCIsZGVuc2l0eShpbmdyZTE2MThfZ3JhJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHJlZ2lvbj09MiklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobGluZ19tZW5fcGQpJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbCgpKSwKICAgICAgICAgICAgICAgIHlBeGlzPTEpJT4lCiAgaGNfYWRkX3NlcmllcyhuYW1lPSJyZWdpw7NuIDMgRTk0LUU5Ni1FOTgiLGRlbnNpdHkoaW5ncmU5NDk2OThfZ3JhJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHJlZ2lvbj09MyklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobGluZ19tZW5fcGQpJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbCgpKSwKICAgICAgICAgICAgICAgIHlBeGlzPTIpJT4lCiAgaGNfYWRkX3NlcmllcyhuYW1lPSJyZWdpw7NuIDMgRTE2LUUxOCIsZGVuc2l0eShpbmdyZTE2MThfZ3JhJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHJlZ2lvbj09MyklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobGluZ19tZW5fcGQpJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbCgpKSwKICAgICAgICAgICAgICAgIHlBeGlzPTIpJT4lCiAgaGNfYWRkX3NlcmllcyhuYW1lPSJyZWdpw7NuIDQgRTk0LUU5Ni1FOTgiLGRlbnNpdHkoaW5ncmU5NDk2OThfZ3JhJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHJlZ2lvbj09NCklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobGluZ19tZW5fcGQpJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbCgpKSwKICAgICAgICAgICAgICAgIHlBeGlzPTMpJT4lCiAgaGNfYWRkX3NlcmllcyhuYW1lPSJyZWdpw7NuIDQgRTE2LUUxOCIsZGVuc2l0eShpbmdyZTE2MThfZ3JhJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHJlZ2lvbj09NCklPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QobGluZ19tZW5fcGQpJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVsbCgpKSwKICAgICAgICAgICAgICAgIHlBeGlzPTMpJT4lCiAgCiNoY195QXhpcyh0aXRsZSA9IGxpc3QodGV4dCA9IlByb3BvcmNpw7NuIGRlIHNlbGVjY2lvbmFkb3MiICkpJT4lCiAgCmhjX2FkZF90aGVtZShoY190aGVtZV9nZ3Bsb3QyKCkpJT4lCiAgaGNfdGl0bGUodGV4dCA9ICJEZW5zaWRhZCBwb3IgcmVnacOzbiBFOTQtRTk2LUU5OCwgRTE2LUUxOCAiKSU+JQogICAgICAgICAgICNtYXJnaW4gPSAyMCwgYWxpZ24gPSAibGVmdCIsCiAgICAgICNzdHlsZSA9IGxpc3QoY29sb3IgPSAiIzkwZWQ3ZCIsIHVzZUhUTUwgPSBUUlVFKSkgJT4lIAogIyBoY19zdWJ0aXRsZSh0ZXh0ID0gIlV0aWxpY2UgbGEgaGVycmFtaWVudGEgZGUgem9vbSBlbiBsYQogIyAgICAgICAgICAgICBwYXJ0ZSBpbmZlcmlvciIpJT4lCiAjIGhjX3Rvb2x0aXAoY3Jvc3NoYWlycyA9IFRSVUUsIGJhY2tncm91bmRDb2xvciA9ICIjRkNGRkM1IiwKICAjICAgICAgICAgICBzaGFyZWQgPSBUUlVFLCBib3JkZXJXaWR0aCA9IDUpICU+JSAKI2hjX3lBeGlzKHRpdGxlID0gbGlzdCh0ZXh0ID0gcmVwKCJOw7ptZXJvIGRlIGNhc29zIGNvbmZpcm1hZG9zIiw0KSklPiUKICAgIGhjX2V4cG9ydGluZyhlbmFibGVkID0gVFJVRSwKICAgICAgZmlsZW5hbWUgPSAiZGF0b3MiLAogICAgICBidXR0b25zID0gbGlzdChjb250ZXh0QnV0dG9uID0gbGlzdChtZW51SXRlbXMgPSBteU1lbnVJdGVtcykpKQpgYGAKCgoKCgojIGRlbnNpZGFkIHBvciByZWdpw7NuCgpgYGB7cn0KCmRlbl9yZWdpb248LWZ1bmN0aW9uKGRmKXsKYTE8LWRmJT4lZmlsdGVyKHJlZ2lvbj09MSklPiVzZWxlY3QobGluZ19tZW5fcGQpJT4lcHVsbCgpCmEyPC1kZiU+JWZpbHRlcihyZWdpb249PTIpJT4lc2VsZWN0KGxpbmdfbWVuX3BkKSU+JXB1bGwoKQphMzwtZGYlPiVmaWx0ZXIocmVnaW9uPT0zKSU+JXNlbGVjdChsaW5nX21lbl9wZCklPiVwdWxsKCkKYTQ8LSBkZiU+JWZpbHRlcihyZWdpb249PTQpJT4lc2VsZWN0KGxpbmdfbWVuX3BkKSU+JXB1bGwoKQoKaGNoYXJ0KAogIGRlbnNpdHkoYTEpLCAKICB0eXBlID0gImFyZWEiLCAKICBuYW1lID0gInJlZ2nDs24gMSIKICApJT4lCiAgaGNfYWRkX3NlcmllcygKICAgIGRlbnNpdHkoYTIpLCB0eXBlID0gImFyZWEiLAogICAgbmFtZSA9ICJyZWdpw7NuIDIiCiAgICApJT4lCiAgaGNfYWRkX3NlcmllcygKICAgIGRlbnNpdHkoYTMpLCB0eXBlID0gImFyZWEiLAogICAgbmFtZSA9ICJyZWdpw7NuIDMiCiAgICApJT4lCiAgaGNfYWRkX3NlcmllcygKICAgIGRlbnNpdHkoYTQpLCB0eXBlID0gImFyZWEiLAogICAgbmFtZSA9ICJyZWdpw7NuIDQiCiAgICApJT4lCmhjX3lBeGlzKHRpdGxlID0gbGlzdCh0ZXh0ID0iUHJvcG9yY2nDs24gZGUgc2VsZWNjaW9uYWRvcyIgKSklPiUKICAgIGhjX2FkZF90aGVtZShoY190aGVtZV9nZ3Bsb3QyKCkpJT4lCiAgICBoY190aXRsZSgKICAgIHRleHQgPSAiRGVuc2lkYWQgZGUgaW5ncmVzbyBwb3IgcmVnacOzbiwgRTE2LUUxOCIKICApICU+JQogIGhjX3hBeGlzKHRpdGxlPWxpc3QodGV4dD0iTG9nYXJpdG1vIGRlbCBJbmdyZXNvIChkZWZsYWN0YWRvKSIpKSAlPiUKICAgIGhjX2V4cG9ydGluZyhlbmFibGVkID0gVFJVRSwKICAgICAgICAgICAgICAgZmlsZW5hbWUgPSAiZGF0b3MiLAogICAgICAgICAgICAgICBidXR0b25zID0gbGlzdChjb250ZXh0QnV0dG9uID0gbGlzdChtZW51SXRlbXMgPSBteU1lbnVJdGVtcykpKQp9CgoKZGVuX3JlZ2lvbihpbmdyZTE2MThfZ3JhKQpgYGAKCiMgZWRhZCByZWdpb24gaW5ncmVzbwoKYGBge3J9Cm15TWVudUl0ZW1zIDwtIGMoImRvd25sb2FkUE5HIiwgImRvd25sb2FkSlBFRyIsICJkb3dubG9hZFBERiIsICdkb3dubG9hZFNWRycsICdwcmludENoYXJ0JykKaW5ncmVzb19lZGFkX3JlZ2lvbjwtZnVuY3Rpb24oZGYpewpkZiAlPiUKICBncm91cF9ieShyZWdpb24sZWRhZCklPiUKICBzdW1tYXJpc2UoCiAgIHByb19pbmcgPSBtZWFuKGluZ19tZW5fcCkqSU4KICApJT4lCmhjaGFydCggImxpbmUiLCAKICAgICAgICBoY2Flcyh4ID0gZWRhZCwgeSA9IHByb19pbmcsIGdyb3VwID0gcmVnaW9uICkpJT4lCiAgaGNfeUF4aXModGl0bGUgPSBsaXN0KHRleHQgPSAiUHJvbWVkaW8gZGUgaW5ncmVzbyIpKSU+JQogICAgaGNfYWRkX3RoZW1lKGhjX3RoZW1lX2dncGxvdDIoKSklPiUKICAgIGhjX3RpdGxlKAogICAgdGV4dCA9ICJQcm9tZWRpbyBkZSBpbmdyZXNvIHBvciBlZGFkICB5IHJlZ2nDs24gRTk4IikgJT4lCiAgaGNfeEF4aXModGl0bGU9bGlzdCh0ZXh0PSJFZGFkIikpICU+JQogICAgaGNfZXhwb3J0aW5nKGVuYWJsZWQgPSBUUlVFLAogICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJkYXRvcyIsCiAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KGNvbnRleHRCdXR0b24gPSBsaXN0KG1lbnVJdGVtcyA9IG15TWVudUl0ZW1zKSkpCn0KaW5ncmVzb19lZGFkX3JlZ2lvbihlbmlnaF85OCkKYGBgCgoKCgojIE1hcGEgcmVnaW9uYWwKCgpgYGB7cn0KbXlNZW51SXRlbXMgPC0gYygiZG93bmxvYWRQTkciLCAiZG93bmxvYWRKUEVHIiwgImRvd25sb2FkUERGIiwgJ2Rvd25sb2FkU1ZHJywgJ3ByaW50Q2hhcnQnKQptYXBkYXRhIDwtIGdldF9kYXRhX2Zyb21fbWFwKGRvd25sb2FkX21hcF9kYXRhKCJjb3VudHJpZXMvbXgvbXgtYWxsIikpCgptYXBkYXRhCgptYXBhPC1tYXBkYXRhICU+JSAKICBzZWxlY3QoY29kZSA9IGB3b2UtbmFtZWApICU+JQogIGFycmFuZ2UoY29kZSklPiUKICBtdXRhdGUodHogPSBpZmVsc2UoY29kZSAgJWluJSBjKCJCYWphIENhbGlmb3JuaWEiLCAiQ2hpaHVhaHVhIiwgIkNvYWh1aWxhIiwgIk51ZXZvIExlw7NuIiwgIlNvbm9yYSIsICJUYW1hdWxpcGFzIiksInJlZ2nDs24gMSIsCmlmZWxzZShjb2RlICAlaW4lIGMoIkFndWFzY2FsaWVudGVzIiwiQmFqYSBDYWxpZm9ybmlhIFN1ciIsICJDb2xpbWEiLCAiRHVyYW5nbyIsICJKYWxpc2NvIiwgIk1pY2hvYWPDoW4iLCAiTmF5YXJpdCIsICJTYW4gTHVpcyBQb3Rvc8OtIiwgIlNpbmFsb2EiLCAiWmFjYXRlY2FzIiksInJlZ2nDs24gMiIsCiAgaWZlbHNlKGNvZGUgICVpbiUgYygiQ2FtcGVjaGUiLCAiQ2hpYXBhcyIsICJHdWVycmVybyIsICJPYXhhY2EiLCAiUXVpbnRhbmEgUm9vIiwgIlRhYmFzY28iLCAiVmVyYWNydXoiLCJZdWNhdMOhbiIpLCJyZWdpw7NuIDQiLCAicmVnacOzbiAzIikgIAogICAgICAgICAgICAgICAgICAgICAgICApICApLAp2YWx1ZSA9IGFzLmludGVnZXIoZmFjdG9yKHR6KSkpCgpkdGFfY2xzcyA8LSBtYXBhICU+JSAKICBncm91cF9ieSh0eikgJT4lIAogIHN1bW1hcmlzZSh2YWx1ZSA9IHVuaXF1ZSh2YWx1ZSkpICU+JSAKICBhcnJhbmdlKHZhbHVlKSAlPiUgCiAgcmVuYW1lKG5hbWUgPSB0eiwgZnJvbSA9IHZhbHVlKSAlPiUgCiAgbXV0YXRlKHRvID0gZnJvbSArIDEpICU+JSAKICBsaXN0X3BhcnNlKCkKCgpoY21hcCgiY291bnRyaWVzL214L214LWFsbCIsIGRhdGEgPSBtYXBhLCB2YWx1ZSA9ICJ2YWx1ZSIsCiAgICAgIGpvaW5CeSA9IGMoIndvZS1uYW1lIiwiY29kZSIpLCBuYW1lID0gIkVzdGFkbyIsCiAgICAgIHRvb2x0aXAgPSBsaXN0KHBvaW50Rm9ybWF0ID0gIntwb2ludC5uYW1lfSB7cG9pbnQudHp9IikpJT4lCiAgaGNfdGl0bGUoCiAgICB0ZXh0ID0gIlJlZ2lvbmVzIGRlIE3DqXhpY28iCiAgKSU+JQogIGhjX2FkZF90aGVtZShoY190aGVtZV9nZ3Bsb3QyKCkpJT4lCmhjX2NvbG9yQXhpcyhkYXRhQ2xhc3NDb2xvciA9ICJjYXRlZ29yeSIsCiAgICAgICAgICAgICBkYXRhQ2xhc3Nlcz1kdGFfY2xzcyklPiUKaGNfZXhwb3J0aW5nKGVuYWJsZWQgPSBUUlVFLAogICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJkYXRvcyIsCiAgICAgICAgICAgICAgIGJ1dHRvbnMgPSBsaXN0KGNvbnRleHRCdXR0b24gPSBsaXN0KG1lbnVJdGVtcyA9IG15TWVudUl0ZW1zKSkpCgpgYGAKCgpgYGB7cn0KZGF0YSA8LSB0aWJibGUoCiAgY291bnRyeSA9IAogICAgYygiUFQiLCAiSUUiLCAiR0IiLCAiSVMiLAogICAgICAKICAgICAgIk5PIiwgIlNFIiwgIkRLIiwgIkRFIiwgIk5MIiwgIkJFIiwgIkxVIiwgIkVTIiwgIkZSIiwgIlBMIiwgIkNaIiwgIkFUIiwKICAgICAgIkNIIiwgIkxJIiwgIlNLIiwgIkhVIiwgIlNJIiwgIklUIiwgIlNNIiwgIkhSIiwgIkJBIiwgIllGIiwgIk1FIiwgIkFMIiwgIk1LIiwKICAgICAgCiAgICAgICJGSSIsICJFRSIsICJMViIsICJMVCIsICJCWSIsICJVQSIsICJNRCIsICJSTyIsICJCRyIsICJHUiIsICJUUiIsICJDWSIsCiAgICAgIAogICAgICAiUlUiKSwgIAogIHR6ID0gYyhyZXAoIlVUQyIsIDQpLCByZXAoIlVUQyArIDEiLDI1KSwgcmVwKCJVQ1QgKyAyIiwxMiksICJVVEMgKyAzIikKICApCgpkYXRhIDwtIGRhdGEgJT4lIAogIG11dGF0ZSh2YWx1ZSA9IGN1bXN1bSghZHVwbGljYXRlZCh0eikpKQpgYGAKCiMjIGluZGl2aWR1b3MgcmVnaW9uCgpgYGB7cn0KbnJvdyhkZmhfYyU+JWZpbHRlcihyZWdpb249PTQpKQpgYGAKCiMgY2FsdWNsbyBkZSBiY2VybwoKCmBgYHtyfQpwcm9tZWRpb19iZXRhMDwtZnVuY3Rpb24oZGYsaSl7CnJldHVybihkZiRyZWdyZXNpb25bW2ldXSRjb2VmZmljaWVudHNbM10pCn0KCm1lYW4odW5saXN0KGxhcHBseSgxOjEwMCxwcm9tZWRpb19iZXRhMCxkZj1yZWdfY2RfMTAwKSkpCnNkKHVubGlzdChsYXBwbHkoMToxMDAscHJvbWVkaW9fYmV0YTAsZGY9cmVnX2NkXzEwMCkpKQoKCmBgYAoKYGBge3J9CnByb21lZGlvX3BhcGFzPC1mdW5jdGlvbihkZixpKXsKcmV0dXJuKGRmJHJlZ3Jlc2lvbnA5OFtbaV1dJGNvZWZmaWNpZW50c1syN10pCn0KbWVhbih1bmxpc3QobGFwcGx5KDE6MTAscHJvbWVkaW9fcGFwYXMsZGY9cmVnX2NkXzEwMCkpKQpzZCh1bmxpc3QobGFwcGx5KDE6MTAscHJvbWVkaW9fcGFwYXMsZGY9cmVnX2NkXzEwMCkpKQoKYGBgCmBgYHtyfQpwZXJjZW50aWxlcmFuazwtZnVuY3Rpb24oeCl7CiAgcng8LXJsZShzb3J0KHgpKQogIHNtYWxsZXI8LWN1bXN1bShjKDAsIHJ4JGxlbmd0aHMpKVtzZXEobGVuZ3RoKHJ4JGxlbmd0aHMpKV0KICBsYXJnZXI8LXJldihjdW1zdW0oYygwLCByZXYocngkbGVuZ3RocykpKSlbLTFdCiAgcnhwcjwtc21hbGxlci8oc21hbGxlcitsYXJnZXIpCiAgcnhwclttYXRjaCh4LCByeCR2YWx1ZXMpXQp9CgphPC1jKDAsMiwzLDQsNSwxLDEsMSkKcmFuayhhKS9sZW5ndGgoYSkKCnBlcmNlbnRpbGVyYW5rKGEpCnBlcmNlbnRfcmFuayhhKQpgYGAKCgoK