Presentación del tema

El presente documento electrónico explora el desempeño de las agrupaciones políticas ponderado por circuito electoral en la Elección General de 2021 para la categoría concejal en el Municipio de Lanús (Provincia de Buenos Aires).

Obtención de datos

Para desandar la exploración se utilizarán los datos detallados de las Elecciones Generales de 2021, obtenidos por medio de un pedido de información pública a la Cámara Nacional Electoral. El dataset contiene los resultados que obtuvieron las agrupaciones por cargo, escuela, circuito y distrito en todo el país.

library(readr)
library(tidyverse)
library(sf)
library(leaflet)
library(ggthemes)
library(viridis)

mesas_escrutadas <- read_delim(
  "elecciones/e2021_generales/mesas_escrutadas_cierre.csv", 
             delim = ";", 
             escape_double = FALSE,
             trim_ws = TRUE)

Se aplican funciones de resumen:

head

head(mesas_escrutadas)
## # A tibble: 6 x 18
##   Agrupacion  Cargo Codigo Distr~1 Estab~2 Fecha IdCargo IdCir~3 IdDis~4 IdSec~5
##   <chr>       <chr>  <dbl> <chr>   <chr>   <chr>   <dbl> <chr>     <dbl>   <dbl>
## 1 <NA>        DIPU~     22 Ciudad~ Colegi~ 14-1~       6 6             1       1
## 2 <NA>        DIPU~     22 Ciudad~ Colegi~ 14-1~       6 6             1       1
## 3 <NA>        DIPU~     22 Ciudad~ Colegi~ 14-1~       6 6             1       1
## 4 <NA>        DIPU~     22 Ciudad~ Colegi~ 14-1~       6 6             1       1
## 5 <NA>        DIPU~     22 Ciudad~ Colegi~ 14-1~       6 6             1       1
## 6 JUNTOS POR~ DIPU~     22 Ciudad~ Colegi~ 14-1~       6 6             1       1
## # ... with 8 more variables: Mesa <chr>, Seccion <chr>, electores <dbl>,
## #   envio <dbl>, idAgrupacion <dbl>, idAgrupacionInt <dbl>, tipoVoto <chr>,
## #   votos <dbl>, and abbreviated variable names 1: Distrito,
## #   2: Establecimiento, 3: IdCircuito, 4: IdDistrito, 5: IdSeccion
## # i Use `colnames()` to see all variable names

summary

summary(mesas_escrutadas)
##   Agrupacion           Cargo               Codigo        Distrito        
##  Length:2665130     Length:2665130     Min.   :    1   Length:2665130    
##  Class :character   Class :character   1st Qu.:  315   Class :character  
##  Mode  :character   Mode  :character   Median : 6235   Mode  :character  
##                                        Mean   : 8798                     
##                                        3rd Qu.:10489                     
##                                        Max.   :50186                     
##                                                                          
##  Establecimiento       Fecha              IdCargo        IdCircuito       
##  Length:2665130     Length:2665130     Min.   : 2.000   Length:2665130    
##  Class :character   Class :character   1st Qu.: 3.000   Class :character  
##  Mode  :character   Mode  :character   Median : 3.000   Mode  :character  
##                                        Mean   : 4.269                     
##                                        3rd Qu.: 6.000                     
##                                        Max.   :10.000                     
##                                                                           
##    IdDistrito       IdSeccion          Mesa             Seccion         
##  Min.   : 1.000   Min.   :  1.00   Length:2665130     Length:2665130    
##  1st Qu.: 2.000   1st Qu.:  5.00   Class :character   Class :character  
##  Median : 2.000   Median : 14.00   Mode  :character   Mode  :character  
##  Mean   : 7.423   Mean   : 35.96                                        
##  3rd Qu.:13.000   3rd Qu.: 62.00                                        
##  Max.   :24.000   Max.   :135.00                                        
##                                                                         
##    electores         envio        idAgrupacion     idAgrupacionInt  
##  Min.   :  1.0   Min.   : 1.00   Min.   :   2.0    Min.   :  7      
##  1st Qu.:346.0   1st Qu.:15.00   1st Qu.: 501.0    1st Qu.: 41      
##  Median :350.0   Median :20.00   Median : 503.0    Median : 91      
##  Mean   :343.3   Mean   :22.93   Mean   : 429.6    Mean   :114      
##  3rd Qu.:352.0   3rd Qu.:27.00   3rd Qu.: 506.0    3rd Qu.:170      
##  Max.   :595.0   Max.   :96.00   Max.   :2000.0    Max.   :638      
##                                  NA's   :1195120   NA's   :1195120  
##    tipoVoto             votos       
##  Length:2665130     Min.   :  0.00  
##  Class :character   1st Qu.:  0.00  
##  Mode  :character   Median :  6.00  
##                     Mean   : 21.84  
##                     3rd Qu.: 20.00  
##                     Max.   :304.00  
## 

class

class(mesas_escrutadas)
## [1] "spec_tbl_df" "tbl_df"      "tbl"         "data.frame"

names

names(mesas_escrutadas)
##  [1] "Agrupacion"      "Cargo"           "Codigo"          "Distrito"       
##  [5] "Establecimiento" "Fecha"           "IdCargo"         "IdCircuito"     
##  [9] "IdDistrito"      "IdSeccion"       "Mesa"            "Seccion"        
## [13] "electores"       "envio"           "idAgrupacion"    "idAgrupacionInt"
## [17] "tipoVoto"        "votos"

dim

dim(mesas_escrutadas)
## [1] 2665130      18

Los primeros resultados indican que se trata de un conjunto de datos relativamente “grande”, contando con 2.665.130 observaciones y 18 variables, en formato numérico y de texto.

Transformación de los datos

Para continuar la tarea, se filtran los datos para la sección Lanús y el cargo Concejales para dar cuenta de la premisa planteada al principio del documento.

lanus_concejales <- mesas_escrutadas%>%
  filter(Cargo=="CONCEJALES")%>%
  filter(Seccion=="Lanús")

Una nueva transformación crea un nuevo conjunto de datos que filtra sólo los votos positivos que obtuvieron las agrupaciones, tal como lo establece la Constitución Nacional para realizar los conteos en las elecciones generales.

Llegado este punto se procesa, por circuito electoral, la cantidad de votos de cada una de las agrupaciones por la cantidad de electores, con el objetivo de generar una nueva variable de ponderación llamada ratio.

lanus1<-lanus_concejales%>%
  filter(tipoVoto=="positivo")%>% #filtra votos positivos
  group_by(IdCircuito, Agrupacion)%>%
  summarise(votosxcirc=sum(votos),
            electoresxcirc=sum(electores))%>%
  mutate(ratio=votosxcirc/electoresxcirc) #crea ratio

El hecho de construir ratio es una decisión teórica que procura dar cuenta de la particularidad local de cada circuito electoral de Lanús y coadyuvar heurísticamente a una lectura comparativa de los datos en dos sentidos:

  1. Lectura del fenómeno del voto para una agrupación específica por circuito electoral para detectar zonas con mejor o peor ratio voto/electores.

  2. Comparación general del ratio por circuito electoral de las distintas agrupaciones.

Primeras impresiones

El nuevo df lanus1 consta de 6 variables, 130 observaciones. Suma los votos afirmativos totales por circuito electoral de las distintas agrupaciones además de calcular la performance de las mismas ponderando la razon votos/electores.

Con este set ya se estará en condiciones de comenzar a reflexionar en torno a la preferencia electoral en 2021 de los lanusenses a una escala de circuito electoral.

Exploración Gráfica

Ante de generar los mapas será importante visualizar la cantidad de electores por circuito para conocer el peso cuantitativo de cada uno.

lanus1%>%
  select(IdCircuito, electoresxcirc)%>%
  unique()%>%
  arrange(electoresxcirc)%>%
  ggplot() +
  aes(x=reorder(IdCircuito,-electoresxcirc), 
      y = electoresxcirc) +
  geom_point(aes(size = electoresxcirc, 
                 fill = electoresxcirc),
             shape = 21, alpha = 0.7) +
  scale_fill_viridis_c(guide = "legend") +
  labs(x = "Circuito número",
       y = "Total electores",
       title = "Cuadro 1:",
       subtitle = "Ratio",
       caption = "Fuente: elaboración propia en base a datos de la CNE.")+
  theme_minimal()

El circuito con mayor cantidad de electores es el 262 y el que menos tiene el 264.

Seguidamente interesará conocer cómo se plasma la variable ratio de cada fuerza por circuito electoral, para ello se presenta un cuadro con graficas barra facetadas.

ggplot(lanus1) +
  aes(x = IdCircuito, y = ratio, fill = IdCircuito) +
  geom_col() +
  scale_fill_hue(direction = 1) +
  labs(
    x = "Circuito número",
    y = "Ratio votos/electores",
    title = "Cuadro 2: io",
    subtitle = "Ratio",
    caption = "Fuente: elaboración propia en base a datos de la CNE.") +
  coord_flip() +
  theme_linedraw() +
  theme(legend.position = "none",
        strip.text.x = element_text(size = 4.1))+
  facet_wrap(vars(Agrupacion))

Con esta primera imagen podremos observar que las agrupaciones Juntos y Frente de Todos presentaron las valores más altos para la variable ratio, destacando el Frente de izquierda como la que tuvo mejor performance entre aquellas agrupaciones con menor caudal de votos.

Mapeo de electores por circuito

Con el objetivo de localizar los datos previamente explorados se procede a obtener un archivo con las coordenadas de los circuitos electorales de Lanús.

circuitos <- read_sf("geojson/circuitos_cne/circuitos02_cne.geojson")%>%
  filter(departamen=="Lanús")%>%
  mutate(IdCircuito=substring(circuito, 2))

Los mismos se unen al objeto lanus1 para crear lanus2 como conjunto de datos geográficos.

lanus2<-lanus1%>%
  left_join(circuitos, by="IdCircuito")%>%
  st_as_sf()

Se genera un mapa leaflet recreando espacialmente el ejercicio propuesto en el cuadro 1. La escala viridis será utilizada aquí, y a lo largo de todo el trabajo, para reflejar en cada polígono trazado una mayor (color claro) o menor (color oscuro) magnitud de un fenómeno: electores, votos, ratio, etc.

pal <- colorNumeric(
  palette = "viridis",
  domain = as.numeric(na.omit(lanus2$electoresxcirc)),
  alpha = TRUE,
  reverse = F, #X
  na.color = "#808080")

map_electores <- leaflet(options = leafletOptions(attributionControl=FALSE))%>%
  setView(lng = -58.3907, lat = -34.7074, zoom = 12) %>%
  addTiles()%>%
  addProviderTiles("CartoDB.Positron", group = "Base") %>%
  addProviderTiles("Esri.WorldImagery", group = "Satelital") %>%
  addPolygons(data=lanus2, 
              weight = 0.6, 
              smoothFactor = 0.8, 
              color = "#8c92ac", 
              opacity = 0.4, 
              fillOpacity = 0.3, 
              popup = paste0("Región: ",lanus2$IdCircuito,
                             "<br>",
                             "Electores: ", lanus2$electoresxcirc),
              fillColor = ~pal(lanus2$electoresxcirc),
              highlightOptions = highlightOptions(color= "#92D4CA",
              weight = 2,bringToFront = TRUE, opacity = 0.9))%>%
  addLegend(position = c("bottomleft"), 
            pal = pal, 
            values = lanus2$electoresxcirc, 
            title = "N Electores", 
                labFormat = labelFormat(suffix = ""), 
            opacity = 0.7,
            )%>%
  addLayersControl(baseGroups = 
                     c("Base","Satelital"),
                   position = "topleft",
              options = layersControlOptions(collapsed = TRUE))

map_electores

La localización de los datos en un mapa permite reconocer los circuitos más poblados, son el 273 y 262, al norte y sur del municipio respectivamente. 264 y 259 son los circuitos que cuentan con menos electores.

Ratio por agrupación

Posteriormente, se recrea con ggplot la propuesta del cuadro 2 para visualizar en un mapa de cloropetas la variable ratio (votos/electores) por circuito electoral para las distintas agrupaciones.

Juntos

FPV

Avanza Libertad

Frente de Izquierda

Vamos con vos

Comparativas

La secuencia realiza un facetado que compara mediante dos gráficos con escalas diferenciadas las agrupaciones con mayor ratio por un lado y las terceras fuerzas por otro.

a1<-lanus2%>%
  # filter(!Agrupacion %in% c("JUNTOS","FRENTE DE TODOS"))%>%
  filter(Agrupacion %in% c("FRENTE DE TODOS", "JUNTOS"))%>%
  ggplot() +  
  geom_sf(aes(fill = ratio)) + 
  facet_wrap(~Agrupacion)+
  scale_fill_viridis_c() +
  theme_map()+
  theme(legend.position = "bottom") +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        strip.text.x = element_text(size = 6),
        axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank())

b2<-lanus2%>%
  # filter(!Agrupacion %in% c("JUNTOS","FRENTE DE TODOS"))%>%
  filter(Agrupacion %in% c("FRENTE DE IZQUIERDA Y DE TRABAJADORES - UNIDAD", "FRENTE VAMOS CON VOS", "AVANZA LIBERTAD"))%>%
  ggplot() +  
  geom_sf(aes(fill = ratio)) + 
  facet_wrap(~Agrupacion)+
  scale_fill_viridis_c() +
  theme_map()+
  theme(legend.position = "bottom") +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        strip.text.x = element_text(size = 6),
        axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank())

Juntos | Frente De todos

El mapa que compara FDT y Juntos denota un patrón en el cual los circuitos del centro tienden a manifestar una preferencia electoral por Juntos y los de la periferia por el Frente de Todos.

Frente de Izquierda| Avanza Libertad| Vamos Con Vos

Con respecto a las terceras fuerzas el panorama presenta mayor complejidad puesto que el Frente de Izquierda y Avanza Libertad presentan situaciones similares, aunque la Izquierda con una leve mejoría en la variable ratio circuito por circuito. Con respecto al Frente Vamos Con Vos en la comparativa sólo muestra mayor presencia en un territorio del norte del municipio.

Conclusiones

El presente documento electrónico procuró poner en juego los conocimientos aprendidos en el módulo llevando adelante una exploración geográfica de orden general, asistida por R ,de un fenómeno concreto y medible: las Elecciones Generales en Lanús de 2021, específicamente para la categoría concejal y con datos agrupados por circuito.

Con la intensión de encontrar en los datos uno o mas insights, se construyó la variable ratio que ha permitido realizar una lectura ponderada de los votos por circuito electoral para reconocer visualmente cual fue el desempeño de cada agrupación en cuanto z votos ajustados por la cantidad de electores totales por territorio.

Los resultados de esta exploración gráfica de carácter general indican que la fuerza que mejor desempeño ha tenido en la compulsa por circuito electoral ha sido Juntos, aunque el Frente de Todos ese mantuvo cerca, ganando en los circuitos con mayor cantidad de electores.

Las terceras fuerzas quedaron lejos de las dos primeras, lo cual refuerza el carácter bipartidista de la gimansia política en Lanús. Aún así, el Frente de Izquierda es la agrupación que levemente emerge con una mejor performance por sobre Avanza Libertad y el Frente Vamos Con Vos.

Si bien como reza el refrán popular “al final del día todos los votos valen 1”, la exploración de la relación voto/electores ponderada por circuito ha permitido conocer la penetración de una agrupación en un territorio dado y se presta como un insumo extra para evaluar cuestiones tales como la estrategia política, las campañas de comunicación y la gestión de los rescursos de la militancia.

Quedará para futuros trabajos seguir explorando estos datos con nuevas aperturas, temporalidades y algoritmos.

LS0tDQp0aXRsZTogIlRyYWJham8gRmluYWw6IENpZW5jaWEgZGUgZGF0b3MgSUkiDQphdXRob3I6ICJQZWRybyBELiBPcmRlbiINCmRhdGU6ICIxOC84LzIwMjIiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIHRoZW1lOiBzaW1wbGV4DQotLS0NCg0KYGBgez1odG1sfQ0KPHN0eWxlPg0KLmh0bWwtd2lkZ2V0IHsNCiAgICBtYXJnaW46IGF1dG87DQp9DQo8L3N0eWxlPg0KYGBgDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIyBQcmVzZW50YWNpw7NuIGRlbCB0ZW1hIHsjcHJlc2VudGFjacOzbi1kZWwtdGVtYX0NCg0KRWwgcHJlc2VudGUgZG9jdW1lbnRvIGVsZWN0csOzbmljbyBleHBsb3JhIGVsIGRlc2VtcGXDsW8gZGUgbGFzIGFncnVwYWNpb25lcyBwb2zDrXRpY2FzIHBvbmRlcmFkbyBwb3IgY2lyY3VpdG8gZWxlY3RvcmFsIGVuIGxhIEVsZWNjacOzbiBHZW5lcmFsIGRlIDIwMjEgcGFyYSBsYSBjYXRlZ29yw61hIGNvbmNlamFsIGVuIGVsIE11bmljaXBpbyBkZSBMYW7DunMgKFByb3ZpbmNpYSBkZSBCdWVub3MgQWlyZXMpLg0KDQojIyBPYnRlbmNpw7NuIGRlIGRhdG9zIHsjb2J0ZW5jacOzbi1kZS1kYXRvc30NCg0KUGFyYSBkZXNhbmRhciBsYSBleHBsb3JhY2nDs24gc2UgdXRpbGl6YXLDoW4gbG9zIGRhdG9zIGRldGFsbGFkb3MgZGUgbGFzICoqRWxlY2Npb25lcyBHZW5lcmFsZXMgZGUgMjAyMSoqLCBvYnRlbmlkb3MgcG9yIG1lZGlvIGRlIHVuIHBlZGlkbyBkZSBpbmZvcm1hY2nDs24gcMO6YmxpY2EgYSBsYSBDw6FtYXJhIE5hY2lvbmFsIEVsZWN0b3JhbC4gRWwgZGF0YXNldCBjb250aWVuZSBsb3MgcmVzdWx0YWRvcyBxdWUgb2J0dXZpZXJvbiBsYXMgYWdydXBhY2lvbmVzIHBvciBjYXJnbywgZXNjdWVsYSwgY2lyY3VpdG8geSBkaXN0cml0byBlbiB0b2RvIGVsIHBhw61zLg0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShzZikNCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KHZpcmlkaXMpDQoNCm1lc2FzX2VzY3J1dGFkYXMgPC0gcmVhZF9kZWxpbSgNCiAgImVsZWNjaW9uZXMvZTIwMjFfZ2VuZXJhbGVzL21lc2FzX2VzY3J1dGFkYXNfY2llcnJlLmNzdiIsIA0KICAgICAgICAgICAgIGRlbGltID0gIjsiLCANCiAgICAgICAgICAgICBlc2NhcGVfZG91YmxlID0gRkFMU0UsDQogICAgICAgICAgICAgdHJpbV93cyA9IFRSVUUpDQpgYGANCg0KU2UgYXBsaWNhbiBmdW5jaW9uZXMgZGUgcmVzdW1lbjoNCg0KKipoZWFkKioNCg0KYGBge3J9DQpoZWFkKG1lc2FzX2VzY3J1dGFkYXMpDQpgYGANCg0KKipzdW1tYXJ5KioNCg0KYGBge3J9DQpzdW1tYXJ5KG1lc2FzX2VzY3J1dGFkYXMpDQpgYGANCg0KKipjbGFzcyoqDQoNCmBgYHtyfQ0KY2xhc3MobWVzYXNfZXNjcnV0YWRhcykNCmBgYA0KDQoqKm5hbWVzKioNCg0KYGBge3J9DQpuYW1lcyhtZXNhc19lc2NydXRhZGFzKQ0KYGBgDQoNCioqZGltKioNCg0KYGBge3J9DQpkaW0obWVzYXNfZXNjcnV0YWRhcykNCmBgYA0KDQpMb3MgcHJpbWVyb3MgcmVzdWx0YWRvcyBpbmRpY2FuIHF1ZSBzZSB0cmF0YSBkZSB1biBjb25qdW50byBkZSBkYXRvcyByZWxhdGl2YW1lbnRlICJncmFuZGUiLCBjb250YW5kbyBjb24gMi42NjUuMTMwIG9ic2VydmFjaW9uZXMgeSAxOCB2YXJpYWJsZXMsIGVuIGZvcm1hdG8gbnVtw6lyaWNvIHkgZGUgdGV4dG8uDQoNCiMjIFRyYW5zZm9ybWFjacOzbiBkZSBsb3MgZGF0b3MNCg0KUGFyYSBjb250aW51YXIgbGEgdGFyZWEsIHNlIGZpbHRyYW4gbG9zIGRhdG9zIHBhcmEgbGEgc2VjY2nDs24gKipMYW7DunMqKiB5IGVsIGNhcmdvICoqQ29uY2VqYWxlcyoqIHBhcmEgZGFyIGN1ZW50YSBkZSBsYSBwcmVtaXNhIHBsYW50ZWFkYSBhbCBwcmluY2lwaW8gZGVsIGRvY3VtZW50by4NCg0KYGBge3J9DQpsYW51c19jb25jZWphbGVzIDwtIG1lc2FzX2VzY3J1dGFkYXMlPiUNCiAgZmlsdGVyKENhcmdvPT0iQ09OQ0VKQUxFUyIpJT4lDQogIGZpbHRlcihTZWNjaW9uPT0iTGFuw7pzIikNCmBgYA0KDQpVbmEgbnVldmEgdHJhbnNmb3JtYWNpw7NuIGNyZWEgdW4gbnVldm8gY29uanVudG8gZGUgZGF0b3MgcXVlIGZpbHRyYSBzw7NsbyBsb3Mgdm90b3MgcG9zaXRpdm9zIHF1ZSBvYnR1dmllcm9uIGxhcyBhZ3J1cGFjaW9uZXMsIHRhbCBjb21vIGxvIGVzdGFibGVjZSBsYSBbQ29uc3RpdHVjacOzbiBOYWNpb25hbF0oaHR0cDovL3NlcnZpY2lvcy5pbmZvbGVnLmdvYi5hci9pbmZvbGVnSW50ZXJuZXQvYW5leG9zLzAtNDk5OS84MDQvbm9ybWEuaHRtKSBwYXJhIHJlYWxpemFyIGxvcyBjb250ZW9zIGVuIGxhcyBlbGVjY2lvbmVzIGdlbmVyYWxlcy4NCg0KTGxlZ2FkbyBlc3RlIHB1bnRvIHNlIHByb2Nlc2EsIHBvciBjaXJjdWl0byBlbGVjdG9yYWwsIGxhIGNhbnRpZGFkIGRlIFt2b3Rvc117LnVsfSBkZSBjYWRhIHVuYSBkZSBsYXMgYWdydXBhY2lvbmVzIHBvciBsYSBjYW50aWRhZCBkZSBlbGVjdG9yZXMsIGNvbiBlbCBvYmpldGl2byBkZSBnZW5lcmFyIHVuYSBudWV2YSB2YXJpYWJsZSBkZSBwb25kZXJhY2nDs24gbGxhbWFkYSBgcmF0aW9gLg0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KbGFudXMxPC1sYW51c19jb25jZWphbGVzJT4lDQogIGZpbHRlcih0aXBvVm90bz09InBvc2l0aXZvIiklPiUgI2ZpbHRyYSB2b3RvcyBwb3NpdGl2b3MNCiAgZ3JvdXBfYnkoSWRDaXJjdWl0bywgQWdydXBhY2lvbiklPiUNCiAgc3VtbWFyaXNlKHZvdG9zeGNpcmM9c3VtKHZvdG9zKSwNCiAgICAgICAgICAgIGVsZWN0b3Jlc3hjaXJjPXN1bShlbGVjdG9yZXMpKSU+JQ0KICBtdXRhdGUocmF0aW89dm90b3N4Y2lyYy9lbGVjdG9yZXN4Y2lyYykgI2NyZWEgcmF0aW8NCmBgYA0KDQpFbCBoZWNobyBkZSBjb25zdHJ1aXIgcmF0aW8gZXMgdW5hIGRlY2lzacOzbiB0ZcOzcmljYSBxdWUgcHJvY3VyYSBkYXIgY3VlbnRhIGRlIGxhIHBhcnRpY3VsYXJpZGFkIGxvY2FsIGRlIGNhZGEgY2lyY3VpdG8gZWxlY3RvcmFsIGRlIExhbsO6cyB5IGNvYWR5dXZhciBoZXVyw61zdGljYW1lbnRlIGEgdW5hIGxlY3R1cmEgY29tcGFyYXRpdmEgZGUgbG9zIGRhdG9zIGVuIGRvcyBzZW50aWRvczoNCg0KMSkgIExlY3R1cmEgZGVsIGZlbsOzbWVubyBkZWwgdm90byBwYXJhIHVuYSBhZ3J1cGFjacOzbiBlc3BlY8OtZmljYSBwb3IgY2lyY3VpdG8gZWxlY3RvcmFsIHBhcmEgZGV0ZWN0YXIgem9uYXMgY29uIG1lam9yIG8gcGVvciBgcmF0aW9gIHZvdG8vZWxlY3RvcmVzLg0KDQoyKSAgQ29tcGFyYWNpw7NuIGdlbmVyYWwgZGVsIGByYXRpb2AgcG9yIGNpcmN1aXRvIGVsZWN0b3JhbCBkZSBsYXMgZGlzdGludGFzIGFncnVwYWNpb25lcy4NCg0KIyMgUHJpbWVyYXMgaW1wcmVzaW9uZXMgeyNwcmltZXJhcy1pbXByZXNpb25lc30NCg0KRWwgbnVldm8gZGYgYGxhbnVzMWAgY29uc3RhIGRlIDYgdmFyaWFibGVzLCAxMzAgb2JzZXJ2YWNpb25lcy4gU3VtYSBsb3Mgdm90b3MgYWZpcm1hdGl2b3MgdG90YWxlcyBwb3IgY2lyY3VpdG8gZWxlY3RvcmFsIGRlIGxhcyBkaXN0aW50YXMgYWdydXBhY2lvbmVzIGFkZW3DoXMgZGUgY2FsY3VsYXIgbGEgcGVyZm9ybWFuY2UgZGUgbGFzIG1pc21hcyBwb25kZXJhbmRvIGxhIHJhem9uIHZvdG9zL2VsZWN0b3Jlcy4NCg0KQ29uIGVzdGUgc2V0IHlhIHNlIGVzdGFyw6EgZW4gY29uZGljaW9uZXMgZGUgY29tZW56YXIgYSByZWZsZXhpb25hciBlbiB0b3JubyBhIGxhIHByZWZlcmVuY2lhIGVsZWN0b3JhbCBlbiAyMDIxIGRlIGxvcyBsYW51c2Vuc2VzIGEgdW5hIGVzY2FsYSBkZSBjaXJjdWl0byBlbGVjdG9yYWwuDQoNCiMjIEV4cGxvcmFjacOzbiBHcsOhZmljYSB7I2V4cGxvcmFjacOzbi1ncsOhZmljYX0NCg0KQW50ZSBkZSBnZW5lcmFyIGxvcyBtYXBhcyBzZXLDoSBpbXBvcnRhbnRlIHZpc3VhbGl6YXIgbGEgY2FudGlkYWQgZGUgZWxlY3RvcmVzIHBvciBjaXJjdWl0byBwYXJhIGNvbm9jZXIgZWwgcGVzbyBjdWFudGl0YXRpdm8gZGUgY2FkYSB1bm8uDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG91dC53aWR0aCA9ICc2MCUnLCBmaWcuYWxpZ249J2NlbnRlcid9DQpsYW51czElPiUNCiAgc2VsZWN0KElkQ2lyY3VpdG8sIGVsZWN0b3Jlc3hjaXJjKSU+JQ0KICB1bmlxdWUoKSU+JQ0KICBhcnJhbmdlKGVsZWN0b3Jlc3hjaXJjKSU+JQ0KICBnZ3Bsb3QoKSArDQogIGFlcyh4PXJlb3JkZXIoSWRDaXJjdWl0bywtZWxlY3RvcmVzeGNpcmMpLCANCiAgICAgIHkgPSBlbGVjdG9yZXN4Y2lyYykgKw0KICBnZW9tX3BvaW50KGFlcyhzaXplID0gZWxlY3RvcmVzeGNpcmMsIA0KICAgICAgICAgICAgICAgICBmaWxsID0gZWxlY3RvcmVzeGNpcmMpLA0KICAgICAgICAgICAgIHNoYXBlID0gMjEsIGFscGhhID0gMC43KSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKGd1aWRlID0gImxlZ2VuZCIpICsNCiAgbGFicyh4ID0gIkNpcmN1aXRvIG7Dum1lcm8iLA0KICAgICAgIHkgPSAiVG90YWwgZWxlY3RvcmVzIiwNCiAgICAgICB0aXRsZSA9ICJDdWFkcm8gMToiLA0KICAgICAgIHN1YnRpdGxlID0gIlJhdGlvIiwNCiAgICAgICBjYXB0aW9uID0gIkZ1ZW50ZTogZWxhYm9yYWNpw7NuIHByb3BpYSBlbiBiYXNlIGEgZGF0b3MgZGUgbGEgQ05FLiIpKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpFbCBjaXJjdWl0byBjb24gbWF5b3IgY2FudGlkYWQgZGUgZWxlY3RvcmVzIGVzIGVsIDI2MiB5IGVsIHF1ZSBtZW5vcyB0aWVuZSBlbCAyNjQuDQoNClNlZ3VpZGFtZW50ZSBpbnRlcmVzYXLDoSBjb25vY2VyIGPDs21vIHNlIHBsYXNtYSBsYSB2YXJpYWJsZSBgcmF0aW9gIGRlIGNhZGEgZnVlcnphIHBvciBjaXJjdWl0byBlbGVjdG9yYWwsIHBhcmEgZWxsbyBzZSBwcmVzZW50YSB1biBjdWFkcm8gY29uIGdyYWZpY2FzIGJhcnJhIGZhY2V0YWRhcy4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgb3V0LndpZHRoID0gJzYwJScsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmdncGxvdChsYW51czEpICsNCiAgYWVzKHggPSBJZENpcmN1aXRvLCB5ID0gcmF0aW8sIGZpbGwgPSBJZENpcmN1aXRvKSArDQogIGdlb21fY29sKCkgKw0KICBzY2FsZV9maWxsX2h1ZShkaXJlY3Rpb24gPSAxKSArDQogIGxhYnMoDQogICAgeCA9ICJDaXJjdWl0byBuw7ptZXJvIiwNCiAgICB5ID0gIlJhdGlvIHZvdG9zL2VsZWN0b3JlcyIsDQogICAgdGl0bGUgPSAiQ3VhZHJvIDI6IGlvIiwNCiAgICBzdWJ0aXRsZSA9ICJSYXRpbyIsDQogICAgY2FwdGlvbiA9ICJGdWVudGU6IGVsYWJvcmFjacOzbiBwcm9waWEgZW4gYmFzZSBhIGRhdG9zIGRlIGxhIENORS4iKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHRoZW1lX2xpbmVkcmF3KCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNC4xKSkrDQogIGZhY2V0X3dyYXAodmFycyhBZ3J1cGFjaW9uKSkNCmBgYA0KDQpDb24gZXN0YSBwcmltZXJhIGltYWdlbiBwb2RyZW1vcyBvYnNlcnZhciBxdWUgbGFzIGFncnVwYWNpb25lcyBKdW50b3MgeSBGcmVudGUgZGUgVG9kb3MgcHJlc2VudGFyb24gbGFzIHZhbG9yZXMgbcOhcyBhbHRvcyBwYXJhIGxhIHZhcmlhYmxlIHJhdGlvLCBkZXN0YWNhbmRvIGVsIEZyZW50ZSBkZSBpenF1aWVyZGEgY29tbyBsYSBxdWUgdHV2byBtZWpvciBwZXJmb3JtYW5jZSBlbnRyZSBhcXVlbGxhcyBhZ3J1cGFjaW9uZXMgY29uIG1lbm9yIGNhdWRhbCBkZSB2b3Rvcy4NCg0KIyMgTWFwZW8gZGUgZWxlY3RvcmVzIHBvciBjaXJjdWl0bw0KDQpDb24gZWwgb2JqZXRpdm8gZGUgbG9jYWxpemFyIGxvcyBkYXRvcyBwcmV2aWFtZW50ZSBleHBsb3JhZG9zIHNlIHByb2NlZGUgYSBvYnRlbmVyIHVuIGFyY2hpdm8gY29uIGxhcyBjb29yZGVuYWRhcyBkZSBsb3MgY2lyY3VpdG9zIGVsZWN0b3JhbGVzIGRlIExhbsO6cy4NCg0KYGBge3J9DQpjaXJjdWl0b3MgPC0gcmVhZF9zZigiZ2VvanNvbi9jaXJjdWl0b3NfY25lL2NpcmN1aXRvczAyX2NuZS5nZW9qc29uIiklPiUNCiAgZmlsdGVyKGRlcGFydGFtZW49PSJMYW7DunMiKSU+JQ0KICBtdXRhdGUoSWRDaXJjdWl0bz1zdWJzdHJpbmcoY2lyY3VpdG8sIDIpKQ0KYGBgDQoNCkxvcyBtaXNtb3Mgc2UgdW5lbiBhbCBvYmpldG8gYGxhbnVzMWAgcGFyYSBjcmVhciBgbGFudXMyYCBjb21vIGNvbmp1bnRvIGRlIGRhdG9zIGdlb2dyw6FmaWNvcy4NCg0KYGBge3J9DQpsYW51czI8LWxhbnVzMSU+JQ0KICBsZWZ0X2pvaW4oY2lyY3VpdG9zLCBieT0iSWRDaXJjdWl0byIpJT4lDQogIHN0X2FzX3NmKCkNCmBgYA0KDQpTZSBnZW5lcmEgdW4gbWFwYSBsZWFmbGV0IHJlY3JlYW5kbyBlc3BhY2lhbG1lbnRlIGVsIGVqZXJjaWNpbyBwcm9wdWVzdG8gZW4gZWwgKipjdWFkcm8gMSoqLiBMYSBlc2NhbGEgdmlyaWRpcyBzZXLDoSB1dGlsaXphZGEgYXF1w60sIHkgYSBsbyBsYXJnbyBkZSB0b2RvIGVsIHRyYWJham8sIHBhcmEgcmVmbGVqYXIgZW4gY2FkYSBwb2zDrWdvbm8gdHJhemFkbyB1bmEgbWF5b3IgKGNvbG9yIGNsYXJvKSBvIG1lbm9yIChjb2xvciBvc2N1cm8pIG1hZ25pdHVkIGRlIHVuIGZlbsOzbWVubzogZWxlY3RvcmVzLCB2b3RvcywgcmF0aW8sIGV0Yy4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgb3V0LndpZHRoID0gJzYwJScsIGZpZy5hbGlnbj0nY2VudGVyJ30NCnBhbCA8LSBjb2xvck51bWVyaWMoDQogIHBhbGV0dGUgPSAidmlyaWRpcyIsDQogIGRvbWFpbiA9IGFzLm51bWVyaWMobmEub21pdChsYW51czIkZWxlY3RvcmVzeGNpcmMpKSwNCiAgYWxwaGEgPSBUUlVFLA0KICByZXZlcnNlID0gRiwgI1gNCiAgbmEuY29sb3IgPSAiIzgwODA4MCIpDQoNCm1hcF9lbGVjdG9yZXMgPC0gbGVhZmxldChvcHRpb25zID0gbGVhZmxldE9wdGlvbnMoYXR0cmlidXRpb25Db250cm9sPUZBTFNFKSklPiUNCiAgc2V0VmlldyhsbmcgPSAtNTguMzkwNywgbGF0ID0gLTM0LjcwNzQsIHpvb20gPSAxMikgJT4lDQogIGFkZFRpbGVzKCklPiUNCiAgYWRkUHJvdmlkZXJUaWxlcygiQ2FydG9EQi5Qb3NpdHJvbiIsIGdyb3VwID0gIkJhc2UiKSAlPiUNCiAgYWRkUHJvdmlkZXJUaWxlcygiRXNyaS5Xb3JsZEltYWdlcnkiLCBncm91cCA9ICJTYXRlbGl0YWwiKSAlPiUNCiAgYWRkUG9seWdvbnMoZGF0YT1sYW51czIsIA0KICAgICAgICAgICAgICB3ZWlnaHQgPSAwLjYsIA0KICAgICAgICAgICAgICBzbW9vdGhGYWN0b3IgPSAwLjgsIA0KICAgICAgICAgICAgICBjb2xvciA9ICIjOGM5MmFjIiwgDQogICAgICAgICAgICAgIG9wYWNpdHkgPSAwLjQsIA0KICAgICAgICAgICAgICBmaWxsT3BhY2l0eSA9IDAuMywgDQogICAgICAgICAgICAgIHBvcHVwID0gcGFzdGUwKCJSZWdpw7NuOiAiLGxhbnVzMiRJZENpcmN1aXRvLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVjdG9yZXM6ICIsIGxhbnVzMiRlbGVjdG9yZXN4Y2lyYyksDQogICAgICAgICAgICAgIGZpbGxDb2xvciA9IH5wYWwobGFudXMyJGVsZWN0b3Jlc3hjaXJjKSwNCiAgICAgICAgICAgICAgaGlnaGxpZ2h0T3B0aW9ucyA9IGhpZ2hsaWdodE9wdGlvbnMoY29sb3I9ICIjOTJENENBIiwNCiAgICAgICAgICAgICAgd2VpZ2h0ID0gMixicmluZ1RvRnJvbnQgPSBUUlVFLCBvcGFjaXR5ID0gMC45KSklPiUNCiAgYWRkTGVnZW5kKHBvc2l0aW9uID0gYygiYm90dG9tbGVmdCIpLCANCiAgICAgICAgICAgIHBhbCA9IHBhbCwgDQogICAgICAgICAgICB2YWx1ZXMgPSBsYW51czIkZWxlY3RvcmVzeGNpcmMsIA0KICAgICAgICAgICAgdGl0bGUgPSAiTiBFbGVjdG9yZXMiLCANCiAgICAgICAgICAgICAgICBsYWJGb3JtYXQgPSBsYWJlbEZvcm1hdChzdWZmaXggPSAiIiksIA0KICAgICAgICAgICAgb3BhY2l0eSA9IDAuNywNCiAgICAgICAgICAgICklPiUNCiAgYWRkTGF5ZXJzQ29udHJvbChiYXNlR3JvdXBzID0gDQogICAgICAgICAgICAgICAgICAgICBjKCJCYXNlIiwiU2F0ZWxpdGFsIiksDQogICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSAidG9wbGVmdCIsDQogICAgICAgICAgICAgIG9wdGlvbnMgPSBsYXllcnNDb250cm9sT3B0aW9ucyhjb2xsYXBzZWQgPSBUUlVFKSkNCg0KbWFwX2VsZWN0b3Jlcw0KYGBgDQoNCkxhIGxvY2FsaXphY2nDs24gZGUgbG9zIGRhdG9zIGVuIHVuIG1hcGEgcGVybWl0ZSByZWNvbm9jZXIgbG9zIGNpcmN1aXRvcyBtw6FzIHBvYmxhZG9zLCBzb24gZWwgMjczIHkgMjYyLCBhbCBub3J0ZSB5IHN1ciBkZWwgbXVuaWNpcGlvIHJlc3BlY3RpdmFtZW50ZS4gMjY0IHkgMjU5IHNvbiBsb3MgY2lyY3VpdG9zIHF1ZSBjdWVudGFuIGNvbiBtZW5vcyBlbGVjdG9yZXMuDQoNCiMjIFJhdGlvIHBvciBhZ3J1cGFjacOzbiB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30NCg0KUG9zdGVyaW9ybWVudGUsIHNlIHJlY3JlYSBjb24gZ2dwbG90IGxhIHByb3B1ZXN0YSBkZWwgKipjdWFkcm8gMioqIHBhcmEgdmlzdWFsaXphciBlbiB1biBtYXBhIGRlIGNsb3JvcGV0YXMgbGEgdmFyaWFibGUgYHJhdGlvYCAodm90b3MvZWxlY3RvcmVzKSBwb3IgY2lyY3VpdG8gZWxlY3RvcmFsIHBhcmEgbGFzIGRpc3RpbnRhcyBhZ3J1cGFjaW9uZXMuDQoNCmBgYHtyIGVjaG89IEYgLG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQphIDwtIGxhbnVzMiU+JQ0KICBmaWx0ZXIoQWdydXBhY2lvbiAlaW4lIGMoIkpVTlRPUyIpKSU+JQ0KICBnZ3Bsb3QoKSArICANCiAgZ2VvbV9zZihhZXMoZmlsbCA9IHJhdGlvKSkgKyANCiAgZmFjZXRfd3JhcCh+QWdydXBhY2lvbikrDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKw0KICB0aGVtZV9tYXAoKQ0KDQpiPC1sYW51czIlPiUNCiAgZmlsdGVyKEFncnVwYWNpb24gJWluJSBjKCJGUkVOVEUgREUgVE9ET1MiKSklPiUNCiAgZ2dwbG90KCkgKyAgDQogIGdlb21fc2YoYWVzKGZpbGwgPSByYXRpbykpICsgDQogIGZhY2V0X3dyYXAofkFncnVwYWNpb24pKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsNCiAgdGhlbWVfbWFwKCkNCg0KYzwtbGFudXMyJT4lDQogIGZpbHRlcihBZ3J1cGFjaW9uICVpbiUgYygiQVZBTlpBIExJQkVSVEFEIikpJT4lDQogIGdncGxvdCgpICsgIA0KICBnZW9tX3NmKGFlcyhmaWxsID0gcmF0aW8pKSArIA0KICBmYWNldF93cmFwKH5BZ3J1cGFjaW9uKSsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArDQogIHRoZW1lX21hcCgpDQoNCmQ8LWxhbnVzMiU+JQ0KICBmaWx0ZXIoQWdydXBhY2lvbiAlaW4lIGMoIkZSRU5URSBERSBJWlFVSUVSREEgWSBERSBUUkFCQUpBRE9SRVMgLSBVTklEQUQiKSklPiUNCiAgZ2dwbG90KCkgKyAgDQogIGdlb21fc2YoYWVzKGZpbGwgPSByYXRpbykpICsgDQogIGZhY2V0X3dyYXAofkFncnVwYWNpb24pKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsNCiAgdGhlbWVfbWFwKCkNCg0KZTwtbGFudXMyJT4lDQogIGZpbHRlcihBZ3J1cGFjaW9uICVpbiUgYygiRlJFTlRFIFZBTU9TIENPTiBWT1MiKSklPiUNCiAgZ2dwbG90KCkgKyAgDQogIGdlb21fc2YoYWVzKGZpbGwgPSByYXRpbykpICsgDQogIGZhY2V0X3dyYXAofkFncnVwYWNpb24pKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsNCiAgdGhlbWVfbWFwKCkNCmBgYA0KDQojIyMgSnVudG9zDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBvdXQud2lkdGggPSAnODAlJywgZmlnLmFsaWduPSdjZW50ZXInLCBlY2hvPUZBTFNFfQ0KYQ0KYGBgDQoNCiMjIyBGUFYNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG91dC53aWR0aCA9ICc4MCUnLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcid9DQpiDQpgYGANCg0KIyMjIEF2YW56YSBMaWJlcnRhZA0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnODAlJywgZWNobz1GQUxTRX0NCmMNCmBgYA0KDQojIyMgRnJlbnRlIGRlIEl6cXVpZXJkYQ0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgb3V0LndpZHRoID0gJzgwJScsZmlnLmFsaWduPSdjZW50ZXInLCBlY2hvPUZBTFNFfQ0KZA0KYGBgDQoNCiMjIyBWYW1vcyBjb24gdm9zDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBvdXQud2lkdGggPSAnODAlJyxmaWcuYWxpZ249J2NlbnRlcicsIGVjaG89RkFMU0V9DQplDQpgYGANCg0KIyMgQ29tcGFyYXRpdmFzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQ0KDQpMYSBzZWN1ZW5jaWEgcmVhbGl6YSB1biBmYWNldGFkbyBxdWUgY29tcGFyYSBtZWRpYW50ZSBkb3MgZ3LDoWZpY29zIGNvbiBlc2NhbGFzIGRpZmVyZW5jaWFkYXMgbGFzIGFncnVwYWNpb25lcyBjb24gbWF5b3IgcmF0aW8gcG9yIHVuIGxhZG8geSBsYXMgdGVyY2VyYXMgZnVlcnphcyBwb3Igb3Ryby4NCg0KYGBge3IgfQ0KYTE8LWxhbnVzMiU+JQ0KICAjIGZpbHRlcighQWdydXBhY2lvbiAlaW4lIGMoIkpVTlRPUyIsIkZSRU5URSBERSBUT0RPUyIpKSU+JQ0KICBmaWx0ZXIoQWdydXBhY2lvbiAlaW4lIGMoIkZSRU5URSBERSBUT0RPUyIsICJKVU5UT1MiKSklPiUNCiAgZ2dwbG90KCkgKyAgDQogIGdlb21fc2YoYWVzKGZpbGwgPSByYXRpbykpICsgDQogIGZhY2V0X3dyYXAofkFncnVwYWNpb24pKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsNCiAgdGhlbWVfbWFwKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArDQogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwNCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpKQ0KDQpiMjwtbGFudXMyJT4lDQogICMgZmlsdGVyKCFBZ3J1cGFjaW9uICVpbiUgYygiSlVOVE9TIiwiRlJFTlRFIERFIFRPRE9TIikpJT4lDQogIGZpbHRlcihBZ3J1cGFjaW9uICVpbiUgYygiRlJFTlRFIERFIElaUVVJRVJEQSBZIERFIFRSQUJBSkFET1JFUyAtIFVOSURBRCIsICJGUkVOVEUgVkFNT1MgQ09OIFZPUyIsICJBVkFOWkEgTElCRVJUQUQiKSklPiUNCiAgZ2dwbG90KCkgKyAgDQogIGdlb21fc2YoYWVzKGZpbGwgPSByYXRpbykpICsgDQogIGZhY2V0X3dyYXAofkFncnVwYWNpb24pKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYygpICsNCiAgdGhlbWVfbWFwKCkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArDQogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwNCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCiMjIyBKdW50b3MgXHwgRnJlbnRlIERlIHRvZG9zDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoID0gJzgwJScsIGVjaG89RkFMU0V9DQphMQ0KYGBgDQoNCkVsIG1hcGEgcXVlIGNvbXBhcmEgRkRUIHkgSnVudG9zIGRlbm90YSB1biBwYXRyw7NuIGVuIGVsIGN1YWwgbG9zIGNpcmN1aXRvcyBkZWwgY2VudHJvIHRpZW5kZW4gYSBtYW5pZmVzdGFyIHVuYSBwcmVmZXJlbmNpYSBlbGVjdG9yYWwgcG9yIEp1bnRvcyB5IGxvcyBkZSBsYSBwZXJpZmVyaWEgcG9yIGVsIEZyZW50ZSBkZSBUb2Rvcy4NCg0KIyMjIEZyZW50ZSBkZSBJenF1aWVyZGFcfCBBdmFuemEgTGliZXJ0YWRcfCBWYW1vcyBDb24gVm9zDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGggPSAnODUlJywgZWNobz1GQUxTRSB9DQpiMg0KYGBgDQoNCkNvbiByZXNwZWN0byBhIGxhcyB0ZXJjZXJhcyBmdWVyemFzIGVsIHBhbm9yYW1hIHByZXNlbnRhIG1heW9yIGNvbXBsZWppZGFkIHB1ZXN0byBxdWUgZWwgRnJlbnRlIGRlIEl6cXVpZXJkYSB5IEF2YW56YSBMaWJlcnRhZCBwcmVzZW50YW4gc2l0dWFjaW9uZXMgc2ltaWxhcmVzLCBhdW5xdWUgbGEgSXpxdWllcmRhIGNvbiB1bmEgbGV2ZSBtZWpvcsOtYSBlbiBsYSB2YXJpYWJsZSByYXRpbyBjaXJjdWl0byBwb3IgY2lyY3VpdG8uIENvbiByZXNwZWN0byBhbCBGcmVudGUgVmFtb3MgQ29uIFZvcyBlbiBsYSBjb21wYXJhdGl2YSBzw7NsbyBtdWVzdHJhIG1heW9yIHByZXNlbmNpYSBlbiB1biB0ZXJyaXRvcmlvIGRlbCBub3J0ZSBkZWwgbXVuaWNpcGlvLg0KDQojIyBDb25jbHVzaW9uZXMgeyNjb25jbHVzaW9uZXN9DQoNCkVsIHByZXNlbnRlIGRvY3VtZW50byBlbGVjdHLDs25pY28gcHJvY3Vyw7MgcG9uZXIgZW4ganVlZ28gbG9zIGNvbm9jaW1pZW50b3MgYXByZW5kaWRvcyBlbiBlbCBtw7NkdWxvIGxsZXZhbmRvIGFkZWxhbnRlIHVuYSBleHBsb3JhY2nDs24gZ2VvZ3LDoWZpY2EgZGUgb3JkZW4gZ2VuZXJhbCwgYXNpc3RpZGEgcG9yIFIgLGRlIHVuIGZlbsOzbWVubyBjb25jcmV0byB5IG1lZGlibGU6IGxhcyBFbGVjY2lvbmVzIEdlbmVyYWxlcyBlbiBMYW7DunMgZGUgMjAyMSwgZXNwZWPDrWZpY2FtZW50ZSBwYXJhIGxhIGNhdGVnb3LDrWEgY29uY2VqYWwgeSBjb24gZGF0b3MgYWdydXBhZG9zIHBvciBjaXJjdWl0by4NCg0KQ29uIGxhIGludGVuc2nDs24gZGUgZW5jb250cmFyIGVuIGxvcyBkYXRvcyB1bm8gbyBtYXMgaW5zaWdodHMsIHNlIGNvbnN0cnV5w7MgbGEgdmFyaWFibGUgcmF0aW8gcXVlIGhhIHBlcm1pdGlkbyByZWFsaXphciB1bmEgbGVjdHVyYSBwb25kZXJhZGEgZGUgbG9zIHZvdG9zIHBvciBjaXJjdWl0byBlbGVjdG9yYWwgcGFyYSByZWNvbm9jZXIgdmlzdWFsbWVudGUgY3VhbCBmdWUgZWwgZGVzZW1wZcOxbyBkZSBjYWRhIGFncnVwYWNpw7NuIGVuIGN1YW50byB6IHZvdG9zIGFqdXN0YWRvcyBwb3IgbGEgY2FudGlkYWQgZGUgZWxlY3RvcmVzIHRvdGFsZXMgcG9yIHRlcnJpdG9yaW8uDQoNCkxvcyByZXN1bHRhZG9zIGRlIGVzdGEgZXhwbG9yYWNpw7NuIGdyw6FmaWNhIGRlIGNhcsOhY3RlciBnZW5lcmFsIGluZGljYW4gcXVlIGxhIGZ1ZXJ6YSBxdWUgbWVqb3IgZGVzZW1wZcOxbyBoYSB0ZW5pZG8gZW4gbGEgY29tcHVsc2EgcG9yIGNpcmN1aXRvIGVsZWN0b3JhbCBoYSBzaWRvIEp1bnRvcywgYXVucXVlIGVsIEZyZW50ZSBkZSBUb2RvcyBlc2UgbWFudHV2byBjZXJjYSwgZ2FuYW5kbyBlbiBsb3MgY2lyY3VpdG9zIGNvbiBtYXlvciBjYW50aWRhZCBkZSBlbGVjdG9yZXMuDQoNCkxhcyB0ZXJjZXJhcyBmdWVyemFzIHF1ZWRhcm9uIGxlam9zIGRlIGxhcyBkb3MgcHJpbWVyYXMsIGxvIGN1YWwgcmVmdWVyemEgZWwgY2Fyw6FjdGVyIGJpcGFydGlkaXN0YSBkZSBsYSBnaW1hbnNpYSBwb2zDrXRpY2EgZW4gTGFuw7pzLiBBw7puIGFzw60sIGVsIEZyZW50ZSBkZSBJenF1aWVyZGEgZXMgbGEgYWdydXBhY2nDs24gcXVlIGxldmVtZW50ZSBlbWVyZ2UgY29uIHVuYSBtZWpvciBwZXJmb3JtYW5jZSBwb3Igc29icmUgQXZhbnphIExpYmVydGFkIHkgZWwgRnJlbnRlIFZhbW9zIENvbiBWb3MuDQoNClNpIGJpZW4gY29tbyByZXphIGVsIHJlZnLDoW4gcG9wdWxhciAiYWwgZmluYWwgZGVsIGTDrWEgdG9kb3MgbG9zIHZvdG9zIHZhbGVuIDEiLCBsYSBleHBsb3JhY2nDs24gZGUgbGEgcmVsYWNpw7NuIHZvdG8vZWxlY3RvcmVzIHBvbmRlcmFkYSBwb3IgY2lyY3VpdG8gaGEgcGVybWl0aWRvIGNvbm9jZXIgbGEgcGVuZXRyYWNpw7NuIGRlIHVuYSBhZ3J1cGFjacOzbiBlbiB1biB0ZXJyaXRvcmlvIGRhZG8geSBzZSBwcmVzdGEgY29tbyB1biBpbnN1bW8gZXh0cmEgcGFyYSBldmFsdWFyIGN1ZXN0aW9uZXMgdGFsZXMgY29tbyBsYSBlc3RyYXRlZ2lhIHBvbMOtdGljYSwgbGFzIGNhbXBhw7FhcyBkZSBjb211bmljYWNpw7NuIHkgbGEgZ2VzdGnDs24gZGUgbG9zIHJlc2N1cnNvcyBkZSBsYSBtaWxpdGFuY2lhLg0KDQpRdWVkYXLDoSBwYXJhIGZ1dHVyb3MgdHJhYmFqb3Mgc2VndWlyIGV4cGxvcmFuZG8gZXN0b3MgZGF0b3MgY29uIG51ZXZhcyBhcGVydHVyYXMsIHRlbXBvcmFsaWRhZGVzIHkgYWxnb3JpdG1vcy4NCg==