Establecimiento comercial

Importar bases de datos población

#file.choose()

bd <- read.csv("/Users/joseramonvazquezguzman/Documents/Tecnológico de Monterrey/Septimo semestre/Analítica de datos /M3/ventasM3.csv")

Herramienta “El generador de valor de Datos”

Paso 1. Definir el área del negocio que buscamos impactar y mejorar su KPI.

Los KPIs a impactar son Ventas de productos y Basket size (tamaó de las compras)

Paso 2. Seleccionar plantilla (-s) para crear valor a partir de los datos de los clientes

Segmentación

Paso 3. Generar ideas o conceptos específicos

Generación de ventas cruzadas gracias a al análisis elavorado

Paso 4. Reunir los datos requeridos

Base de datos limpia

Paso 5. Plan de ejecución:

El área de compras debe tener el stock siempre lleno para que los clientes puedan tener siempre a la maano los productos, además que estos tengan una estrategia de venta.

#Observaciones
#Separamos la fecha y hora de la base de datos original
#Reemplazamos todas las comas y puntos por un espacio



summary(bd)
##     BillNo            Itemname            Quantity            Date          
##  Length:522064      Length:522064      Min.   :-9600.00   Length:522064     
##  Class :character   Class :character   1st Qu.:    1.00   Class :character  
##  Mode  :character   Mode  :character   Median :    3.00   Mode  :character  
##                                        Mean   :   10.09                     
##                                        3rd Qu.:   10.00                     
##                                        Max.   :80995.00                     
##                                                                             
##      Hora               Price              CustomerID       Country         
##  Length:522064      Min.   :-11062.060   Min.   :12346    Length:522064     
##  Class :character   1st Qu.:     1.250   1st Qu.:13950    Class :character  
##  Mode  :character   Median :     2.080   Median :15265    Mode  :character  
##                     Mean   :     3.827   Mean   :15317                      
##                     3rd Qu.:     4.130   3rd Qu.:16837                      
##                     Max.   : 13541.330   Max.   :18287                      
##                                          NA's   :134041

Técnicas de limpieza

No se eliminan columnas ya que todas son relevantes ## Eliminar renglones

bd1 <- bd
bd1 <- bd1[bd1$Price > 0,]
summary (bd1)
##     BillNo            Itemname            Quantity           Date          
##  Length:519551      Length:519551      Min.   :    1.0   Length:519551     
##  Class :character   Class :character   1st Qu.:    1.0   Class :character  
##  Mode  :character   Mode  :character   Median :    3.0   Mode  :character  
##                                        Mean   :   10.4                     
##                                        3rd Qu.:   10.0                     
##                                        Max.   :80995.0                     
##                                                                            
##      Hora               Price             CustomerID       Country         
##  Length:519551      Min.   :    0.001   Min.   :12346    Length:519551     
##  Class :character   1st Qu.:    1.250   1st Qu.:13950    Class :character  
##  Mode  :character   Median :    2.080   Median :15265    Mode  :character  
##                     Mean   :    3.888   Mean   :15317                      
##                     3rd Qu.:    4.130   3rd Qu.:16837                      
##                     Max.   :13541.330   Max.   :18287                      
##                                         NA's   :131566

No consideraremos los precios negativos ya que correspondían a una deuda

bd2 <- bd1
bd2 <- bd2[bd2$Price > 0.3,]
summary(bd2)
##     BillNo            Itemname            Quantity            Date          
##  Length:511103      Length:511103      Min.   :    1.00   Length:511103     
##  Class :character   Class :character   1st Qu.:    1.00   Class :character  
##  Mode  :character   Mode  :character   Median :    3.00   Mode  :character  
##                                        Mean   :    9.85                     
##                                        3rd Qu.:   10.00                     
##                                        Max.   :80995.00                     
##                                                                             
##      Hora               Price             CustomerID       Country         
##  Length:511103      Min.   :    0.310   Min.   :12346    Length:511103     
##  Class :character   1st Qu.:    1.250   1st Qu.:13949    Class :character  
##  Mode  :character   Median :    2.100   Median :15271    Mode  :character  
##                     Mean   :    3.948   Mean   :15317                      
##                     3rd Qu.:    4.130   3rd Qu.:16837                      
##                     Max.   :13541.330   Max.   :18287                      
##                                         NA's   :131482

#No consideraremos los precios menores a 4 centavos debido a que eran cargos del banco y eran datos irrelevantes

Revisar cuantos NA tengo en la base de datos

sum(is.na(bd2))
## [1] 131482
sum(is.na(bd))
## [1] 134041

Identificamos que los NA están en el CustomerID por lo que ignoramos esta parte ya que no nos afectará en el resultado

sapply(bd2, function(x) sum(is.na(x)))
##     BillNo   Itemname   Quantity       Date       Hora      Price CustomerID 
##          0          0          0          0          0          0     131482 
##    Country 
##          0
sapply(bd, function(x) sum(is.na(x)))
##     BillNo   Itemname   Quantity       Date       Hora      Price CustomerID 
##          0          0          0          0          0          0     134041 
##    Country 
##          0

Graficamos para revisar si hay algún dato fuera de lo normal y revisar si tiene sentido o si es algún error

bd3 <- bd2
boxplot(bd3$Price, horizontal = TRUE)

boxplot(bd3$Quantity, horizontal = TRUE)  

Agregar columnas

#install.packages("lubridate")
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
bd3$Dia_de_la_Semana <- wday(bd3$Date)
summary(bd3)
##     BillNo            Itemname            Quantity            Date          
##  Length:511103      Length:511103      Min.   :    1.00   Length:511103     
##  Class :character   Class :character   1st Qu.:    1.00   Class :character  
##  Mode  :character   Mode  :character   Median :    3.00   Mode  :character  
##                                        Mean   :    9.85                     
##                                        3rd Qu.:   10.00                     
##                                        Max.   :80995.00                     
##                                                                             
##      Hora               Price             CustomerID       Country         
##  Length:511103      Min.   :    0.310   Min.   :12346    Length:511103     
##  Class :character   1st Qu.:    1.250   1st Qu.:13949    Class :character  
##  Mode  :character   Median :    2.100   Median :15271    Mode  :character  
##                     Mean   :    3.948   Mean   :15317                      
##                     3rd Qu.:    4.130   3rd Qu.:16837                      
##                     Max.   :13541.330   Max.   :18287                      
##                                         NA's   :131482                     
##  Dia_de_la_Semana
##  Min.   :1.000   
##  1st Qu.:2.000   
##  Median :4.000   
##  Mean   :4.011   
##  3rd Qu.:6.000   
##  Max.   :7.000   
## 

Exportar base de datos limpia

bd_limpia <- bd3
write.csv(bd_limpia, file="Actividad_Ventas_Limpia.csv", row.names = FALSE)

Ya que la base de datos esta limpia, se debe de realizar el Market Basket Analysis

#install.packages("plyr")
library(Matrix)

#install.packages("arules")
library(arules)
## 
## Attaching package: 'arules'
## The following objects are masked from 'package:base':
## 
##     abbreviate, write
#install.packages("arulesViz")
library(arulesViz)

#install.packages("datasets")
library(datasets)

#Ordenar de menor a mayor los tickets

bd_limpia <- bd_limpia[order(bd_limpia$BillNo),]
head(bd_limpia)
##   BillNo                            Itemname Quantity       Date     Hora Price
## 1 536365  WHITE HANGING HEART T-LIGHT HOLDER        6 01/12/2010 08:26:00  2.55
## 2 536365                 WHITE METAL LANTERN        6 01/12/2010 08:26:00  3.39
## 3 536365      CREAM CUPID HEARTS COAT HANGER        8 01/12/2010 08:26:00  2.75
## 4 536365 KNITTED UNION FLAG HOT WATER BOTTLE        6 01/12/2010 08:26:00  3.39
## 5 536365      RED WOOLLY HOTTIE WHITE HEART.        6 01/12/2010 08:26:00  3.39
## 6 536365        SET 7 BABUSHKA NESTING BOXES        2 01/12/2010 08:26:00  7.65
##   CustomerID        Country Dia_de_la_Semana
## 1      17850 United Kingdom                5
## 2      17850 United Kingdom                5
## 3      17850 United Kingdom                5
## 4      17850 United Kingdom                5
## 5      17850 United Kingdom                5
## 6      17850 United Kingdom                5
tail(bd_limpia)
##         BillNo                        Itemname Quantity       Date     Hora
## 522060  581587     PACK OF 20 SPACEBOY NAPKINS       12 09/12/2011 12:50:00
## 522061  581587     CHILDREN'S APRON DOLLY GIRL        6 09/12/2011 12:50:00
## 522062  581587    CHILDRENS CUTLERY DOLLY GIRL        4 09/12/2011 12:50:00
## 522063  581587 CHILDRENS CUTLERY CIRCUS PARADE        4 09/12/2011 12:50:00
## 522064  581587    BAKING SET 9 PIECE RETROSPOT        3 09/12/2011 12:50:00
## 288773 A563185                 Adjust bad debt        1 12/08/2011 14:50:00
##           Price CustomerID        Country Dia_de_la_Semana
## 522060     0.85      12680         France                1
## 522061     2.10      12680         France                1
## 522062     4.15      12680         France                1
## 522063     4.15      12680         France                1
## 522064     4.95      12680         France                1
## 288773 11062.06         NA United Kingdom                2

Generar basket

#install.packages("plyr")
library(plyr)
basket <- ddply(bd_limpia,c("BillNo"), function(bd_limpia)paste(bd_limpia$Itemname, collapse = ","))

Eliminar número de Ticket

basket$BillNo <- NULL

Renombramos el nombre de la columna

colnames(basket) <- c("Itemname")

Exportar basket

write.csv(basket,"basketventas.csv", quote = FALSE, row.names = FALSE)

Importar transacciones

#file.choose()
library(Matrix)
library(arules)
library(arulesViz)
tr <- read.transactions("/Users/joseramonvazquezguzman/Documents/Tecnológico de Monterrey/Septimo semestre/Analítica de datos /M3/basketrrr.csv", format = "basket", sep=",")

reglas.asociacion <- apriori(tr, parameter = list(supp=0.001, conf=0.8, maxlen=10))
## Apriori
## 
## Parameter specification:
##  confidence minval smax arem  aval originalSupport maxtime support minlen
##         0.8    0.1    1 none FALSE            TRUE       5   0.001      1
##  maxlen target  ext
##      10  rules TRUE
## 
## Algorithmic control:
##  filter tree heap memopt load sort verbose
##     0.1 TRUE TRUE  FALSE TRUE    2    TRUE
## 
## Absolute minimum support count: 19 
## 
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[8578 item(s), 19559 transaction(s)] done [0.11s].
## sorting and recoding items ... [2644 item(s)] done [0.01s].
## creating transaction tree ... done [0.01s].
## checking subsets of size 1 2 3 4 5 6 7 8 9 10 done [3.00s].
## writing ... [6156148 rule(s)] done [1.08s].
## creating S4 object  ... done [2.78s].
#summary(reglas.asociacion)
#inspect(reglas.asociacion)
top10reglas <- head(reglas.asociacion, n = 10, by = "confidence")
inspect(top10reglas)
##      lhs                                    rhs                                  support confidence    coverage     lift count
## [1]  {SILVER MINI TAPE MEASURE}          => {JUMBO BAG PINK VINTAGE PAISLEY} 0.001124802          1 0.001124802 27.24095    22
## [2]  {SILVER MINI TAPE MEASURE}          => {STRAWBERRY CHARLOTTE BAG}       0.001124802          1 0.001124802 32.32893    22
## [3]  {SILVER MINI TAPE MEASURE}          => {LUNCH BAG CARS BLUE}            0.001124802          1 0.001124802 20.24741    22
## [4]  {SILVER MINI TAPE MEASURE}          => {WOODLAND CHARLOTTE BAG}         0.001124802          1 0.001124802 28.84808    22
## [5]  {SILVER MINI TAPE MEASURE}          => {RED RETROSPOT CHARLOTTE BAG}    0.001124802          1 0.001124802 22.98355    22
## [6]  {PINK POLKADOT BOWL,                                                                                                     
##       SET/20 FRUIT SALAD PAPER NAPKINS}  => {STRAWBERRY CHARLOTTE BAG}       0.001022547          1 0.001022547 32.32893    20
## [7]  {PINK POLKADOT BOWL,                                                                                                     
##       SET/20 FRUIT SALAD PAPER NAPKINS}  => {LUNCH BAG CARS BLUE}            0.001022547          1 0.001022547 20.24741    20
## [8]  {PINK POLKADOT BOWL,                                                                                                     
##       SET/20 FRUIT SALAD PAPER NAPKINS}  => {WOODLAND CHARLOTTE BAG}         0.001022547          1 0.001022547 28.84808    20
## [9]  {PINK POLKADOT BOWL,                                                                                                     
##       SET/20 FRUIT SALAD PAPER NAPKINS}  => {RED RETROSPOT CHARLOTTE BAG}    0.001022547          1 0.001022547 22.98355    20
## [10] {SET/20 FRUIT SALAD PAPER NAPKINS,                                                                                       
##       STRAWBERRY CHARLOTTE BAG}          => {LUNCH BAG CARS BLUE}            0.001073675          1 0.001073675 20.24741    21
plot(top10reglas, method ="graph", engine = "htmlwidget")

Conclusiones

Como estrategia se podría elaborar el MBA para distintos productos y ver la correlación que se genera a partir de un producto, se puede observar en el análisis que hay una asociación entre la regla 2 y regla 6 donde el producto “Strawberry Charlotte” es el correlacionado, esto quiere decir que se tiene una venta mayor hacia este producto, esto para analizar el comportamiento de los productos dentro de la tienda puede ser muy interesante y puede ayudara también el departamento de marketing a interpretar y generar ideas en base a esta información.

LS0tCnRpdGxlOiA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIj5TdXBlcm1lcmNhZG9WZW50YXNNQkE8L3NwYW4+CmF1dGhvcjogIkpvc8OpIFJhbcOzbiBBMDE2MjUyMDMiCmRhdGU6ICIxOS1zZXAtMjAyMiIKb3V0cHV0OiAgCiAgaHRtbF9kb2N1bWVudDoKICAgdG9jOiB0cnVlCiAgIHRvY19mbG9hdDogdHJ1ZQogICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgIAotLS0KCgo8aW1nIHNyYz0gIi9Vc2Vycy9qb3NlcmFtb252YXpxdWV6Z3V6bWFuL0Rlc2t0b3AvZndvZndtc3Mud2VicCIgPgoKIyAqKkVzdGFibGVjaW1pZW50byBjb21lcmNpYWwqKgoKCiMjICBJbXBvcnRhciBiYXNlcyBkZSBkYXRvcyBwb2JsYWNpw7NuCgpgYGB7cn0KCiNmaWxlLmNob29zZSgpCgpiZCA8LSByZWFkLmNzdigiL1VzZXJzL2pvc2VyYW1vbnZhenF1ZXpndXptYW4vRG9jdW1lbnRzL1RlY25vbG/MgWdpY28gZGUgTW9udGVycmV5L1NlcHRpbW8gc2VtZXN0cmUvQW5hbGnMgXRpY2EgZGUgZGF0b3MgL00zL3ZlbnRhc00zLmNzdiIpCgpgYGAKCgojIyMgIEhlcnJhbWllbnRhICJFbCBnZW5lcmFkb3IgZGUgdmFsb3IgZGUgRGF0b3MiIAoKIyMjIyAgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+UGFzbyAxLjwvc3Bhbj4gRGVmaW5pciBlbCDDoXJlYSBkZWwgbmVnb2NpbyBxdWUgYnVzY2Ftb3MgaW1wYWN0YXIgeSBtZWpvcmFyIHN1IEtQSS4KCiMjIyMgIExvcyBLUElzIGEgaW1wYWN0YXIgc29uIFZlbnRhcyBkZSBwcm9kdWN0b3MgeSBCYXNrZXQgc2l6ZSAodGFtYcOzIGRlIGxhcyBjb21wcmFzKQoKIyMjIyAgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZCI+UGFzbyAyLjwvc3Bhbj4gU2VsZWNjaW9uYXIgcGxhbnRpbGxhICgtcykgcGFyYSBjcmVhciB2YWxvciBhIHBhcnRpciBkZSBsb3MgZGF0b3MgZGUgbG9zIGNsaWVudGVzIAojIyMjICBTZWdtZW50YWNpw7NuCgojIyMjICA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5QYXNvIDMuPC9zcGFuPiBHZW5lcmFyIGlkZWFzIG8gY29uY2VwdG9zIGVzcGVjw61maWNvcyAKIyMjIyAgR2VuZXJhY2nDs24gZGUgdmVudGFzIGNydXphZGFzIGdyYWNpYXMgYSBhbCBhbsOhbGlzaXMgZWxhdm9yYWRvCiMjIyMgIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPlBhc28gNC48L3NwYW4+ICBSZXVuaXIgbG9zIGRhdG9zIHJlcXVlcmlkb3MgCiMjIyMgIEJhc2UgZGUgZGF0b3MgbGltcGlhCgojIyMjICA8c3BhbiBzdHlsZT0iY29sb3I6cmVkIj5QYXNvIDUuPC9zcGFuPiBQbGFuIGRlIGVqZWN1Y2nDs246CiMjIyMgRWwgw6FyZWEgZGUgY29tcHJhcyBkZWJlIHRlbmVyIGVsIHN0b2NrIHNpZW1wcmUgbGxlbm8gcGFyYSBxdWUgbG9zIGNsaWVudGVzIHB1ZWRhbiB0ZW5lciBzaWVtcHJlIGEgbGEgbWFhbm8gbG9zIHByb2R1Y3RvcywgYWRlbcOhcyBxdWUgZXN0b3MgdGVuZ2FuIHVuYSBlc3RyYXRlZ2lhIGRlIHZlbnRhLgoKCmBgYHtyfQojT2JzZXJ2YWNpb25lcwojU2VwYXJhbW9zIGxhIGZlY2hhIHkgaG9yYSBkZSBsYSBiYXNlIGRlIGRhdG9zIG9yaWdpbmFsCiNSZWVtcGxhemFtb3MgdG9kYXMgbGFzIGNvbWFzIHkgcHVudG9zIHBvciB1biBlc3BhY2lvCgoKCnN1bW1hcnkoYmQpCmBgYAoKCiMjICBUw6ljbmljYXMgZGUgbGltcGllemEKTm8gc2UgZWxpbWluYW4gY29sdW1uYXMgeWEgcXVlIHRvZGFzIHNvbiByZWxldmFudGVzCiMjICBFbGltaW5hciByZW5nbG9uZXMKCmBgYHtyfQpiZDEgPC0gYmQKYmQxIDwtIGJkMVtiZDEkUHJpY2UgPiAwLF0Kc3VtbWFyeSAoYmQxKQpgYGAKCiMjICBObyBjb25zaWRlcmFyZW1vcyBsb3MgcHJlY2lvcyBuZWdhdGl2b3MgeWEgcXVlIGNvcnJlc3BvbmTDrWFuIGEgdW5hIGRldWRhCmBgYHtyfQpiZDIgPC0gYmQxCmJkMiA8LSBiZDJbYmQyJFByaWNlID4gMC4zLF0Kc3VtbWFyeShiZDIpCmBgYAoKI05vIGNvbnNpZGVyYXJlbW9zIGxvcyBwcmVjaW9zIG1lbm9yZXMgYSA0IGNlbnRhdm9zIGRlYmlkbyBhIHF1ZSBlcmFuIGNhcmdvcyBkZWwgYmFuY28geSBlcmFuIGRhdG9zIGlycmVsZXZhbnRlcwoKIyMgIFJldmlzYXIgY3VhbnRvcyBOQSB0ZW5nbyBlbiBsYSBiYXNlIGRlIGRhdG9zCmBgYHtyfQpzdW0oaXMubmEoYmQyKSkKc3VtKGlzLm5hKGJkKSkKYGBgCgojIyAgSWRlbnRpZmljYW1vcyBxdWUgbG9zIE5BIGVzdMOhbiBlbiBlbCBDdXN0b21lcklEIHBvciBsbyBxdWUgaWdub3JhbW9zIGVzdGEgcGFydGUgeWEgcXVlIG5vIG5vcyBhZmVjdGFyw6EgZW4gZWwgcmVzdWx0YWRvCmBgYHtyfQpzYXBwbHkoYmQyLCBmdW5jdGlvbih4KSBzdW0oaXMubmEoeCkpKQpzYXBwbHkoYmQsIGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpCgpgYGAKCiMjICBHcmFmaWNhbW9zIHBhcmEgcmV2aXNhciBzaSBoYXkgYWxnw7puIGRhdG8gZnVlcmEgZGUgbG8gbm9ybWFsIHkgcmV2aXNhciBzaSB0aWVuZSBzZW50aWRvIG8gc2kgZXMgYWxnw7puIGVycm9yCmBgYHtyfQpiZDMgPC0gYmQyCmJveHBsb3QoYmQzJFByaWNlLCBob3Jpem9udGFsID0gVFJVRSkKYm94cGxvdChiZDMkUXVhbnRpdHksIGhvcml6b250YWwgPSBUUlVFKSAgCmBgYAoKCiMjICBBZ3JlZ2FyIGNvbHVtbmFzICAKCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygibHVicmlkYXRlIikKbGlicmFyeShsdWJyaWRhdGUpCmJkMyREaWFfZGVfbGFfU2VtYW5hIDwtIHdkYXkoYmQzJERhdGUpCnN1bW1hcnkoYmQzKQpgYGAKCiMjICBFeHBvcnRhciBiYXNlIGRlIGRhdG9zIGxpbXBpYQpgYGB7cn0KYmRfbGltcGlhIDwtIGJkMwp3cml0ZS5jc3YoYmRfbGltcGlhLCBmaWxlPSJBY3RpdmlkYWRfVmVudGFzX0xpbXBpYS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCgojIyAgWWEgcXVlIGxhIGJhc2UgZGUgZGF0b3MgZXN0YSBsaW1waWEsIHNlIGRlYmUgZGUgcmVhbGl6YXIgZWwgTWFya2V0IEJhc2tldCBBbmFseXNpcwoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJwbHlyIikKbGlicmFyeShNYXRyaXgpCgojaW5zdGFsbC5wYWNrYWdlcygiYXJ1bGVzIikKbGlicmFyeShhcnVsZXMpCgojaW5zdGFsbC5wYWNrYWdlcygiYXJ1bGVzVml6IikKbGlicmFyeShhcnVsZXNWaXopCgojaW5zdGFsbC5wYWNrYWdlcygiZGF0YXNldHMiKQpsaWJyYXJ5KGRhdGFzZXRzKQpgYGAKCiNPcmRlbmFyIGRlIG1lbm9yIGEgbWF5b3IgbG9zIHRpY2tldHMgCmBgYHtyfQpiZF9saW1waWEgPC0gYmRfbGltcGlhW29yZGVyKGJkX2xpbXBpYSRCaWxsTm8pLF0KaGVhZChiZF9saW1waWEpCnRhaWwoYmRfbGltcGlhKQpgYGAKCiMjICBHZW5lcmFyIGJhc2tldAoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJwbHlyIikKbGlicmFyeShwbHlyKQpiYXNrZXQgPC0gZGRwbHkoYmRfbGltcGlhLGMoIkJpbGxObyIpLCBmdW5jdGlvbihiZF9saW1waWEpcGFzdGUoYmRfbGltcGlhJEl0ZW1uYW1lLCBjb2xsYXBzZSA9ICIsIikpCmBgYAoKIyMgIEVsaW1pbmFyIG7Dum1lcm8gZGUgVGlja2V0CgpgYGB7cn0KYmFza2V0JEJpbGxObyA8LSBOVUxMCmBgYAoKIyMgIFJlbm9tYnJhbW9zIGVsIG5vbWJyZSBkZSBsYSBjb2x1bW5hCmBgYHtyfQpjb2xuYW1lcyhiYXNrZXQpIDwtIGMoIkl0ZW1uYW1lIikKYGBgCgojIyAgRXhwb3J0YXIgYmFza2V0CmBgYHtyfQp3cml0ZS5jc3YoYmFza2V0LCJiYXNrZXR2ZW50YXMuY3N2IiwgcXVvdGUgPSBGQUxTRSwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyMgIEltcG9ydGFyIHRyYW5zYWNjaW9uZXMKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI2ZpbGUuY2hvb3NlKCkKbGlicmFyeShNYXRyaXgpCmxpYnJhcnkoYXJ1bGVzKQpsaWJyYXJ5KGFydWxlc1ZpeikKdHIgPC0gcmVhZC50cmFuc2FjdGlvbnMoIi9Vc2Vycy9qb3NlcmFtb252YXpxdWV6Z3V6bWFuL0RvY3VtZW50cy9UZWNub2xvzIFnaWNvIGRlIE1vbnRlcnJleS9TZXB0aW1vIHNlbWVzdHJlL0FuYWxpzIF0aWNhIGRlIGRhdG9zIC9NMy9iYXNrZXRycnIuY3N2IiwgZm9ybWF0ID0gImJhc2tldCIsIHNlcD0iLCIpCgpyZWdsYXMuYXNvY2lhY2lvbiA8LSBhcHJpb3JpKHRyLCBwYXJhbWV0ZXIgPSBsaXN0KHN1cHA9MC4wMDEsIGNvbmY9MC44LCBtYXhsZW49MTApKQojc3VtbWFyeShyZWdsYXMuYXNvY2lhY2lvbikKI2luc3BlY3QocmVnbGFzLmFzb2NpYWNpb24pCmBgYAoKYGBge3J9CnRvcDEwcmVnbGFzIDwtIGhlYWQocmVnbGFzLmFzb2NpYWNpb24sIG4gPSAxMCwgYnkgPSAiY29uZmlkZW5jZSIpCmluc3BlY3QodG9wMTByZWdsYXMpCnBsb3QodG9wMTByZWdsYXMsIG1ldGhvZCA9ImdyYXBoIiwgZW5naW5lID0gImh0bWx3aWRnZXQiKQpgYGAKCiMgKkNvbmNsdXNpb25lcyoKCkNvbW8gZXN0cmF0ZWdpYSBzZSBwb2Ryw61hIGVsYWJvcmFyIGVsIE1CQSBwYXJhIGRpc3RpbnRvcyBwcm9kdWN0b3MgeSB2ZXIgbGEgY29ycmVsYWNpw7NuIHF1ZSBzZSBnZW5lcmEgYSBwYXJ0aXIgZGUgdW4gcHJvZHVjdG8sIHNlIHB1ZWRlIG9ic2VydmFyIGVuIGVsIGFuw6FsaXNpcyBxdWUgaGF5IHVuYSBhc29jaWFjacOzbiBlbnRyZSBsYSByZWdsYSAyIHkgcmVnbGEgNiBkb25kZSBlbCBwcm9kdWN0byAiU3RyYXdiZXJyeSBDaGFybG90dGUiIGVzIGVsIGNvcnJlbGFjaW9uYWRvLCBlc3RvIHF1aWVyZSBkZWNpciBxdWUgc2UgdGllbmUgdW5hIHZlbnRhIG1heW9yIGhhY2lhIGVzdGUgcHJvZHVjdG8sIGVzdG8gcGFyYSBhbmFsaXphciBlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgcHJvZHVjdG9zIGRlbnRybyBkZSBsYSB0aWVuZGEgcHVlZGUgc2VyIG11eSBpbnRlcmVzYW50ZSB5IHB1ZWRlIGF5dWRhcmEgdGFtYmnDqW4gZWwgZGVwYXJ0YW1lbnRvIGRlIG1hcmtldGluZyBhIGludGVycHJldGFyIHkgZ2VuZXJhciBpZGVhcyBlbiBiYXNlIGEgZXN0YSBpbmZvcm1hY2nDs24uCgoK