Contexto

El analizar la informacion de ventas de 2016 a 2019 de productos de la familia Coca Cola en las tiendas dentro de la zona de Guadalajara en los que se implemento el Proyecto Siglo XX1 de Arca Contiental.

Importar base da datos

#file.choose()

df <- read.csv("C:\\Users\\lcyep\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Tec\\Semestre 3\\Semanas Tec\\Programación R\\arca.csv")

Entender la base de Datos

resumen1 <- summary(df)
resumen1
##        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  
##                    
##                    
## 
#install.packages("dplyr")
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)
##    Territorio      n
## 1 Guadalajara 466508
## 2  Territorio      1
#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 renglon 184065 que tiene títulos en lugar de datos.
2. Cambiar formato (de Enero a Diciembre) de caracter a entero.

Limpieza de la base de datos

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

#install.packages("dplyr")
library(dplyr)
count(df,Territorio, sort = TRUE)
##    Territorio      n
## 1 Guadalajara 466508
## 2  Territorio      1
# Eliminar renglon en blanco
df <- df[-184065,]

# Convertir a valores numericos los valores.

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
#Cuantos NA tengo en la base de datos
sum(is.na(df))
## [1] 3149791
# Sustituir los espacios NA con 0.
df[is.na(df)] <- 0

# Convertir a absoluto los valores.
df$Enero <- abs(df$Enero)
df$Febrero <- abs(df$Febrero)
df$Marzo <- abs(df$Marzo)
df$Abril <- abs(df$Abril)
df$Mayo <- abs(df$Mayo)
df$Junio <- abs(df$Junio)
df$Julio <- abs(df$Julio)
df$Agosto <- abs(df$Agosto)
df$Septiembre <- abs(df$Septiembre)
df$Octubre <- abs(df$Octubre)
df$Noviembre <- abs(df$Noviembre)
df$Diciembre <- abs(df$Diciembre)
df$Año <- as.character(df$Año)

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


# Grafica de caja y bigote

boxplot(df$Enero, horizontal = TRUE)

boxplot(df$Agosto, horizontal = TRUE)

resumen <- summary(df)
resumen
##        ID             Año             Territorio        Sub.Territorio    
##  Min.   :     1   Length:466508      Length:466508      Length:466508     
##  1st Qu.:116628   Class :character   Class :character   Class :character  
##  Median :233256   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :233255                                                           
##  3rd Qu.:349882                                                           
##  Max.   :466509                                                           
##      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.   :  0.000   Min.   :  0.000   Min.   :  0.000  
##  Class :character   1st Qu.:  0.000   1st Qu.:  0.000   1st Qu.:  0.000  
##  Mode  :character   Median :  0.000   Median :  0.000   Median :  0.000  
##                     Mean   :  4.691   Mean   :  4.582   Mean   :  5.402  
##                     3rd Qu.:  2.000   3rd Qu.:  2.000   3rd Qu.:  3.000  
##                     Max.   :999.000   Max.   :986.000   Max.   :986.000  
##      Abril              Mayo             Junio             Julio        
##  Min.   :  0.000   Min.   :  0.000   Min.   :  0.000   Min.   :  0.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.521   Mean   :  6.122   Mean   :  5.908   Mean   :  5.585  
##  3rd Qu.:  3.000   3rd Qu.:  3.000   3rd Qu.:  3.000   3rd Qu.:  3.000  
##  Max.   :993.000   Max.   :991.000   Max.   :998.000   Max.   :993.000  
##      Agosto          Septiembre         Octubre         Noviembre     
##  Min.   :  0.000   Min.   :  0.000   Min.   :  0.00   Min.   :  0.00  
##  1st Qu.:  0.000   1st Qu.:  0.000   1st Qu.:  0.00   1st Qu.:  0.00  
##  Median :  0.000   Median :  0.000   Median :  0.00   Median :  0.00  
##  Mean   :  5.781   Mean   :  3.316   Mean   :  3.33   Mean   :  3.25  
##  3rd Qu.:  3.000   3rd Qu.:  1.000   3rd Qu.:  1.00   3rd Qu.:  1.00  
##  Max.   :999.000   Max.   :993.000   Max.   :998.00   Max.   :991.00  
##    Diciembre           Ventas        
##  Min.   :  0.000   Min.   :    0.00  
##  1st Qu.:  0.000   1st Qu.:    2.00  
##  Median :  0.000   Median :    9.00  
##  Mean   :  3.479   Mean   :   68.61  
##  3rd Qu.:  0.000   3rd Qu.:   32.00  
##  Max.   :997.000   Max.   :11393.00

Observaciones:

  1. Tenemos NA en las columnas de los meses.

  2. Tenemos cantidades negativas.

  3. No teniamos ventas por año.

P1

¿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: Arca Continental en el año 2016 al 2017 hubo un pequeño aumento de ventas. En el 2017 para el 2018 no hubo ningun cambio y al final el cambio del 2018 al 2019 fue el mayor dentro de estos 4 años de datos

#install.packages("ggplot2")

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

P2

¿El incremento en las ventas es similar entre los diferentes tamaños de clientes?

Respuesta: Arca Continental 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. Sin embargo, es relevante mencionar que las empresas de tamaño extragrande mostraron una disminución en sus ventas durante 2019. Por otro lado, las empresas micro, que habían enfrentado un declive desde 2016 hasta 2018, vieron un repunte significativo en sus ventas en 2019.

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"
  )

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 Anuales",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )                   

 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 Anuales",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )                 

 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 Anuales",
    subtitle = "Caso Arca Continental Ventas Anuales"
  ) 

 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 Anuales",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )  

P3

¿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 mas 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 Ventas Anuales"
  )  

 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 la marca de Sprite",
    subtitle = "Caso Arca Continental Ventas Anuales"
  )  

P4

¿Se ha incrementado la venta de productos en envases retornables en los últimos dos años?

Respuesta: No, solo hubo un incremento en el ultimo año.

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 Ventas Anuales"
  ) 

P5

¿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 bajaron en su último año. Sin embargo Isotónicos Regular aumentó 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 Ventas Anuales"
  ) 

P6

¿Puede decirse que la venta mensual de agua está relacionada con la venta mensual de refrescos en los últimos 4 años?

Respuesta: La venta de agua y refrescos no esta relacionada.

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 Ventas Anuales"
  ) 

P7

¿A cuánto ascienden las ventas esperadas para el 2020 en la Coca Cola de 500 ml NR Vidrio?

Respuesta: Acorde a un modelo predictivo utilizando regresion lineal, las ventas esperadas para Coca Cola de 500 ml NR Vidrio en 2020 son de 552639 Unidades, con una R cuadrada ajustada del 67%.

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 
## -24287  40868  -8875  -7706 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)
## (Intercept) -84108995   31243357  -2.692    0.115
## Año             41912      15486   2.706    0.114
## 
## Residual standard error: 34630 on 2 degrees of freedom
## Multiple R-squared:  0.7855, Adjusted R-squared:  0.6783 
## F-statistic: 7.325 on 1 and 2 DF,  p-value: 0.1137
#Ecuación de la recta y= -84108995 + 41912*Año

datos <- data.frame(Año=2020)
predict(regresion,datos)
##      1 
## 552639
LS0tDQp0aXRsZTogIkV2aWRlbmNpYSINCmF1dGhvcjogIkx1aXMgQ2FybG9zIFnDqXBpeiBHb256w6FsZXogQTAwODM1NzUyIg0KZGF0ZTogIjIwMjMtMDktMTMiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRSANCiAgICB0b2NfZmxvYXQ6IFRSVUUgDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiAiYm9vdHN0cmFwIiANCiAgICBoaWdobGlnaHQ6ICJ6ZW5idXJuIg0KLS0tDQoNCiFbXShDOlxcVXNlcnNcXGxjeWVwXFxEb3dubG9hZHNcXDE2NDI2MjQ2ODAxNzguZ2lmKQ0KDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IHJlZDsiPkNvbnRleHRvPC9zcGFuPg0KDQoNCkVsIGFuYWxpemFyIGxhIGluZm9ybWFjaW9uIGRlIHZlbnRhcyBkZSAyMDE2IGEgMjAxOSBkZSBwcm9kdWN0b3MgZGUgbGEgZmFtaWxpYSBDb2NhIENvbGEgZW4gbGFzIHRpZW5kYXMgZGVudHJvIGRlIGxhIHpvbmEgZGUgR3VhZGFsYWphcmEgZW4gbG9zIHF1ZSBzZSBpbXBsZW1lbnRvIGVsIFByb3llY3RvIFNpZ2xvIFhYMSBkZSBBcmNhIENvbnRpZW50YWwuDQoNCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiByZWQ7Ij5JbXBvcnRhciBiYXNlIGRhIGRhdG9zPC9zcGFuPg0KDQoNCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCg0KZGYgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcbGN5ZXBcXE9uZURyaXZlIC0gSW5zdGl0dXRvIFRlY25vbG9naWNvIHkgZGUgRXN0dWRpb3MgU3VwZXJpb3JlcyBkZSBNb250ZXJyZXlcXFRlY1xcU2VtZXN0cmUgM1xcU2VtYW5hcyBUZWNcXFByb2dyYW1hY2nDs24gUlxcYXJjYS5jc3YiKQ0KDQpgYGANCg0KIyMjICA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcmVkOyI+RW50ZW5kZXIgbGEgYmFzZSBkZSBEYXRvczwvc3Bhbj4NCmBgYHtyfQ0KcmVzdW1lbjEgPC0gc3VtbWFyeShkZikNCnJlc3VtZW4xDQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQpsaWJyYXJ5KGRwbHlyKQ0KDQpjb3VudChkZiwgVGVycml0b3JpbyAgLCBzb3J0ID0gVFJVRSkNCiNjb3VudChkZiwgU3ViLlRlcnJpdG9yaW8sIHNvcnQgPSBUUlVFKQ0KI2NvdW50KGRmLCBDRURJLCBzb3J0ID0gVFJVRSkNCiNjb3VudChkZiwgQ2xpZW50ZSwgc29ydCA9IFRSVUUpDQojY291bnQoZGYsIE5vbWJyZSwgc29ydCA9IFRSVUUpDQojY291bnQoZGYsIFRhbWHDsW8uQ3RlLkluZHVzdHJpYSwgc29ydCA9IFRSVUUpDQojY291bnQoZGYsIFNlZ21lbnRvLkRldCwgc29ydCA9IFRSVUUpDQojY291bnQoZGYsIE1hcmNhLCBzb3J0ID0gVFJVRSkNCiNjb3VudChkZiwgUHJlc2VudGFjaW9uLCBzb3J0ID0gVFJVRSkNCiNjb3VudChkZiwgVGFtYcOxbywgc29ydCA9IFRSVUUpDQojY291bnQoZGYsIFJldG9ybmFibGVfTlIsIHNvcnQgPSBUUlVFKQ0KDQpgYGANCg0KT2JzZXJ2YWNpb25lczogIA0KMS4gRWxpbWluYXIgcmVuZ2xvbiAxODQwNjUgcXVlIHRpZW5lIHTDrXR1bG9zIGVuIGx1Z2FyIGRlIGRhdG9zLiAgDQoyLiBDYW1iaWFyIGZvcm1hdG8gKGRlIEVuZXJvIGEgRGljaWVtYnJlKSBkZSBjYXJhY3RlciBhIGVudGVyby4gIA0KDQojIyMgIDxzcGFuIHN0eWxlID0gImNvbG9yOiByZWQ7Ij5MaW1waWV6YSBkZSBsYSBiYXNlIGRlIGRhdG9zPC9zcGFuPg0KDQpPYnNlcnZhY2lvbmVzOiAgICANCjMuIFRlbmVtb3MgTkEgZW4gbGFzIGNvbHVtbmFzIGRlIGxvcyBtZXNlcy4gIA0KNC4gVGVuZW1vcyBjYW50aWRhZGVzIG5lZ2F0aXZhcy4gIA0KNS4gTm8gdGVuaWFtb3MgdmVudGFzIHBvciBhw7FvLiAgDQoNCmBgYHtyfQ0KDQojaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KbGlicmFyeShkcGx5cikNCmNvdW50KGRmLFRlcnJpdG9yaW8sIHNvcnQgPSBUUlVFKQ0KDQojIEVsaW1pbmFyIHJlbmdsb24gZW4gYmxhbmNvDQpkZiA8LSBkZlstMTg0MDY1LF0NCg0KIyBDb252ZXJ0aXIgYSB2YWxvcmVzIG51bWVyaWNvcyBsb3MgdmFsb3Jlcy4NCg0KZGYkRW5lcm8gPC0gYXMuaW50ZWdlcihkZiRFbmVybykNCmRmJEZlYnJlcm8gPC0gYXMuaW50ZWdlcihkZiRGZWJyZXJvKQ0KZGYkTWFyem8gPC0gYXMuaW50ZWdlcihkZiRNYXJ6bykNCmRmJEFicmlsIDwtIGFzLmludGVnZXIoZGYkQWJyaWwpDQpkZiRNYXlvIDwtIGFzLmludGVnZXIoZGYkTWF5bykNCmRmJEp1bmlvIDwtIGFzLmludGVnZXIoZGYkSnVuaW8pDQpkZiRKdWxpbyA8LSBhcy5pbnRlZ2VyKGRmJEp1bGlvKQ0KZGYkQWdvc3RvIDwtIGFzLmludGVnZXIoZGYkQWdvc3RvKQ0KZGYkU2VwdGllbWJyZSA8LSBhcy5pbnRlZ2VyKGRmJFNlcHRpZW1icmUpDQpkZiRPY3R1YnJlIDwtIGFzLmludGVnZXIoZGYkT2N0dWJyZSkNCmRmJE5vdmllbWJyZSA8LSBhcy5pbnRlZ2VyKGRmJE5vdmllbWJyZSkNCmRmJERpY2llbWJyZSA8LSBhcy5pbnRlZ2VyKGRmJERpY2llbWJyZSkNCg0KI0N1YW50b3MgTkEgdGVuZ28gZW4gbGEgYmFzZSBkZSBkYXRvcw0Kc3VtKGlzLm5hKGRmKSkNCg0KIyBTdXN0aXR1aXIgbG9zIGVzcGFjaW9zIE5BIGNvbiAwLg0KZGZbaXMubmEoZGYpXSA8LSAwDQoNCiMgQ29udmVydGlyIGEgYWJzb2x1dG8gbG9zIHZhbG9yZXMuDQpkZiRFbmVybyA8LSBhYnMoZGYkRW5lcm8pDQpkZiRGZWJyZXJvIDwtIGFicyhkZiRGZWJyZXJvKQ0KZGYkTWFyem8gPC0gYWJzKGRmJE1hcnpvKQ0KZGYkQWJyaWwgPC0gYWJzKGRmJEFicmlsKQ0KZGYkTWF5byA8LSBhYnMoZGYkTWF5bykNCmRmJEp1bmlvIDwtIGFicyhkZiRKdW5pbykNCmRmJEp1bGlvIDwtIGFicyhkZiRKdWxpbykNCmRmJEFnb3N0byA8LSBhYnMoZGYkQWdvc3RvKQ0KZGYkU2VwdGllbWJyZSA8LSBhYnMoZGYkU2VwdGllbWJyZSkNCmRmJE9jdHVicmUgPC0gYWJzKGRmJE9jdHVicmUpDQpkZiROb3ZpZW1icmUgPC0gYWJzKGRmJE5vdmllbWJyZSkNCmRmJERpY2llbWJyZSA8LSBhYnMoZGYkRGljaWVtYnJlKQ0KZGYkQcOxbyA8LSBhcy5jaGFyYWN0ZXIoZGYkQcOxbykNCg0KIyBBZ3JlZ2FyIGNvbHVtbmEgZGUgVmVudGFzDQpkZiRWZW50YXMgPC0gZGYkRW5lcm8gKyBkZiRGZWJyZXJvICsgZGYkTWFyem8gKyBkZiRBYnJpbCArIGRmJE1heW8gKyAgZGYkQWJyaWwgKyBkZiRNYXlvICsgZGYkIEp1bmlvICsgZGYkSnVsaW8gKyBkZiRBZ29zdG8gKyBkZiRTZXB0aWVtYnJlICsgZGYkT2N0dWJyZSArZGYkTm92aWVtYnJlICsgZGYkRGljaWVtYnJlICANCg0KDQojIEdyYWZpY2EgZGUgY2FqYSB5IGJpZ290ZQ0KDQpib3hwbG90KGRmJEVuZXJvLCBob3Jpem9udGFsID0gVFJVRSkNCmJveHBsb3QoZGYkQWdvc3RvLCBob3Jpem9udGFsID0gVFJVRSkNCg0KDQoNCnJlc3VtZW4gPC0gc3VtbWFyeShkZikNCnJlc3VtZW4NCg0KDQoNCmBgYA0KDQpPYnNlcnZhY2lvbmVzOiAgDQoNCjMuIFRlbmVtb3MgTkEgZW4gbGFzIGNvbHVtbmFzIGRlIGxvcyBtZXNlcy4gIA0KDQo0LiBUZW5lbW9zIGNhbnRpZGFkZXMgbmVnYXRpdmFzLiANCg0KNS4gTm8gdGVuaWFtb3MgdmVudGFzIHBvciBhw7FvLiAgDQoNCg0KDQojIyMgIDxzcGFuIHN0eWxlID0gImNvbG9yOiByZWQ7Ij5QMTwvc3Bhbj4NCg0Kwr9QdWVkZSBvYnNlcnZhcnNlIHVuIGNyZWNpbWllbnRvIGVuIGxhcyB2ZW50YXMgZGUgYWxndW5vcyBkZSBsb3Mgc2VnbWVudG9zIGRlIHByb2R1Y3RvcyBkZSBsYSBmYW1pbGlhIENvY2EgQ29sYSBlbiBsYXMgdGllbmRhcyBlbiBsYXMgcXVlIHNlIGltcGxlbWVudMOzIGVsIFByb3llY3RvIFNpZ2xvIFhYSSBkZSBBcmNhIENvbnRpbmVudGFsPyAgDQoNCioqUmVzcHVlc3RhOiBBcmNhIENvbnRpbmVudGFsIGVuIGVsIGHDsW8gMjAxNiBhbCAyMDE3IGh1Ym8gdW4gcGVxdWXDsW8gYXVtZW50byBkZSB2ZW50YXMuIEVuIGVsIDIwMTcgcGFyYSBlbCAyMDE4IG5vIGh1Ym8gbmluZ3VuIGNhbWJpbyB5IGFsIGZpbmFsIGVsIGNhbWJpbyBkZWwgMjAxOCBhbCAyMDE5IGZ1ZSBlbCBtYXlvciBkZW50cm8gZGUgZXN0b3MgNCBhw7FvcyBkZSBkYXRvcyoqICANCg0KYGBge3J9DQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCg0KbGlicmFyeShnZ3Bsb3QyKQ0KZ2dwbG90KGRmLCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIEFudWFsZXMiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCBWZW50YXMgQW51YWxlcyINCiAgKQ0KYGBgDQoNCg0KDQoNCiMjIyAgPHNwYW4gc3R5bGUgPSAiY29sb3I6IHJlZDsiPlAyPC9zcGFuPg0KDQrCv0VsIGluY3JlbWVudG8gZW4gbGFzIHZlbnRhcyBlcyBzaW1pbGFyIGVudHJlIGxvcyBkaWZlcmVudGVzIHRhbWHDsW9zIGRlIGNsaWVudGVzPyAgDQoNCioqUmVzcHVlc3RhOiBBcmNhIENvbnRpbmVudGFsIGV4cGVyaW1lbnTDsyB1biBhdW1lbnRvIGVuIGxhcyB2ZW50YXMgZW4gMjAxOSBkZWJpZG8gYWwgY3JlY2ltaWVudG8gZW4gZWwgbsO6bWVybyBkZSBjbGllbnRlcyBkZSBlbXByZXNhcyBncmFuZGVzLCBtaWNybyB5IHBlcXVlw7Fhcy4gRHVyYW50ZSBlc2UgYcOxbywgZWwgYWx6YSBmdWUgZXNwZWNpYWxtZW50ZSBub3RhYmxlIGRlYmlkbyBhIGxhIGluY29ycG9yYWNpw7NuIGRlIGVtcHJlc2FzIGdyYW5kZXMgeSBwZXF1ZcOxYXMuIFNpbiBlbWJhcmdvLCBlcyByZWxldmFudGUgbWVuY2lvbmFyIHF1ZSBsYXMgZW1wcmVzYXMgZGUgdGFtYcOxbyBleHRyYWdyYW5kZSBtb3N0cmFyb24gdW5hIGRpc21pbnVjacOzbiBlbiBzdXMgdmVudGFzIGR1cmFudGUgMjAxOS4gUG9yIG90cm8gbGFkbywgbGFzIGVtcHJlc2FzIG1pY3JvLCBxdWUgaGFiw61hbiBlbmZyZW50YWRvIHVuIGRlY2xpdmUgZGVzZGUgMjAxNiBoYXN0YSAyMDE4LCB2aWVyb24gdW4gcmVwdW50ZSBzaWduaWZpY2F0aXZvIGVuIHN1cyB2ZW50YXMgZW4gMjAxOS4qKiANCg0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBBbnVhbGVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwgVmVudGFzIEFudWFsZXMiDQogICkNCg0KZGYyIDwtIGRmJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWEgPT0iRXh0cmEgR3JhbmRlIikNCiBnZ3Bsb3QoZGYyLCBhZXMoeD1Bw7FvLCB5PSBWZW50YXMsIGNvbG91ciA9IFRhbWHDsW8uQ3RlLkluZHVzdHJpYSkpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJJZGVudGl0eSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJWZW50YXMgQW51YWxlcyIsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIFZlbnRhcyBBbnVhbGVzIg0KICApICAgICAgICAgICAgICAgICAgIA0KIA0KIGRmMyA8LSBkZiU+JSBmaWx0ZXIoVGFtYcOxby5DdGUuSW5kdXN0cmlhID09IkdyYW5kZSIpDQogZ2dwbG90KGRmMywgYWVzKHg9QcOxbywgeT0gVmVudGFzLCBjb2xvdXIgPSBUYW1hw7FvLkN0ZS5JbmR1c3RyaWEpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIEFudWFsZXMiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCBWZW50YXMgQW51YWxlcyINCiAgKSAgICAgICAgICAgICAgICAgDQogDQogZGY0IDwtIGRmJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWEgPT0iTWljcm8iKQ0KIGdncGxvdChkZjQsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBBbnVhbGVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwgVmVudGFzIEFudWFsZXMiDQogICkgDQogDQogZGY1IDwtIGRmJT4lIGZpbHRlcihUYW1hw7FvLkN0ZS5JbmR1c3RyaWEgPT0iUGVxdWXDsW8iKQ0KIGdncGxvdChkZjUsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBBbnVhbGVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwgVmVudGFzIEFudWFsZXMiDQogICkgIA0KYGBgDQoNCiANCg0KIyMjICA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcmVkOyI+UDM8L3NwYW4+IA0KDQrCv0N1w6FsIGVzIGVsIGNvbXBvcnRhbWllbnRvIG9ic2VydmFkbyBkZSBsYXMgdW5pZGFkZXMgdmVuZGlkYXMgcG9yIG1lcyBkZSBjYWRhIHVuYSBkZSBsYXMgbWFyY2FzLCBpbmRlcGVuZGllbnRlbWVudGUgZGUgc3VzIHJlc3BlY3RpdmFzIHByZXNlbnRhY2lvbmVzPyAgDQoNCioqUmVzcHVlc3RhOiBMYSBtYXJjYSBDb2NhLUNvbGEgZXMgbGEgbWFzIHZlbmRpZGEgZGUgdG9kYXMsIGNvbiBpbmNyZW1lbnRvIGRlIHZlbnRhcyBlbiAyMDE5LiBMYSBtYXJjYSBTcHJpdGUgY29uIGluY3JlbWVudG8gZGUgdmVudGFzIGHDsW8gY29uIEHDsW8uICoqDQoNCmBgYHtyfQ0KZGY2IDwtIGRmJT4lIGZpbHRlcihNYXJjYSA9PSJDb2NhLUNvbGEiKQ0KIGdncGxvdChkZjYsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyBkZSBDb2NhLUNvbGEiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCBWZW50YXMgQW51YWxlcyINCiAgKSAgDQogDQogDQogZGY3IDwtIGRmJT4lIGZpbHRlcihNYXJjYSA9PSJTcHJpdGUiKQ0KIGdncGxvdChkZjcsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyBkZSBsYSBtYXJjYSBkZSBTcHJpdGUiLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCBWZW50YXMgQW51YWxlcyINCiAgKSAgDQpgYGANCg0KIyMjICA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcmVkOyI+UDQ8L3NwYW4+DQoNCsK/U2UgaGEgaW5jcmVtZW50YWRvIGxhIHZlbnRhIGRlIHByb2R1Y3RvcyBlbiBlbnZhc2VzIHJldG9ybmFibGVzIGVuIGxvcyDDumx0aW1vcyBkb3MgYcOxb3M/ICANCg0KKipSZXNwdWVzdGE6IE5vLCBzb2xvIGh1Ym8gdW4gaW5jcmVtZW50byBlbiBlbCB1bHRpbW8gYcOxby4qKg0KDQpgYGB7cn0NCmRmOCA8LSBkZiU+JSBmaWx0ZXIoUmV0b3JuYWJsZV9OUiA9PSJSZXRvcm5hYmxlIikNCg0KIGdncGxvdChkZjgsIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgY29sb3VyID0gVGFtYcOxby5DdGUuSW5kdXN0cmlhKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyBkZSBlbnZhc2VzIHJldG9ybmFibGVzIiwNCiAgICBzdWJ0aXRsZSA9ICJDYXNvIEFyY2EgQ29udGluZW50YWwgVmVudGFzIEFudWFsZXMiDQogICkgDQpgYGANCg0KIyMjICA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcmVkOyI+UDU8L3NwYW4+DQoNCsK/RWwgY29tcG9ydGFtaWVudG8gZGUgbGEgdmVudGEgZGUgYWd1YSBoYSBpbmNyZW1lbnRhZG8gZW4gcmVsYWNpw7NuIGFsIGRlIGxvcyByZWZyZXNjb3MgbyBsYXMgYmViaWRhcyBpc290w7NuaWNhcz8gIA0KDQoqKlJlc3B1ZXN0YTogTGFzIHZlbnRhcyBkZSBBZ3VhIFB1cmlmaWNhZGEgeSBDb2xhcyBSZWd1bGFyIGJhamFyb24gZW4gc3Ugw7psdGltbyBhw7FvLiBTaW4gZW1iYXJnbyBJc290w7NuaWNvcyBSZWd1bGFyIGF1bWVudMOzIGHDsW8gY29uIGHDsW8uICoqDQoNCmBgYHtyfQ0KZGY5IDwtIGRmJT4lIGZpbHRlcihTZWdtZW50by5EZXQgPT0iQWd1YSBQdXJpZmljYWRhIiB8IFNlZ21lbnRvLkRldCA9PSAiSXNvdMOzbmljb3MgUmVndWxhciIgfCBTZWdtZW50by5EZXQ9PSJDb2xhcyBSZWd1bGFyIikNCg0KIGdncGxvdChkZjksIGFlcyh4PUHDsW8sIHk9IFZlbnRhcywgZmlsbD0gU2VnbWVudG8uRGV0KSkgKw0KICBnZW9tX2Jhcihwb3NpdGlvbj0iZG9kZ2UiICxzdGF0ID0gIklkZW50aXR5IikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlZlbnRhcyBwb3IgYcOxbyIgLA0KICAgIHN1YnRpdGxlID0gIkNhc28gQXJjYSBDb250aW5lbnRhbCBWZW50YXMgQW51YWxlcyINCiAgKSANCmBgYA0KDQojIyMgIDxzcGFuIHN0eWxlID0gImNvbG9yOiByZWQ7Ij5QNjwvc3Bhbj4NCg0Kwr9QdWVkZSBkZWNpcnNlIHF1ZSBsYSB2ZW50YSBtZW5zdWFsIGRlIGFndWEgZXN0w6EgcmVsYWNpb25hZGEgY29uIGxhIHZlbnRhIG1lbnN1YWwgZGUgcmVmcmVzY29zIGVuIGxvcyDDumx0aW1vcyA0IGHDsW9zPyAgDQoNCioqUmVzcHVlc3RhOiBMYSB2ZW50YSBkZSBhZ3VhIHkgcmVmcmVzY29zIG5vIGVzdGEgcmVsYWNpb25hZGEuICoqDQoNCmBgYHtyfQ0KZGYxMCA8LSBkZiU+JSBmaWx0ZXIoU2VnbWVudG8uRGV0ID09IkFndWEgUHVyaWZpY2FkYSIgfCAgU2VnbWVudG8uRGV0PT0iQ29sYXMgUmVndWxhciIpDQoNCiBnZ3Bsb3QoZGYxMCwgYWVzKHg9QcOxbywgeT0gVmVudGFzLCBmaWxsPSBTZWdtZW50by5EZXQpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uPSJkb2RnZSIgLHN0YXQgPSAiSWRlbnRpdHkiKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiVmVudGFzIHBvciBhw7FvIiAsDQogICAgc3VidGl0bGUgPSAiQ2FzbyBBcmNhIENvbnRpbmVudGFsIFZlbnRhcyBBbnVhbGVzIg0KICApIA0KYGBgDQoNCg0KIyMjICA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcmVkOyI+UDc8L3NwYW4+DQoNCsK/QSBjdcOhbnRvIGFzY2llbmRlbiBsYXMgdmVudGFzIGVzcGVyYWRhcyBwYXJhIGVsIDIwMjAgZW4gbGEgQ29jYSBDb2xhIGRlIDUwMCBtbCBOUiBWaWRyaW8/ICANCg0KKipSZXNwdWVzdGE6IEFjb3JkZSBhIHVuIG1vZGVsbyBwcmVkaWN0aXZvIHV0aWxpemFuZG8gcmVncmVzaW9uIGxpbmVhbCwgbGFzIHZlbnRhcyBlc3BlcmFkYXMgcGFyYSBDb2NhIENvbGEgZGUgNTAwIG1sIE5SIFZpZHJpbyBlbiAyMDIwIHNvbiBkZSA1NTI2MzkgVW5pZGFkZXMsIGNvbiB1bmEgUiBjdWFkcmFkYSBhanVzdGFkYSBkZWwgNjclLiAqKg0KDQpgYGB7cn0NCmRmMTEgPC0gZGYlPiUgZmlsdGVyKE1hcmNhID09IkNvY2EtQ29sYSIgJiAgUHJlc2VudGFjaW9uPT0iNTAwIG1sIE5SIFZpZHJpbyIpDQoNCmRmMTIgPC0gYWdncmVnYXRlKFZlbnRhcyB+IEHDsW8sIGRmMTEsIHN1bSkNCmRmMTIkQcOxbyA8LSBhcy5pbnRlZ2VyKGRmMTIkQcOxbykNCg0KDQpyZWdyZXNpb24gPC0gbG0oVmVudGFzIH4gQcOxbywgZGF0YSA9IGRmMTIpDQpzdW1tYXJ5KHJlZ3Jlc2lvbikNCg0KI0VjdWFjacOzbiBkZSBsYSByZWN0YSB5PSAtODQxMDg5OTUgKyA0MTkxMipBw7FvDQoNCmRhdG9zIDwtIGRhdGEuZnJhbWUoQcOxbz0yMDIwKQ0KcHJlZGljdChyZWdyZXNpb24sZGF0b3MpDQpgYGANCg0KDQoNCg0KDQoNCg0K