A01722140 | Marcelo Tam Arica, A01570977 | Mariana Leal López, A01656904 | Mariano Bautista Arreguin, A01733969 | Luis Roberto Cagide Fortson, A01747001 | Andrea Ortiz Castro, A00834279 | Constantino Millet Xacur

Librerías

#install.packages("readxl")
library(readxl)
#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
#install.packages(#ggplot2")
library(ggplot2)
#install.packages("janitor")
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test

Entender la base de datos

library(readxl)
library(dplyr)
library(ggplot2)

file_path <- "/Users/marianaaleal/Desktop/TEC 2025/Generación de escenarios futuros con analítica/Alimentos.xlsx"
data <- read_excel(file_path, sheet = "base2")
data <- read_excel(file_path, .name_repair = "universal")
## New names:
## • `Dic 21` -> `Dic.21`
## • `Enero 22` -> `Enero.22`
## • `Feb 22` -> `Feb.22`
## • `Marzo 22` -> `Marzo.22`
## • `Abr 22` -> `Abr.22`
## • `Mayo 22` -> `Mayo.22`
## • `Jun 22` -> `Jun.22`
## • `Jul 22` -> `Jul.22`
## • `Agosto 22` -> `Agosto.22`
## • `Set 22` -> `Set.22`
## • `Oct 22` -> `Oct.22`
## • `Nov 22` -> `Nov.22`
## • `Dic 22` -> `Dic.22`
## • `Enero 23` -> `Enero.23`
## • `Feb 23` -> `Feb.23`
## • `Marzo 23` -> `Marzo.23`
## • `Abr 23` -> `Abr.23`
## • `Mayo 23` -> `Mayo.23`
## • `Jun 23` -> `Jun.23`
## • `Jul 23` -> `Jul.23`
## • `Agosto 23` -> `Agosto.23`
## • `Set 23` -> `Set.23`
## • `Oct 23` -> `Oct.23`
## • `Nov 23` -> `Nov.23`
## • `Dic 23` -> `Dic.23`
## • `Enero 24` -> `Enero.24`
## • `Feb 24` -> `Feb.24`
## • `Marzo 24` -> `Marzo.24`
## • `Abr 24` -> `Abr.24`
## • `Mayo 24` -> `Mayo.24`
## • `Jun 24` -> `Jun.24`
## • `Jul 24` -> `Jul.24`
## • `Agosto 24` -> `Agosto.24`
## • `Set 24` -> `Set.24`
## • `Oct 24` -> `Oct.24`
## • `Nov 24` -> `Nov.24`
## • `Dic 24` -> `Dic.24`
print(names(data))
##  [1] "Markets"   "CANASTO"   "CATEGORIA" "Dic.21"    "Enero.22"  "Feb.22"   
##  [7] "Marzo.22"  "Abr.22"    "Mayo.22"   "Jun.22"    "Jul.22"    "Agosto.22"
## [13] "Set.22"    "Oct.22"    "Nov.22"    "Dic.22"    "Enero.23"  "Feb.23"   
## [19] "Marzo.23"  "Abr.23"    "Mayo.23"   "Jun.23"    "Jul.23"    "Agosto.23"
## [25] "Set.23"    "Oct.23"    "Nov.23"    "Dic.23"    "Enero.24"  "Feb.24"   
## [31] "Marzo.24"  "Abr.24"    "Mayo.24"   "Jun.24"    "Jul.24"    "Agosto.24"
## [37] "Set.24"    "Oct.24"    "Nov.24"    "Dic.24"
summary(data)
##    Markets            CANASTO           CATEGORIA             Dic.21         
##  Length:1016        Length:1016        Length:1016        Min.   :1.350e+02  
##  Class :character   Class :character   Class :character   1st Qu.:4.534e+06  
##  Mode  :character   Mode  :character   Mode  :character   Median :2.777e+07  
##                                                           Mean   :1.341e+08  
##                                                           3rd Qu.:8.558e+07  
##                                                           Max.   :2.279e+10  
##                                                           NA's   :21         
##     Enero.22             Feb.22             Marzo.22        
##  Min.   :1.350e+02   Min.   :5.400e+02   Min.   :9.000e+01  
##  1st Qu.:4.575e+06   1st Qu.:3.928e+06   1st Qu.:4.526e+06  
##  Median :2.893e+07   Median :2.574e+07   Median :2.910e+07  
##  Mean   :1.384e+08   Mean   :1.266e+08   Mean   :1.411e+08  
##  3rd Qu.:8.728e+07   3rd Qu.:7.926e+07   3rd Qu.:8.619e+07  
##  Max.   :2.352e+10   Max.   :2.150e+10   Max.   :2.401e+10  
##  NA's   :21          NA's   :22          NA's   :21         
##      Abr.22             Mayo.22              Jun.22         
##  Min.   :4.820e+02   Min.   :2.310e+02   Min.   :2.910e+02  
##  1st Qu.:4.434e+06   1st Qu.:4.502e+06   1st Qu.:4.475e+06  
##  Median :2.834e+07   Median :2.862e+07   Median :2.921e+07  
##  Mean   :1.368e+08   Mean   :1.397e+08   Mean   :1.418e+08  
##  3rd Qu.:8.499e+07   3rd Qu.:8.593e+07   3rd Qu.:8.882e+07  
##  Max.   :2.328e+10   Max.   :2.377e+10   Max.   :2.410e+10  
##  NA's   :22          NA's   :22          NA's   :22         
##      Jul.22            Agosto.22             Set.22         
##  Min.   :5.010e+02   Min.   :2.020e+02   Min.   :1.400e+02  
##  1st Qu.:4.569e+06   1st Qu.:4.554e+06   1st Qu.:4.518e+06  
##  Median :3.028e+07   Median :2.994e+07   Median :2.915e+07  
##  Mean   :1.475e+08   Mean   :1.459e+08   Mean   :1.458e+08  
##  3rd Qu.:9.324e+07   3rd Qu.:9.264e+07   3rd Qu.:9.270e+07  
##  Max.   :2.509e+10   Max.   :2.484e+10   Max.   :2.481e+10  
##  NA's   :22          NA's   :22          NA's   :22         
##      Oct.22              Nov.22              Dic.22         
##  Min.   :6.700e+01   Min.   :3.400e+01   Min.   :4.000e+01  
##  1st Qu.:4.548e+06   1st Qu.:4.514e+06   1st Qu.:4.963e+06  
##  Median :2.966e+07   Median :2.853e+07   Median :3.060e+07  
##  Mean   :1.491e+08   Mean   :1.449e+08   Mean   :1.552e+08  
##  3rd Qu.:9.451e+07   3rd Qu.:9.093e+07   3rd Qu.:9.744e+07  
##  Max.   :2.536e+10   Max.   :2.463e+10   Max.   :2.639e+10  
##  NA's   :22          NA's   :23          NA's   :23         
##     Enero.23             Feb.23             Marzo.23        
##  Min.   :1.300e+01   Min.   :2.782e+03   Min.   :4.812e+03  
##  1st Qu.:5.273e+06   1st Qu.:4.359e+06   1st Qu.:5.095e+06  
##  Median :3.224e+07   Median :2.822e+07   Median :3.131e+07  
##  Mean   :1.595e+08   Mean   :1.446e+08   Mean   :1.574e+08  
##  3rd Qu.:1.011e+08   3rd Qu.:9.101e+07   3rd Qu.:9.878e+07  
##  Max.   :2.717e+10   Max.   :2.461e+10   Max.   :2.679e+10  
##  NA's   :20          NA's   :22          NA's   :22         
##      Abr.23             Mayo.23              Jun.23         
##  Min.   :5.554e+03   Min.   :6.401e+03   Min.   :6.658e+03  
##  1st Qu.:4.866e+06   1st Qu.:4.950e+06   1st Qu.:5.120e+06  
##  Median :3.047e+07   Median :3.165e+07   Median :3.157e+07  
##  Mean   :1.541e+08   Mean   :1.555e+08   Mean   :1.542e+08  
##  3rd Qu.:9.856e+07   3rd Qu.:9.775e+07   3rd Qu.:9.719e+07  
##  Max.   :2.622e+10   Max.   :2.646e+10   Max.   :2.622e+10  
##  NA's   :22          NA's   :22          NA's   :22         
##      Jul.23            Agosto.23             Set.23         
##  Min.   :5.587e+03   Min.   :5.339e+03   Min.   :6.634e+03  
##  1st Qu.:4.970e+06   1st Qu.:4.902e+06   1st Qu.:4.875e+06  
##  Median :3.292e+07   Median :3.274e+07   Median :3.157e+07  
##  Mean   :1.610e+08   Mean   :1.558e+08   Mean   :1.527e+08  
##  3rd Qu.:1.020e+08   3rd Qu.:9.721e+07   3rd Qu.:9.375e+07  
##  Max.   :2.736e+10   Max.   :2.648e+10   Max.   :2.597e+10  
##  NA's   :22          NA's   :22          NA's   :22         
##      Oct.23              Nov.23              Dic.23         
##  Min.   :4.000e+00   Min.   :1.195e+03   Min.   :3.900e+01  
##  1st Qu.:4.825e+06   1st Qu.:4.707e+06   1st Qu.:5.192e+06  
##  Median :3.257e+07   Median :3.158e+07   Median :3.364e+07  
##  Mean   :1.573e+08   Mean   :1.535e+08   Mean   :1.648e+08  
##  3rd Qu.:9.313e+07   3rd Qu.:9.372e+07   3rd Qu.:1.015e+08  
##  Max.   :2.680e+10   Max.   :2.618e+10   Max.   :2.811e+10  
##  NA's   :20          NA's   :20          NA's   :20         
##     Enero.24             Feb.24             Marzo.24        
##  Min.   :1.079e+03   Min.   :4.840e+02   Min.   :1.450e+02  
##  1st Qu.:5.321e+06   1st Qu.:4.706e+06   1st Qu.:5.012e+06  
##  Median :3.417e+07   Median :3.057e+07   Median :3.271e+07  
##  Mean   :1.663e+08   Mean   :1.547e+08   Mean   :1.625e+08  
##  3rd Qu.:1.049e+08   3rd Qu.:9.448e+07   3rd Qu.:1.006e+08  
##  Max.   :2.827e+10   Max.   :2.649e+10   Max.   :2.782e+10  
##  NA's   :22          NA's   :15          NA's   :15         
##      Abr.24             Mayo.24              Jun.24         
##  Min.   :2.510e+02   Min.   :2.630e+02   Min.   :4.400e+01  
##  1st Qu.:4.771e+06   1st Qu.:4.957e+06   1st Qu.:4.961e+06  
##  Median :3.295e+07   Median :3.218e+07   Median :3.249e+07  
##  Mean   :1.591e+08   Mean   :1.588e+08   Mean   :1.608e+08  
##  3rd Qu.:9.886e+07   3rd Qu.:9.900e+07   3rd Qu.:1.001e+08  
##  Max.   :2.721e+10   Max.   :2.717e+10   Max.   :2.747e+10  
##  NA's   :16          NA's   :16          NA's   :16         
##      Jul.24            Agosto.24             Set.24         
##  Min.   :5.020e+02   Min.   :9.300e+01   Min.   :3.225e+03  
##  1st Qu.:4.953e+06   1st Qu.:5.176e+06   1st Qu.:5.219e+06  
##  Median :3.407e+07   Median :3.491e+07   Median :3.418e+07  
##  Mean   :1.687e+08   Mean   :1.668e+08   Mean   :1.650e+08  
##  3rd Qu.:1.067e+08   3rd Qu.:1.063e+08   3rd Qu.:1.052e+08  
##  Max.   :2.878e+10   Max.   :2.832e+10   Max.   :2.796e+10  
##  NA's   :17          NA's   :22          NA's   :25         
##      Oct.24              Nov.24              Dic.24         
##  Min.   :1.800e+02   Min.   :1.454e+03   Min.   :3.680e+02  
##  1st Qu.:5.223e+06   1st Qu.:5.239e+06   1st Qu.:5.607e+06  
##  Median :3.526e+07   Median :3.392e+07   Median :3.457e+07  
##  Mean   :1.689e+08   Mean   :1.626e+08   Mean   :1.717e+08  
##  3rd Qu.:1.062e+08   3rd Qu.:1.006e+08   3rd Qu.:1.081e+08  
##  Max.   :2.875e+10   Max.   :2.762e+10   Max.   :2.921e+10  
##  NA's   :21          NA's   :23          NA's   :23

Preguntas Equipo #2

1. ¿Cuál es el canal más beneficiado para el canasto de alimentos y por qué está creciendo?

canal_mas_beneficiado <- data %>%
  group_by(Markets) %>%  # Agrupar por la columna "Markets" (canales)
  summarise(Total_Ventas = sum(`Dic.23`, na.rm = TRUE)) %>%  # Usar "Dic.23" como ventas recientes
  arrange(desc(Total_Ventas)) %>%
  slice(1)

# Gráfico
ggplot(canal_mas_beneficiado, aes(x = reorder(Markets, -Total_Ventas), y = Total_Ventas, fill = Markets)) +
  geom_bar(stat = "identity", color = "black") +
  labs(title = "Canal más beneficiado (Dic. 2023)",
       x = "Canal",
       y = "Total de Ventas") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Resultado
print("Canal más beneficiado:")
## [1] "Canal más beneficiado:"
print(canal_mas_beneficiado)
## # A tibble: 1 × 2
##   Markets           Total_Ventas
##   <chr>                    <dbl>
## 1 Total Mexico_ MT_ 82080624888.

2. ¿Qué categorías impulsan su desarrollo?

categorias_impulsoras <- data %>%
  group_by(CATEGORIA) %>%
  summarise(Total_Crecimiento = sum(`Dic.23` - `Dic.22`, na.rm = TRUE)) %>%
  arrange(desc(Total_Crecimiento)) %>%
  slice(1:5)  # Top 5 categorías

# Gráfico
ggplot(categorias_impulsoras, aes(x = reorder(CATEGORIA, -Total_Crecimiento), y = Total_Crecimiento, fill = CATEGORIA)) +
  geom_bar(stat = "identity", color = "black") +
  labs(title = "Top 5 Categorías que impulsan el desarrollo (Dic. 2023 vs Dic. 2022)",
       x = "Categoría",
       y = "Crecimiento") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Resultado
print("Categorías que impulsan el desarrollo:")
## [1] "Categorías que impulsan el desarrollo:"
print(categorias_impulsoras)
## # A tibble: 5 × 2
##   CATEGORIA                                  Total_Crecimiento
##   <chr>                                                  <dbl>
## 1 <NA>                                             3436989004.
## 2 QUESOS PROCESADOS                                1071063010.
## 3 SOPAS PROCESADAS                                 1021113504.
## 4 TORTILLAS + TOSTADAS + TOTOPOS CANASTOS CX        938032303.
## 5 CREMAS COMESTIBLES                                727867314.

3. ¿El crecimiento de este canal para alimentos se debe a un efecto precio, surtido, presencia?

4. ¿Cuáles son las categorías que han ganado espacio en anaquel y cómo les ha funcionado?

categorias_anaquel <- data %>%
  group_by(CATEGORIA) %>%
  summarise(Efecto_Surtido = mean(`Dic.23` / `Dic.22`, na.rm = TRUE)) %>%
  arrange(desc(Efecto_Surtido)) %>%
  slice(1:5)  # Top 5 categorías

# Gráfico
ggplot(categorias_anaquel, aes(x = reorder(CATEGORIA, -Efecto_Surtido), y = Efecto_Surtido, fill = CATEGORIA)) +
  geom_bar(stat = "identity", color = "black") +
  labs(title = "Top 5 Categorías que han ganado espacio en anaquel (Dic. 2023 vs Dic. 2022)",
       x = "Categoría",
       y = "Efecto Surtido") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

5. ¿Las tendencias de ahorro generan búsquedas de presentaciones grandes o pequeñas? ¿Quiénes se llevan cada tipo de producto?

tendencias_ahorro <- data %>%
  group_by(CATEGORIA) %>%
  summarise(Total_Ventas = sum(`Dic.23`, na.rm = TRUE)) %>%
  arrange(desc(Total_Ventas))

# Gráfico
ggplot(tendencias_ahorro, aes(x = reorder(CATEGORIA, -Total_Ventas), y = Total_Ventas, fill = CATEGORIA)) +
  geom_bar(stat = "identity", color = "black") +
  labs(title = "Tendencias de ahorro y ventas por categoría (Dic. 2023)",
       x = "Categoría",
       y = "Total de Ventas") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

6. ¿Qué creen que estén haciendo los consumidores en su búsqueda de ahorro?

comportamiento_ahorro <- data %>%
  group_by(CATEGORIA) %>%
  summarise(Total_Ventas = sum(`Dic.23`, na.rm = TRUE)) %>%
  arrange(desc(Total_Ventas))

# Gráfico
ggplot(comportamiento_ahorro, aes(x = reorder(CATEGORIA, -Total_Ventas), y = Total_Ventas, fill = CATEGORIA)) +
  geom_bar(stat = "identity", color = "black") +
  labs(title = "Comportamiento de los consumidores en búsqueda de ahorro (Dic. 2023)",
       x = "Categoría",
       y = "Total de Ventas") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

7. ¿Qué podemos esperar para 2025? ¿Cómo pueden las marcas mexicanas acelerar la recuperación en volumen ante un canasto sensible?

proyeccion_2025 <- data %>%
  group_by(Markets, CATEGORIA) %>%
  summarise(Proyeccion = mean(`Dic.24`, na.rm = TRUE)) %>%
  arrange(desc(Proyeccion))
## `summarise()` has grouped output by 'Markets'. You can override using the
## `.groups` argument.
# Gráfico
ggplot(proyeccion_2025, aes(x = reorder(CATEGORIA, -Proyeccion), y = Proyeccion, fill = Markets)) +
  geom_bar(stat = "identity", position = "dodge", color = "black") +
  labs(title = "Proyección de ventas para 2025 por categoría y canal",
       x = "Categoría",
       y = "Proyección de Ventas") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
## Warning: Removed 5 rows containing missing values or values outside the scale range
## (`geom_bar()`).

LS0tCnRpdGxlOiAiRXZpZGVuY2lhIDFfQmFzZSBnZW5lcmFsIgphdXRob3I6ICJFcXVpcG8gIzIiCmRhdGU6ICJGZWJydWFyeSAyMDI1IgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQogICAgY29kZV9kb3dubG9hZDogVFJVRQogICAgdGhlbWU6IGRhcmtseQogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgY3NzOiBzdHlsZXMuY3NzCi0tLQojIyMjIEEwMTcyMjE0MCB8IE1hcmNlbG8gVGFtIEFyaWNhLCBBMDE1NzA5NzcgfCBNYXJpYW5hIExlYWwgTMOzcGV6LCBBMDE2NTY5MDQgfCBNYXJpYW5vIEJhdXRpc3RhIEFycmVndWluLCBBMDE3MzM5NjkgfCBMdWlzIFJvYmVydG8gQ2FnaWRlIEZvcnRzb24sIEEwMTc0NzAwMSB8IEFuZHJlYSBPcnRpeiBDYXN0cm8sIEEwMDgzNDI3OSB8IENvbnN0YW50aW5vIE1pbGxldCBYYWN1cgoKIVsgXShodHRwczovL2RyaXZlLmdvb2dsZS5jb20vdWM/aWQ9MUlfTTRJTFVIdF9ScWZvOS0tQlFnemRGOEhfSUxXMUp3KQoKIyBMaWJyZXLDrWFzCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygicmVhZHhsIikKbGlicmFyeShyZWFkeGwpCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpCmxpYnJhcnkoZHBseXIpCiNpbnN0YWxsLnBhY2thZ2VzKCNnZ3Bsb3QyIikKbGlicmFyeShnZ3Bsb3QyKQojaW5zdGFsbC5wYWNrYWdlcygiamFuaXRvciIpCmxpYnJhcnkoamFuaXRvcikKYGBgCgojIEVudGVuZGVyIGxhIGJhc2UgZGUgZGF0b3MKYGBge3J9CmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCgpmaWxlX3BhdGggPC0gIi9Vc2Vycy9tYXJpYW5hYWxlYWwvRGVza3RvcC9URUMgMjAyNS9HZW5lcmFjacOzbiBkZSBlc2NlbmFyaW9zIGZ1dHVyb3MgY29uIGFuYWzDrXRpY2EvQWxpbWVudG9zLnhsc3giCmRhdGEgPC0gcmVhZF9leGNlbChmaWxlX3BhdGgsIHNoZWV0ID0gImJhc2UyIikKZGF0YSA8LSByZWFkX2V4Y2VsKGZpbGVfcGF0aCwgLm5hbWVfcmVwYWlyID0gInVuaXZlcnNhbCIpCgpwcmludChuYW1lcyhkYXRhKSkKc3VtbWFyeShkYXRhKQpgYGAKIyBQcmVndW50YXMgRXF1aXBvICMyCiMjIyAxLiDCv0N1w6FsIGVzIGVsIGNhbmFsIG3DoXMgYmVuZWZpY2lhZG8gcGFyYSBlbCBjYW5hc3RvIGRlIGFsaW1lbnRvcyB5IHBvciBxdcOpIGVzdMOhIGNyZWNpZW5kbz8KCmBgYHtyfQpjYW5hbF9tYXNfYmVuZWZpY2lhZG8gPC0gZGF0YSAlPiUKICBncm91cF9ieShNYXJrZXRzKSAlPiUgICMgQWdydXBhciBwb3IgbGEgY29sdW1uYSAiTWFya2V0cyIgKGNhbmFsZXMpCiAgc3VtbWFyaXNlKFRvdGFsX1ZlbnRhcyA9IHN1bShgRGljLjIzYCwgbmEucm0gPSBUUlVFKSkgJT4lICAjIFVzYXIgIkRpYy4yMyIgY29tbyB2ZW50YXMgcmVjaWVudGVzCiAgYXJyYW5nZShkZXNjKFRvdGFsX1ZlbnRhcykpICU+JQogIHNsaWNlKDEpCgojIEdyw6FmaWNvCmdncGxvdChjYW5hbF9tYXNfYmVuZWZpY2lhZG8sIGFlcyh4ID0gcmVvcmRlcihNYXJrZXRzLCAtVG90YWxfVmVudGFzKSwgeSA9IFRvdGFsX1ZlbnRhcywgZmlsbCA9IE1hcmtldHMpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGNvbG9yID0gImJsYWNrIikgKwogIGxhYnModGl0bGUgPSAiQ2FuYWwgbcOhcyBiZW5lZmljaWFkbyAoRGljLiAyMDIzKSIsCiAgICAgICB4ID0gIkNhbmFsIiwKICAgICAgIHkgPSAiVG90YWwgZGUgVmVudGFzIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKCiMgUmVzdWx0YWRvCnByaW50KCJDYW5hbCBtw6FzIGJlbmVmaWNpYWRvOiIpCnByaW50KGNhbmFsX21hc19iZW5lZmljaWFkbykKCmBgYAoKCgojIyMgMi4gwr9RdcOpIGNhdGVnb3LDrWFzIGltcHVsc2FuIHN1IGRlc2Fycm9sbG8/CmBgYHtyfQpjYXRlZ29yaWFzX2ltcHVsc29yYXMgPC0gZGF0YSAlPiUKICBncm91cF9ieShDQVRFR09SSUEpICU+JQogIHN1bW1hcmlzZShUb3RhbF9DcmVjaW1pZW50byA9IHN1bShgRGljLjIzYCAtIGBEaWMuMjJgLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBhcnJhbmdlKGRlc2MoVG90YWxfQ3JlY2ltaWVudG8pKSAlPiUKICBzbGljZSgxOjUpICAjIFRvcCA1IGNhdGVnb3LDrWFzCgojIEdyw6FmaWNvCmdncGxvdChjYXRlZ29yaWFzX2ltcHVsc29yYXMsIGFlcyh4ID0gcmVvcmRlcihDQVRFR09SSUEsIC1Ub3RhbF9DcmVjaW1pZW50byksIHkgPSBUb3RhbF9DcmVjaW1pZW50bywgZmlsbCA9IENBVEVHT1JJQSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgY29sb3IgPSAiYmxhY2siKSArCiAgbGFicyh0aXRsZSA9ICJUb3AgNSBDYXRlZ29yw61hcyBxdWUgaW1wdWxzYW4gZWwgZGVzYXJyb2xsbyAoRGljLiAyMDIzIHZzIERpYy4gMjAyMikiLAogICAgICAgeCA9ICJDYXRlZ29yw61hIiwKICAgICAgIHkgPSAiQ3JlY2ltaWVudG8iKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQoKIyBSZXN1bHRhZG8KcHJpbnQoIkNhdGVnb3LDrWFzIHF1ZSBpbXB1bHNhbiBlbCBkZXNhcnJvbGxvOiIpCnByaW50KGNhdGVnb3JpYXNfaW1wdWxzb3JhcykKCmBgYAoKIyMjIDMuIMK/RWwgY3JlY2ltaWVudG8gZGUgZXN0ZSBjYW5hbCBwYXJhIGFsaW1lbnRvcyBzZSBkZWJlIGEgdW4gZWZlY3RvIHByZWNpbywgc3VydGlkbywgcHJlc2VuY2lhPwoKCgoKIyMjIDQuIMK/Q3XDoWxlcyBzb24gbGFzIGNhdGVnb3LDrWFzIHF1ZSBoYW4gZ2FuYWRvIGVzcGFjaW8gZW4gYW5hcXVlbCB5IGPDs21vIGxlcyBoYSBmdW5jaW9uYWRvPwpgYGB7cn0KY2F0ZWdvcmlhc19hbmFxdWVsIDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkoQ0FURUdPUklBKSAlPiUKICBzdW1tYXJpc2UoRWZlY3RvX1N1cnRpZG8gPSBtZWFuKGBEaWMuMjNgIC8gYERpYy4yMmAsIG5hLnJtID0gVFJVRSkpICU+JQogIGFycmFuZ2UoZGVzYyhFZmVjdG9fU3VydGlkbykpICU+JQogIHNsaWNlKDE6NSkgICMgVG9wIDUgY2F0ZWdvcsOtYXMKCiMgR3LDoWZpY28KZ2dwbG90KGNhdGVnb3JpYXNfYW5hcXVlbCwgYWVzKHggPSByZW9yZGVyKENBVEVHT1JJQSwgLUVmZWN0b19TdXJ0aWRvKSwgeSA9IEVmZWN0b19TdXJ0aWRvLCBmaWxsID0gQ0FURUdPUklBKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHRpdGxlID0gIlRvcCA1IENhdGVnb3LDrWFzIHF1ZSBoYW4gZ2FuYWRvIGVzcGFjaW8gZW4gYW5hcXVlbCAoRGljLiAyMDIzIHZzIERpYy4gMjAyMikiLAogICAgICAgeCA9ICJDYXRlZ29yw61hIiwKICAgICAgIHkgPSAiRWZlY3RvIFN1cnRpZG8iKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQoKYGBgCgoKCiMjIyA1LiDCv0xhcyB0ZW5kZW5jaWFzIGRlIGFob3JybyBnZW5lcmFuIGLDunNxdWVkYXMgZGUgcHJlc2VudGFjaW9uZXMgZ3JhbmRlcyBvIHBlcXVlw7Fhcz8gwr9RdWnDqW5lcyBzZSBsbGV2YW4gY2FkYSB0aXBvIGRlIHByb2R1Y3RvPwpgYGB7cn0KdGVuZGVuY2lhc19haG9ycm8gPC0gZGF0YSAlPiUKICBncm91cF9ieShDQVRFR09SSUEpICU+JQogIHN1bW1hcmlzZShUb3RhbF9WZW50YXMgPSBzdW0oYERpYy4yM2AsIG5hLnJtID0gVFJVRSkpICU+JQogIGFycmFuZ2UoZGVzYyhUb3RhbF9WZW50YXMpKQoKIyBHcsOhZmljbwpnZ3Bsb3QodGVuZGVuY2lhc19haG9ycm8sIGFlcyh4ID0gcmVvcmRlcihDQVRFR09SSUEsIC1Ub3RhbF9WZW50YXMpLCB5ID0gVG90YWxfVmVudGFzLCBmaWxsID0gQ0FURUdPUklBKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHRpdGxlID0gIlRlbmRlbmNpYXMgZGUgYWhvcnJvIHkgdmVudGFzIHBvciBjYXRlZ29yw61hIChEaWMuIDIwMjMpIiwKICAgICAgIHggPSAiQ2F0ZWdvcsOtYSIsCiAgICAgICB5ID0gIlRvdGFsIGRlIFZlbnRhcyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKCgojIyMgNi4gwr9RdcOpIGNyZWVuIHF1ZSBlc3TDqW4gaGFjaWVuZG8gbG9zIGNvbnN1bWlkb3JlcyBlbiBzdSBiw7pzcXVlZGEgZGUgYWhvcnJvPwoKYGBge3J9CmNvbXBvcnRhbWllbnRvX2Fob3JybyA8LSBkYXRhICU+JQogIGdyb3VwX2J5KENBVEVHT1JJQSkgJT4lCiAgc3VtbWFyaXNlKFRvdGFsX1ZlbnRhcyA9IHN1bShgRGljLjIzYCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgYXJyYW5nZShkZXNjKFRvdGFsX1ZlbnRhcykpCgojIEdyw6FmaWNvCmdncGxvdChjb21wb3J0YW1pZW50b19haG9ycm8sIGFlcyh4ID0gcmVvcmRlcihDQVRFR09SSUEsIC1Ub3RhbF9WZW50YXMpLCB5ID0gVG90YWxfVmVudGFzLCBmaWxsID0gQ0FURUdPUklBKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHRpdGxlID0gIkNvbXBvcnRhbWllbnRvIGRlIGxvcyBjb25zdW1pZG9yZXMgZW4gYsO6c3F1ZWRhIGRlIGFob3JybyAoRGljLiAyMDIzKSIsCiAgICAgICB4ID0gIkNhdGVnb3LDrWEiLAogICAgICAgeSA9ICJUb3RhbCBkZSBWZW50YXMiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQoKYGBgCgoKCgojIyMgNy4gwr9RdcOpIHBvZGVtb3MgZXNwZXJhciBwYXJhIDIwMjU/IMK/Q8OzbW8gcHVlZGVuIGxhcyBtYXJjYXMgbWV4aWNhbmFzIGFjZWxlcmFyIGxhIHJlY3VwZXJhY2nDs24gZW4gdm9sdW1lbiBhbnRlIHVuIGNhbmFzdG8gc2Vuc2libGU/CmBgYHtyfQpwcm95ZWNjaW9uXzIwMjUgPC0gZGF0YSAlPiUKICBncm91cF9ieShNYXJrZXRzLCBDQVRFR09SSUEpICU+JQogIHN1bW1hcmlzZShQcm95ZWNjaW9uID0gbWVhbihgRGljLjI0YCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgYXJyYW5nZShkZXNjKFByb3llY2Npb24pKQoKIyBHcsOhZmljbwpnZ3Bsb3QocHJveWVjY2lvbl8yMDI1LCBhZXMoeCA9IHJlb3JkZXIoQ0FURUdPUklBLCAtUHJveWVjY2lvbiksIHkgPSBQcm95ZWNjaW9uLCBmaWxsID0gTWFya2V0cykpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKHRpdGxlID0gIlByb3llY2Npw7NuIGRlIHZlbnRhcyBwYXJhIDIwMjUgcG9yIGNhdGVnb3LDrWEgeSBjYW5hbCIsCiAgICAgICB4ID0gIkNhdGVnb3LDrWEiLAogICAgICAgeSA9ICJQcm95ZWNjacOzbiBkZSBWZW50YXMiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQoKYGBgCgo=