Instalar paquetes y llmar librerías

#install.packages("tidyverse") # Paquete para manipulación de datos
library(tidyverse)
## Warning: package 'ggplot2' was built under R version 4.3.2
## Warning: package 'tidyr' was built under R version 4.3.2
## Warning: package 'purrr' was built under R version 4.3.3
## Warning: package 'lubridate' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# install.packages("dplyr")
library(dplyr)

Importar base de datos

bd <- read_csv("~/Desktop/Bootcamp R/abarrotes.csv")
## Rows: 200625 Columns: 22
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (12): vcClaveTienda, DescGiro, Fecha, Marca, Fabricante, Producto, Nomb...
## dbl   (7): Codigo Barras, PLU, Precio, Ult.Costo, Unidades, F.Ticket, Mts 2
## time  (3): Hora, Hora inicio, Hora cierre
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
summary(bd)
##  vcClaveTienda        DescGiro         Codigo Barras            PLU        
##  Length:200625      Length:200625      Min.   :8.347e+05   Min.   : 1.00   
##  Class :character   Class :character   1st Qu.:7.501e+12   1st Qu.: 1.00   
##  Mode  :character   Mode  :character   Median :7.501e+12   Median : 1.00   
##                                        Mean   :5.950e+12   Mean   : 2.11   
##                                        3rd Qu.:7.501e+12   3rd Qu.: 1.00   
##                                        Max.   :1.750e+13   Max.   :30.00   
##                                                            NA's   :199188  
##     Fecha               Hora             Marca            Fabricante       
##  Length:200625      Length:200625     Length:200625      Length:200625     
##  Class :character   Class1:hms        Class :character   Class :character  
##  Mode  :character   Class2:difftime   Mode  :character   Mode  :character  
##                     Mode  :numeric                                         
##                                                                            
##                                                                            
##                                                                            
##    Producto             Precio          Ult.Costo         Unidades     
##  Length:200625      Min.   :-147.00   Min.   :  0.38   Min.   : 0.200  
##  Class :character   1st Qu.:  11.00   1st Qu.:  8.46   1st Qu.: 1.000  
##  Mode  :character   Median :  16.00   Median : 12.31   Median : 1.000  
##                     Mean   :  19.42   Mean   : 15.31   Mean   : 1.262  
##                     3rd Qu.:  25.00   3rd Qu.: 19.23   3rd Qu.: 1.000  
##                     Max.   :1000.00   Max.   :769.23   Max.   :96.000  
##                                                                        
##     F.Ticket      NombreDepartamento NombreFamilia      NombreCategoria   
##  Min.   :     1   Length:200625      Length:200625      Length:200625     
##  1st Qu.: 33964   Class :character   Class :character   Class :character  
##  Median :105993   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :193990                                                           
##  3rd Qu.:383005                                                           
##  Max.   :450040                                                           
##                                                                           
##     Estado              Mts 2      Tipo ubicación         Giro          
##  Length:200625      Min.   :47.0   Length:200625      Length:200625     
##  Class :character   1st Qu.:53.0   Class :character   Class :character  
##  Mode  :character   Median :60.0   Mode  :character   Mode  :character  
##                     Mean   :56.6                                        
##                     3rd Qu.:60.0                                        
##                     Max.   :62.0                                        
##                                                                         
##  Hora inicio       Hora cierre      
##  Length:200625     Length:200625    
##  Class1:hms        Class1:hms       
##  Class2:difftime   Class2:difftime  
##  Mode  :numeric    Mode  :numeric   
##                                     
##                                     
## 
str(bd)
## spc_tbl_ [200,625 × 22] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ vcClaveTienda     : chr [1:200625] "MX001" "MX001" "MX001" "MX001" ...
##  $ DescGiro          : chr [1:200625] "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ Codigo Barras     : num [1:200625] 7.5e+12 7.5e+12 7.5e+12 7.5e+12 7.5e+12 ...
##  $ PLU               : num [1:200625] NA NA NA NA NA NA NA NA NA NA ...
##  $ Fecha             : chr [1:200625] "19/06/2020" "19/06/2020" "19/06/2020" "19/06/2020" ...
##  $ Hora              : 'hms' num [1:200625] 08:16:21 08:23:33 08:24:33 08:24:33 ...
##   ..- attr(*, "units")= chr "secs"
##  $ Marca             : chr [1:200625] "NUTRI LECHE" "DAN UP" "BIMBO" "PEPSI" ...
##  $ Fabricante        : chr [1:200625] "MEXILAC" "DANONE DE MEXICO" "GRUPO BIMBO" "PEPSI-COLA MEXICANA" ...
##  $ Producto          : chr [1:200625] "Nutri Leche 1 Litro" "DANUP STRAWBERRY P/BEBER 350GR NAL" "Rebanadas Bimbo 2Pz" "Pepsi N.R. 400Ml" ...
##  $ Precio            : num [1:200625] 16 14 5 8 19.5 16 14 5 8 19.5 ...
##  $ Ult.Costo         : num [1:200625] 12.3 14 5 8 15 ...
##  $ Unidades          : num [1:200625] 1 1 1 1 1 1 1 1 1 1 ...
##  $ F.Ticket          : num [1:200625] 1 2 3 3 4 1 2 3 3 4 ...
##  $ NombreDepartamento: chr [1:200625] "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ NombreFamilia     : chr [1:200625] "Lacteos y Refrigerados" "Lacteos y Refrigerados" "Pan y Tortilla" "Bebidas" ...
##  $ NombreCategoria   : chr [1:200625] "Leche" "Yogurt" "Pan Dulce Empaquetado" "Refrescos Plástico (N.R.)" ...
##  $ Estado            : chr [1:200625] "Nuevo León" "Nuevo León" "Nuevo León" "Nuevo León" ...
##  $ Mts 2             : num [1:200625] 60 60 60 60 60 60 60 60 60 60 ...
##  $ Tipo ubicación    : chr [1:200625] "Esquina" "Esquina" "Esquina" "Esquina" ...
##  $ Giro              : chr [1:200625] "Abarrotes" "Abarrotes" "Abarrotes" "Abarrotes" ...
##  $ Hora inicio       : 'hms' num [1:200625] 08:00:00 08:00:00 08:00:00 08:00:00 ...
##   ..- attr(*, "units")= chr "secs"
##  $ Hora cierre       : 'hms' num [1:200625] 22:00:00 22:00:00 22:00:00 22:00:00 ...
##   ..- attr(*, "units")= chr "secs"
##  - attr(*, "spec")=
##   .. cols(
##   ..   vcClaveTienda = col_character(),
##   ..   DescGiro = col_character(),
##   ..   `Codigo Barras` = col_double(),
##   ..   PLU = col_double(),
##   ..   Fecha = col_character(),
##   ..   Hora = col_time(format = ""),
##   ..   Marca = col_character(),
##   ..   Fabricante = col_character(),
##   ..   Producto = col_character(),
##   ..   Precio = col_double(),
##   ..   Ult.Costo = col_double(),
##   ..   Unidades = col_double(),
##   ..   F.Ticket = col_double(),
##   ..   NombreDepartamento = col_character(),
##   ..   NombreFamilia = col_character(),
##   ..   NombreCategoria = col_character(),
##   ..   Estado = col_character(),
##   ..   `Mts 2` = col_double(),
##   ..   `Tipo ubicación` = col_character(),
##   ..   Giro = col_character(),
##   ..   `Hora inicio` = col_time(format = ""),
##   ..   `Hora cierre` = col_time(format = "")
##   .. )
##  - attr(*, "problems")=<externalptr>
head(bd, n=10)
## # A tibble: 10 × 22
##    vcClaveTienda DescGiro  `Codigo Barras`   PLU Fecha Hora     Marca Fabricante
##    <chr>         <chr>               <dbl> <dbl> <chr> <time>   <chr> <chr>     
##  1 MX001         Abarrotes   7501020540666    NA 19/0… 08:16:21 NUTR… MEXILAC   
##  2 MX001         Abarrotes   7501032397906    NA 19/0… 08:23:33 DAN … DANONE DE…
##  3 MX001         Abarrotes   7501000112845    NA 19/0… 08:24:33 BIMBO GRUPO BIM…
##  4 MX001         Abarrotes   7501031302741    NA 19/0… 08:24:33 PEPSI PEPSI-COL…
##  5 MX001         Abarrotes   7501026027543    NA 19/0… 08:26:28 BLAN… FABRICA D…
##  6 MX001         Abarrotes   7501020540666    NA 19/0… 08:16:21 NUTR… MEXILAC   
##  7 MX001         Abarrotes   7501032397906    NA 19/0… 08:23:33 DAN … DANONE DE…
##  8 MX001         Abarrotes   7501000112845    NA 19/0… 08:24:33 BIMBO GRUPO BIM…
##  9 MX001         Abarrotes   7501031302741    NA 19/0… 08:24:33 PEPSI PEPSI-COL…
## 10 MX001         Abarrotes   7501026027543    NA 19/0… 08:26:28 BLAN… FABRICA D…
## # ℹ 14 more variables: Producto <chr>, Precio <dbl>, Ult.Costo <dbl>,
## #   Unidades <dbl>, F.Ticket <dbl>, NombreDepartamento <chr>,
## #   NombreFamilia <chr>, NombreCategoria <chr>, Estado <chr>, `Mts 2` <dbl>,
## #   `Tipo ubicación` <chr>, Giro <chr>, `Hora inicio` <time>,
## #   `Hora cierre` <time>
tail(bd, n=10)
## # A tibble: 10 × 22
##    vcClaveTienda DescGiro `Codigo Barras`   PLU Fecha  Hora     Marca Fabricante
##    <chr>         <chr>              <dbl> <dbl> <chr>  <time>   <chr> <chr>     
##  1 MX005         Depósito   7622210464811    NA 07/08… 19:30:13 TRID… CADBURY A…
##  2 MX005         Depósito   7622210464811    NA 25/07… 18:42:24 TRID… CADBURY A…
##  3 MX005         Depósito   7622210464811    NA 18/07… 22:45:58 TRID… CADBURY A…
##  4 MX005         Depósito   7622210464811    NA 12/07… 00:36:34 TRID… CADBURY A…
##  5 MX005         Depósito   7622210464811    NA 12/07… 01:08:25 TRID… CADBURY A…
##  6 MX005         Depósito   7622210464811    NA 23/10… 22:17:37 TRID… CADBURY A…
##  7 MX005         Depósito   7622210464811    NA 10/10… 20:30:20 TRID… CADBURY A…
##  8 MX005         Depósito   7622210464811    NA 10/10… 22:40:43 TRID… CADBURY A…
##  9 MX005         Depósito   7622210464811    NA 27/06… 22:30:19 TRID… CADBURY A…
## 10 MX005         Depósito   7622210464811    NA 26/06… 23:43:34 TRID… CADBURY A…
## # ℹ 14 more variables: Producto <chr>, Precio <dbl>, Ult.Costo <dbl>,
## #   Unidades <dbl>, F.Ticket <dbl>, NombreDepartamento <chr>,
## #   NombreFamilia <chr>, NombreCategoria <chr>, Estado <chr>, `Mts 2` <dbl>,
## #   `Tipo ubicación` <chr>, Giro <chr>, `Hora inicio` <time>,
## #   `Hora cierre` <time>
count(bd,vcClaveTienda, sort= TRUE)
## # A tibble: 5 × 2
##   vcClaveTienda     n
##   <chr>         <int>
## 1 MX001         96469
## 2 MX004         83455
## 3 MX005         10021
## 4 MX002          6629
## 5 MX003          4051
count(bd,DescGiro, sort= TRUE)
## # A tibble: 3 × 2
##   DescGiro        n
##   <chr>       <int>
## 1 Abarrotes  100520
## 2 Carnicería  83455
## 3 Depósito    16650
count(bd, Fecha, sort= TRUE)
## # A tibble: 195 × 2
##    Fecha          n
##    <chr>      <int>
##  1 31/05/2020  1938
##  2 07/06/2020  1875
##  3 21/06/2020  1856
##  4 24/05/2020  1822
##  5 03/05/2020  1788
##  6 28/06/2020  1782
##  7 06/06/2020  1770
##  8 14/06/2020  1754
##  9 12/07/2020  1729
## 10 04/07/2020  1704
## # ℹ 185 more rows
count(bd,Marca, sort= TRUE)
## # A tibble: 540 × 2
##    Marca           n
##    <chr>       <int>
##  1 COCA COLA   18686
##  2 PEPSI       15967
##  3 TECATE      11674
##  4 BIMBO        8317
##  5 LALA         5866
##  6 MARINELA     3696
##  7 DORITOS      3142
##  8 CHEETOS      3130
##  9 NUTRI LECHE  3128
## 10 MARLBORO     2579
## # ℹ 530 more rows
count(bd,Fabricante, sort= TRUE)
## # A tibble: 241 × 2
##    Fabricante                          n
##    <chr>                           <int>
##  1 COCA COLA                       27519
##  2 PEPSI-COLA MEXICANA             22416
##  3 SABRITAS                        14296
##  4 CERVECERIA CUAUHTEMOC MOCTEZUMA 13681
##  5 GRUPO BIMBO                     13078
##  6 SIGMA ALIMENTOS                  8014
##  7 GRUPO INDUSTRIAL LALA            5868
##  8 GRUPO GAMESA                     5527
##  9 NESTLE                           3698
## 10 JUGOS DEL VALLE S.A. DE C.V.     3581
## # ℹ 231 more rows
count(bd,Producto, sort= TRUE)
## # A tibble: 3,404 × 2
##    Producto                        n
##    <chr>                       <int>
##  1 Pepsi N.R. 1.5L              5108
##  2 Coca Cola Retornable 2.5L    3771
##  3 Caguamon Tecate Light 1.2Lt  3471
##  4 Pepsi N. R. 2.5L             2899
##  5 Cerveza Tecate Light 340Ml   2619
##  6 Cerveza Tecate Light 16Oz    2315
##  7 Coca Cola Retornable 1.5L    2124
##  8 Pepsi N.R. 3L                1832
##  9 Coca Cola Retornable 500Ml   1659
## 10 PEPSI N.R. 1.5L              1631
## # ℹ 3,394 more rows
count(bd,NombreDepartamento, sort= TRUE)
## # A tibble: 9 × 2
##   NombreDepartamento        n
##   <chr>                 <int>
## 1 Abarrotes            198279
## 2 Bebes e Infantiles     1483
## 3 Ferretería              377
## 4 Farmacia                255
## 5 Vinos y Licores         104
## 6 Papelería                74
## 7 Mercería                 44
## 8 Productos a Eliminar      8
## 9 Carnes                    1
count(bd,NombreFamilia, sort= TRUE)
## # A tibble: 51 × 2
##    NombreFamilia              n
##    <chr>                  <int>
##  1 Bebidas                64918
##  2 Botanas                21583
##  3 Lacteos y Refrigerados 17659
##  4 Cerveza                14017
##  5 Pan y Tortilla         10502
##  6 Limpieza del Hogar      8724
##  7 Galletas                7487
##  8 Cigarros                6817
##  9 Cuidado Personal        5433
## 10 Salsas y Sazonadores    5320
## # ℹ 41 more rows
count(bd,NombreCategoria, sort= TRUE)
## # A tibble: 174 × 2
##    NombreCategoria               n
##    <chr>                     <int>
##  1 Refrescos Plástico (N.R.) 32862
##  2 Refrescos Retornables     13880
##  3 Frituras                  11082
##  4 Lata                       8150
##  5 Leche                      7054
##  6 Cajetilla                  6329
##  7 Botella                    5867
##  8 Productos sin Categoria    5455
##  9 Papas Fritas               5344
## 10 Jugos y Néctares           5295
## # ℹ 164 more rows
count(bd,Estado, sort= TRUE)
## # A tibble: 5 × 2
##   Estado           n
##   <chr>        <int>
## 1 Nuevo León   96469
## 2 Sinaloa      83455
## 3 Quintana Roo 10021
## 4 Jalisco       6629
## 5 Chiapas       4051
count(bd,`Tipo ubicación`, sort= TRUE)
## # A tibble: 3 × 2
##   `Tipo ubicación`      n
##   <chr>             <int>
## 1 Esquina          189945
## 2 Rotonda            6629
## 3 Entre calles       4051
count(bd,Giro, sort= TRUE)
## # A tibble: 2 × 2
##   Giro            n
##   <chr>       <int>
## 1 Abarrotes  183975
## 2 Mini súper  16650

Asignar una variable e Imprimir el resultado

x <- 3
y <- 2

x
## [1] 3
y
## [1] 2

Operacionas aritméticas

suma <- x + y
suma
## [1] 5
resta <- x - y
resta
## [1] 1
multiplicacion <- x*y
multiplicacion
## [1] 6
division <- x/y
division
## [1] 1.5
division_entera <- x%/% y
division_entera
## [1] 1
residuo <- x %% y
residuo
## [1] 1
potencia <- x**2
potencia
## [1] 9
potencia_2 <- x ^ 2
potencia_2
## [1] 9
raiz_cubica <- x**(1/3)
raiz_cubica
## [1] 1.44225

Funciones

raiz_cuadrada <- sqrt(x)
raiz_cuadrada
## [1] 1.732051
exponencial <- exp(1)
exponencial
## [1] 2.718282
absoluto <- abs(x)
absoluto
## [1] 3
signo <- sign(x)
signo
## [1] 1
redondeo_arriba <- ceiling (x/y)
redondeo_arriba
## [1] 2
redondeo_abajo <- floor(x/y)
redondeo_abajo
## [1] 1
truncar <- trunc(x/y)
truncar
## [1] 1

Constantes

pi
## [1] 3.141593
radio <- 5
area_circulo <- pi*radio**2
area_circulo 
## [1] 78.53982

Vectores

a <- c(1,2,3,4,5) # Secuencia de enteros 1:5
a
## [1] 1 2 3 4 5
b <- c(1,10, by = 0.5)
b
##             by 
##  1.0 10.0  0.5
nombres <- c("Juan","Ana","Pedro","Carla","Sara")
nombres
## [1] "Juan"  "Ana"   "Pedro" "Carla" "Sara"
calificaciones <- c(100,90,50,100,65)
calificaciones
## [1] 100  90  50 100  65
promedio <- mean(calificaciones)
promedio
## [1] 81
orden_ascendente <- sort(calificaciones)
orden_ascendente
## [1]  50  65  90 100 100
orden_descendente <- sort(calificaciones, decreasing = TRUE)

Tablas

tabla_de_calificaciones <- data.frame(nombres,calificaciones)
tabla_de_calificaciones$estatus <- ifelse(tabla_de_calificaciones$calificaciones >= 70, "Aprobado","Reprobado")
tabla_de_calificaciones
##   nombres calificaciones   estatus
## 1    Juan            100  Aprobado
## 2     Ana             90  Aprobado
## 3   Pedro             50 Reprobado
## 4   Carla            100  Aprobado
## 5    Sara             65 Reprobado
summary(tabla_de_calificaciones)
##    nombres          calificaciones   estatus         
##  Length:5           Min.   : 50    Length:5          
##  Class :character   1st Qu.: 65    Class :character  
##  Mode  :character   Median : 90    Mode  :character  
##                     Mean   : 81                      
##                     3rd Qu.:100                      
##                     Max.   :100
str(tabla_de_calificaciones)
## 'data.frame':    5 obs. of  3 variables:
##  $ nombres       : chr  "Juan" "Ana" "Pedro" "Carla" ...
##  $ calificaciones: num  100 90 50 100 65
##  $ estatus       : chr  "Aprobado" "Aprobado" "Reprobado" "Aprobado" ...
head(tabla_de_calificaciones)
##   nombres calificaciones   estatus
## 1    Juan            100  Aprobado
## 2     Ana             90  Aprobado
## 3   Pedro             50 Reprobado
## 4   Carla            100  Aprobado
## 5    Sara             65 Reprobado
tail(tabla_de_calificaciones)
##   nombres calificaciones   estatus
## 1    Juan            100  Aprobado
## 2     Ana             90  Aprobado
## 3   Pedro             50 Reprobado
## 4   Carla            100  Aprobado
## 5    Sara             65 Reprobado
# Select para seleccionar columnas
resultados <- select(tabla_de_calificaciones, -c(nombres))
# Filter para filtrar renglones
resultados <- filter(resultados, estatus =="Aprobado")

Actividad 1. Calculadora IMC

alumno <- c("Yessica", "Jennifer", "Maggie", "Erika", "Marilu")
peso <- c(60,55,90,70,88)
altura <- c(1.60,1.70,1.65,1.90,1.50)

tabla_salud <- data.frame(alumno,peso,altura)
tabla_salud$IMC <- tabla_salud$peso/(tabla_salud$altura^2)
tabla_salud$resultado <- ifelse(tabla_salud$IMC <18.5,"Bajo Peso",ifelse(tabla_salud$IMC <= 24.9, "Peso normal", ifelse(tabla_salud$IMC <= 29.9, "Sobrepeso", "Obesidad")))
tabla_salud
##     alumno peso altura      IMC   resultado
## 1  Yessica   60   1.60 23.43750 Peso normal
## 2 Jennifer   55   1.70 19.03114 Peso normal
## 3   Maggie   90   1.65 33.05785    Obesidad
## 4    Erika   70   1.90 19.39058 Peso normal
## 5   Marilu   88   1.50 39.11111    Obesidad
# Gráficas

semana <- c(1:10)
ventas <- c(150,160,165,180,190,185,175,200,210,195)
plot(semana,ventas, type= "l", main="Ventas Semanales (K USD)")

datos_ventas <- data.frame(semana, ventas)
regresion <- lm(ventas ~ semana, data=datos_ventas)
summary(regresion)
## 
## Call:
## lm(formula = ventas ~ semana, data = datos_ventas)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -14.2727  -5.1894  -0.2273   6.7576  11.7576 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  150.667      6.301  23.912 9.97e-09 ***
## semana         5.515      1.015   5.431 0.000623 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 9.224 on 8 degrees of freedom
## Multiple R-squared:  0.7866, Adjusted R-squared:   0.76 
## F-statistic:  29.5 on 1 and 8 DF,  p-value: 0.0006226
datos_nuevos <- data.frame(Semana=11:20)
prediccion <- predict(regresion, datos_nuevos)
prediccion
##        1        2        3        4        5        6        7        8 
## 156.1818 161.6970 167.2121 172.7273 178.2424 183.7576 189.2727 194.7879 
##        9       10 
## 200.3030 205.8182

Conclusiones

R es un lenguaje de programación útil para realizar cálculos, principalmente estadísticos y forma parte de las herramientes del Big Data.

RStudio es el entorno donde se puede programar R, y gracias a que también aquí se puede programar Pyhton hace unos años se anunció que su nombre será Posit.

En esta introducción, lo qeu llama la atención es la constatnte aparición de alertas o errores en el programa, los cuales encontramos que principalmente se deben a que la versión no es la más reciente a la falta de instalación de paquetes o llamar a las librerías, problemas de escritura (typos) y los muchos argumentos que tienen las funciones.

Si desde un inicio programamos de forma estructurada, disciplinada y meticulosa, podremos preveer muchas de las alertas o errores y así obtendremos los muchos beneficios de la programación en R, como la predicción de pronósticos.

LS0tCnRpdGxlOiAiQ29tYW5kb3MgQsOhc2ljb3MiCmF1dGhvcjogIlllc3NpY2EgQWNvc3RhIC0gQTAwODMzNjE3IgpkYXRlOiAiMjAyNS0wMy0xOCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICB0b2M6IFRSVUUKICAgICAgdG9jX2Zsb2F0OiBUUlVFCiAgICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUKICAgICAgdGhlbWU6ICJjb3NtbyIKLS0tCgoKIVtdKC9Vc2Vycy95ZXNzaWNhYWNvc3RhL0Rlc2t0b3AvQm9vdGNhbXAgUi9naWZfaW1jLmdpZikKCiMgSW5zdGFsYXIgcGFxdWV0ZXMgeSBsbG1hciBsaWJyZXLDrWFzCgpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpICMgUGFxdWV0ZSBwYXJhIG1hbmlwdWxhY2nDs24gZGUgZGF0b3MKbGlicmFyeSh0aWR5dmVyc2UpCiMgaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQpsaWJyYXJ5KGRwbHlyKQpgYGAKCiMgSW1wb3J0YXIgYmFzZSBkZSBkYXRvcwpgYGB7cn0KYmQgPC0gcmVhZF9jc3YoIn4vRGVza3RvcC9Cb290Y2FtcCBSL2FiYXJyb3Rlcy5jc3YiKQpzdW1tYXJ5KGJkKQpzdHIoYmQpCmhlYWQoYmQsIG49MTApCnRhaWwoYmQsIG49MTApCmBgYApgYGB7cn0KY291bnQoYmQsdmNDbGF2ZVRpZW5kYSwgc29ydD0gVFJVRSkKY291bnQoYmQsRGVzY0dpcm8sIHNvcnQ9IFRSVUUpCmNvdW50KGJkLCBGZWNoYSwgc29ydD0gVFJVRSkKY291bnQoYmQsTWFyY2EsIHNvcnQ9IFRSVUUpCmNvdW50KGJkLEZhYnJpY2FudGUsIHNvcnQ9IFRSVUUpCmNvdW50KGJkLFByb2R1Y3RvLCBzb3J0PSBUUlVFKQpjb3VudChiZCxOb21icmVEZXBhcnRhbWVudG8sIHNvcnQ9IFRSVUUpCmNvdW50KGJkLE5vbWJyZUZhbWlsaWEsIHNvcnQ9IFRSVUUpCmNvdW50KGJkLE5vbWJyZUNhdGVnb3JpYSwgc29ydD0gVFJVRSkKY291bnQoYmQsRXN0YWRvLCBzb3J0PSBUUlVFKQpjb3VudChiZCxgVGlwbyB1YmljYWNpw7NuYCwgc29ydD0gVFJVRSkKY291bnQoYmQsR2lybywgc29ydD0gVFJVRSkKCmBgYAoKIyBBc2lnbmFyIHVuYSB2YXJpYWJsZSBlIEltcHJpbWlyIGVsIHJlc3VsdGFkbwoKYGBge3J9CnggPC0gMwp5IDwtIDIKCngKeQpgYGAKCgojIE9wZXJhY2lvbmFzIGFyaXRtw6l0aWNhcwoKYGBge3J9CnN1bWEgPC0geCArIHkKc3VtYQoKcmVzdGEgPC0geCAtIHkKcmVzdGEKCm11bHRpcGxpY2FjaW9uIDwtIHgqeQptdWx0aXBsaWNhY2lvbgoKCmRpdmlzaW9uIDwtIHgveQpkaXZpc2lvbgoKZGl2aXNpb25fZW50ZXJhIDwtIHglLyUgeQpkaXZpc2lvbl9lbnRlcmEKCnJlc2lkdW8gPC0geCAlJSB5CnJlc2lkdW8KCgpwb3RlbmNpYSA8LSB4KioyCnBvdGVuY2lhCgpwb3RlbmNpYV8yIDwtIHggXiAyCnBvdGVuY2lhXzIKCnJhaXpfY3ViaWNhIDwtIHgqKigxLzMpCnJhaXpfY3ViaWNhCgpgYGAKCgojIEZ1bmNpb25lcwoKYGBge3J9CgpyYWl6X2N1YWRyYWRhIDwtIHNxcnQoeCkKcmFpel9jdWFkcmFkYQoKZXhwb25lbmNpYWwgPC0gZXhwKDEpCmV4cG9uZW5jaWFsCgphYnNvbHV0byA8LSBhYnMoeCkKYWJzb2x1dG8KCnNpZ25vIDwtIHNpZ24oeCkKc2lnbm8KCnJlZG9uZGVvX2FycmliYSA8LSBjZWlsaW5nICh4L3kpCnJlZG9uZGVvX2FycmliYQoKcmVkb25kZW9fYWJham8gPC0gZmxvb3IoeC95KQpyZWRvbmRlb19hYmFqbwoKdHJ1bmNhciA8LSB0cnVuYyh4L3kpCnRydW5jYXIKYGBgCgojIENvbnN0YW50ZXMKYGBge3J9CnBpCnJhZGlvIDwtIDUKYXJlYV9jaXJjdWxvIDwtIHBpKnJhZGlvKioyCmFyZWFfY2lyY3VsbyAKYGBgCgojIFZlY3RvcmVzCmBgYHtyfQphIDwtIGMoMSwyLDMsNCw1KSAjIFNlY3VlbmNpYSBkZSBlbnRlcm9zIDE6NQphCgoKYiA8LSBjKDEsMTAsIGJ5ID0gMC41KQpiCgpub21icmVzIDwtIGMoIkp1YW4iLCJBbmEiLCJQZWRybyIsIkNhcmxhIiwiU2FyYSIpCm5vbWJyZXMKCmNhbGlmaWNhY2lvbmVzIDwtIGMoMTAwLDkwLDUwLDEwMCw2NSkKY2FsaWZpY2FjaW9uZXMKCnByb21lZGlvIDwtIG1lYW4oY2FsaWZpY2FjaW9uZXMpCnByb21lZGlvCgpvcmRlbl9hc2NlbmRlbnRlIDwtIHNvcnQoY2FsaWZpY2FjaW9uZXMpCm9yZGVuX2FzY2VuZGVudGUKCm9yZGVuX2Rlc2NlbmRlbnRlIDwtIHNvcnQoY2FsaWZpY2FjaW9uZXMsIGRlY3JlYXNpbmcgPSBUUlVFKQpgYGAKCgojIFRhYmxhcwpgYGB7cn0KdGFibGFfZGVfY2FsaWZpY2FjaW9uZXMgPC0gZGF0YS5mcmFtZShub21icmVzLGNhbGlmaWNhY2lvbmVzKQp0YWJsYV9kZV9jYWxpZmljYWNpb25lcyRlc3RhdHVzIDwtIGlmZWxzZSh0YWJsYV9kZV9jYWxpZmljYWNpb25lcyRjYWxpZmljYWNpb25lcyA+PSA3MCwgIkFwcm9iYWRvIiwiUmVwcm9iYWRvIikKdGFibGFfZGVfY2FsaWZpY2FjaW9uZXMKCgpzdW1tYXJ5KHRhYmxhX2RlX2NhbGlmaWNhY2lvbmVzKQpzdHIodGFibGFfZGVfY2FsaWZpY2FjaW9uZXMpCmhlYWQodGFibGFfZGVfY2FsaWZpY2FjaW9uZXMpCnRhaWwodGFibGFfZGVfY2FsaWZpY2FjaW9uZXMpCgpgYGAKCmBgYHtyfQojIFNlbGVjdCBwYXJhIHNlbGVjY2lvbmFyIGNvbHVtbmFzCnJlc3VsdGFkb3MgPC0gc2VsZWN0KHRhYmxhX2RlX2NhbGlmaWNhY2lvbmVzLCAtYyhub21icmVzKSkKIyBGaWx0ZXIgcGFyYSBmaWx0cmFyIHJlbmdsb25lcwpyZXN1bHRhZG9zIDwtIGZpbHRlcihyZXN1bHRhZG9zLCBlc3RhdHVzID09IkFwcm9iYWRvIikKCmBgYAoKIyBBY3RpdmlkYWQgMS4gQ2FsY3VsYWRvcmEgSU1DCmBgYHtyfQphbHVtbm8gPC0gYygiWWVzc2ljYSIsICJKZW5uaWZlciIsICJNYWdnaWUiLCAiRXJpa2EiLCAiTWFyaWx1IikKcGVzbyA8LSBjKDYwLDU1LDkwLDcwLDg4KQphbHR1cmEgPC0gYygxLjYwLDEuNzAsMS42NSwxLjkwLDEuNTApCgp0YWJsYV9zYWx1ZCA8LSBkYXRhLmZyYW1lKGFsdW1ubyxwZXNvLGFsdHVyYSkKdGFibGFfc2FsdWQkSU1DIDwtIHRhYmxhX3NhbHVkJHBlc28vKHRhYmxhX3NhbHVkJGFsdHVyYV4yKQp0YWJsYV9zYWx1ZCRyZXN1bHRhZG8gPC0gaWZlbHNlKHRhYmxhX3NhbHVkJElNQyA8MTguNSwiQmFqbyBQZXNvIixpZmVsc2UodGFibGFfc2FsdWQkSU1DIDw9IDI0LjksICJQZXNvIG5vcm1hbCIsIGlmZWxzZSh0YWJsYV9zYWx1ZCRJTUMgPD0gMjkuOSwgIlNvYnJlcGVzbyIsICJPYmVzaWRhZCIpKSkKdGFibGFfc2FsdWQKCmBgYAoKYGBge3J9CiMgR3LDoWZpY2FzCgpzZW1hbmEgPC0gYygxOjEwKQp2ZW50YXMgPC0gYygxNTAsMTYwLDE2NSwxODAsMTkwLDE4NSwxNzUsMjAwLDIxMCwxOTUpCnBsb3Qoc2VtYW5hLHZlbnRhcywgdHlwZT0gImwiLCBtYWluPSJWZW50YXMgU2VtYW5hbGVzIChLIFVTRCkiKQpkYXRvc192ZW50YXMgPC0gZGF0YS5mcmFtZShzZW1hbmEsIHZlbnRhcykKcmVncmVzaW9uIDwtIGxtKHZlbnRhcyB+IHNlbWFuYSwgZGF0YT1kYXRvc192ZW50YXMpCnN1bW1hcnkocmVncmVzaW9uKQoKZGF0b3NfbnVldm9zIDwtIGRhdGEuZnJhbWUoU2VtYW5hPTExOjIwKQpwcmVkaWNjaW9uIDwtIHByZWRpY3QocmVncmVzaW9uLCBkYXRvc19udWV2b3MpCnByZWRpY2Npb24KYGBgCgojIENvbmNsdXNpb25lcwoqKlIqKiBlcyB1biBsZW5ndWFqZSBkZSBwcm9ncmFtYWNpw7NuIMO6dGlsIHBhcmEgcmVhbGl6YXIgY8OhbGN1bG9zLCBwcmluY2lwYWxtZW50ZSBlc3RhZMOtc3RpY29zIHkgZm9ybWEgcGFydGUgZGUgbGFzIGhlcnJhbWllbnRlcyBkZWwgKkJpZyBEYXRhKi4KCipSU3R1ZGlvKiBlcyBlbCBlbnRvcm5vIGRvbmRlIHNlIHB1ZWRlIHByb2dyYW1hciAqUiosIHkgZ3JhY2lhcyBhIHF1ZSB0YW1iacOpbiBhcXXDrSBzZSBwdWVkZSBwcm9ncmFtYXIgKlB5aHRvbiogaGFjZSB1bm9zIGHDsW9zIHNlIGFudW5jacOzIHF1ZSBzdSBub21icmUgc2Vyw6EgKlBvc2l0Ki4KCkVuIGVzdGEgaW50cm9kdWNjacOzbiwgbG8gcWV1IGxsYW1hIGxhIGF0ZW5jacOzbiBlcyBsYSBjb25zdGF0bnRlIGFwYXJpY2nDs24gZGUgYWxlcnRhcyBvIGVycm9yZXMgZW4gZWwgcHJvZ3JhbWEsIGxvcyBjdWFsZXMgZW5jb250cmFtb3MgcXVlIHByaW5jaXBhbG1lbnRlIHNlIGRlYmVuIGEgcXVlIGxhIHZlcnNpw7NuIG5vIGVzIGxhIG3DoXMgcmVjaWVudGUgYSBsYSBmYWx0YSBkZSBpbnN0YWxhY2nDs24gZGUgcGFxdWV0ZXMgbyBsbGFtYXIgYSBsYXMgbGlicmVyw61hcywgcHJvYmxlbWFzIGRlIGVzY3JpdHVyYSAoKnR5cG9zKikgeSBsb3MgbXVjaG9zIGFyZ3VtZW50b3MgcXVlIHRpZW5lbiBsYXMgZnVuY2lvbmVzLgoKU2kgZGVzZGUgdW4gaW5pY2lvIHByb2dyYW1hbW9zIGRlIGZvcm1hIGVzdHJ1Y3R1cmFkYSwgZGlzY2lwbGluYWRhIHkgbWV0aWN1bG9zYSwgcG9kcmVtb3MgcHJldmVlciBtdWNoYXMgZGUgbGFzIGFsZXJ0YXMgbyBlcnJvcmVzIHkgYXPDrSBvYnRlbmRyZW1vcyBsb3MgbXVjaG9zIGJlbmVmaWNpb3MgZGUgbGEgcHJvZ3JhbWFjacOzbiBlbiAqUiosIGNvbW8gbGEgcHJlZGljY2nDs24gZGUgcHJvbsOzc3RpY29zLgo=