Contexto

Arca Continental implementó el Proyecto Siglo XXI desde 2016 en algunos de los establecimientos de la Zona Metropolitana de Guadalajara, a continuación se mostrarán los resultados obtenidos al haber implementado esta estrategia.

Importar la base de datos

# file.choose()
df <- read.csv("C:\\Users\\HP\\Downloads\\arca.csv")

Entender la base de datos

summary(df)
##        ID              Año        Territorio        Sub.Territorio    
##  Min.   :     1   Min.   :2016   Length:466509      Length:466509     
##  1st Qu.:116628   1st Qu.:2017   Class :character   Class :character  
##  Median :233255   Median :2018   Mode  :character   Mode  :character  
##  Mean   :233255   Mean   :2018                                        
##  3rd Qu.:349882   3rd Qu.:2019                                        
##  Max.   :466509   Max.   :2019                                        
##      CEDI             Cliente             Nombre          Tamaño.Cte.Industria
##  Length:466509      Length:466509      Length:466509      Length:466509       
##  Class :character   Class :character   Class :character   Class :character    
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character    
##                                                                               
##                                                                               
##                                                                               
##  Segmento.Det          Marca           Presentacion          Tamaño         
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Retornable_NR         Enero             Febrero             Marzo          
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##     Abril               Mayo              Junio              Julio          
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##     Agosto           Septiembre          Octubre           Noviembre        
##  Length:466509      Length:466509      Length:466509      Length:466509     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##   Diciembre        
##  Length:466509     
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# count(df,Territorio,sort=TRUE)
# count(df,Sub.Territorio,sort=TRUE)
# count(df, CEDI,sort=TRUE)
# count(df,Cliente,sort=TRUE)
# count(df,Nombre,sort=TRUE)
# count(df,Tamaño.Cte.Industria,sort=TRUE)
# count(df,Segmento.Det,sort=TRUE)
# count(df,Marca,sort=TRUE)
# count(df,Presentacion,sort=TRUE)
# count(df,Tamaño,sort=TRUE)
# count(df,Retornable_NR,sort=TRUE)

Observaciones: 1. Eliminar el reglon 184065. 2. Cambiar formato de fechas de caracter a entero. ### Limpiar la base de datos

df <- df[-184065,]

df$Enero <- as.integer(df$Enero)
## Warning: NAs introducidos por coerción
df$Febrero <- as.integer(df$Febrero)
## Warning: NAs introducidos por coerción
df$Marzo <- as.integer(df$Marzo)
## Warning: NAs introducidos por coerción
df$Abril <- as.integer(df$Abril)
## Warning: NAs introducidos por coerción
df$Mayo <- as.integer(df$Mayo)
## Warning: NAs introducidos por coerción
df$Junio <- as.integer(df$Junio)
## Warning: NAs introducidos por coerción
df$Julio <- as.integer(df$Julio)
## Warning: NAs introducidos por coerción
df$Agosto <- as.integer(df$Agosto)
## Warning: NAs introducidos por coerción
df$Septiembre <- as.integer(df$Septiembre)
## Warning: NAs introducidos por coerción
df$Octubre <- as.integer(df$Octubre)
## Warning: NAs introducidos por coerción
df$Noviembre <- as.integer(df$Noviembre)
## Warning: NAs introducidos por coerción
df$Diciembre <- as.integer(df$Diciembre)
## Warning: NAs introducidos por coerción
summary(df)
##        ID              Año        Territorio        Sub.Territorio    
##  Min.   :     1   Min.   :2016   Length:466508      Length:466508     
##  1st Qu.:116628   1st Qu.:2017   Class :character   Class :character  
##  Median :233256   Median :2018   Mode  :character   Mode  :character  
##  Mean   :233255   Mean   :2018                                        
##  3rd Qu.:349882   3rd Qu.:2019                                        
##  Max.   :466509   Max.   :2019                                        
##                                                                       
##      CEDI             Cliente             Nombre          Tamaño.Cte.Industria
##  Length:466508      Length:466508      Length:466508      Length:466508       
##  Class :character   Class :character   Class :character   Class :character    
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character    
##                                                                               
##                                                                               
##                                                                               
##                                                                               
##  Segmento.Det          Marca           Presentacion          Tamaño         
##  Length:466508      Length:466508      Length:466508      Length:466508     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##  Retornable_NR          Enero           Febrero           Marzo       
##  Length:466508      Min.   :-19.00   Min.   :-11.00   Min.   :-32.00  
##  Class :character   1st Qu.:  1.00   1st Qu.:  1.00   1st Qu.:  1.00  
##  Mode  :character   Median :  2.00   Median :  2.00   Median :  3.00  
##                     Mean   :  9.39   Mean   :  9.09   Mean   : 10.54  
##                     3rd Qu.:  6.00   3rd Qu.:  6.00   3rd Qu.:  6.00  
##                     Max.   :999.00   Max.   :986.00   Max.   :986.00  
##                     NA's   :233551   NA's   :231285   NA's   :227506  
##      Abril             Mayo             Junio             Julio       
##  Min.   :-70.00   Min.   :-106.00   Min.   :-211.00   Min.   :-60.00  
##  1st Qu.:  1.00   1st Qu.:   1.00   1st Qu.:   1.00   1st Qu.:  1.00  
##  Median :  3.00   Median :   3.00   Median :   3.00   Median :  2.00  
##  Mean   : 10.62   Mean   :  11.44   Mean   :  10.98   Mean   : 10.72  
##  3rd Qu.:  6.00   3rd Qu.:   7.00   3rd Qu.:   6.00   3rd Qu.:  6.00  
##  Max.   :993.00   Max.   : 991.00   Max.   : 998.00   Max.   :993.00  
##  NA's   :224185   NA's   :217072    NA's   :215907    NA's   :223537  
##      Agosto          Septiembre        Octubre         Noviembre     
##  Min.   :-211.00   Min.   :-527     Min.   :-38.0    Min.   :-25.0   
##  1st Qu.:   1.00   1st Qu.:   1     1st Qu.:  1.0    1st Qu.:  1.0   
##  Median :   3.00   Median :   3     Median :  3.0    Median :  3.0   
##  Mean   :  10.95   Mean   :  12     Mean   : 12.1    Mean   : 11.8   
##  3rd Qu.:   6.00   3rd Qu.:   7     3rd Qu.:  7.0    3rd Qu.:  6.0   
##  Max.   : 999.00   Max.   : 993     Max.   :998.0    Max.   :991.0   
##  NA's   :220366    NA's   :337401   NA's   :338482   NA's   :338545  
##    Diciembre     
##  Min.   :-28     
##  1st Qu.:  1     
##  Median :  3     
##  Mean   : 13     
##  3rd Qu.:  7     
##  Max.   :997     
##  NA's   :341954

Observaciones: 3. Tenemos NA en las columnas de los meses. 4. Renemos cantidades negativas. 5. No tenemos ventas por año.

# Cuántos NA tengo en la base de datos variable?
sum(is.na(df))
## [1] 3149791
# Cuántos NA tengo por variable?
sapply(df, function(x) sum(is.na(x)))
##                   ID                  Año           Territorio 
##                    0                    0                    0 
##       Sub.Territorio                 CEDI              Cliente 
##                    0                    0                    0 
##               Nombre Tamaño.Cte.Industria         Segmento.Det 
##                    0                    0                    0 
##                Marca         Presentacion               Tamaño 
##                    0                    0                    0 
##        Retornable_NR                Enero              Febrero 
##                    0               233551               231285 
##                Marzo                Abril                 Mayo 
##               227506               224185               217072 
##                Junio                Julio               Agosto 
##               215907               223537               220366 
##           Septiembre              Octubre            Noviembre 
##               337401               338482               338545 
##            Diciembre 
##               341954
# Reemplazar NA con CEROS
df[is.na(df)]<-0

# Agregar columna de Ventas
df$Ventas <- df$Enero+df$Febrero+df$Marzo+df$Abril+df$Mayo+df$Junio+df$Julio+df$Agosto+df$Septiembre+df$Octubre+df$Noviembre+df$Diciembre

summary(df)
##        ID              Año        Territorio        Sub.Territorio    
##  Min.   :     1   Min.   :2016   Length:466508      Length:466508     
##  1st Qu.:116628   1st Qu.:2017   Class :character   Class :character  
##  Median :233256   Median :2018   Mode  :character   Mode  :character  
##  Mean   :233255   Mean   :2018                                        
##  3rd Qu.:349882   3rd Qu.:2019                                        
##  Max.   :466509   Max.   :2019                                        
##      CEDI             Cliente             Nombre          Tamaño.Cte.Industria
##  Length:466508      Length:466508      Length:466508      Length:466508       
##  Class :character   Class :character   Class :character   Class :character    
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character    
##                                                                               
##                                                                               
##                                                                               
##  Segmento.Det          Marca           Presentacion          Tamaño         
##  Length:466508      Length:466508      Length:466508      Length:466508     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Retornable_NR          Enero           Febrero            Marzo        
##  Length:466508      Min.   :-19.00   Min.   :-11.000   Min.   :-32.000  
##  Class :character   1st Qu.:  0.00   1st Qu.:  0.000   1st Qu.:  0.000  
##  Mode  :character   Median :  0.00   Median :  0.000   Median :  0.000  
##                     Mean   :  4.69   Mean   :  4.581   Mean   :  5.401  
##                     3rd Qu.:  2.00   3rd Qu.:  2.000   3rd Qu.:  3.000  
##                     Max.   :999.00   Max.   :986.000   Max.   :986.000  
##      Abril              Mayo              Junio            Julio        
##  Min.   :-70.000   Min.   :-106.000   Min.   :-211.0   Min.   :-60.000  
##  1st Qu.:  0.000   1st Qu.:   0.000   1st Qu.:   0.0   1st Qu.:  0.000  
##  Median :  0.000   Median :   0.000   Median :   0.0   Median :  0.000  
##  Mean   :  5.519   Mean   :   6.117   Mean   :   5.9   Mean   :  5.583  
##  3rd Qu.:  3.000   3rd Qu.:   3.000   3rd Qu.:   3.0   3rd Qu.:  3.000  
##  Max.   :993.000   Max.   : 991.000   Max.   : 998.0   Max.   :993.000  
##      Agosto           Septiembre          Octubre          Noviembre      
##  Min.   :-211.000   Min.   :-527.000   Min.   :-38.000   Min.   :-25.000  
##  1st Qu.:   0.000   1st Qu.:   0.000   1st Qu.:  0.000   1st Qu.:  0.000  
##  Median :   0.000   Median :   0.000   Median :  0.000   Median :  0.000  
##  Mean   :   5.777   Mean   :   3.311   Mean   :  3.327   Mean   :  3.248  
##  3rd Qu.:   3.000   3rd Qu.:   1.000   3rd Qu.:  1.000   3rd Qu.:  1.000  
##  Max.   : 999.000   Max.   : 993.000   Max.   :998.000   Max.   :991.000  
##    Diciembre           Ventas       
##  Min.   :-28.000   Min.   :-527.00  
##  1st Qu.:  0.000   1st Qu.:   2.00  
##  Median :  0.000   Median :   7.00  
##  Mean   :  3.477   Mean   :  56.93  
##  3rd Qu.:  0.000   3rd Qu.:  26.00  
##  Max.   :997.000   Max.   :9517.00

Resultados

Se utilizó dicha información para dar respuesta a las siguientes preguntas detonantes:

Pregunta 1

¿Puede observarse un crecimiento en las ventas de algunos de los segmentos de productos de la familia Coca Cola en las tiendas en las que se implementó el Proyecto Siglo XXI de Arca Continental? Respuesta: Las ventas incrementaron en mayor medida devido a los nuevos mercados que incursionó Arca identificando nuevos mercados objetivos, por otro lado se observa un ligero incremento en la venta de bebidas de sabores light.

#install.packages("ggplot2")

library(ggplot2)
ggplot(df, aes(x=Año, y= Ventas, colour = Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )

ggplot(df, aes(x=Año, y= Ventas, colour = Segmento.Det)) +
  geom_point() +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )

Pregunta 2

¿El incremento en las ventas es similar entre los diferentes tamaños de clientes? Respuesta: Arca experimentó un aumento en las ventas en 2019 debido al crecimiento en el número de clientes de empresas grandes, micro y pequeñas. Durante ese año, el alza fue especialmente notable debido a la incorporación de empresas grandes y pequeñas.

ggplot(df, aes(x=Año, y= Ventas, colour = Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas Anuales",
    subtitle = "Caso Arca Continental"
  )

df2 <- df %>% filter(Tamaño.Cte.Industria=="Extra Grande")

ggplot(df2, aes(x=Año, y= Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental"
  )

df3 <- df %>% filter(Tamaño.Cte.Industria=="Grande")

ggplot(df3, aes(x=Año, y= Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental"
  )

df4 <- df %>% filter(Tamaño.Cte.Industria=="Micro")

ggplot(df4, aes(x=Año, y= Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental"
  )

df5 <- df %>% filter(Tamaño.Cte.Industria=="Pequeño")

ggplot(df5, aes(x=Año, y= Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental"
  )

Pregunta 3

¿Cuál es el comportamiento observado de las unidades vendidas por mes de cada una de las marcas, independientemente de sus respectivas presentaciones? Respuesta: La marca Coca-Cola es la más vendida de todas, con incremento de ventas en 2019. La marca Sprite con incremento de ventas año con año

df6 <- df %>% filter(Marca=="Coca-Cola")

ggplot(df6, aes(x=Año, y= Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año de Coca Cola",
    subtitle = "Caso Arca Continental"
  )

df7 <- df %>% filter(Marca=="Sprite")

ggplot(df7, aes(x=Año, y= Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año de Sprite",
    subtitle = "Caso Arca Continental"
  )

Pregunta 4

¿Se ha incrementado la venta de productos en envases retornables en los últimos dos años? Respuesta: Si, crubiendo más tamaños de mercados.

df8 <- df %>% filter(Retornable_NR=="Retornable")

ggplot(df8, aes(x=Año, y= Ventas, colour=Tamaño.Cte.Industria)) +
  geom_bar(stat = "Identity") +
  labs(
    title = "Ventas por año de envases retornables",
    subtitle = "Caso Arca Continental"
  )

Pregunta 5

¿El comportamiento de la venta de agua ha incrementado en relación al de los refrescos o las bebidas isotónicas? Respuesta: Las ventas de Agua Purificada y Colas regular ah bajado en el último año. Pero por otro lado, las bebidas Isotónicas han estado en aumento año con año.

df9 <- df %>% filter(Segmento.Det=="Agua Purificada" | Segmento.Det=="Isotónicos Regular" | Segmento.Det=="Colas Regular")

ggplot(df9, aes(x=Año, y= Ventas, fill=Segmento.Det)) +
  geom_bar(position="dodge", stat = "Identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental"
  )

Pregunta 6

¿Puede decirse que la venta mensual de agua está relacionada con la venta mensual de refrescos en los últimos 4 años? Respuesta: No existe relación porque mientras una variable, la de refrescos, está en potencial crecimiento la otra está manteniendose hasta disminuyendo.

df10 <- df %>% filter(Segmento.Det=="Agua Purificada" | Segmento.Det=="Colas Regular")

ggplot(df10, aes(x=Año, y= Ventas, fill=Segmento.Det)) +
  geom_bar(position="dodge", stat = "Identity") +
  labs(
    title = "Ventas por año",
    subtitle = "Caso Arca Continental"
  )

Pregunta 7

¿A cuánto ascienden las ventas esperadas para el 2020 en la Coca Cola de 500 ml NR Vidrio? Respuesta: NoAcorde a un modelo predictivo utilizando regresion lineal, las ventas esperadas para Coca Cola de 500ml NR Vidrio en 2020 es de 444,066 unidades, con una R cuadrada ajustada del 48%.

df11 <- df %>% filter(Marca=="Coca-Cola" & Presentacion=="500 ml NR Vidrio") 

df12 <- aggregate(Ventas ~ Año, df11, sum)
df12$Año <- as.integer(df12$Año)
regresion <- lm(Ventas ~ Año, data=df12)
summary(regresion)
## 
## Call:
## lm(formula = Ventas ~ Año, data = df12)
## 
## Residuals:
##        1        2        3        4 
## -23838.5  35316.5    882.5 -12360.5 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)
## (Intercept) -54970595   28310425  -1.942    0.192
## Año             27433      14032   1.955    0.190
## 
## Residual standard error: 31380 on 2 degrees of freedom
## Multiple R-squared:  0.6565, Adjusted R-squared:  0.4847 
## F-statistic: 3.822 on 1 and 2 DF,  p-value: 0.1898
#Ecuacion de la recta y = -54,970,595 + 27,433*Año
datos <- data.frame(Año=2020)
predict(regresion,datos)
##        1 
## 444065.5
LS0tDQp0aXRsZTogIkFyY2EgQ29udGluZW50YWwiDQphdXRob3I6ICJGYWJpYW5hIE1lZGluYWNlbGxpIEEwMDgzNTg2Ig0KZGF0ZTogIjIwMjMtMDktMTMiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiAic2FuZHN0b25lIg0KICAgIGhpZ2hsaWdodDogInRhbmdvIg0KLS0tDQohW10oQzpcXFVzZXJzXFxIUFxcRGVza3RvcFxcQm9vdGNhbXAgZGUgUHJvZ3JhbWFjacOzblxcNzdlNi5naWYpDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkNvbnRleHRvPC9zcGFuPg0KQXJjYSBDb250aW5lbnRhbCBpbXBsZW1lbnTDsyBlbCBQcm95ZWN0byBTaWdsbyBYWEkgZGVzZGUgMjAxNiBlbiBhbGd1bm9zIGRlIGxvcyBlc3RhYmxlY2ltaWVudG9zIGRlIGxhIFpvbmEgTWV0cm9wb2xpdGFuYSBkZSBHdWFkYWxhamFyYSwgYSBjb250aW51YWNpw7NuIHNlIG1vc3RyYXLDoW4gbG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIGFsIGhhYmVyIGltcGxlbWVudGFkbyBlc3RhIGVzdHJhdGVnaWEuIA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5JbXBvcnRhciBsYSBiYXNlIGRlIGRhdG9zPC9zcGFuPg0KYGBge3J9DQojIGZpbGUuY2hvb3NlKCkNCmRmIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXEhQXFxEb3dubG9hZHNcXGFyY2EuY3N2IikNCmBgYA0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+RW50ZW5kZXIgbGEgYmFzZSBkZSBkYXRvczwvc3Bhbj4NCmBgYHtyfQ0Kc3VtbWFyeShkZikNCmxpYnJhcnkoZHBseXIpDQojIGNvdW50KGRmLFRlcnJpdG9yaW8sc29ydD1UUlVFKQ0KIyBjb3VudChkZixTdWIuVGVycml0b3Jpbyxzb3J0PVRSVUUpDQojIGNvdW50KGRmLCBDRURJLHNvcnQ9VFJVRSkNCiMgY291bnQoZGYsQ2xpZW50ZSxzb3J0PVRSVUUpDQojIGNvdW50KGRmLE5vbWJyZSxzb3J0PVRSVUUpDQojIGNvdW50KGRmLFRhbWHDsW8uQ3RlLkluZHVzdHJpYSxzb3J0PVRSVUUpDQojIGNvdW50KGRmLFNlZ21lbnRvLkRldCxzb3J0PVRSVUUpDQojIGNvdW50KGRmLE1hcmNhLHNvcnQ9VFJVRSkNCiMgY291bnQoZGYsUHJlc2VudGFjaW9uLHNvcnQ9VFJVRSkNCiMgY291bnQoZGYsVGFtYcOxbyxzb3J0PVRSVUUpDQojIGNvdW50KGRmLFJldG9ybmFibGVfTlIsc29ydD1UUlVFKQ0KYGBgDQpPYnNlcnZhY2lvbmVzOg0KMS4gRWxpbWluYXIgZWwgcmVnbG9uIDE4NDA2NS4NCjIuIENhbWJpYXIgZm9ybWF0byBkZSBmZWNoYXMgZGUgY2FyYWN0ZXIgYSBlbnRlcm8uDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5MaW1waWFyIGxhIGJhc2UgZGUgZGF0b3M8L3NwYW4+DQpgYGB7cn0NCmRmIDwtIGRmWy0xODQwNjUsXQ0KDQpkZiRFbmVybyA8LSBhcy5pbnRlZ2VyKGRmJEVuZXJvKQ0KZGYkRmVicmVybyA8LSBhcy5pbnRlZ2VyKGRmJEZlYnJlcm8pDQpkZiRNYXJ6byA8LSBhcy5pbnRlZ2VyKGRmJE1hcnpvKQ0KZGYkQWJyaWwgPC0gYXMuaW50ZWdlcihkZiRBYnJpbCkNCmRmJE1heW8gPC0gYXMuaW50ZWdlcihkZiRNYXlvKQ0KZGYkSnVuaW8gPC0gYXMuaW50ZWdlcihkZiRKdW5pbykNCmRmJEp1bGlvIDwtIGFzLmludGVnZXIoZGYkSnVsaW8pDQpkZiRBZ29zdG8gPC0gYXMuaW50ZWdlcihkZiRBZ29zdG8pDQpkZiRTZXB0aWVtYnJlIDwtIGFzLmludGVnZXIoZGYkU2VwdGllbWJyZSkNCmRmJE9jdHVicmUgPC0gYXMuaW50ZWdlcihkZiRPY3R1YnJlKQ0KZGYkTm92aWVtYnJlIDwtIGFzLmludGVnZXIoZGYkTm92aWVtYnJlKQ0KZGYkRGljaWVtYnJlIDwtIGFzLmludGVnZXIoZGYkRGljaWVtYnJlKQ0KDQpzdW1tYXJ5KGRmKQ0KYGBgDQpPYnNlcnZhY2lvbmVzOiANCjMuIFRlbmVtb3MgTkEgZW4gbGFzIGNvbHVtbmFzIGRlIGxvcyBtZXNlcy4gDQo0LiBSZW5lbW9zIGNhbnRpZGFkZXMgbmVnYXRpdmFzLiANCjUuIE5vIHRlbmVtb3MgdmVudGFzIHBvciBhw7FvLiANCmBgYHtyfQ0KIyBDdcOhbnRvcyBOQSB0ZW5nbyBlbiBsYSBiYXNlIGRlIGRhdG9zIHZhcmlhYmxlPw0Kc3VtKGlzLm5hKGRmKSkNCg0KIyBDdcOhbnRvcyBOQSB0ZW5nbyBwb3IgdmFyaWFibGU/DQpzYXBwbHkoZGYsIGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpDQoNCiMgUmVlbXBsYXphciBOQSBjb24gQ0VST1MNCmRmW2lzLm5hKGRmKV08LTANCg0KIyBBZ3JlZ2FyIGNvbHVtbmEgZGUgVmVudGFzDQpkZiRWZW50YXMgPC0gZGYkRW5lcm8rZGYkRmVicmVybytkZiRNYXJ6bytkZiRBYnJpbCtkZiRNYXlvK2RmJEp1bmlvK2RmJEp1bGlvK2RmJEFnb3N0bytkZiRTZXB0aWVtYnJlK2RmJE9jdHVicmUrZGYkTm92aWVtYnJlK2RmJERpY2llbWJyZQ0KDQpzdW1tYXJ5KGRmKQ0KYGBgDQoNCiMjIyBSZXN1bHRhZG9zIA0KDQpTZSB1dGlsaXrDsyBkaWNoYSBpbmZvcm1hY2nDs24gcGFyYSBkYXIgcmVzcHVlc3RhIGEgbGFzIHNpZ3VpZW50ZXMgcHJlZ3VudGFzIGRldG9uYW50ZXM6IA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5QcmVndW50YSAxPC9zcGFuPg0Kwr9QdWVkZSBvYnNlcnZhcnNlIHVuIGNyZWNpbWllbnRvIGVuIGxhcyB2ZW50YXMgZGUgYWxndW5vcyBkZSBsb3Mgc2VnbWVudG9zIGRlIHByb2R1Y3RvcyBkZSBsYSBmYW1pbGlhIENvY2EgQ29sYSBlbiBsYXMgdGllbmRhcyBlbiBsYXMgcXVlIHNlIGltcGxlbWVudMOzIGVsIFByb3llY3RvIFNpZ2xvIFhYSSBkZSBBcmNhIENvbnRpbmVudGFsPw0KKipSZXNwdWVzdGE6IExhcyB2ZW50YXMgaW5jcmVtZW50YXJvbiBlbiBtYXlvciBtZWRpZGEgZGV2aWRvIGEgbG9zIG51ZXZvcyBtZXJjYWRvcyBxdWUgaW5jdXJzaW9uw7MgQXJjYSBpZGVudGlmaWNhbmRvIG51ZXZvcyBtZXJjYWRvcyBvYmpldGl2b3MsIHBvciBvdHJvIGxhZG8gc2Ugb2JzZXJ2YSB1biBsaWdlcm8gaW5jcmVtZW50byBlbiBsYSB2ZW50YSBkZSBiZWJpZGFzIGRlIHNhYm9yZXMgbGlnaHQuKioNCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQpnZ3Bsb3QoZGYsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBBbnVhbGVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwgVmVudGFzIEFudWFsZXMiDQogICkNCg0KZ2dwbG90KGRmLCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91ciA9IFNlZ21lbnRvLkRldCkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgQW51YWxlcyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIFZlbnRhcyBBbnVhbGVzIg0KICApDQoNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5QcmVndW50YSAyPC9zcGFuPg0Kwr9FbCBpbmNyZW1lbnRvIGVuIGxhcyB2ZW50YXMgZXMgc2ltaWxhciBlbnRyZSBsb3MgZGlmZXJlbnRlcyB0YW1hw7FvcyBkZSBjbGllbnRlcz8NCioqUmVzcHVlc3RhOiBBcmNhIGV4cGVyaW1lbnTDsyB1biBhdW1lbnRvIGVuIGxhcyB2ZW50YXMgZW4gMjAxOSBkZWJpZG8gYWwgY3JlY2ltaWVudG8gZW4gZWwgbsO6bWVybyBkZSBjbGllbnRlcyBkZSBlbXByZXNhcyBncmFuZGVzLCBtaWNybyB5IHBlcXVlw7Fhcy4gRHVyYW50ZSBlc2UgYcOxbywgZWwgYWx6YSBmdWUgZXNwZWNpYWxtZW50ZSBub3RhYmxlIGRlYmlkbyBhIGxhIGluY29ycG9yYWNpw7NuIGRlIGVtcHJlc2FzIGdyYW5kZXMgeSBwZXF1ZcOxYXMuKioNCmBgYHtyfQ0KZ2dwbG90KGRmLCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91ciA9IFRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJJZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgQW51YWxlcyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIg0KICApDQoNCmRmMiA8LSBkZiAlPiUgZmlsdGVyKFRhbWHDsW8uQ3RlLkluZHVzdHJpYT09IkV4dHJhIEdyYW5kZSIpDQoNCmdncGxvdChkZjIsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyPVRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJJZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgcG9yIGHDsW8iLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCINCiAgKQ0KDQpkZjMgPC0gZGYgJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWE9PSJHcmFuZGUiKQ0KDQpnZ3Bsb3QoZGYzLCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91cj1UYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIHBvciBhw7FvIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiDQogICkNCg0KZGY0IDwtIGRmICU+JSBmaWx0ZXIoVGFtYcOxby5DdGUuSW5kdXN0cmlhPT0iTWljcm8iKQ0KDQpnZ3Bsb3QoZGY0LCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91cj1UYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIHBvciBhw7FvIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiDQogICkNCg0KZGY1IDwtIGRmICU+JSBmaWx0ZXIoVGFtYcOxby5DdGUuSW5kdXN0cmlhPT0iUGVxdWXDsW8iKQ0KDQpnZ3Bsb3QoZGY1LCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91cj1UYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIHBvciBhw7FvIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiDQogICkNCmBgYA0KIA0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+UHJlZ3VudGEgMzwvc3Bhbj4NCsK/Q3XDoWwgZXMgZWwgY29tcG9ydGFtaWVudG8gb2JzZXJ2YWRvIGRlIGxhcyB1bmlkYWRlcyB2ZW5kaWRhcyBwb3IgbWVzIGRlIGNhZGEgdW5hIGRlIGxhcyBtYXJjYXMsIGluZGVwZW5kaWVudGVtZW50ZSBkZSBzdXMgcmVzcGVjdGl2YXMgcHJlc2VudGFjaW9uZXM/DQoqKlJlc3B1ZXN0YTogTGEgbWFyY2EgQ29jYS1Db2xhIGVzIGxhIG3DoXMgdmVuZGlkYSBkZSB0b2RhcywgY29uIGluY3JlbWVudG8gZGUgdmVudGFzIGVuIDIwMTkuIExhIG1hcmNhIFNwcml0ZSBjb24gaW5jcmVtZW50byBkZSB2ZW50YXMgYcOxbyBjb24gYcOxbyAqKg0KYGBge3J9DQpkZjYgPC0gZGYgJT4lIGZpbHRlcihNYXJjYT09IkNvY2EtQ29sYSIpDQoNCmdncGxvdChkZjYsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyPVRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJJZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgcG9yIGHDsW8gZGUgQ29jYSBDb2xhIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiDQogICkNCg0KZGY3IDwtIGRmICU+JSBmaWx0ZXIoTWFyY2E9PSJTcHJpdGUiKQ0KDQpnZ3Bsb3QoZGY3LCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91cj1UYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIHBvciBhw7FvIGRlIFNwcml0ZSIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIg0KICApDQpgYGANCiANCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPlByZWd1bnRhIDQ8L3NwYW4+DQrCv1NlIGhhIGluY3JlbWVudGFkbyBsYSB2ZW50YSBkZSBwcm9kdWN0b3MgZW4gZW52YXNlcyByZXRvcm5hYmxlcyBlbiBsb3Mgw7psdGltb3MgZG9zIGHDsW9zPw0KKipSZXNwdWVzdGE6IFNpLCBjcnViaWVuZG8gbcOhcyB0YW1hw7FvcyBkZSBtZXJjYWRvcy4qKg0KYGBge3J9DQpkZjggPC0gZGYgJT4lIGZpbHRlcihSZXRvcm5hYmxlX05SPT0iUmV0b3JuYWJsZSIpDQoNCmdncGxvdChkZjgsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyPVRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJJZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgcG9yIGHDsW8gZGUgZW52YXNlcyByZXRvcm5hYmxlcyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIg0KICApDQpgYGANCiANCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPlByZWd1bnRhIDU8L3NwYW4+DQrCv0VsIGNvbXBvcnRhbWllbnRvIGRlIGxhIHZlbnRhIGRlIGFndWEgaGEgaW5jcmVtZW50YWRvIGVuIHJlbGFjacOzbiBhbCBkZSBsb3MgcmVmcmVzY29zIG8gbGFzIGJlYmlkYXMgaXNvdMOzbmljYXM/DQoqKlJlc3B1ZXN0YTogTGFzIHZlbnRhcyBkZSBBZ3VhIFB1cmlmaWNhZGEgeSBDb2xhcyByZWd1bGFyIGFoIGJhamFkbyBlbiBlbCDDumx0aW1vIGHDsW8uIFBlcm8gcG9yIG90cm8gbGFkbywgbGFzIGJlYmlkYXMgSXNvdMOzbmljYXMgaGFuIGVzdGFkbyBlbiBhdW1lbnRvIGHDsW8gY29uIGHDsW8uKioNCmBgYHtyfQ0KZGY5IDwtIGRmICU+JSBmaWx0ZXIoU2VnbWVudG8uRGV0PT0iQWd1YSBQdXJpZmljYWRhIiB8IFNlZ21lbnRvLkRldD09Iklzb3TDs25pY29zIFJlZ3VsYXIiIHwgU2VnbWVudG8uRGV0PT0iQ29sYXMgUmVndWxhciIpDQoNCmdncGxvdChkZjksIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgZmlsbD1TZWdtZW50by5EZXQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIsIHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIHBvciBhw7FvIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiDQogICkNCmBgYA0KIA0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+UHJlZ3VudGEgNjwvc3Bhbj4NCsK/UHVlZGUgZGVjaXJzZSBxdWUgbGEgdmVudGEgbWVuc3VhbCBkZSBhZ3VhIGVzdMOhIHJlbGFjaW9uYWRhIGNvbiBsYSB2ZW50YSBtZW5zdWFsIGRlIHJlZnJlc2NvcyBlbiBsb3Mgw7psdGltb3MgNCBhw7Fvcz8NCioqUmVzcHVlc3RhOiBObyBleGlzdGUgcmVsYWNpw7NuIHBvcnF1ZSBtaWVudHJhcyB1bmEgdmFyaWFibGUsIGxhIGRlIHJlZnJlc2NvcywgZXN0w6EgZW4gcG90ZW5jaWFsIGNyZWNpbWllbnRvIGxhIG90cmEgZXN0w6EgbWFudGVuaWVuZG9zZSBoYXN0YSBkaXNtaW51eWVuZG8uKioNCmBgYHtyfQ0KZGYxMCA8LSBkZiAlPiUgZmlsdGVyKFNlZ21lbnRvLkRldD09IkFndWEgUHVyaWZpY2FkYSIgfCBTZWdtZW50by5EZXQ9PSJDb2xhcyBSZWd1bGFyIikNCg0KZ2dwbG90KGRmMTAsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgZmlsbD1TZWdtZW50by5EZXQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIsIHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIHBvciBhw7FvIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwiDQogICkNCmBgYA0KIA0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+UHJlZ3VudGEgNzwvc3Bhbj4NCsK/QSBjdcOhbnRvIGFzY2llbmRlbiBsYXMgdmVudGFzIGVzcGVyYWRhcyBwYXJhIGVsIDIwMjAgZW4gbGEgQ29jYSBDb2xhIGRlIDUwMCBtbCBOUiBWaWRyaW8/DQoqKlJlc3B1ZXN0YTogTm9BY29yZGUgYSB1biBtb2RlbG8gcHJlZGljdGl2byB1dGlsaXphbmRvIHJlZ3Jlc2lvbiBsaW5lYWwsIGxhcyB2ZW50YXMgZXNwZXJhZGFzIHBhcmEgQ29jYSBDb2xhIGRlIDUwMG1sIE5SIFZpZHJpbyBlbiAyMDIwIGVzIGRlIDQ0NCwwNjYgdW5pZGFkZXMsIGNvbiB1bmEgUiBjdWFkcmFkYSBhanVzdGFkYSBkZWwgNDglLioqDQpgYGB7cn0NCmRmMTEgPC0gZGYgJT4lIGZpbHRlcihNYXJjYT09IkNvY2EtQ29sYSIgJiBQcmVzZW50YWNpb249PSI1MDAgbWwgTlIgVmlkcmlvIikgDQoNCmRmMTIgPC0gYWdncmVnYXRlKFZlbnRhcyB+IEHDsW8sIGRmMTEsIHN1bSkNCmRmMTIkQcOxbyA8LSBhcy5pbnRlZ2VyKGRmMTIkQcOxbykNCnJlZ3Jlc2lvbiA8LSBsbShWZW50YXMgfiBBw7FvLCBkYXRhPWRmMTIpDQpzdW1tYXJ5KHJlZ3Jlc2lvbikNCiNFY3VhY2lvbiBkZSBsYSByZWN0YSB5ID0gLTU0LDk3MCw1OTUgKyAyNyw0MzMqQcOxbw0KZGF0b3MgPC0gZGF0YS5mcmFtZShBw7FvPTIwMjApDQpwcmVkaWN0KHJlZ3Jlc2lvbixkYXRvcykNCmBgYA0KDQoNCg0KDQoNCg0K