knitr::include_url("https://form.com.mx/")

¿Quien es Form?*

FORM es una empresa mexicana dedicada a generar soluciones integrales de empaque para la industria automotriz. Fue fundada en el 2011 por Felipe Flores García y hoy en día cuenta con más de 130 empleados. FORM toma gran importancia a ser parte de un entorno sostenible, por lo que diseña empaques ecológicos generando un impacto positivo al medio ambiente, es por ello que su principal material es el cartón, con el cual obtienen el 50% de sus ganancias y representa el 90% de sus gastos y costos. Por ello la importancia de una buena logística y cadena de suministros en FORM, para optimizar y eficientizar y de ese modo tener rentabilidad.

Entregable 2.4 Equipo 2

1. Scrap

Llamar base de datos.

#file.choose()
SCRAP<- read.csv("C:\\Users\\danyc\\Downloads\\FORM - Scrap Limpia .csv")

Entender Base de Datos

resumen <- summary(SCRAP)
resumen
##   Referencia           Fecha               Hora             Producto        
##  Length:250         Length:250         Length:250         Length:250        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##     Cantidad      Unidad.de.medida   Ubicación.de.origen Ubicación.de.desecho
##  Min.   : 0.000   Length:250         Length:250          Length:250          
##  1st Qu.: 1.000   Class :character   Class :character    Class :character    
##  Median : 2.000   Mode  :character   Mode  :character    Mode  :character    
##  Mean   : 6.696                                                              
##  3rd Qu.: 7.000                                                              
##  Max.   :96.000                                                              
##     Estado         
##  Length:250        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

1.¿Cuántas variables y cuántos registros tiene la base de datos?

R= 250 registros y 9 variables
str(SCRAP)
## 'data.frame':    250 obs. of  9 variables:
##  $ Referencia          : chr  "SP/08731" "SP/08730" "SP/08729" "SP/08728" ...
##  $ Fecha               : chr  "31/08/2022" "31/08/2022" "31/08/2022" "31/08/2022" ...
##  $ Hora                : chr  "14:55:40" "14:49:25" "13:49:29" "09:30:07" ...
##  $ Producto            : chr  "[BACKFRAME 60% CUELLO ARMADO] 18805. 60% Backframe. Cuello Armado." "[N61506747 CAJA] N61506747. Kit. Caja." "[N61506729 SEPARADOR] N61506729. Kit. Separador." "[341332 DIVISOR - U611 & U625] 341332. U611. U625. Divisor Troquelado." ...
##  $ Cantidad            : num  2 1 1 31 1 1 1 9 2 1 ...
##  $ Unidad.de.medida    : chr  "Unidad(es)" "Unidad(es)" "Unidad(es)" "Unidad(es)" ...
##  $ Ubicación.de.origen : chr  "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...
##  $ Ubicación.de.desecho: chr  "Virtual Locations/Scrapped" "Virtual Locations/Scrapped" "Virtual Locations/Scrapped" "Virtual Locations/Scrapped" ...
##  $ Estado              : chr  "Hecho" "Hecho" "Hecho" "Hecho" ...
#library(psych)
#install.packages("psych")
#describe(FORM)

Nota:En esta base de datos se eliminaron la columana que no era relevante para el analisis,Se eliminan Referencia, Producto, Unidad.de.medida , Ubicación.de.desecho, Estado, debido a que son irrelevantes, por que es el mismo dato para todos los registros.Por lo tanto es irrelevante.

bd1<- SCRAP
bd1<-subset(SCRAP,select=-c(Referencia, Unidad.de.medida , Ubicación.de.desecho, Estado))
str(bd1)
## 'data.frame':    250 obs. of  5 variables:
##  $ Fecha              : chr  "31/08/2022" "31/08/2022" "31/08/2022" "31/08/2022" ...
##  $ Hora               : chr  "14:55:40" "14:49:25" "13:49:29" "09:30:07" ...
##  $ Producto           : chr  "[BACKFRAME 60% CUELLO ARMADO] 18805. 60% Backframe. Cuello Armado." "[N61506747 CAJA] N61506747. Kit. Caja." "[N61506729 SEPARADOR] N61506729. Kit. Separador." "[341332 DIVISOR - U611 & U625] 341332. U611. U625. Divisor Troquelado." ...
##  $ Cantidad           : num  2 1 1 31 1 1 1 9 2 1 ...
##  $ Ubicación.de.origen: chr  "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Calidad/Entrega de PT" "SAB/Pre-Production" ...
summary(bd1)
##     Fecha               Hora             Producto            Cantidad     
##  Length:250         Length:250         Length:250         Min.   : 0.000  
##  Class :character   Class :character   Class :character   1st Qu.: 1.000  
##  Mode  :character   Mode  :character   Mode  :character   Median : 2.000  
##                                                           Mean   : 6.696  
##                                                           3rd Qu.: 7.000  
##                                                           Max.   :96.000  
##  Ubicación.de.origen
##  Length:250         
##  Class :character   
##  Mode  :character   
##                     
##                     
## 

2. Para el caso de variables cuantitativas considerar la posibilidad de reemplazar la presencia de “missing values” con estadísticos descriptivos (por ejemplo, media, mediana, moda).*

#install.packages("dplyr")
#install.packages("mirage")
#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
#library(mirage)

Tecnica 5:Valores faltantes

¿Cuantos N/A tengo en mi base de datos?

#Debido a que en la base de datos no se encuentran Missing Values, en esta base de datos no se pueden remplazar valores por media, mediana y moda ya que no aplica.

#bd1<-SCRAP
#bd1

sum(is.na(bd1))
## [1] 0
sum(is.na(SCRAP))
## [1] 0
sapply(bd1, function(x) sum(is.na(x)))
##               Fecha                Hora            Producto            Cantidad 
##                   0                   0                   0                   0 
## Ubicación.de.origen 
##                   0
sapply(SCRAP, function(x) sum(is.na(x)))
##           Referencia                Fecha                 Hora 
##                    0                    0                    0 
##             Producto             Cantidad     Unidad.de.medida 
##                    0                    0                    0 
##  Ubicación.de.origen Ubicación.de.desecho               Estado 
##                    0                    0                    0

Cambiar columnas y variables

Cambiar los nombres de las columnas / variables a nombres más cortos y específicos. Por ejemplo, municipio → mpio, salario mínimo diario → salario_min.

#seleccionar columnas / variables.
bd1<-SCRAP %>% select(one_of('Fecha','Hora','Producto','Cantidad','Ubicación.de.origen'))

#Renombrar las columnas /variables seleccionadas. 
colnames(bd1) <-c ('Fecha','Hora','Prod.','Cant.','Origen')

Nota: Se cambiaron los nombres de las variables a nombres mas cortos. Para no contar con nombres largos.

Tabla de estadísticos descriptivos

Crear tabla que muestre los principales estadísticos descrptivos (media,mediana, moda, desviación estandar) de cada una de las variables para cada base de datos. Comentar brevemente los principales resultados que se muestran en la tabla.

#DESCARGAR EL PAQUETE
#install.packages("kkbleExtra") 


#summary(bd1)
#describe(bd1)

#install.packages("sd")
#install.packages("modeest")
#library(modeest)
#sd(FORM_1$Kilo, na.rm = FALSE)
#install.packages("dplyr")
#library(dplyr)

#library(kbleExtra)
summary(bd1)
##     Fecha               Hora              Prod.               Cant.       
##  Length:250         Length:250         Length:250         Min.   : 0.000  
##  Class :character   Class :character   Class :character   1st Qu.: 1.000  
##  Mode  :character   Mode  :character   Mode  :character   Median : 2.000  
##                                                           Mean   : 6.696  
##                                                           3rd Qu.: 7.000  
##                                                           Max.   :96.000  
##     Origen         
##  Length:250        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
sd(bd1$Cantidad, na.rm= TRUE)  
## [1] NA
Variable<-c("Cant.")
Mediana<-c("2.00")
Media <- c("6.696")
Moda <- c("1") #EXCEL 
Desviación_estandar<-c("11.84885")
table1 <- data.frame (Variable, Mediana, Media, Moda, Desviación_estandar)
knitr::kable(table1)
Variable Mediana Media Moda Desviación_estandar
Cant. 2.00 6.696 1 11.84885

##Crear 1-2 “time series plots” (line plot) que muestran la dispersión de variables selecionadas.

#install.packages("ggplot2")
#install.packages("barplot")
library(ggplot2)
summary(bd1)
##     Fecha               Hora              Prod.               Cant.       
##  Length:250         Length:250         Length:250         Min.   : 0.000  
##  Class :character   Class :character   Class :character   1st Qu.: 1.000  
##  Mode  :character   Mode  :character   Mode  :character   Median : 2.000  
##                                                           Mean   : 6.696  
##                                                           3rd Qu.: 7.000  
##                                                           Max.   :96.000  
##     Origen         
##  Length:250        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
ggplot(bd1,aes(x=Cant.))+
  geom_line(aes(y=Origen),color="Red")+
  labs(x="Cant",y="Origen", color="Legend")+
   ggtitle("Mayores catidades de Scrap por origen")

Infromacíon Relevante.

En esta actividad de la limpia y organización de la base de datos de Scrap. Nos dimos cuentas que la base de datos contaba con distintas variables que no eran tan relevantes para analizar la bd scrap. Por lo tanto decidiomos eliminarlas para contar con menos variables y asi poder realizar un mejor analisis.

En este analisis nos dimos cuenta que los datos estaban orgnaizados es decir no contaban con missing values por lo tanto es algo bueno para el analisis, de todos modos es importante conciderarlos si es relevante para el analisis, en este caso no se hubieran eliminado si no que se hubieran remplazado por la mediana dependiendte de la variable que estuvieramos analisando.

Analisando estas variables se confirma que en el area de pre-producción,es donde se genera la mayoria del scrap en su mayoria se genera casi el 85% de scrap, que generan dentro de la empresa, por lo tanto es alago alarmante por lo tanto se tienen que tomar decisiones importantes para poder realizar cambios en esta area para reducir la cantidad de scrap.

2. Merma

Llamar base de datos.

#file.choose()
FORM <- read.csv("C:\\Users\\danyc\\Downloads\\FORM - Merma limpia.csv")

Entender Base de Datos

resumen <- summary(FORM)
resumen
##     Fecha               Kilos      
##  Length:42          Min.   : 1040  
##  Class :character   1st Qu.: 3682  
##  Mode  :character   Median : 4025  
##                     Mean   : 4415  
##                     3rd Qu.: 4325  
##                     Max.   :18900

1.¿Cuántas variables y cuántos registros tiene la base de datos?

R= 52 registros y 2 variables
str(FORM)
## 'data.frame':    42 obs. of  2 variables:
##  $ Fecha: chr  "11/01/22" "22/01/22" "18/02/22" "24/02/22" ...
##  $ Kilos: num  8890 5670 18900 3930 4000 4190 2980 3290 4200 3810 ...
library(psych)
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
#install.packages("psych")
describe(FORM)
##        vars  n   mean      sd median trimmed    mad  min   max range skew
## Fecha*    1 42   21.5   12.27   21.5   21.50  15.57    1    42    41 0.00
## Kilos     2 42 4414.9 2571.79 4025.0 4025.76 504.08 1040 18900 17860 4.29
##        kurtosis     se
## Fecha*    -1.29   1.89
## Kilos     21.29 396.84

Nota:En esta base de datos se eliminaron la columana que no era relevante para el analisis, Se eliminaron los registros de total de merma y la columna de mes ya que no eran irrelevantes. Por lo tanto nos quedamos con 52 registros y 2 variables.

2.Para el caso de variables cuantitativas considerar la posibilidad de reemplazar la presencia de “missing values” con estadísticos descriptivos (por ejemplo, media, mediana, moda).*

#install.packages("dplyr")
#install.packages("merge)
library(dplyr)
#library(merge)
#Remplazar valores faltantes por la mediana: No se pueden cambair debido a que los NA´S de la base de datos no tienen información. Por lo tanto se van a Eliminar. 

FORM_1<-FORM
FORM_1<- na.omit(FORM_1)
summary(FORM_1)
##     Fecha               Kilos      
##  Length:42          Min.   : 1040  
##  Class :character   1st Qu.: 3682  
##  Mode  :character   Median : 4025  
##                     Mean   : 4415  
##                     3rd Qu.: 4325  
##                     Max.   :18900
#summary(FORM) 
#str(FORM)
#FORM$Kilos<-as.numeric(FORM$Kilos)
#FORM<-FORM %>% mutate(Kilos=if_else(is.na(Kilos),median(Kilos,na.rm = T),Kilos))

Nota:En esta base de datos la unica variable que se puede remplazar por la mediana es la columna de kilos. Ya se remplazaron los valores faltantes por la mediana.

Cambiar nombres de columnas y variables

Cambiar los nombres de las columnas / variables a nombres más cortos y específicos. Por ejemplo, municipio → mpio, salario mínimo diario → salario_min.

#seleccionar columnas / variables.
#FORM<-FORM %>% select(-one_of('Fecha','Kilos'))

#Renombrar las columnas /variables seleccionadas. 
colnames(FORM_1) <-c ('Fcha','Kilo')

Respecto a variables cualitativas (por ejemplo, género, cliente,municipio, estado) homogenizar el nombre de las diferentes categorías.

Respecto a La base de datos analizada no aplica el paso de homogenizar las variables ya que en este caso solo se cuenta con dos variables en la base de datos.

Tabla de estadísticos descriptivos

Crear tabla que muestre los principales estadísticos descriptivos (media,mediana, moda, desviación estandar) de cada una de las variables para cada base de datos. Comentar brevemente los principales resultados que se muestran en la tabla.

#DESCARGAR EL PAQUETE 
#install.packages("kbleExtra") 


#summary(FORM_1)


#install.packages("sd")
#install.packages("modeest")
#library(modeest)
#sd(FORM_1$Kilo, na.rm = FALSE)
#install.packages("dplyr")
#library(dplyr)
median(FORM_1$Kilo, na.rm = TRUE)
## [1] 4025
mean(FORM_1$Kilo, na.rm = TRUE)
## [1] 4414.905
sd(FORM_1$Kilo, na.rm = FALSE)
## [1] 2571.793
#mfv(FORM_1$Kilo)

variable<-c("'Kilo")
Mediana<-c("4025")
Media <- c("4415")
Moda <- c("4190")
Desviación_estandar<-c("2571.793")
table1 <- data.frame (variable, Mediana, Media, Moda, Desviación_estandar)
knitr::kable(table1)
variable Mediana Media Moda Desviación_estandar
’Kilo 4025 4415 4190 2571.793

Time Serie Plots

Crear 1-2 “time series plots” (line plot) que muestran la dispersión de variables selecionadas.

FORM_1$Fcha<-as.Date(FORM_1$Fcha,format="%d/%m/%y") 

#install.packages("ggplot2")
library(ggplot2)
summary(FORM_1)
##       Fcha                 Kilo      
##  Min.   :2022-01-11   Min.   : 1040  
##  1st Qu.:2022-04-05   1st Qu.: 3682  
##  Median :2022-06-11   Median : 4025  
##  Mean   :2022-06-04   Mean   : 4415  
##  3rd Qu.:2022-08-10   3rd Qu.: 4325  
##  Max.   :2022-09-21   Max.   :18900
ggplot(FORM_1,aes(x=Fcha))+
  geom_line(aes(y=Kilo),color="blue")+
  labs(x="Fcha",y="Kilo", color="Legend")+
   ggtitle("Kilos de merma por mes")

7.Información Relevante

Una reflexión que se toma sobre esta actividad es que solo contamos con dos variables relevantes las cual nos puede decir algo, en este caso solo se utilizo la de fecha y la de los kilos de merma.

Un dato impactante es que la mayoría de las veces la empresa tiene una merma constante, esta varia pero casi todos los meses cuentan con al rededor de 5 toneladas de merma, de acuerdo con las fechas que nos dieron en esta base de datos se analizo que de enero a marzo existió una gran cantidad de merma que llego al rededor de 17 toneladas de merma, por lo tanto se debe de analizar en la empresa que fue lo que sucedió en este lapso de tiempo, puedo ser que un cliente cancelara algún pedido, que haya generado una gran cantidad de merma.

3. Delivery Plan

Importar la base de datos

#file.choose()
delivery<-read.csv("C:\\Users\\danyc\\Downloads\\DELIVERY.csv")
summary(delivery)
##     ID_Fecha        Fecha             CLIENTE             Pedidos       
##  Min.   : 1.00   Length:228         Length:228         Min.   :    0.0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:    0.0  
##  Median : 6.50   Mode  :character   Mode  :character   Median :    0.0  
##  Mean   : 6.50                                         Mean   : 1703.1  
##  3rd Qu.: 9.25                                         3rd Qu.:  233.8  
##  Max.   :12.00                                         Max.   :52779.0

Observaciones

1.Se hizo limpieza manual de la base de datos para acomodar los clientes como variables y las fechas como registros.

2.Se sustituyeron NAs por cero.

3.Se eliminaron columnas no usadas y que no agreegan valor para el analisis que se busca hacer.

Descargar librerías y paquetes

library(foreign)
library(dplyr)
library(forcats)
library(ggplot2)
library(readr)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(naniar)
library(dlookr)
## 
## Attaching package: 'dlookr'
## The following object is masked from 'package:psych':
## 
##     describe
## The following object is masked from 'package:base':
## 
##     transform

Cuantas variables y registros hay

str(delivery)
## 'data.frame':    228 obs. of  4 variables:
##  $ ID_Fecha: int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Fecha   : chr  "31/01/22" "31/01/22" "31/01/22" "31/01/22" ...
##  $ CLIENTE : chr  "STB3" "STB 1" "YF RAMOS" "INOAC POLYTEC" ...
##  $ Pedidos : int  481 0 227 0 400 328 393 0 8975 449 ...

Contamos con 3 variables y 380 observaciones.

Contar total de pedidos por cliente

deliverySUM = colSums(delivery[4])

as.data.frame(deliverySUM)
##         deliverySUM
## Pedidos      388317

Contamos con 52,0281 pedidos

#file.choose()
deliveryCLIENTS<-read.csv("C:\\Users\\danyc\\Downloads\\DeliveryCLIENTS.xlsx - Sheet1.csv")
summary(deliveryCLIENTS)
##     Fecha                STB3            STB.1           YF.RAMOS   
##  Length:19          Min.   :   0.0   Min.   : 0.000   Min.   :   0  
##  Class :character   1st Qu.:  13.5   1st Qu.: 0.000   1st Qu.:  54  
##  Mode  :character   Median : 200.0   Median : 0.000   Median : 100  
##                     Mean   : 297.1   Mean   : 2.632   Mean   : 211  
##                     3rd Qu.: 460.5   3rd Qu.: 0.000   3rd Qu.: 230  
##                     Max.   :1015.0   Max.   :50.000   Max.   :1243  
##  INOAC.POLYTEC       MERIDIAN     YANFENG.sm          YFTO       
##  Min.   : 0.000   Min.   :  0   Min.   :  0.00   Min.   : 138.0  
##  1st Qu.: 0.000   1st Qu.:  0   1st Qu.:  0.00   1st Qu.: 358.5  
##  Median : 0.000   Median :  0   Median : 41.00   Median : 628.0  
##  Mean   : 2.684   Mean   : 33   Mean   : 95.05   Mean   : 869.6  
##  3rd Qu.: 0.000   3rd Qu.:  0   3rd Qu.:142.50   3rd Qu.: 871.5  
##  Max.   :40.000   Max.   :400   Max.   :328.00   Max.   :2556.0  
##      YF.QRO            TRMX           DENSO           SEGROVE      
##  Min.   : 0.000   Min.   :    0   Min.   :   0.0   Min.   :  0.00  
##  1st Qu.: 0.000   1st Qu.: 2822   1st Qu.: 150.5   1st Qu.:  0.00  
##  Median : 0.000   Median : 6240   Median : 372.0   Median :  0.00  
##  Mean   : 2.737   Mean   : 5796   Mean   :1241.3   Mean   : 38.74  
##  3rd Qu.: 0.000   3rd Qu.: 8374   3rd Qu.:1083.0   3rd Qu.:  0.00  
##  Max.   :36.000   Max.   :11833   Max.   :8834.0   Max.   :736.00  
##      HANON        ANTOLIN.TOLUCA ANTOLIN.ARTEAGA     HELLA      
##  Min.   :  0.00   Min.   :0      Mode:logical    Min.   :    0  
##  1st Qu.:  0.00   1st Qu.:0      NA's:19         1st Qu.: 4160  
##  Median :  0.00   Median :0                      Median : 8580  
##  Mean   : 21.58   Mean   :0                      Mean   :15013  
##  3rd Qu.:  0.00   3rd Qu.:0                      3rd Qu.:21191  
##  Max.   :360.00   Max.   :0                      Max.   :52779  
##       UFI              ISRI            TRMX.1  ABC.QUERETARO        VARROC    
##  Min.   :  0.00   Min.   :   0.0   Min.   :0   Min.   :0.0000   Min.   :   0  
##  1st Qu.:  0.00   1st Qu.:   0.0   1st Qu.:0   1st Qu.:0.0000   1st Qu.:2078  
##  Median :  0.00   Median :   0.0   Median :0   Median :0.0000   Median :3509  
##  Mean   : 45.74   Mean   : 157.9   Mean   :0   Mean   :0.4211   Mean   :3555  
##  3rd Qu.:  3.50   3rd Qu.:   0.0   3rd Qu.:0   3rd Qu.:0.0000   3rd Qu.:4974  
##  Max.   :492.00   Max.   :3000.0   Max.   :0   Max.   :8.0000   Max.   :8810  
##  Total.pedidos.mes 
##  Length:19         
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
deliveryCLIENTS = colSums(deliveryCLIENTS[2:21])
as.data.frame(deliveryCLIENTS)
##                 deliveryCLIENTS
## STB3                       5644
## STB.1                        50
## YF.RAMOS                   4009
## INOAC.POLYTEC                51
## MERIDIAN                    627
## YANFENG.sm                 1806
## YFTO                      16522
## YF.QRO                       52
## TRMX                     110127
## DENSO                     23584
## SEGROVE                     736
## HANON                       410
## ANTOLIN.TOLUCA                0
## ANTOLIN.ARTEAGA              NA
## HELLA                    285238
## UFI                         869
## ISRI                       3000
## TRMX.1                        0
## ABC.QUERETARO                 8
## VARROC                    67548
barplot.default(deliveryCLIENTS)

Con este plot podemos ver que hay muchos clientes con muy pocos pedidos.

Técnicas de Limpieza

Técnica 1: eliminar NAs

Se decidió realizar está técnica para asegurarnos de que no se tenga falta de datos y en caso de tenerlos evitar que estas eviten tener un analisis asertivo al no agregar valor a la base de datos.

¿Cuantos NA tengo en la base de datos?

sum(is.na(delivery))
## [1] 0

Cuantos NA tengo por variable?

Sapply: Para contar los NA.

sapply(delivery, function(x) sum(is.na(x)))
## ID_Fecha    Fecha  CLIENTE  Pedidos 
##        0        0        0        0

Se encontró un solo NA

Técnica 2: eliminar filas

Se decidó realizar está técnica para eliminar los clientes que tienen menos de 5,000 pedidos.

Eliminar filas con el nombre de los clientes que se desean eliminar.

#delivery1 <- subset (delivery1,  CLIENTE == "STB3") #Para conservar ciertas filas

delivery1<-delivery

delivery1<-delivery1[delivery1$CLIENTE!="STB 1", ]
delivery1<-delivery1[delivery1$CLIENTE!="YF RAMOS", ]
delivery1<-delivery1[delivery1$CLIENTE!="INOAC POLYTEC", ]
delivery1<-delivery1[delivery1$CLIENTE!="MERIDIAN", ]
delivery1<-delivery1[delivery1$CLIENTE!="YANFENG sm", ]
delivery1<-delivery1[delivery1$CLIENTE!="YF QRO", ]
delivery1<-delivery1[delivery1$CLIENTE!="SEGROVE", ]
delivery1<-delivery1[delivery1$CLIENTE!="HANON", ]
delivery1<-delivery1[delivery1$CLIENTE!="ANTOLIN TOLUCA", ]
delivery1<-delivery1[delivery1$CLIENTE!="ANTOLIN ARTEAGA", ]
delivery1<-delivery1[delivery1$CLIENTE!="ABC QUERETARO", ]
delivery1<-delivery1[delivery1$CLIENTE!="UFI", ]
delivery1<-delivery1[delivery1$CLIENTE!="ISRI", ]

summary(delivery1)
##     ID_Fecha        Fecha             CLIENTE             Pedidos     
##  Min.   : 1.00   Length:72          Length:72          Min.   :    0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:   99  
##  Median : 6.50   Mode  :character   Mode  :character   Median : 1009  
##  Mean   : 6.50                                         Mean   : 5339  
##  3rd Qu.: 9.25                                         3rd Qu.: 5928  
##  Max.   :12.00                                         Max.   :52779

*Tabla de Media, Moda y Mediana

table3<-describe(delivery1)
knitr::kable(table3)
described_variables n na mean sd se_mean IQR skewness kurtosis p00 p01 p05 p10 p20 p25 p30 p40 p50 p60 p70 p75 p80 p90 p95 p99 p100
ID_Fecha 72 0 6.500 3.476278 0.4096833 5.5 0.000000 -1.217513 1 1 1 2 3.0 3.75 4.0 5 6.5 8.0 9.0 9.25 10 11.0 12.0 12.00 12
Pedidos 72 0 5339.167 10093.190781 1189.4939408 5829.5 3.128063 10.742837 0 0 0 0 10.8 99.00 260.6 507 1009.0 2451.6 4289.4 5928.50 8380 12577.3 27194.4 49479.63 52779

Identificar variables

Cuantitativa: Discreta, Continua Escala de medición:Intervalo, Razón Cualitativa Escala de medición: Nominales, Ordinales

Variable<-c("Fecha","STB3","YFTO", "TRMX", "DENSO","HELLA","VARROC","Total.pedidos.mes")
Type<-c("Cuantitativa (discreta)", "Cualitativa", "Cualitativa", "Cualitativa","Cualitativa","Cualitativa","Cualitativa","Cuantitativa (discreta)")
Measurement<-c("Razón","Nominal","Nominal","Nominal","Nominal","Nominal","Nominal","Razón")
table2<-data_frame(Variable,Type,Measurement)
## Warning: `data_frame()` was deprecated in tibble 1.1.0.
## Please use `tibble()` instead.
knitr::kable(table2)
Variable Type Measurement
Fecha Cuantitativa (discreta) Razón
STB3 Cualitativa Nominal
YFTO Cualitativa Nominal
TRMX Cualitativa Nominal
DENSO Cualitativa Nominal
HELLA Cualitativa Nominal
VARROC Cualitativa Nominal
Total.pedidos.mes Cuantitativa (discreta) Razón

Gráfica Cualitativa

#install.packages("plyr")
library(plyr)
## ------------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## ------------------------------------------------------------------------------
## 
## Attaching package: 'plyr'
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
delivery2<-delivery1

delivery2<- aggregate(delivery2$Pedidos, by=list(category=delivery2$CLIENTE), FUN=sum)
pie(delivery2$x, labels = delivery2$category)

Con esta gráfica podemos darnos cuenta de los clientes que tienen mayores pedidos y en este caso es HELLA en primer lugar y TRMX en segundo lugar.

Gráfica Cuantitativa

delivery2<-delivery2 %>% dplyr::rename(pedidos="x")
delivery2<-delivery2 %>% dplyr::rename(Clientes="category")

delivery2$Clientes<-as.factor(delivery2$Clientes)
ggplot(delivery2, aes(x=Clientes, y=pedidos, fill=pedidos))+
         geom_bar(stat="identity")+
         theme_minimal()+
         labs(title="Pedidos por cliente")

Esta gráfica sirve para tener de manera más visual el impacto que tiene cada uno de los clientes en la empresa FORM. Podemos ver que HELLA es el cliente más significativo con casi el triple de pedidos que el siguiente cliente con mayores pedidos, TRMX. De lado derecho se tiene un legend que muestra la tonalidad de los plots para ver que tantos pedidos tiene, por ello HELLAS tiene un color azul claro, representando más de 250,000 pedidos.

Comportamiento de clientes por fecha

summary(delivery1)
##     ID_Fecha        Fecha             CLIENTE             Pedidos     
##  Min.   : 1.00   Length:72          Length:72          Min.   :    0  
##  1st Qu.: 3.75   Class :character   Class :character   1st Qu.:   99  
##  Median : 6.50   Mode  :character   Mode  :character   Median : 1009  
##  Mean   : 6.50                                         Mean   : 5339  
##  3rd Qu.: 9.25                                         3rd Qu.: 5928  
##  Max.   :12.00                                         Max.   :52779
ggplot(delivery1,aes(x=ID_Fecha, y=Pedidos, group=CLIENTE,colour=CLIENTE))+
  geom_line()+
  ggtitle("Pedidos por cliente")

Con esta gráfica utilizamos el ID Fecha para conocer los pedidos que se tiene por cliente cada mes y vemos un significativo incremento de pedidos en el mes de septiembre y octubre. contamos con un legen que indica cada línea con un color para nombrar la información de cada uno de los clientes.

Gráfica Boxplot

boxplot(delivery1$Pedidos, main= "Pedidos")

delivery3<-delivery1
delivery3$CLIENTE <-as.factor(delivery3$CLIENTE)
ggplot(delivery3, aes(x=CLIENTE, y=Pedidos))+
  geom_boxplot(color="blue", fill="purple")

En esta gráfica podemos visualizarcuantos pedidos tiene programados cada cliente y los clientes que sobre salen son HELLA y TRMX, algo muy relevante en esta gráfica es que se muestra la moda de cada uno, así como también la minima de pedidos y la máxima, y en este caso no se tiene una dispersión por ninguno de los clientes.

Conclusión - Delivery Plan

Para realizar el análisis de la base de datos de “Delivery Plan” fué necesario primero hacer un arreglo de la base de datos de manera manual en el excel. Estó para simplificar el uso de la base de datos y permitir que R pueda analizarla y extraer los datos para generar gráficas. Después aplicamos dos diferentes bases de datos, nos aseguramos de que no haya NAs y eliminamos filas que correspondían a los clientes que tenían menos de 5,000 pedidos. Nos quedamos con una base de datos con los 6 clientes más significativos para FORM. Continuamos identificando las variables en dónde 6 de 8 variables eran cualitativas al ser los clientes de FORM.

Graficamos una gráfica de Pie para identificar de manera visual los mayores clientes, los que vienen siendo HELLA y TRMX. También hicimos un “Barplot” para mostrar la cantidad de pedidos programados que tiene cada cliente, Hella siendo el cliente con mayor pedidos con más de 225,000 y TRMX siguiendo con 80,000. Decidimos también visualizar el comportamiento de los clientes según la fecha y nos dimos cuenta que entre el mes de septiembre y octubre hubo un incremento de pedidos establecidos. Y por último se realizó el “Boxplot” para de ese modo ver de manera precisa la moda de clos pedidos que suele hacer cada uno de los clientes.

4. Recursos Humanos

Limpieza, Transformación y Organización de Bases de Datos

## Descargar librerías
library(foreign)
library(dplyr)        # data manipulation 
library(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization
library(readr)        # read specific csv files
library(janitor)      # data exploration and cleaning 
library(Hmisc)        # several useful functions for data analysis 
## Loading required package: lattice
## Loading required package: survival
## Loading required package: Formula
## 
## Attaching package: 'Hmisc'
## The following objects are masked from 'package:plyr':
## 
##     is.discrete, summarize
## The following object is masked from 'package:dlookr':
## 
##     describe
## The following object is masked from 'package:psych':
## 
##     describe
## The following objects are masked from 'package:dplyr':
## 
##     src, summarize
## The following objects are masked from 'package:base':
## 
##     format.pval, units
library(psych)        # functions for multivariate analysis 
library(naniar)       # summaries and visualization of missing values NAs
library(dlookr)       # summaries and visualization of missing values NAs
library(corrplot)     # correlation plots
## corrplot 0.92 loaded
library(jtools)       # presentation of regression analysis 
## 
## Attaching package: 'jtools'
## The following object is masked from 'package:Hmisc':
## 
##     %nin%
library(lmtest)       # diagnostic checks - linear regression analysis 
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(car)          # diagnostic checks - linear regression analysis
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:psych':
## 
##     logit
## The following object is masked from 'package:dplyr':
## 
##     recode
library(olsrr)        # diagnostic checks - linear regression analysis 
## 
## Attaching package: 'olsrr'
## The following object is masked from 'package:datasets':
## 
##     rivers
library(kableExtra)   # HTML table attributes
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
library(gmodels)
library(openxlsx)
library(crosstable)
## 
## Attaching package: 'crosstable'
## The following object is masked from 'package:plyr':
## 
##     compact

*Nota: Como parte de la limpieza de datos de ambos documentos, se realizaron los promedios de los valores faltantes de forma manual en Excel.

A partir de esta parte del documento, el análisis estará dividido en dos partes. En la primera se analizará la base de datos con la información de los colaboradores actuales de la empresa, mientras que en la segunda se analizarán los datos de aquellos empleados que ya fueron bajas por motivos de despido, renuncia voluntaria, entre otros.

BASE DE DATOS: COLABORADORES DE RECURSOS HUMANOS

## 1. Número de registros y variables

### Importar base de datos
#file.choose()
df1 <-read.csv("C:\\Users\\danyc\\Downloads\\hr csv 1.csv")
summary(df1)
##  No..De.Empleado   APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  1.00   Length:113         Length:113         Length:113         
##  1st Qu.: 31.00   Class :character   Class :character   Class :character   
##  Median : 63.00   Mode  :character   Mode  :character   Mode  :character   
##  Mean   : 75.86                                                            
##  3rd Qu.:127.00                                                            
##  Max.   :169.00                                                            
##       EDAD          GENERO              RFC            FECHA.DE.ALTA     
##  Min.   : 0.00   Length:113         Length:113         Length:113        
##  1st Qu.:25.00   Class :character   Class :character   Class :character  
##  Median :33.00   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :35.74                                                           
##  3rd Qu.:45.00                                                           
##  Max.   :73.00                                                           
##   PRIMER.MES         CUARTO.MES             BAJA           PUESTO         
##  Length:113         Length:113         Min.   :0.0000   Length:113        
##  Class :character   Class :character   1st Qu.:0.0000   Class :character  
##  Mode  :character   Mode  :character   Median :0.0000   Mode  :character  
##                                        Mean   :0.3451                     
##                                        3rd Qu.:0.0000                     
##                                        Max.   :3.0000                     
##  DEPARTAMENTO       SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:113         Min.   :144.4       Min.   :     0       
##  Class :character   1st Qu.:176.7       1st Qu.:     0       
##  Mode  :character   Median :180.7       Median :     0       
##                     Mean   :181.2       Mean   :  2244       
##                     3rd Qu.:180.7       3rd Qu.:     0       
##                     Max.   :441.4       Max.   :182096       
##  N..CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:113          Length:113         Length:113        
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :6.770e+07                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :1.922e+09                                                             
##  NUMERO.INTERNO       COLONIA           MUNICIPIO            ESTADO         
##  Length:113         Length:113         Length:113         Length:113        
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  CODIGO.POSTAL   ESTADO.CIVIL       TARJETA.CUENTA        X          
##  Min.   :25016   Length:113         Length:113         Mode:logical  
##  1st Qu.:66640   Class :character   Class :character   NA's:113      
##  Median :66646   Mode  :character   Mode  :character                 
##  Mean   :63365                                                       
##  3rd Qu.:66649                                                       
##  Max.   :67493                                                       
##    X.1         
##  Mode:logical  
##  NA's:113      
##                
##                
##                
## 
describe(df1)
## df1 
## 
##  28  Variables      113  Observations
## --------------------------------------------------------------------------------
## No..De.Empleado 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0      113        1    75.86    61.43      6.6     12.2 
##      .25      .50      .75      .90      .95 
##     31.0     63.0    127.0    157.8    163.4 
## 
## lowest :   1   2   3   4   5, highest: 165 166 167 168 169
## --------------------------------------------------------------------------------
## APELLIDOS 
##        n  missing distinct 
##      113        0      109 
## 
## lowest : AGUILERA RODRIGUEZ ALVAREZ DORIA      ARRIAGA REYES      BADILLO LOZANO     BALUIS PAULINO    
## highest: VAZQUEZ GAYTAN     VERA VALDEZ        YABERT ALVARADO    ZAMARRON PUENTES   ZAPATA GARCIA     
## --------------------------------------------------------------------------------
## NOMBRE 
##        n  missing distinct 
##      113        0      107 
## 
## lowest : ADELAIDA         ADRIANA          ADRIANA IRENE    ALFREDO          ALMA DELIA      
## highest: VICTOR DE JESUS  YOLANDA          YOLANDA JUDITH   YUDITH ESMERALDA YULIANA MIREYA  
## --------------------------------------------------------------------------------
## FECHA.DE.NACIMIENTO 
##        n  missing distinct 
##      113        0      113 
## 
## lowest : 01/04/2003 01/05/1990 01/05/2000 01/07/1967 02/06/1982
## highest: 30/11/1968 30/12/1992 31/05/1992 31/07/1990 31/10/1967
## --------------------------------------------------------------------------------
## EDAD 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0       42    0.999    35.74    15.03     19.0     20.0 
##      .25      .50      .75      .90      .95 
##     25.0     33.0     45.0     55.0     57.4 
## 
## lowest :  0 18 19 20 21, highest: 58 59 60 67 73
## --------------------------------------------------------------------------------
## GENERO 
##        n  missing distinct 
##      113        0        2 
##                               
## Value       FEMENINO MASCULINO
## Frequency         61        52
## Proportion      0.54      0.46
## --------------------------------------------------------------------------------
## RFC 
##        n  missing distinct 
##      113        0      113 
## 
## lowest : AADE890611LN5 AIRE011022G3A AURJ6902215X8 BALA8103249E8 BAMJ970519V10
## highest: VAPA8709199G6 VEVM9412238W8 YAAM670808L59 ZAGA770505VA6 ZAPJ830218LZ9
## --------------------------------------------------------------------------------
## FECHA.DE.ALTA 
##        n  missing distinct 
##      113        0       94 
## 
## lowest : 01/06/2022 01/07/2010 01/07/2011 01/08/2022 01/12/2017
## highest: 28/08/2020 29/11/2018 30/01/2013 30/06/2022 30/07/2019
## --------------------------------------------------------------------------------
## PRIMER.MES 
##        n  missing distinct 
##      113        0       94 
## 
## lowest : 01/03/2013 01/06/2019 01/07/2022 01/09/2022 02/02/2022
## highest: 29/12/2018 30/07/2022 31/07/2010 31/07/2011 31/12/2017
## --------------------------------------------------------------------------------
## CUARTO.MES 
##        n  missing distinct 
##      113        0       95 
## 
## lowest : 01/09/2022 01/12/2022 02/02/2022 02/07/2021 02/08/2019
## highest: 30/05/2013 30/08/2019 31/03/2018 31/08/2022 31/10/2014
## --------------------------------------------------------------------------------
## BAJA 
##        n  missing distinct     Info     Mean      Gmd 
##      113        0        2    0.305   0.3451   0.6163 
##                       
## Value          0     3
## Frequency    100    13
## Proportion 0.885 0.115
## --------------------------------------------------------------------------------
## PUESTO 
##        n  missing distinct 
##      113        0       21 
## 
## lowest : AYUDANTE DE MANTENIMIENTO AYUDANTE GENERAL          CHOFER                    COSTURERO/A               ENFERMERO/A              
## highest: RECIBO                    RESIDENTE                 SERVICIO AL CLIENTE       SOLDADOR                  SUPERVISOR/A             
## --------------------------------------------------------------------------------
## DEPARTAMENTO 
##        n  missing distinct 
##      113        0       19 
## 
## lowest : AY FLEXO          CALIDAD           CEDIS             CELDAS            CORTADORAS       
## highest: PRODUCCION RETORN ROTATIVA          STABILUS          TROQUEL           VARIOS           
## --------------------------------------------------------------------------------
## SALARIO.DIARIO.IMSS 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0       17    0.848    181.2    22.55    151.6    151.6 
##      .25      .50      .75      .90      .95 
##    176.7    180.7    180.7    180.7    221.5 
## 
## lowest : 144.45 151.61 151.67 152.86 175.79, highest: 240.75 260.01 279.61 337.05 441.37
##                                                                          
## Value      144.45 151.61 151.67 152.86 175.79 176.72 180.68 181.68 184.68
## Frequency       3     11      5      1      1     23     59      1      1
## Proportion  0.027  0.097  0.044  0.009  0.009  0.204  0.522  0.009  0.009
##                                                                   
## Value      185.68 208.65 240.71 240.75 260.01 279.61 337.05 441.37
## Frequency       1      1      1      1      1      1      1      1
## Proportion  0.009  0.009  0.009  0.009  0.009  0.009  0.009  0.009
## --------------------------------------------------------------------------------
## FACTOR.CRED.INFONAVIT 
##        n  missing distinct     Info     Mean      Gmd 
##      113        0        5    0.102     2244     4460 
## 
## lowest :      0.00   1726.06  13619.00  56118.00 182096.00
## highest:      0.00   1726.06  13619.00  56118.00 182096.00
##                                                             
## Value           0.00   1726.06  13619.00  56118.00 182096.00
## Frequency        109         1         1         1         1
## Proportion     0.965     0.009     0.009     0.009     0.009
## --------------------------------------------------------------------------------
## N..CREDITO.INFONAVIT 
##         n   missing  distinct      Info      Mean       Gmd 
##       113         0         5     0.102  67697774 131776900 
## 
## lowest :          0 1905321932 1910498716 1912437884 1921589926
## highest:          0 1905321932 1910498716 1912437884 1921589926
##                                                                  
## Value               0 1905321932 1910498716 1912437884 1921589926
## Frequency         109          1          1          1          1
## Proportion      0.965      0.009      0.009      0.009      0.009
## --------------------------------------------------------------------------------
## LUGAR.DE.NACIMIENTO 
##        n  missing distinct 
##      113        0       13 
## 
## lowest : CHIAPAS          CIUDAD DE MEXICO COAHUILA         DURANGO          GUANAJUATO      
## highest: SAN LUIS POTOSI  TABASCO          TAMAULIPAS       VERACRUZ         ZACATECAS       
## --------------------------------------------------------------------------------
## CURP 
##        n  missing distinct 
##      113        0      113 
## 
## lowest : AADE890611HNLLRD   AIRE011022MNLRYRA6 AURJ690221HNLGDM07 BALA810324MVZDZD08 BAMJ970519HTSRRN01
## highest: VEVM941223HSPRLN07 VXCA630828HZSZPL02 YAAM670808HZSBLR18 ZAGA770505MTSPRD06 ZAPJ830218MNLMNS04
## --------------------------------------------------------------------------------
## CALLE 
##        n  missing distinct 
##      113        0      102 
## 
## lowest : AGUSTIN LARA       AHITI              ALAMO CHOPO        ALAMO TEMBLON      ALBISO            
## highest: VILLA PLACENCIA    VILLAS DE MADRID   VIRREYES DEL NORTE VISTAS DEL RIO     ZOLDANO           
## --------------------------------------------------------------------------------
## NUMERO.INTERNO 
##        n  missing distinct 
##      113        0       92 
## 
## lowest : 106B 107  108  109  1109, highest: 821B 825  832  833  835 
## --------------------------------------------------------------------------------
## COLONIA 
##        n  missing distinct 
##      113        0       67 
## 
## lowest : ALAMOS DEL PARQUE          ANALCO 2                   ANZURES                    BALCONES DE HUINALA        C. H. BLAS CHUMACERO C.T.M
## highest: VILLAS DE HUINALA          VILLAS DE SAN CARLOS       VISTAS DEL RIO             VIVIENDA DIGNA             ZONA CENTRO               
## --------------------------------------------------------------------------------
## MUNICIPIO 
##        n  missing distinct 
##      113        0        9 
## 
## lowest : APODACA                  CAÑADA BLANCA            GUADALUPE                JUAREZ                   MONTERREY               
## highest: MONTERREY                PESQUERIA                RAMOS ARIZPE             SALTILLO                 SAN NICOLAS DE LOS GARZA
## --------------------------------------------------------------------------------
## ESTADO 
##        n  missing distinct 
##      113        0        2 
##                                 
## Value        COAHUILA NUEVO LEON
## Frequency           9        104
## Proportion       0.08       0.92
## --------------------------------------------------------------------------------
## CODIGO.POSTAL 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0       43    0.972    63365     6375    25901    64846 
##      .25      .50      .75      .90      .95 
##    66640    66646    66649    67117    67256 
## 
## lowest : 25016 25088 25115 25290 25900, highest: 67255 67258 67266 67267 67493
##                                                                             
## Value      25000 25100 25300 25900 64100 64800 65000 66100 66400 66500 66600
## Frequency      1     2     2     4     2     1     1     1     1     1    71
## Proportion 0.009 0.018 0.018 0.035 0.018 0.009 0.009 0.009 0.009 0.009 0.628
##                                         
## Value      66700 67100 67200 67300 67500
## Frequency     10     5     3     7     1
## Proportion 0.088 0.044 0.027 0.062 0.009
## 
## For the frequency table, variable is rounded to the nearest 100
## --------------------------------------------------------------------------------
## ESTADO.CIVIL 
##        n  missing distinct 
##      113        0        4 
##                                                               
## Value          CASADO/A DIVORCIADO/A    SOLTERO/A  UNION LIBRE
## Frequency            44            3           46           20
## Proportion        0.389        0.027        0.407        0.177
## --------------------------------------------------------------------------------
## TARJETA.CUENTA 
##        n  missing distinct 
##      113        0        2 
##                               
## Value        BANORTE SANTANDER
## Frequency        101        12
## Proportion     0.894     0.106
## --------------------------------------------------------------------------------
## 
## Variables with all observations missing:
## 
## [1] X   X.1

2. Clasificación de variables

variable<-c("No..De.Empleado","APELLIDOS","NOMBRE","FECHA.DE.NACIMIENTO","EDAD","GENERO","RFC","FECHA.DE.ALTA","PRIMER.MES","CUARTO.MES","BAJA","PUESTO","DEPARTAMENTO","SALARIO.DIARIO.IMSS","FACTOR.CRED.INFONAVIT","N..CREDITO.INFONAVIT","LUGAR.DE.NACIMIENTO","CURP","CALLE","NUMERO.INTERNO","COLONIA","MUNICIPIO","ESTADO","CODIGO.POSTAL","ESTADO.CIVIL","TARJETA.CUENTA")
Type<-c(
        "quantitative (continous)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "quantitative (continous)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "quantitative (continous)",
        "quantitative (continous)",
        "quantitative (continous)",
        "quantitative (continous)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "quantitative (continous)",
        "quantitative (continous)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "quantitative (continous)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "qualitative (discrete)",
        "quanitative (continous)",
        "qualitative (discrete)",
        "qualitative (discrete)"
        )

table<-data.frame(variable,Type)
knitr::kable(table)
variable Type
No..De.Empleado quantitative (continous)
APELLIDOS qualitative (discrete)
NOMBRE qualitative (discrete)
FECHA.DE.NACIMIENTO qualitative (discrete)
EDAD quantitative (continous)
GENERO qualitative (discrete)
RFC qualitative (discrete)
FECHA.DE.ALTA quantitative (continous)
PRIMER.MES quantitative (continous)
CUARTO.MES quantitative (continous)
BAJA quantitative (continous)
PUESTO qualitative (discrete)
DEPARTAMENTO qualitative (discrete)
SALARIO.DIARIO.IMSS quantitative (continous)
FACTOR.CRED.INFONAVIT quantitative (continous)
N..CREDITO.INFONAVIT qualitative (discrete)
LUGAR.DE.NACIMIENTO qualitative (discrete)
CURP qualitative (discrete)
CALLE qualitative (discrete)
NUMERO.INTERNO quantitative (continous)
COLONIA qualitative (discrete)
MUNICIPIO qualitative (discrete)
ESTADO qualitative (discrete)
CODIGO.POSTAL quanitative (continous)
ESTADO.CIVIL qualitative (discrete)
TARJETA.CUENTA qualitative (discrete)

3. Escalas de medición

variables <- c(
  "No..De.Empleado",
  "APELLIDOS",
  "NOMBRE",
  "FECHA.DE.NACIMIENTO",
  "EDAD",
  "GENERO",
  "RFC",
  "FECHA.DE.ALTA",
  "PRIMER.MES",
  "CUARTO.MES",
  "BAJA",
  "PUESTO",
  "DEPARTAMENTO",
  "SALARIO.DIARIO.IMSS",
  "FACTOR.CRED.INFONAVIT",
  "N..CREDITO.INFONAVIT",
  "LUGAR.DE.NACIMIENTO",
  "CURP",
  "CALLE",
  "NUMERO.INTERNO",
  "COLONIA",
  "MUNICIPIO",
  "ESTADO",
  "CODIGO.POSTAL",
  "ESTADO.CIVIL",
  "TARJETA.CUENTA"
  )

tipos <- c(
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo",
              "Cualitativo",
              "Cuantitativo",
              "Cualitativo",
              "Cualitativo"
              )

escalas <- c(
            "Intervalo",
             "Nominal",
             "Nominal",
             "Intervalo",
            "Intervalo",
             "Nominal",
            "Nominal",
            "Razón",
            "Razón",
            "Razón",
            "Razón",
            "Ordinal",
            "Nominal",
            "Razón",
            "Razón",
            "Nominal",
            "Nominal",
            "Nominal",
            "Nominal",
            "Razón",
            "Nominal",
            "Nominal",
            "Nominal",
            "Ordinal",
            "Nominal",
            "Nominal"
            )

table1 <- data.frame (variables, tipos, escalas)
knitr::kable(table1)
variables tipos escalas
No..De.Empleado Cuantitativo Intervalo
APELLIDOS Cualitativo Nominal
NOMBRE Cualitativo Nominal
FECHA.DE.NACIMIENTO Cualitativo Intervalo
EDAD Cuantitativo Intervalo
GENERO Cualitativo Nominal
RFC Cualitativo Nominal
FECHA.DE.ALTA Cuantitativo Razón
PRIMER.MES Cuantitativo Razón
CUARTO.MES Cuantitativo Razón
BAJA Cuantitativo Razón
PUESTO Cualitativo Ordinal
DEPARTAMENTO Cualitativo Nominal
SALARIO.DIARIO.IMSS Cuantitativo Razón
FACTOR.CRED.INFONAVIT Cuantitativo Razón
N..CREDITO.INFONAVIT Cualitativo Nominal
LUGAR.DE.NACIMIENTO Cualitativo Nominal
CURP Cualitativo Nominal
CALLE Cualitativo Nominal
NUMERO.INTERNO Cuantitativo Razón
COLONIA Cualitativo Nominal
MUNICIPIO Cualitativo Nominal
ESTADO Cualitativo Nominal
CODIGO.POSTAL Cuantitativo Ordinal
ESTADO.CIVIL Cualitativo Nominal
TARJETA.CUENTA Cualitativo Nominal
#Las escalas de medición permiten organizar datos en orden jerárquico. Éstas pueden ser clasificadas de acuerdo a una degradación de las características de distintas variables. Entre las variables usadas están nominal (aquellas que son mutuamente excluyentes y no asignan un orden o jerarquía), ordinal (establecen un orden, puede ser creciente o decreciente), intervalo (establecen un orden determinado por un intervalo numérico) y razón (existe un intervalo numérico; el cero representa la ausencia de valor; es un cero absoluto).

4. Limpieza de datos

Remover valores irrelevantes (eliminar renglones duplicados) y conversión de datos son técnicas elegidas para realizar la limpieza de datos debido a las necesidades de la base de datos y el beneficio que generó para el análisis descriptivo, obteniendo información más clara y concisa.

### Eliminar renglones duplicados
df2<-df1
df2<-distinct(df2)

### ¿Cuántos NA's tengo en la base de datos? Primera limpieza
sum(is.na(df2))
## [1] 226
### Eliminar columnas
df3<-df2
df3 <- subset(df3, select =-c (X))
df3 <- subset(df3, select =-c (X.1))
df3 <- subset(df3, select =-c (NOMBRE))
df3 <- subset(df3, select =-c (APELLIDOS))
df3 <- subset(df3, select =-c (RFC))
df3 <- subset(df3, select =-c (CUARTO.MES))
df3 <- subset(df3, select =-c (FACTOR.CRED.INFONAVIT))
df3 <- subset(df3, select =-c (CURP))
df3 <- subset(df3, select =-c (CALLE))
df3 <- subset(df3, select =-c (NUMERO.INTERNO))
df3 <- subset(df3, select =-c (TARJETA.CUENTA))

### ¿Cuántos NA's tengo en la base de datos? Segunda limpieza
sum(is.na(df3))
## [1] 0

5. Análisis Exploratorio de las Bases de Datos

Nota: Si salen los counts si se pone solo el documento de RH, si se junta con las otras, sale error, para mejor visualizacion ver canva apartado RH.

describe(df3)
## df3 
## 
##  17  Variables      113  Observations
## --------------------------------------------------------------------------------
## No..De.Empleado 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0      113        1    75.86    61.43      6.6     12.2 
##      .25      .50      .75      .90      .95 
##     31.0     63.0    127.0    157.8    163.4 
## 
## lowest :   1   2   3   4   5, highest: 165 166 167 168 169
## --------------------------------------------------------------------------------
## FECHA.DE.NACIMIENTO 
##        n  missing distinct 
##      113        0      113 
## 
## lowest : 01/04/2003 01/05/1990 01/05/2000 01/07/1967 02/06/1982
## highest: 30/11/1968 30/12/1992 31/05/1992 31/07/1990 31/10/1967
## --------------------------------------------------------------------------------
## EDAD 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0       42    0.999    35.74    15.03     19.0     20.0 
##      .25      .50      .75      .90      .95 
##     25.0     33.0     45.0     55.0     57.4 
## 
## lowest :  0 18 19 20 21, highest: 58 59 60 67 73
## --------------------------------------------------------------------------------
## GENERO 
##        n  missing distinct 
##      113        0        2 
##                               
## Value       FEMENINO MASCULINO
## Frequency         61        52
## Proportion      0.54      0.46
## --------------------------------------------------------------------------------
## FECHA.DE.ALTA 
##        n  missing distinct 
##      113        0       94 
## 
## lowest : 01/06/2022 01/07/2010 01/07/2011 01/08/2022 01/12/2017
## highest: 28/08/2020 29/11/2018 30/01/2013 30/06/2022 30/07/2019
## --------------------------------------------------------------------------------
## PRIMER.MES 
##        n  missing distinct 
##      113        0       94 
## 
## lowest : 01/03/2013 01/06/2019 01/07/2022 01/09/2022 02/02/2022
## highest: 29/12/2018 30/07/2022 31/07/2010 31/07/2011 31/12/2017
## --------------------------------------------------------------------------------
## BAJA 
##        n  missing distinct     Info     Mean      Gmd 
##      113        0        2    0.305   0.3451   0.6163 
##                       
## Value          0     3
## Frequency    100    13
## Proportion 0.885 0.115
## --------------------------------------------------------------------------------
## PUESTO 
##        n  missing distinct 
##      113        0       21 
## 
## lowest : AYUDANTE DE MANTENIMIENTO AYUDANTE GENERAL          CHOFER                    COSTURERO/A               ENFERMERO/A              
## highest: RECIBO                    RESIDENTE                 SERVICIO AL CLIENTE       SOLDADOR                  SUPERVISOR/A             
## --------------------------------------------------------------------------------
## DEPARTAMENTO 
##        n  missing distinct 
##      113        0       19 
## 
## lowest : AY FLEXO          CALIDAD           CEDIS             CELDAS            CORTADORAS       
## highest: PRODUCCION RETORN ROTATIVA          STABILUS          TROQUEL           VARIOS           
## --------------------------------------------------------------------------------
## SALARIO.DIARIO.IMSS 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0       17    0.848    181.2    22.55    151.6    151.6 
##      .25      .50      .75      .90      .95 
##    176.7    180.7    180.7    180.7    221.5 
## 
## lowest : 144.45 151.61 151.67 152.86 175.79, highest: 240.75 260.01 279.61 337.05 441.37
##                                                                          
## Value      144.45 151.61 151.67 152.86 175.79 176.72 180.68 181.68 184.68
## Frequency       3     11      5      1      1     23     59      1      1
## Proportion  0.027  0.097  0.044  0.009  0.009  0.204  0.522  0.009  0.009
##                                                                   
## Value      185.68 208.65 240.71 240.75 260.01 279.61 337.05 441.37
## Frequency       1      1      1      1      1      1      1      1
## Proportion  0.009  0.009  0.009  0.009  0.009  0.009  0.009  0.009
## --------------------------------------------------------------------------------
## N..CREDITO.INFONAVIT 
##         n   missing  distinct      Info      Mean       Gmd 
##       113         0         5     0.102  67697774 131776900 
## 
## lowest :          0 1905321932 1910498716 1912437884 1921589926
## highest:          0 1905321932 1910498716 1912437884 1921589926
##                                                                  
## Value               0 1905321932 1910498716 1912437884 1921589926
## Frequency         109          1          1          1          1
## Proportion      0.965      0.009      0.009      0.009      0.009
## --------------------------------------------------------------------------------
## LUGAR.DE.NACIMIENTO 
##        n  missing distinct 
##      113        0       13 
## 
## lowest : CHIAPAS          CIUDAD DE MEXICO COAHUILA         DURANGO          GUANAJUATO      
## highest: SAN LUIS POTOSI  TABASCO          TAMAULIPAS       VERACRUZ         ZACATECAS       
## --------------------------------------------------------------------------------
## COLONIA 
##        n  missing distinct 
##      113        0       67 
## 
## lowest : ALAMOS DEL PARQUE          ANALCO 2                   ANZURES                    BALCONES DE HUINALA        C. H. BLAS CHUMACERO C.T.M
## highest: VILLAS DE HUINALA          VILLAS DE SAN CARLOS       VISTAS DEL RIO             VIVIENDA DIGNA             ZONA CENTRO               
## --------------------------------------------------------------------------------
## MUNICIPIO 
##        n  missing distinct 
##      113        0        9 
## 
## lowest : APODACA                  CAÑADA BLANCA            GUADALUPE                JUAREZ                   MONTERREY               
## highest: MONTERREY                PESQUERIA                RAMOS ARIZPE             SALTILLO                 SAN NICOLAS DE LOS GARZA
## --------------------------------------------------------------------------------
## ESTADO 
##        n  missing distinct 
##      113        0        2 
##                                 
## Value        COAHUILA NUEVO LEON
## Frequency           9        104
## Proportion       0.08       0.92
## --------------------------------------------------------------------------------
## CODIGO.POSTAL 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      113        0       43    0.972    63365     6375    25901    64846 
##      .25      .50      .75      .90      .95 
##    66640    66646    66649    67117    67256 
## 
## lowest : 25016 25088 25115 25290 25900, highest: 67255 67258 67266 67267 67493
##                                                                             
## Value      25000 25100 25300 25900 64100 64800 65000 66100 66400 66500 66600
## Frequency      1     2     2     4     2     1     1     1     1     1    71
## Proportion 0.009 0.018 0.018 0.035 0.018 0.009 0.009 0.009 0.009 0.009 0.628
##                                         
## Value      66700 67100 67200 67300 67500
## Frequency     10     5     3     7     1
## Proportion 0.088 0.044 0.027 0.062 0.009
## 
## For the frequency table, variable is rounded to the nearest 100
## --------------------------------------------------------------------------------
## ESTADO.CIVIL 
##        n  missing distinct 
##      113        0        4 
##                                                               
## Value          CASADO/A DIVORCIADO/A    SOLTERO/A  UNION LIBRE
## Frequency            44            3           46           20
## Proportion        0.389        0.027        0.407        0.177
## --------------------------------------------------------------------------------
#count(df3, GENERO, sort = TRUE)
#count(df3, PUESTO, sort = TRUE)
#count(df3, DEPARTAMENTO, sort = TRUE)
#count(df3, SALARIO.DIARIO.IMSS, sort = TRUE)
#count(df3, LUGAR.DE.NACIMIENTO, sort = TRUE)

tibble(df3)
## # A tibble: 113 × 17
##    No..De.Em…¹ FECHA…²  EDAD GENERO FECHA…³ PRIME…⁴  BAJA PUESTO DEPAR…⁵ SALAR…⁶
##          <int> <chr>   <int> <chr>  <chr>   <chr>   <int> <chr>  <chr>     <dbl>
##  1           1 10/09/…    67 MASCU… 01/07/… 31/07/…     0 SUPER… PRODUC…    177.
##  2           2 14/05/…    43 FEMEN… 01/07/… 31/07/…     0 SUPER… PRODUC…    177.
##  3           3 21/11/…    73 MASCU… 22/11/… 22/12/…     0 EXTER… EXTERNO    177.
##  4           4 01/05/…    32 FEMEN… 30/01/… 01/03/…     0 SUPER… PRODUC…    337.
##  5           5 06/09/…    57 FEMEN… 05/05/… 04/06/…     0 SUPER… COSTURA    441.
##  6           6 22/06/…    38 MASCU… 03/07/… 02/08/…     0 SERVI… CEDIS      177.
##  7           7 01/07/…    55 FEMEN… 06/08/… 05/09/…     0 COSTU… COSTURA    260.
##  8           8 10/12/…    26 MASCU… 23/08/… 22/09/…     0 AYUDA… PRODUC…    241.
##  9           9 03/11/…    27 MASCU… 11/01/… 10/02/…     0 AYUDA… CEDIS      177.
## 10          10 18/08/…    37 FEMEN… 20/02/… 22/03/…     0 COSTU… COSTURA    153.
## # … with 103 more rows, 7 more variables: N..CREDITO.INFONAVIT <int>,
## #   LUGAR.DE.NACIMIENTO <chr>, COLONIA <chr>, MUNICIPIO <chr>, ESTADO <chr>,
## #   CODIGO.POSTAL <int>, ESTADO.CIVIL <chr>, and abbreviated variable names
## #   ¹​No..De.Empleado, ²​FECHA.DE.NACIMIENTO, ³​FECHA.DE.ALTA, ⁴​PRIMER.MES,
## #   ⁵​DEPARTAMENTO, ⁶​SALARIO.DIARIO.IMSS

En esta primera parte del análisis estadístico descriptivo, vemos que el conteo total de empleados actuales es de 113 y hay un mayor número de mujeres (54%) contra empleados que son hombres (46%).

En cuanto a los puestos, vemos que existe una gran cantidad de ayudantes generales, pues es el puesto que ocupa mayor capital humano, contra aquellos que ocupan menos que van desde servicio al cliente hasta operadores.

Entre los departamentos con mayor cantidad de empleados, vemos que está varios y producción retorn. El departamento de “Varios” fue creado para catalogar a aquellos empleados que en la base de datos no tenían definida un área en concreto.

Vemos que la mayoría de los empleados ganan $180.68 pesos de salario diario por el IMSS y de todos los empleados, se calcula que tienen un promedio de salario diario de $236.62 pesos.

En cuanto al lugar de origen, vemos que la mayoría de los empleados provienen del Estado de Nuevo León (70%) y Veracruz (11%), viendo que el 19% restante de los empleados son provenientes de Zona Centro o estados colidantes de Nuevo León.

5.1 Tabla de frecuencia (1)

Las tablas de frecuencia son una ordenación en forma de tabla de los datos estadísticos, asignando a cada dato su frecuencia correspondiente, es decir, el número de veces que aparece un determinado valor en un estudio estadístico.

### Tabla de frecuencia: Salario diario de acuerdo al género
proportion <- prop.table(table(df3$GENERO,df3$SALARIO.DIARIO.IMSS))
proportion %>%
  kbl() %>%
  kable_styling()
144.45 151.61 151.67 152.86 175.79 176.72 180.68 181.68 184.68 185.68 208.65 240.71 240.75 260.01 279.61 337.05 441.37
FEMENINO 0.0265487 0.0619469 0.0088496 0.0088496 0.0000000 0.0619469 0.3008850 0.0088496 0.0088496 0.0088496 0.0088496 0.0088496 0.0000000 0.0088496 0.0000000 0.0088496 0.0088496
MASCULINO 0.0000000 0.0353982 0.0353982 0.0000000 0.0088496 0.1415929 0.2212389 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0088496 0.0000000 0.0088496 0.0000000 0.0000000

Esta tabla de frecuencia representa el valor decimal del salario diario de acuerdo al género, es decir, la cantidad de empleados en valor decimal que reciben cierto salario diario de acuerdo a su género.

BASE DE DATOS: BAJAS DE RECURSOS HUMANOS

A partir de la siguiente base de datos, se analizará específicamente la información de aquellas personas que se dieron de baja en años anteriores con el objetivo de entender las principales razones de la alta rotación en la empresa.

### Importar base de datos

df4 <-read.csv("C:\\Users\\danyc\\Downloads\\HR_Bajas 2.csv")
summary(df4)
##   NO.DE.BAJAS      APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  5.00   Length:78          Length:78          Min.   :25585      
##  1st Qu.: 49.75   Class :character   Class :character   1st Qu.:31751      
##  Median :167.50   Mode  :character   Mode  :character   Median :33797      
##  Mean   :139.60                                         Mean   :33611      
##  3rd Qu.:212.75                                         3rd Qu.:36519      
##  Max.   :238.00                                         Max.   :44632      
##       EDAD          GENERO          FECHA.DE.ALTA   MOTIVO.DE.BAJA    
##  Min.   : 0.00   Length:78          Min.   :43961   Length:78         
##  1st Qu.:22.25   Class :character   1st Qu.:44567   Class :character  
##  Median :30.00   Mode  :character   Median :44726   Mode  :character  
##  Mean   :30.50                      Mean   :44664                     
##  3rd Qu.:36.00                      3rd Qu.:44759                     
##  Max.   :52.00                      Max.   :44790                     
##  DIAS.TRABAJADOS       BAJA          PUESTO          DEPARTAMENTO      
##  Min.   :  0.00   Min.   :44569   Length:78          Length:78         
##  1st Qu.:  9.00   1st Qu.:44613   Class :character   Class :character  
##  Median : 19.00   Median :44741   Mode  :character   Mode  :character  
##  Mean   : 45.10   Mean   :44709                                        
##  3rd Qu.: 39.75   3rd Qu.:44784                                        
##  Max.   :730.00   Max.   :44814                                        
##  NO.SEGURO.SOCIAL   SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:78          Min.   :151.6       Min.   :   0.0       
##  Class :character   1st Qu.:180.7       1st Qu.:   0.0       
##  Mode  :character   Median :180.7       Median :   0.0       
##                     Mean   :174.3       Mean   : 130.4       
##                     3rd Qu.:180.7       3rd Qu.:   0.0       
##                     Max.   :183.7       Max.   :2795.3       
##  NO.CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:78           Length:78          Length:78         
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :1.871e+08                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :6.919e+09                                                             
##  NUMERO.INTERNO       COLONIA          CODIGO.POSTAL    MUNICIPIO        
##  Length:78          Length:78          Min.   :25019   Length:78         
##  Class :character   Class :character   1st Qu.:33604   Class :character  
##  Mode  :character   Mode  :character   Median :33604   Mode  :character  
##                                        Mean   :46508                     
##                                        3rd Qu.:66645                     
##                                        Max.   :67450                     
##     ESTADO          ESTADO.CIVIL       TARJETA.CUENTA    
##  Length:78          Length:78          Length:78         
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
## 
### ¿Cuántos NA's tengo en la base de datos?
sum(is.na(df4))
## [1] 0
### Borrar todos los registros NA's de una tabla
df5<-df4
df5<-na.omit(df5)
summary(df5)
##   NO.DE.BAJAS      APELLIDOS            NOMBRE          FECHA.DE.NACIMIENTO
##  Min.   :  5.00   Length:78          Length:78          Min.   :25585      
##  1st Qu.: 49.75   Class :character   Class :character   1st Qu.:31751      
##  Median :167.50   Mode  :character   Mode  :character   Median :33797      
##  Mean   :139.60                                         Mean   :33611      
##  3rd Qu.:212.75                                         3rd Qu.:36519      
##  Max.   :238.00                                         Max.   :44632      
##       EDAD          GENERO          FECHA.DE.ALTA   MOTIVO.DE.BAJA    
##  Min.   : 0.00   Length:78          Min.   :43961   Length:78         
##  1st Qu.:22.25   Class :character   1st Qu.:44567   Class :character  
##  Median :30.00   Mode  :character   Median :44726   Mode  :character  
##  Mean   :30.50                      Mean   :44664                     
##  3rd Qu.:36.00                      3rd Qu.:44759                     
##  Max.   :52.00                      Max.   :44790                     
##  DIAS.TRABAJADOS       BAJA          PUESTO          DEPARTAMENTO      
##  Min.   :  0.00   Min.   :44569   Length:78          Length:78         
##  1st Qu.:  9.00   1st Qu.:44613   Class :character   Class :character  
##  Median : 19.00   Median :44741   Mode  :character   Mode  :character  
##  Mean   : 45.10   Mean   :44709                                        
##  3rd Qu.: 39.75   3rd Qu.:44784                                        
##  Max.   :730.00   Max.   :44814                                        
##  NO.SEGURO.SOCIAL   SALARIO.DIARIO.IMSS FACTOR.CRED.INFONAVIT
##  Length:78          Min.   :151.6       Min.   :   0.0       
##  Class :character   1st Qu.:180.7       1st Qu.:   0.0       
##  Mode  :character   Median :180.7       Median :   0.0       
##                     Mean   :174.3       Mean   : 130.4       
##                     3rd Qu.:180.7       3rd Qu.:   0.0       
##                     Max.   :183.7       Max.   :2795.3       
##  NO.CREDITO.INFONAVIT LUGAR.DE.NACIMIENTO     CURP              CALLE          
##  Min.   :0.000e+00    Length:78           Length:78          Length:78         
##  1st Qu.:0.000e+00    Class :character    Class :character   Class :character  
##  Median :0.000e+00    Mode  :character    Mode  :character   Mode  :character  
##  Mean   :1.871e+08                                                             
##  3rd Qu.:0.000e+00                                                             
##  Max.   :6.919e+09                                                             
##  NUMERO.INTERNO       COLONIA          CODIGO.POSTAL    MUNICIPIO        
##  Length:78          Length:78          Min.   :25019   Length:78         
##  Class :character   Class :character   1st Qu.:33604   Class :character  
##  Mode  :character   Mode  :character   Median :33604   Mode  :character  
##                                        Mean   :46508                     
##                                        3rd Qu.:66645                     
##                                        Max.   :67450                     
##     ESTADO          ESTADO.CIVIL       TARJETA.CUENTA    
##  Length:78          Length:78          Length:78         
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
## 
### Eliminar columnas
df3<-df2
df3 <- subset(df3, select =-c (APELLIDOS))
df3 <- subset(df3, select =-c (NOMBRE))
df3 <- subset(df3, select =-c (FACTOR.CRED.INFONAVIT))
df3 <- subset(df3, select =-c (CURP))
df3 <- subset(df3, select =-c (CALLE))
df3 <- subset(df3, select =-c (NUMERO.INTERNO))
df3 <- subset(df3, select =-c (TARJETA.CUENTA))


### ¿Cuántos NA's tengo en la base de datos?
sum(is.na(df5))
## [1] 0
# Con los datos presentados anteriormente, vemos que la edad promedio de los colaboradores es de 35 años, además de que ganan un promedio de $180 pesos.

5.2.1 Tabla cruzada (1)

table(df5$PUESTO, df5$MOTIVO.DE.BAJA)
##                              
##                               BAJA POR FALTAS RENUNCIA VOLUNTARIA
##   AYUDANTE DE EMBARQUES                     0                   0
##   AYUDANTE GENERAL                         50                  18
##   COSTURERO/A                               1                   0
##   GUARDIA DE SEGURIDAD                      0                   1
##   INSPECTOR DE CALIDAD                      1                   0
##   JEFE DE SEGURIDAD E HIGIENE               0                   1
##   MONTACARGUISTA                            1                   1
##   RESIDENTE                                 1                   0
##   SOLDADOR                                  1                   0
##                              
##                               TERMINO DE CONTRATO
##   AYUDANTE DE EMBARQUES                         1
##   AYUDANTE GENERAL                              1
##   COSTURERO/A                                   0
##   GUARDIA DE SEGURIDAD                          0
##   INSPECTOR DE CALIDAD                          0
##   JEFE DE SEGURIDAD E HIGIENE                   0
##   MONTACARGUISTA                                0
##   RESIDENTE                                     0
##   SOLDADOR                                      0

En la tabla vemos que se destacan tres razones principales de bajas de empleados, las cuales son: bajas por faltas, renuncia voluntaria o término de contrato. En su mayoría, hubo una baja por faltas del puesto de ayudante general y renuncia voluntaria para el mismo puesto. Al igual que en la base de datos anterior, vemos que el puesto con mayor rotación a nivel histórico es de ayudante general. Esto sugiere que existe un alto número de contrataciones para el puesto debido a una mala gestión administrativa o bajo rendimiento de los empleados.

5.2.2 Tabla cruzada (2)

table(df5$GENERO, df5$MOTIVO.DE.BAJA)
##            
##             BAJA POR FALTAS RENUNCIA VOLUNTARIA TERMINO DE CONTRATO
##   FEMENINO               40                  12                   1
##   MASCULINO              15                   9                   1

La tabla cruzada anterior nos muestra la relación entre los motivos de baja contra el género, es decir, las principales razones de baja de acuerdo al género de cada empleado. Vemos que hubo un total de 53 bajas del género femenino, destacando las bajas por faltas (representa un 75% de las bajas femeninas). Para el género masculino, hubo un total de 25 faltas, destacando principalmente las bajas por faltas (representa un 60% de las bajas masculinas).

5.3 Gráficos de datos cuantitativos y cualitativos (2)

## 5.3.1 Pie chart

### Pie chart: Representación de bajas acorde al estado de residencia
pie(table(df5$ESTADO), col=c("orange","coral1"),
    main="Representación de bajas acorde al estado de residencia")

La gráfica anterior nos muestra que hay un mayor número de ex-empleados que viven en el Estado de Nuevo León. Sin embargo, hay un porcentaje que reside en Coahuila. Esto se puede interpretar con que hay un alto nivel de rotación existente debido a la lejanía de residencia de los empleados.

Pie chart: Representación de bajas acorde al género

pie(table(df5$GENERO), col=c("orange","coral1"),
    main="Representación de bajas acorde al género")

La anterior gráfica de pastel reafirma lo que mencionamos anteriormente. De acuerdo a las bajas realizadas, la mayoría de los ex-empleados son del género femenino.

5.4 Gráficos de dispersión (2)

### Gráfica de dispersión: Número de bajas VS. Días trabajados
plot(x= df5$NO.DE.BAJAS,
     y=df5$DIAS.TRABAJADOS)

La gráfica de dispersión nos muestra la intensidad de relación entre la variable de días trabajados y número de bajas. Esto nos dice que hubo un alto número de bajas de empleados que trabajaron menos de 200 días, es decir, la mayoría de los ex-empleados estuvieron en FORM menos de 1 año.

### Boxplot: Correlación en bajas acorde a variables de género y edad
ggplot(df5, aes(GENERO,SALARIO.DIARIO.IMSS,fill=GENERO)) +
geom_bar(stat = "identity") +
  scale_fill_brewer(palette = "Set2") + ggtitle("Salario diario por género")

La gráfica anterior nos muestra la correlación entre el género y el salario diario de los empleados. En este, entendemos que el género femenino tiene un salario diario total más alto que los de género masculino.

6. Referencias

Ana Karen García. (2022, September 8). Industria automotriz anota un buen agosto: crecen producción, exportaciones y ventas internas. El Economista; El Economista. https://www.eleconomista.com.mx/empresas/Industria-automotriz-anota-un-buen-agosto-crecen-produccion-exportaciones-y-ventas-internas-20220907-0031.html

Hernández, F., & Usuga, O. (2022). 9 Tablas de frecuencia | Manual de R. Retrieved 24 September 2022, from https://fhernanb.github.io/Manual-de-R/tablas.html#ejemplo-tabla-de-frecuencia-relativa-de-una-v%C3%ADa

9 Estilos y formatos de tabla | Tablas y graficos con R y R Studio. (2022). Retrieved 24 September 2022, from https://tables.investigaonline.com/tse-formateo.html

5. Production

Importar librerias

library(foreign)
library(dplyr)        # data manipulation 
library(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization 
library(janitor)      # data exploration and cleaning 
#install.packages("Hmisc")
library(Hmisc)        # several useful functions for data analysis 
#install.packages("psych")
library(psych)        # functions for multivariate analysis 
#install.packages("naniar")
library(naniar)       # summaries and visualization of missing values NAs

#install.packages("dlookr")
library(dlookr)  # summaries and visualization of missing values NAs
#install.packages("corrplot")
library(corrplot)     # correlation plots
#install.packages("jtools")
library(jtools)       # presentation of regression analysis 
#install.packages("lmtest")
library(lmtest)       # diagnostic checks - linear regression analysis 
#install.packages("car")
library(car)          # diagnostic checks - linear regression analysis
#install.packages("olsrr")
library(olsrr)        # diagnostic checks - linear regression analysis 
#install.packages("kableExtra")
library(kableExtra)   # HTML table attributes
library(tidyverse)

Importar base de datos

#file.choose()
produccion<-read.csv("C:\\Users\\danyc\\Downloads\\Base produccion form - Base produccion form - Base produccion form - Base produccion form.csv.csv.csv" )

library(dplyr)

Produccion 3988 registros y 15 variables

1. Entender y limpiar la base de datos

describe(produccion)
## produccion 
## 
##  15  Variables      3985  Observations
## --------------------------------------------------------------------------------
## Fecha 
##        n  missing distinct 
##     3985        0       58 
## 
## lowest : 01/09/2022 02/08/2022 02/09/2022 03/08/2022 03/09/2022
## highest: 29/07/2022 29/08/2022 30/07/2022 30/08/2022 31/08/2022
## --------------------------------------------------------------------------------
## CLIENTE 
##        n  missing distinct 
##     3984        1       11 
## 
## lowest : DENSO                HANON SYSTEMS        HELLA                MERIDIAN LIGHTWEIGHT STABILUS 1          
## highest: TRMX                 VARROC               VL-017-13939         VL-017-14086         YANFENG             
## --------------------------------------------------------------------------------
## ID.FORM 
##        n  missing distinct 
##     3798      187      292 
## 
## lowest : 00-00-19213              00-00-19216              00-00-19217              00-00-19218              00-00-19246             
## highest: YN-68-8155-18805         YN-68-8155-68-8160-18277 YN-RAMOS II-18104        YN-RAMOS II-18107        YN-RAMOS II-18109       
## --------------------------------------------------------------------------------
## PRODUCTO 
##        n  missing distinct 
##     3985        0      381 
## 
## lowest : 0371813. CAJA IMP. AZUL. PC0015. ( 1 Pza). 1 Pza/Golpe.                                                                     0371813. CAJA IMP. AZUL. ST00200. PC0015. ( 1 Pza). 1 Pza/Golpe. Calidad rechaza Suaje por Medidas.                         048541 (IMC 200). CAJA. S.M. "048541" ( 66.5 x 154 c.m.). CORTE para Troquel. 0.5Pza/Golpe. ( 2 partes).                    048541 . CAJA. S.M. "048541". SOLAPA PEGADA. ST0205 ( 66.5 x 154 c.m.). 0.5Pza/Golpe. ( 2 partes).                          051660 (SUN RISE MEDICAL). CAJA S.M. " 051660". SOLAPA PEGADA POR FUERA. ST0201. 2pza/Golpe. 1 Pza.                        
## highest: VW416 G4 CHATTANOOGA. CELDA. CORTE para TROQUEL.                                                                            VW416 G4 CHATTANOOGA. CHAROLA ENSAMBLADA. Solictar Sello Manual a Calidad. ( 1 Charola + 5 Celdas + 1 Zig Zad + 1 Divisor). Y0194915 PTN. WS FC 42C 1BT P2. BASE CARRIER. CAJA con Celda ITB 48 cav. SR0090. Etiqueta Blanca.                           Y0199488 PTN. WS IP 80 CELL IBT. BEZEL OC LOWER. CAJA con Celda ITB 80 cav. Etiqueta Blanca. SR0088.                        Y0199489 PTN.WS IP 60 CELL IBT. KIN. CAJA con Celda ITB. Etiiqueta Blanca.                                                 
## --------------------------------------------------------------------------------
## PIEZAS.PROG. 
##        n  missing distinct 
##     3985        0      300 
## 
## lowest : 1     10    100   1000  100ca, highest: 96 la 96cel 96sie 98    99   
## --------------------------------------------------------------------------------
## TMO..MIN. 
##        n  missing distinct 
##     3166      819       20 
## 
## lowest : 0    0:00 10   100  120 , highest: 60   70   75   80   90  
##                                                                             
## Value          0  0:00    10   100   120    15   150    20    25    30    35
## Frequency     20     4   720     2     4   518     1   509   900    44   101
## Proportion 0.006 0.001 0.227 0.001 0.001 0.164 0.000 0.161 0.284 0.014 0.032
##                                                                 
## Value         40    45     5    50    60    70    75    80    90
## Frequency    118    10     1   130    47     8    17     2    10
## Proportion 0.037 0.003 0.000 0.041 0.015 0.003 0.005 0.001 0.003
## --------------------------------------------------------------------------------
## HR..FIN 
##        n  missing distinct 
##     3131      854      158 
## 
## lowest : 0:00 0:55 1:00 1:05 1:10, highest: 9:36 9:40 9:45 9:50 9:55
## --------------------------------------------------------------------------------
## ESTACION.ARRANQUE 
##        n  missing distinct 
##     3985        0       15 
## 
## lowest : C1        c1y2      C1Y2      c2        C2       
## highest: RANURADOR ROTATIVA  SIERRA    STABILUS  TROQUEL  
## 
## C1 (265, 0.066), c1y2 (2, 0.001), C1Y2 (309, 0.078), c2 (1, 0.000), C2 (45,
## 0.011), C3 (336, 0.084), CAJAS (328, 0.082), CELDAS (157, 0.039), FLEXO (307,
## 0.077), LAMINADO (83, 0.021), RANURADOR (126, 0.032), ROTATIVA (800, 0.201),
## SIERRA (41, 0.010), STABILUS (219, 0.055), TROQUEL (966, 0.242)
## --------------------------------------------------------------------------------
## Laminas.procesadas 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##     3985        0      350    0.976    102.1      127      0.0      0.0 
##      .25      .50      .75      .90      .95 
##      0.0     51.0    184.0    232.0    400.8 
## 
## lowest :    0    1    2    3    4, highest: 1229 1240 1244 1262 1263
## --------------------------------------------------------------------------------
## INICIO.SEP.UP 
##        n  missing distinct 
##     3459      526      598 
## 
## lowest : :51   0     0:00  0:38  04.05, highest: 9:54  9:55  9:56  9:57  9:59 
## --------------------------------------------------------------------------------
## FIN.INICIO.DE.SEP.UP 
##        n  missing distinct 
##     3471      514      645 
## 
## lowest : 0     0:39  01.07 02.05 09.01, highest: 9:56  9:57  9:58  9:59  956  
## --------------------------------------------------------------------------------
## INICIO.de.PROCESO 
##        n  missing distinct 
##     3750      235      755 
## 
## lowest : 0     0:00  0:35  02.06 03.08, highest: 9:56  9:57  9:58  9:59  923  
## --------------------------------------------------------------------------------
## FIN.de.PROCESO 
##        n  missing distinct 
##     3729      256      763 
## 
## lowest : 0    0.01 0:00 0:35 0:59, highest: 9:55 9:56 9:57 9:58 9:59
## --------------------------------------------------------------------------------
## TIEMPO.CALIDAD 
##        n  missing distinct 
##     3652      333       26 
## 
## lowest : 0     1     1.4   10    10:04, highest: 8:18  8:38  9     9:05  9:47 
## --------------------------------------------------------------------------------
## TIEMPO.MATERIALES 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      496     3489       31    0.611    3.169    5.371        0        0 
##      .25      .50      .75      .90      .95 
##        0        0        1       11       15 
## 
## lowest :  0  1  2  3  4, highest: 39 44 48 49 60
## --------------------------------------------------------------------------------

Paso 1. De caracter a fecha (Tecnica 4. Convertir tipos de datos)

bdp<-produccion
bdp$Fecha<- as.Date(bdp$Fecha, format= "%d/%m/%Y")
summary(bdp)
##      Fecha              CLIENTE            ID.FORM            PRODUCTO        
##  Min.   :2022-07-15   Length:3985        Length:3985        Length:3985       
##  1st Qu.:2022-08-03   Class :character   Class :character   Class :character  
##  Median :2022-08-20   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :2022-08-19                                                           
##  3rd Qu.:2022-09-06                                                           
##  Max.   :2022-09-21                                                           
##                                                                               
##  PIEZAS.PROG.        TMO..MIN.           HR..FIN          ESTACION.ARRANQUE 
##  Length:3985        Length:3985        Length:3985        Length:3985       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##  Laminas.procesadas INICIO.SEP.UP      FIN.INICIO.DE.SEP.UP INICIO.de.PROCESO 
##  Min.   :   0.0     Length:3985        Length:3985          Length:3985       
##  1st Qu.:   0.0     Class :character   Class :character     Class :character  
##  Median :  51.0     Mode  :character   Mode  :character     Mode  :character  
##  Mean   : 102.1                                                               
##  3rd Qu.: 184.0                                                               
##  Max.   :1263.0                                                               
##                                                                               
##  FIN.de.PROCESO     TIEMPO.CALIDAD     TIEMPO.MATERIALES
##  Length:3985        Length:3985        Min.   : 0.000   
##  Class :character   Class :character   1st Qu.: 0.000   
##  Mode  :character   Mode  :character   Median : 0.000   
##                                        Mean   : 3.169   
##                                        3rd Qu.: 1.000   
##                                        Max.   :60.000   
##                                        NA's   :3489
tibble(bdp)
## # A tibble: 3,985 × 15
##    Fecha      CLIENTE    ID.FORM PRODU…¹ PIEZA…² TMO..…³ HR..FIN ESTAC…⁴ Lamin…⁵
##    <date>     <chr>      <chr>   <chr>   <chr>   <chr>   <chr>   <chr>     <int>
##  1 2022-07-16 TRMX       00-059… "TGTX.… 1       "10"    "9:05"  C1Y2          3
##  2 2022-07-22 STABILUS 3 00-00-… "MOTOR… 1       "10"    "10:40" C1Y2          2
##  3 2022-07-28 STABILUS 3 00-00-… "MOTOR… 1       "10"    "11:20" C1Y2          2
##  4 2022-08-12 TRMX       TR-059… "TR137… 1       "10"    "9:35"  C1            1
##  5 2022-08-12 TRMX       TR-059… "TR137… 1       "10"    "9:45"  C1            1
##  6 2022-09-10 DENSO      DN-034… "MCV. … 1       "10"    "8:45"  c1y2          1
##  7 2022-07-23 DENSO      DN-034… "TOYOT… 2       ""      ""      CELDAS        0
##  8 2022-08-05 HELLA      HE-073… "SUDAF… 2       "10"    "11:20" C1Y2          3
##  9 2022-08-05 HELLA      HE-073… "SUDAF… 2       "10"    "11:30" C1Y2          0
## 10 2022-08-05 HELLA      HE-073… "SUDAF… 2       "10"    "11:40" C1Y2          0
## # … with 3,975 more rows, 6 more variables: INICIO.SEP.UP <chr>,
## #   FIN.INICIO.DE.SEP.UP <chr>, INICIO.de.PROCESO <chr>, FIN.de.PROCESO <chr>,
## #   TIEMPO.CALIDAD <chr>, TIEMPO.MATERIALES <int>, and abbreviated variable
## #   names ¹​PRODUCTO, ²​PIEZAS.PROG., ³​TMO..MIN., ⁴​ESTACION.ARRANQUE,
## #   ⁵​Laminas.procesadas

Paso 2. Eliminar columnas inservibles(Tecnica 1. Remover valores irrelevantes)

bdp1<-bdp
bdp1 <- subset(bdp1, select =-c (ID.FORM))
bdp1 <- subset(bdp1, select =-c (INICIO.SEP.UP,FIN.INICIO.DE.SEP.UP, TIEMPO.MATERIALES))
bdp1 <- subset(bdp1, select =-c (HR..FIN, INICIO.de.PROCESO, FIN.de.PROCESO))

Cambiar nombres

colnames(bdp1)<-c('fecha','cliente','producto','piezas_prog','tiempo_min','esta_arranque','laminas_procesadas','tiempo_calidad')

Paso 3. Cambiar de caracter a Numerico (Tecnica 4. Convertir tipos de datos)

bdp1$piezas_prog<-as.numeric(bdp1$piezas_prog)               
## Warning: NAs introducidos por coerción
bdp1$tiempo_min<-as.numeric(bdp1$tiempo_min)                 
## Warning: NAs introducidos por coerción
bdp1$laminas_procesadas<-as.numeric(bdp1$laminas_procesadas) 
bdp1$tiempo_calidad<-as.numeric(bdp1$tiempo_calidad)         
## Warning: NAs introducidos por coerción
bdp2<-bdp1
bdp2$tiempo_min <- substr(bdp2$tiempo_min, start = 1, stop = 2)
tibble(bdp2)  
## # A tibble: 3,985 × 8
##    fecha      cliente    producto        pieza…¹ tiemp…² esta_…³ lamin…⁴ tiemp…⁵
##    <date>     <chr>      <chr>             <dbl> <chr>   <chr>     <dbl>   <dbl>
##  1 2022-07-16 TRMX       "TGTX. CAJA RS…       1 10      C1Y2          3       1
##  2 2022-07-22 STABILUS 3 "MOTORGEAR. KI…       1 10      C1Y2          2       1
##  3 2022-07-28 STABILUS 3 "MOTORGEAR. KI…       1 10      C1Y2          2       2
##  4 2022-08-12 TRMX       "TR13773. CAJA…       1 10      C1            1       1
##  5 2022-08-12 TRMX       "TR13776. CAJA…       1 10      C1            1       1
##  6 2022-09-10 DENSO      "MCV. VALVE. P…       1 10      c1y2          1      NA
##  7 2022-07-23 DENSO      "TOYOTA. MCV. …       2 <NA>    CELDAS        0       0
##  8 2022-08-05 HELLA      "SUDAFRICA. TA…       2 10      C1Y2          3       1
##  9 2022-08-05 HELLA      "SUDAFRICA. \"…       2 10      C1Y2          0       0
## 10 2022-08-05 HELLA      "SUDAFRICA. PA…       2 10      C1Y2          0       0
## # … with 3,975 more rows, and abbreviated variable names ¹​piezas_prog,
## #   ²​tiempo_min, ³​esta_arranque, ⁴​laminas_procesadas, ⁵​tiempo_calidad
bdp2$tiempo_min <- as.integer(bdp2$tiempo_min)
str(bdp2)  
## 'data.frame':    3985 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : num  1 1 1 1 1 1 2 2 2 2 ...
##  $ tiempo_min        : int  10 10 10 10 10 10 NA 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: num  3 2 2 1 1 1 0 3 0 0 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 NA 0 1 0 0 ...
bdp2$piezas_prog <- substr(bdp2$piezas_prog, start = 1, stop = 2)
tibble(bdp2)  
## # A tibble: 3,985 × 8
##    fecha      cliente    producto        pieza…¹ tiemp…² esta_…³ lamin…⁴ tiemp…⁵
##    <date>     <chr>      <chr>           <chr>     <int> <chr>     <dbl>   <dbl>
##  1 2022-07-16 TRMX       "TGTX. CAJA RS… 1            10 C1Y2          3       1
##  2 2022-07-22 STABILUS 3 "MOTORGEAR. KI… 1            10 C1Y2          2       1
##  3 2022-07-28 STABILUS 3 "MOTORGEAR. KI… 1            10 C1Y2          2       2
##  4 2022-08-12 TRMX       "TR13773. CAJA… 1            10 C1            1       1
##  5 2022-08-12 TRMX       "TR13776. CAJA… 1            10 C1            1       1
##  6 2022-09-10 DENSO      "MCV. VALVE. P… 1            10 c1y2          1      NA
##  7 2022-07-23 DENSO      "TOYOTA. MCV. … 2            NA CELDAS        0       0
##  8 2022-08-05 HELLA      "SUDAFRICA. TA… 2            10 C1Y2          3       1
##  9 2022-08-05 HELLA      "SUDAFRICA. \"… 2            10 C1Y2          0       0
## 10 2022-08-05 HELLA      "SUDAFRICA. PA… 2            10 C1Y2          0       0
## # … with 3,975 more rows, and abbreviated variable names ¹​piezas_prog,
## #   ²​tiempo_min, ³​esta_arranque, ⁴​laminas_procesadas, ⁵​tiempo_calidad
bdp2$piezas_prog <- as.integer(bdp2$piezas_prog)
str(bdp2)
## 'data.frame':    3985 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 1 2 2 2 2 ...
##  $ tiempo_min        : int  10 10 10 10 10 10 NA 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: num  3 2 2 1 1 1 0 3 0 0 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 NA 0 1 0 0 ...
bdp2$laminas_procesadas <- substr(bdp2$laminas_procesadas, start = 1, stop = 2)
tibble(bdp2)  
## # A tibble: 3,985 × 8
##    fecha      cliente    producto        pieza…¹ tiemp…² esta_…³ lamin…⁴ tiemp…⁵
##    <date>     <chr>      <chr>             <int>   <int> <chr>   <chr>     <dbl>
##  1 2022-07-16 TRMX       "TGTX. CAJA RS…       1      10 C1Y2    3             1
##  2 2022-07-22 STABILUS 3 "MOTORGEAR. KI…       1      10 C1Y2    2             1
##  3 2022-07-28 STABILUS 3 "MOTORGEAR. KI…       1      10 C1Y2    2             2
##  4 2022-08-12 TRMX       "TR13773. CAJA…       1      10 C1      1             1
##  5 2022-08-12 TRMX       "TR13776. CAJA…       1      10 C1      1             1
##  6 2022-09-10 DENSO      "MCV. VALVE. P…       1      10 c1y2    1            NA
##  7 2022-07-23 DENSO      "TOYOTA. MCV. …       2      NA CELDAS  0             0
##  8 2022-08-05 HELLA      "SUDAFRICA. TA…       2      10 C1Y2    3             1
##  9 2022-08-05 HELLA      "SUDAFRICA. \"…       2      10 C1Y2    0             0
## 10 2022-08-05 HELLA      "SUDAFRICA. PA…       2      10 C1Y2    0             0
## # … with 3,975 more rows, and abbreviated variable names ¹​piezas_prog,
## #   ²​tiempo_min, ³​esta_arranque, ⁴​laminas_procesadas, ⁵​tiempo_calidad
bdp2$laminas_procesadas <- as.integer(bdp2$laminas_procesadas)
str(bdp2) 
## 'data.frame':    3985 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 1 2 2 2 2 ...
##  $ tiempo_min        : int  10 10 10 10 10 10 NA 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: int  3 2 2 1 1 1 0 3 0 0 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 NA 0 1 0 0 ...

Paso 4. Cambiar de N/A a promedios

bdp3 <- bdp2
bdp3$tiempo_min[is.na(bdp3$tiempo_min)]<-mean(bdp3$tiempo_min, na.rm = TRUE)
summary (bdp3) 
##      fecha              cliente            producto          piezas_prog  
##  Min.   :2022-07-15   Length:3985        Length:3985        Min.   : 1.0  
##  1st Qu.:2022-08-03   Class :character   Class :character   1st Qu.:12.0  
##  Median :2022-08-20   Mode  :character   Mode  :character   Median :20.0  
##  Mean   :2022-08-19                                         Mean   :27.2  
##  3rd Qu.:2022-09-06                                         3rd Qu.:40.0  
##  Max.   :2022-09-21                                         Max.   :99.0  
##                                                             NA's   :179   
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad   
##  Min.   : 0.00   Length:3985        Min.   : 0.00      Min.   : 0.0000  
##  1st Qu.:15.00   Class :character   1st Qu.: 0.00      1st Qu.: 0.0000  
##  Median :22.13   Mode  :character   Median :19.00      Median : 1.0000  
##  Mean   :22.13                      Mean   :21.42      Mean   : 0.8628  
##  3rd Qu.:25.00                      3rd Qu.:32.00      3rd Qu.: 1.0000  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.0000  
##                                                        NA's   :343

Paso 5. Cambiar de N/A a 0

bdp4 <- bdp3
bdp4$laminas_procesadas[bdp4$laminas_procesadas < 1]<- NA
summary (bdp4)
##      fecha              cliente            producto          piezas_prog  
##  Min.   :2022-07-15   Length:3985        Length:3985        Min.   : 1.0  
##  1st Qu.:2022-08-03   Class :character   Class :character   1st Qu.:12.0  
##  Median :2022-08-20   Mode  :character   Mode  :character   Median :20.0  
##  Mean   :2022-08-19                                         Mean   :27.2  
##  3rd Qu.:2022-09-06                                         3rd Qu.:40.0  
##  Max.   :2022-09-21                                         Max.   :99.0  
##                                                             NA's   :179   
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad   
##  Min.   : 0.00   Length:3985        Min.   : 1.00      Min.   : 0.0000  
##  1st Qu.:15.00   Class :character   1st Qu.:15.00      1st Qu.: 0.0000  
##  Median :22.13   Mode  :character   Median :21.00      Median : 1.0000  
##  Mean   :22.13                      Mean   :30.08      Mean   : 0.8628  
##  3rd Qu.:25.00                      3rd Qu.:41.00      3rd Qu.: 1.0000  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.0000  
##                                     NA's   :1148       NA's   :343

Paso 6. Borra N/As

bdp5 <- bdp4
bdp5 <- na.omit(bdp5)    
str(bdp5)
## 'data.frame':    2679 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 2 3 3 4 4 ...
##  $ tiempo_min        : num  10 10 10 10 10 10 10 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: int  3 2 2 1 1 3 2 5 5 10 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 1 0 1 1 1 ...
##  - attr(*, "na.action")= 'omit' Named int [1:1306] 6 7 9 10 18 22 25 27 28 30 ...
##   ..- attr(*, "names")= chr [1:1306] "6" "7" "9" "10" ...

Verificar eliminacion de NA´s

colSums(is.na(bdp5))
##              fecha            cliente           producto        piezas_prog 
##                  0                  0                  0                  0 
##         tiempo_min      esta_arranque laminas_procesadas     tiempo_calidad 
##                  0                  0                  0                  0
summary(bdp5)
##      fecha              cliente            producto          piezas_prog   
##  Min.   :2022-07-15   Length:2679        Length:2679        Min.   : 1.00  
##  1st Qu.:2022-08-02   Class :character   Class :character   1st Qu.:13.00  
##  Median :2022-08-18   Mode  :character   Mode  :character   Median :20.00  
##  Mean   :2022-08-18                                         Mean   :26.53  
##  3rd Qu.:2022-09-02                                         3rd Qu.:32.50  
##  Max.   :2022-09-21                                         Max.   :99.00  
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad 
##  Min.   : 0.00   Length:2679        Min.   : 1.00      Min.   : 0.00  
##  1st Qu.:15.00   Class :character   1st Qu.:16.00      1st Qu.: 1.00  
##  Median :20.00   Mode  :character   Median :21.00      Median : 1.00  
##  Mean   :22.16                      Mean   :30.18      Mean   : 1.16  
##  3rd Qu.:25.00                      3rd Qu.:41.00      3rd Qu.: 1.00  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.00
str(bdp5)
## 'data.frame':    2679 obs. of  8 variables:
##  $ fecha             : Date, format: "2022-07-16" "2022-07-22" ...
##  $ cliente           : chr  "TRMX" "STABILUS 3" "STABILUS 3" "TRMX" ...
##  $ producto          : chr  "TGTX. CAJA RSC. ( 1 Pieza) con SOBRE. Kit: TR-059-19014" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "MOTORGEAR. KIT. TAPA GRAL. Grapada. 1 Pza/ Kit. ( Kit 19211)" "TR13773. CAJA RSC Imp. Negra con SOBRE ( 2 Partes). PC0048." ...
##  $ piezas_prog       : int  1 1 1 1 1 2 3 3 4 4 ...
##  $ tiempo_min        : num  10 10 10 10 10 10 10 10 10 10 ...
##  $ esta_arranque     : chr  "C1Y2" "C1Y2" "C1Y2" "C1" ...
##  $ laminas_procesadas: int  3 2 2 1 1 3 2 5 5 10 ...
##  $ tiempo_calidad    : num  1 1 2 1 1 1 0 1 1 1 ...
##  - attr(*, "na.action")= 'omit' Named int [1:1306] 6 7 9 10 18 22 25 27 28 30 ...
##   ..- attr(*, "names")= chr [1:1306] "6" "7" "9" "10" ...
summary(bdp5)
##      fecha              cliente            producto          piezas_prog   
##  Min.   :2022-07-15   Length:2679        Length:2679        Min.   : 1.00  
##  1st Qu.:2022-08-02   Class :character   Class :character   1st Qu.:13.00  
##  Median :2022-08-18   Mode  :character   Mode  :character   Median :20.00  
##  Mean   :2022-08-18                                         Mean   :26.53  
##  3rd Qu.:2022-09-02                                         3rd Qu.:32.50  
##  Max.   :2022-09-21                                         Max.   :99.00  
##    tiempo_min    esta_arranque      laminas_procesadas tiempo_calidad 
##  Min.   : 0.00   Length:2679        Min.   : 1.00      Min.   : 0.00  
##  1st Qu.:15.00   Class :character   1st Qu.:16.00      1st Qu.: 1.00  
##  Median :20.00   Mode  :character   Median :21.00      Median : 1.00  
##  Mean   :22.16                      Mean   :30.18      Mean   : 1.16  
##  3rd Qu.:25.00                      3rd Qu.:41.00      3rd Qu.: 1.00  
##  Max.   :90.00                      Max.   :98.00      Max.   :22.00

2.Clasifica cada variable en cualitativa, cuantitativa discreta o cuantitativa continua y Escalas de Medicion.

Variable<-c("Fecha ","cliente","producto", "Piezas programadas","tiempo min","Estacion de arranque","Laminas procesadas", "Tiempo de calidad")
Type<-c("Cualitativa","Cualitativa","Cualitativa", "Cuantitativa(Discreta)", "Cuantitativa(Discreta)","Cualitativa", "Cuantitativa(Discreta)", "Cuantitativa discreta")
Medicion <-c("Nominal", "Nominal","Nominal", "Intervalo", "Intervalo","Nominal", "Intervalo", "Intervalo") 
table<-data.frame(Variable,Type, Medicion)
knitr::kable(table)
Variable Type Medicion
Fecha Cualitativa Nominal
cliente Cualitativa Nominal
producto Cualitativa Nominal
Piezas programadas Cuantitativa(Discreta) Intervalo
tiempo min Cuantitativa(Discreta) Intervalo
Estacion de arranque Cualitativa Nominal
Laminas procesadas Cuantitativa(Discreta) Intervalo
Tiempo de calidad Cuantitativa discreta Intervalo

Exportar csv

write.csv(bdp5,"C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form_produccionbaselimpia.csv", row.names=FALSE)

Importar base de datos limpia

bdl<-read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form_produccionbaselimpia.csv")

Datos descriptivos

*Tabla de Media, Moda y Mediana

Los datos aqui muestran una desviacion estandar y datos muy alejados entre los puntos variables lo cual nos indica una alteracion en la uniformidad de los datos lo cual nos puede indicar alguna falla en los datos o bien un detalle de productividad.

bd6<-bdl
tabla<-describe(bd6)

Graficas

Barplots-3

Recopilando la informacion me tope con estos datos lo cual nos informa acerca de los clientes mas destacados para form y el tiempo minimo de tardanza en el ensamblaje de los productos, en este caso el primer lugar con mas eficiencia por cliente fue stabilus en la primera vuelta. Nota: LA visualizacion no se completa en este rmd, para mejor visualizacion ver archivo individual.

#bd6<-bd6 %>% select(piezas_prog,tiempo_min,cliente ) %>% group_by(cliente) %>% 
  #summarise(piezas_prog=sum(piezas_prog),tiempo_min=sum(tiempo_min)) %>% arrange(desc(piezas_prog))

#bd6<-bd6[-c(7,8,9),] 


#ggplot(bd6,aes(x=reorder(tiempo_min,piezas_prog), y=piezas_prog,fill=cliente)) +
#  geom_bar(stat="identity")


Dentro de esta segunda tabla de barras se puede ver desplegado la cantidad de piezas programadas que se tuvo por mes en los periodos de los meses julio, agosto y septiembre. Esto nos dice acerca de la mayor productividad de agosto, pero porque es esto?

datoscopia<-bdl
datoscopia$ano<-strftime(datoscopia$fecha, "%Y")
datoscopia$mes<-strftime(datoscopia$fecha, "%m")

data_agg<- aggregate(piezas_prog~mes + ano, datoscopia, FUN = sum)
data_agglamina<- aggregate(laminas_procesadas~mes + ano, datoscopia, FUN = sum)
ggplot(data_agg,aes(x=mes,y=piezas_prog)) +
  geom_bar(stat="identity")

En esta grafica se puede visualizar la dependencia del tiempo minimo de produccion con las piezas programadas dependiendo de la estacion de arranque, la mayor productividad general tiene unarelacion con la estacion C1 y la C1y2 ya que se ve que es la que menos tiempo hace con mas procesamiento de laminas.

ggplot(datoscopia,aes(x=tiempo_min, y=piezas_prog,fill=esta_arranque)) +
  geom_bar(stat="identity")

Dispersion-2

En esta tabla se muestra un claro ejemplo de comparacion que entre mas tiempo de calidad se le de al cliente se lograra hacer un tiempo mucho mas minimo efectivizando los procesos y terminandolos mas rapido como fue con los clientes en azul.

ggplot(datoscopia, aes(x=tiempo_calidad, y=tiempo_min, color=cliente)) +
  geom_point() + geom_rug()

En esta grafica, se iene la intencion de ver a los compradores predominantes dentro de FORM durante los tres meses predictivos, esto para poder lograr una atencion especializada y ver mas o menos el tiempo que toman sus productos y generar un tipo de procesos mas fluido.

ggplot(datoscopia, aes(x=cliente, y=laminas_procesadas, color=mes)) +
  geom_point() + geom_rug()

Series de tiempo-1

Aqui se puede ver una serie de tiempo no lineal, lo cual nos dice que no se tienen procesos claros y estables para la produccion lo cual lo convierte en un proceso variable y con fallas en los tiempos de entregas como resultado.

ggplot(datoscopia,aes(x=fecha))+
  geom_line(aes(y=piezas_prog),color="orange")+
  labs(x="Fecha",y="piezas programadas", color="orange")+
  ggtitle("Grafica de tasa de rendimiento")

6. Performance

Importar base de datos

#file.choose()
base_de_datos<-read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form\\Formdeliveryfinal3.csv" )

Instalacion de paquetes

library(foreign)
library(dplyr)        # data manipulation 
library(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization 
library(janitor)      # data exploration and cleaning 
#install.packages("Hmisc")
#library(Hmisc)        # several useful functions for data analysis 
#install.packages("psych")
#library(psych)        # functions for multivariate analysis 
#install.packages("naniar")
#library(naniar)       # summaries and visualization of missing values NAs
#install.packages("dlookr")
#library(dlookr)  # summaries and visualization of missing values NAs
#install.packages("corrplot")
#library(corrplot)     # correlation plots
#install.packages("jtools")
#library(jtools)       # presentation of regression analysis 
#install.packages("lmtest")
#library(lmtest)       # diagnostic checks - linear regression analysis 
#install.packages("car")
#library(car)          # diagnostic checks - linear regression analysis
#install.packages("olsrr")
#library(olsrr)        # diagnostic checks - linear regression analysis 
#install.packages("kableExtra")
#library(kableExtra)   # HTML table attributes
library(tidyverse)

Entender mi base de datos

  1. ¿Cuántas variables y cuantos registros tiene la base de datos? Se muestran 8 variables y 1440 registros dentro de la base de datos.
bd<-base_de_datos
summary(bd)
##      Target    Cliente             Vueltas      Plan.arrival   
##  Min.   :1   Length:1440        Min.   :1.00   Min.   : 0.000  
##  1st Qu.:1   Class :character   1st Qu.:1.00   1st Qu.: 0.000  
##  Median :1   Mode  :character   Median :1.50   Median : 4.000  
##  Mean   :1                      Mean   :1.75   Mean   : 6.625  
##  3rd Qu.:1                      3rd Qu.:2.25   3rd Qu.:10.750  
##  Max.   :1                      Max.   :3.00   Max.   :20.000  
##   Real.arrival    Real.departure     Diference           Fecha          
##  Min.   : 0.000   Min.   : 0.000   Min.   :-14.3500   Length:1440       
##  1st Qu.: 0.000   1st Qu.: 0.000   1st Qu.:  0.0000   Class :character  
##  Median : 0.000   Median : 0.000   Median :  0.0000   Mode  :character  
##  Mean   : 3.823   Mean   : 4.142   Mean   :  0.3155                     
##  3rd Qu.: 8.000   3rd Qu.: 9.000   3rd Qu.:  0.8000                     
##  Max.   :23.500   Max.   :24.500   Max.   : 20.0000
str(bd)
## 'data.frame':    1440 obs. of  8 variables:
##  $ Target        : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Cliente       : chr  "PRINTEL " "MAHLE" "MAHLE" "MAHLE" ...
##  $ Vueltas       : int  1 1 2 3 1 1 2 3 1 1 ...
##  $ Plan.arrival  : int  16 8 9 20 0 0 0 0 16 8 ...
##  $ Real.arrival  : num  16 8 9 20 0 0 0 0 16 8 ...
##  $ Real.departure: num  19.3 8.55 10 21 0 0 0 0 18.1 9 ...
##  $ Diference     : num  3.3 0.55 1 1 0 0 0 0 2.1 1 ...
##  $ Fecha         : chr  "2/1/2022" "2/1/2022" "2/1/2022" "2/1/2022" ...

Count de Variables y Escalas

  1. Clasifica cada variable en cualitativa, cuantitativa discreta o cuantitativa continua.
Variable<-c("`Target`","`Cliente`","`Vueltas`","`Plan.arrival`","`Real.arrival`","`Real.departure`","`Diference`","`Fecha`")
Type<-c("quantiative (discrete)", "quantiative (continous)", "quantitative (continous)", "quantitative (continous)")
table<-data.frame(Variable,Type)
knitr::kable(table)
Variable Type
Target quantiative (discrete)
Cliente quantiative (continous)
Vueltas quantitative (continous)
Plan.arrival quantitative (continous)
Real.arrival quantiative (discrete)
Real.departure quantiative (continous)
Diference quantitative (continous)
Fecha quantitative (continous)
  1. Elige la escala de medición de cada variable.
variables <- c("`Target`","`Cliente`","`Vueltas`","`Plan.arrival`","`Real.arrival`","`Real.departure`","`Diference`","`Fecha`")
tipos <- c("cuantitativo (discreto)  ", "cualitativo  ", "cuantitativo (discreto)  ", "cuantitativo (continuo)  ", "cuantitativo (continuo)  ", "cuantitativo (continuo)  ", "cuantitativo (continuo)  ", "cualitativo  ")
escalas <- c("intervalo", "nominal", "razon", "razon", "razon", "razon", "razon", "ordinal")
table1 <- data.frame (variables, tipos, escalas)
knitr::kable(table1)
variables tipos escalas
Target cuantitativo (discreto) intervalo
Cliente cualitativo nominal
Vueltas cuantitativo (discreto) razon
Plan.arrival cuantitativo (continuo) razon
Real.arrival cuantitativo (continuo) razon
Real.departure cuantitativo (continuo) razon
Diference cuantitativo (continuo) razon
Fecha cualitativo ordinal

Limpieza de bases de datos

  1. Aplica al menos 2 técnicas de limpieza de bases de datos y explícalas brevemente, ¿por qué realizaste esas técnicas?

Las técnicas elegidas en nuestra limpia de datos se eligieron por las necesidades que presentaba la base y la utilidad o no que tenían nuestras variables

CONVERSION DE CARACTER A FECHA (TECNICA DE CONVERSION DE DATOS)

bd1<-bd
bd1$Fecha<- as.Date(bd1$Fecha, format= "%d/%m/%y")
summary(bd1)
##      Target    Cliente             Vueltas      Plan.arrival   
##  Min.   :1   Length:1440        Min.   :1.00   Min.   : 0.000  
##  1st Qu.:1   Class :character   1st Qu.:1.00   1st Qu.: 0.000  
##  Median :1   Mode  :character   Median :1.50   Median : 4.000  
##  Mean   :1                      Mean   :1.75   Mean   : 6.625  
##  3rd Qu.:1                      3rd Qu.:2.25   3rd Qu.:10.750  
##  Max.   :1                      Max.   :3.00   Max.   :20.000  
##   Real.arrival    Real.departure     Diference            Fecha           
##  Min.   : 0.000   Min.   : 0.000   Min.   :-14.3500   Min.   :2020-01-02  
##  1st Qu.: 0.000   1st Qu.: 0.000   1st Qu.:  0.0000   1st Qu.:2020-05-07  
##  Median : 0.000   Median : 0.000   Median :  0.0000   Median :2022-02-13  
##  Mean   : 3.823   Mean   : 4.142   Mean   :  0.3155   Mean   :2021-06-24  
##  3rd Qu.: 8.000   3rd Qu.: 9.000   3rd Qu.:  0.8000   3rd Qu.:2022-05-02  
##  Max.   :23.500   Max.   :24.500   Max.   : 20.0000   Max.   :2022-07-23
tibble(bd1)
## # A tibble: 1,440 × 8
##    Target Cliente    Vueltas Plan.arrival Real.arri…¹ Real.…² Difer…³ Fecha     
##     <int> <chr>        <int>        <int>       <dbl>   <dbl>   <dbl> <date>    
##  1      1 "PRINTEL "       1           16          16   19.3     3.3  2020-01-02
##  2      1 "MAHLE"          1            8           8    8.55    0.55 2020-01-02
##  3      1 "MAHLE"          2            9           9   10       1    2020-01-02
##  4      1 "MAHLE"          3           20          20   21       1    2020-01-02
##  5      1 "MAGNA"          1            0           0    0       0    2020-01-02
##  6      1 "VARROC"         1            0           0    0       0    2020-01-02
##  7      1 "VARROC"         2            0           0    0       0    2020-01-02
##  8      1 "VARROC"         3            0           0    0       0    2020-01-02
##  9      1 "PRINTEL "       1           16          16   18.1     2.1  2020-01-03
## 10      1 "MAHLE"          1            8           8    9       1    2020-01-03
## # … with 1,430 more rows, and abbreviated variable names ¹​Real.arrival,
## #   ²​Real.departure, ³​Diference

¿Cuantos N/A tengo en mi base de datos?

sum(is.na(bd1))
## [1] 0

Eliminar columnas

bd2<-bd1
bd2 <- subset(bd2, select =-c (Target))

Nota:

Se elimina el target ya que no nos muestra una información detallada al darnos datos nulos de tener un 1 en todos lados.

LIMPIEZA POR METODO ESTADISTICO

bd3<-bd2
boxplot(bd3$Plan.arrival, horizontal=TRUE)

boxplot(bd3$Real.arrival, horizontal=TRUE)

boxplot(bd3$Real.departure, horizontal=TRUE)

boxplot(bd3$Diference, horizontal=TRUE)

Agregar columna de promedio

bd3$Promedio_real_arrival<- mean(bd3$Real.arrival)

Convertir varaibles de caracter a numerico.

bd3$Vueltas<-as.numeric(bd3$Vueltas)     ### missing values are converted to NA's
bd3$Plan.arrival<-as.numeric(bd3$Plan.arrival)  
bd3$Real.arrival<-as.numeric(bd3$Real.arrival)  
bd3$Real.departure<-as.numeric(bd3$Real.departure)  
bd3$Diference<-as.numeric(bd3$Diference)  
bd3$Promedio_real_arrival<-as.numeric(bd3$Promedio_real_arrival) 

bd3<-as.data.frame(bd3) 
bd3$Fecha<-as.Date(bd3$Fecha,format="%m/%d/%Y") 
bd3$Cliente<-as.factor(bd3$Cliente) 

tibble(bd3)
## # A tibble: 1,440 × 8
##    Cliente    Vueltas Plan.arrival Real.arr…¹ Real.…² Difer…³ Fecha      Prome…⁴
##    <fct>        <dbl>        <dbl>      <dbl>   <dbl>   <dbl> <date>       <dbl>
##  1 "PRINTEL "       1           16         16   19.3     3.3  2020-01-02    3.82
##  2 "MAHLE"          1            8          8    8.55    0.55 2020-01-02    3.82
##  3 "MAHLE"          2            9          9   10       1    2020-01-02    3.82
##  4 "MAHLE"          3           20         20   21       1    2020-01-02    3.82
##  5 "MAGNA"          1            0          0    0       0    2020-01-02    3.82
##  6 "VARROC"         1            0          0    0       0    2020-01-02    3.82
##  7 "VARROC"         2            0          0    0       0    2020-01-02    3.82
##  8 "VARROC"         3            0          0    0       0    2020-01-02    3.82
##  9 "PRINTEL "       1           16         16   18.1     2.1  2020-01-03    3.82
## 10 "MAHLE"          1            8          8    9       1    2020-01-03    3.82
## # … with 1,430 more rows, and abbreviated variable names ¹​Real.arrival,
## #   ²​Real.departure, ³​Diference, ⁴​Promedio_real_arrival

Notas:

Se muestra que la diferencia de nuestros arrivals no es mucha, pero habría que revisar si el promedio total nos ayudaría. se agrego una columna de promedio general de nuestros arrivals reales.

Renombrar variables cuantitativas y cualitativas

#Seleccionar variables
bd4 <- bd3 %>% select (one_of("Cliente","Vueltas","Plan.arrival","Real.arrival","Real.departure", "Diference", "Fecha","Promedio_real_arrival"))
#Renombrar variabes
colnames(bd3)<-c("Cle", "Vueltas", "P.arrival", "R.arrival", "R.dep", "Dif", "Fecha", "Prom.R.arrival")

Exportar base de datos

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

Conclusión

Para esta actividad, pudimos limpiar la base de datos que tiene Form al modificarla al 100% para poder acomodar los requerimientos que tiene R para insertar las bases y que hagan sentido a la hora de trabajarlo.

Para esta base de datos ahora lo que nos permitirá lograr es hacer gráficas y tablas para detallar y mostrar la información importante de nuestra base.

Analisis Exploratorio de la Base de Datos

Exportar la base de datos

#file.choose()
bd_limpia<-read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form\\formbaselimpia.csv")

Tabla principales estadísticos descrptivos

bd_limpia <- bd3
summary(bd_limpia)
##        Cle         Vueltas       P.arrival        R.arrival     
##  MAGNA   :180   Min.   :1.00   Min.   : 0.000   Min.   : 0.000  
##  MAHLE   :540   1st Qu.:1.00   1st Qu.: 0.000   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.50   Median : 4.000   Median : 0.000  
##  VARROC  :540   Mean   :1.75   Mean   : 6.625   Mean   : 3.823  
##                 3rd Qu.:2.25   3rd Qu.:10.750   3rd Qu.: 8.000  
##                 Max.   :3.00   Max.   :20.000   Max.   :23.500  
##      R.dep             Dif               Fecha            Prom.R.arrival 
##  Min.   : 0.000   Min.   :-14.3500   Min.   :2020-01-02   Min.   :3.823  
##  1st Qu.: 0.000   1st Qu.:  0.0000   1st Qu.:2020-05-07   1st Qu.:3.823  
##  Median : 0.000   Median :  0.0000   Median :2022-02-13   Median :3.823  
##  Mean   : 4.142   Mean   :  0.3155   Mean   :2021-06-24   Mean   :3.823  
##  3rd Qu.: 9.000   3rd Qu.:  0.8000   3rd Qu.:2022-05-02   3rd Qu.:3.823  
##  Max.   :24.500   Max.   : 20.0000   Max.   :2022-07-23   Max.   :3.823
sd(bd_limpia$Vueltas, na.rm = FALSE)
## [1] 0.8294442
sd(bd_limpia$P.arrival, na.rm = FALSE)
## [1] 7.501563
sd(bd_limpia$R.arrival, na.rm = FALSE)
## [1] 6.505902
sd(bd_limpia$R.dep, na.rm = FALSE)
## [1] 6.948665
sd(bd_limpia$Dif, na.rm = FALSE)
## [1] 0.9218758
Variable<-c("Vueltas","P.arrival", "R.arrival", "R.dep", "Dif")
Mediana<-c("1.50 ","4.000","0.000 ","0.000 ","0.0000 ")
Media <- c("1.75","6.625","3.823","4.142","4.142")
Moda <- c("1","0","0","0","0")
Desviación_estandar<-c("0.8294442"," 7.501563","6.505902","6.948665","6.948665")
table1 <- data.frame (Variable, Mediana, Media, Moda, Desviación_estandar)
knitr::kable(table1)
Variable Mediana Media Moda Desviación_estandar
Vueltas 1.50 1.75 1 0.8294442
P.arrival 4.000 6.625 0 7.501563
R.arrival 0.000 3.823 0 6.505902
R.dep 0.000 4.142 0 6.948665
Dif 0.0000 4.142 0 6.948665

Notas:

Se ocupo summary para poder obtener la moda, mediana y media de las variables y posteriormente se calcula la desviación estandar con la función sd()

Tabla de Frecuencia

#install.packages('epiDisplay')
library(epiDisplay)
## Loading required package: MASS
## 
## Attaching package: 'MASS'
## The following object is masked from 'package:olsrr':
## 
##     cement
## The following object is masked from 'package:dplyr':
## 
##     select
## Loading required package: nnet
## 
## Attaching package: 'epiDisplay'
## The following object is masked from 'package:gmodels':
## 
##     ci
## The following object is masked from 'package:lmtest':
## 
##     lrtest
## The following object is masked from 'package:jtools':
## 
##     summ
## The following object is masked from 'package:lattice':
## 
##     dotplot
## The following objects are masked from 'package:psych':
## 
##     alpha, cs, lookup
## The following object is masked from 'package:ggplot2':
## 
##     alpha
tab1(bd_limpia$Dif, sort.group = "decreasing", cum.percent = TRUE) 

## bd_limpia$Dif : 
##         Frequency Percent Cum. percent
## 0            1014    70.4         70.4
## 1             192    13.3         83.8
## 1.1            20     1.4         85.1
## 1.05           17     1.2         86.3
## 1.2            16     1.1         87.4
## 0.5            14     1.0         88.4
## 1.15           11     0.8         89.2
## 0.9             8     0.6         89.7
## 0.4             8     0.6         90.3
## 1.5             7     0.5         90.8
## 0.8             7     0.5         91.2
## 0.55            7     0.5         91.7
## 2               6     0.4         92.2
## 1.8             6     0.4         92.6
## 1.3             6     0.4         93.0
## 0.3             6     0.4         93.4
## 1.4             5     0.3         93.8
## 1.25            5     0.3         94.1
## 0.95            5     0.3         94.4
## 0.2             5     0.3         94.8
## 1.45            4     0.3         95.1
## 1.35            3     0.2         95.3
## 0.45            3     0.2         95.5
## 0.35            3     0.2         95.7
## 0.1             3     0.2         95.9
## 3.1             2     0.1         96.0
## 2.6             2     0.1         96.2
## 2.38            2     0.1         96.3
## 2.15            2     0.1         96.5
## 1.6             2     0.1         96.6
## 1.03            2     0.1         96.7
## 0.85            2     0.1         96.9
## 0.7             2     0.1         97.0
## 0.6             2     0.1         97.2
## 0.15            2     0.1         97.3
## 4.4             1     0.1         97.4
## 4               1     0.1         97.4
## 3.3             1     0.1         97.5
## 3.05            1     0.1         97.6
## 20              1     0.1         97.6
## 2.85            1     0.1         97.7
## 2.52            1     0.1         97.8
## 2.5             1     0.1         97.8
## 2.4             1     0.1         97.9
## 2.35            1     0.1         98.0
## 2.3             1     0.1         98.1
## 2.27            1     0.1         98.1
## 2.2             1     0.1         98.2
## 2.1             1     0.1         98.3
## 2.05            1     0.1         98.3
## 1.95            1     0.1         98.4
## 1.9             1     0.1         98.5
## 1.88            1     0.1         98.5
## 1.85            1     0.1         98.6
## 1.74            1     0.1         98.7
## 1.73            1     0.1         98.8
## 1.7             1     0.1         98.8
## 1.66            1     0.1         98.9
## 1.65            1     0.1         99.0
## 1.55            1     0.1         99.0
## 1.14            1     0.1         99.1
## 1.13            1     0.1         99.2
## 1.07            1     0.1         99.2
## 1.04            1     0.1         99.3
## 1.01            1     0.1         99.4
## 0.99            1     0.1         99.4
## 0.98            1     0.1         99.5
## 0.75            1     0.1         99.6
## 0.47            1     0.1         99.7
## 0.43            1     0.1         99.7
## 0.34            1     0.1         99.8
## 0.25            1     0.1         99.9
## -14.35          1     0.1         99.9
## -12.15          1     0.1        100.0
##   Total      1440   100.0        100.0
tab1(bd_limpia$R.arrival, sort.group = "decreasing", cum.percent = TRUE)

## bd_limpia$R.arrival : 
##         Frequency Percent Cum. percent
## 0            1009    70.1         70.1
## 8             100     6.9         77.0
## 20             83     5.8         82.8
## 9              81     5.6         88.4
## 18             11     0.8         89.2
## 9.4            10     0.7         89.9
## 15              9     0.6         90.5
## 18.2            8     0.6         91.0
## 16              7     0.5         91.5
## 9.5             6     0.4         91.9
## 9.2             6     0.4         92.4
## 9.1             6     0.4         92.8
## 10              6     0.4         93.2
## 9.15            5     0.3         93.5
## 15.1            5     0.3         93.9
## 16.2            4     0.3         94.2
## 9.3             3     0.2         94.4
## 15.2            3     0.2         94.6
## 9.45            2     0.1         94.7
## 9.26            2     0.1         94.9
## 9.12            2     0.1         95.0
## 9.08            2     0.1         95.1
## 8.1             2     0.1         95.3
## 8.05            2     0.1         95.4
## 7.35            2     0.1         95.6
## 7.3             2     0.1         95.7
## 6               2     0.1         95.8
## 23.3            2     0.1         96.0
## 20.2            2     0.1         96.1
## 20.1            2     0.1         96.2
## 19.2            2     0.1         96.4
## 18.4            2     0.1         96.5
## 18.3            2     0.1         96.7
## 16.4            2     0.1         96.8
## 15.3            2     0.1         96.9
## 13              2     0.1         97.1
## 9.35            1     0.1         97.2
## 9.25            1     0.1         97.2
## 9.17            1     0.1         97.3
## 9.11            1     0.1         97.4
## 9.05            1     0.1         97.4
## 8.52            1     0.1         97.5
## 8.45            1     0.1         97.6
## 7.45            1     0.1         97.6
## 7.34            1     0.1         97.7
## 23.5            1     0.1         97.8
## 23.2            1     0.1         97.8
## 23.15           1     0.1         97.9
## 23              1     0.1         98.0
## 22.4            1     0.1         98.1
## 22.08           1     0.1         98.1
## 21.15           1     0.1         98.2
## 21.1            1     0.1         98.3
## 21.05           1     0.1         98.3
## 20.4            1     0.1         98.4
## 20.3            1     0.1         98.5
## 20.15           1     0.1         98.5
## 20.05           1     0.1         98.6
## 19.48           1     0.1         98.7
## 19.15           1     0.1         98.8
## 19.1            1     0.1         98.8
## 18.5            1     0.1         98.9
## 18.35           1     0.1         99.0
## 18.15           1     0.1         99.0
## 18.1            1     0.1         99.1
## 18.05           1     0.1         99.2
## 17.3            1     0.1         99.2
## 17              1     0.1         99.3
## 15.45           1     0.1         99.4
## 15.4            1     0.1         99.4
## 15.16           1     0.1         99.5
## 14              1     0.1         99.6
## 13.4            1     0.1         99.7
## 11.37           1     0.1         99.7
## 11              1     0.1         99.8
## 10.42           1     0.1         99.9
## 10.4            1     0.1         99.9
## 10.05           1     0.1        100.0
##   Total      1440   100.0        100.0

Notas:

Viendo el gráfico de distribución se pueden ver las frecuencias en las diferencias, se ve una mayor parte en el número 0, lo cual nos indica un buen desarrollo en delivery.

“Time series plots” (line plot)

#Checar que la base de datos esta estructurada y un resumen de la descripción estadistica
summary(bd_limpia)
##        Cle         Vueltas       P.arrival        R.arrival     
##  MAGNA   :180   Min.   :1.00   Min.   : 0.000   Min.   : 0.000  
##  MAHLE   :540   1st Qu.:1.00   1st Qu.: 0.000   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.50   Median : 4.000   Median : 0.000  
##  VARROC  :540   Mean   :1.75   Mean   : 6.625   Mean   : 3.823  
##                 3rd Qu.:2.25   3rd Qu.:10.750   3rd Qu.: 8.000  
##                 Max.   :3.00   Max.   :20.000   Max.   :23.500  
##      R.dep             Dif               Fecha            Prom.R.arrival 
##  Min.   : 0.000   Min.   :-14.3500   Min.   :2020-01-02   Min.   :3.823  
##  1st Qu.: 0.000   1st Qu.:  0.0000   1st Qu.:2020-05-07   1st Qu.:3.823  
##  Median : 0.000   Median :  0.0000   Median :2022-02-13   Median :3.823  
##  Mean   : 4.142   Mean   :  0.3155   Mean   :2021-06-24   Mean   :3.823  
##  3rd Qu.: 9.000   3rd Qu.:  0.8000   3rd Qu.:2022-05-02   3rd Qu.:3.823  
##  Max.   :24.500   Max.   : 20.0000   Max.   :2022-07-23   Max.   :3.823
#Graficar 
ggplot(bd_limpia,aes(x=Fecha, y=Dif,color=Cle))+
  geom_line()+
  labs(x="Fecha",y="Delay in Minutes", color="Legend")+
  ggtitle("Delays in Performance by Client")

### Checar la presencia de missing values

bd_limpia1 <- bd_limpia
bd_limpia1<-bd_limpia1[-c(300,292),] # Quitar las filas 300 y 292 por que presentan datos negativos y que no sirven para el analisis.
summary(bd_limpia1) # no missing values
##        Cle         Vueltas        P.arrival        R.arrival     
##  MAGNA   :180   Min.   :1.000   Min.   : 0.000   Min.   : 0.000  
##  MAHLE   :538   1st Qu.:1.000   1st Qu.: 0.000   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.000   Median : 0.000   Median : 0.000  
##  VARROC  :540   Mean   :1.748   Mean   : 6.606   Mean   : 3.796  
##                 3rd Qu.:2.000   3rd Qu.: 9.000   3rd Qu.: 8.000  
##                 Max.   :3.000   Max.   :20.000   Max.   :23.500  
##      R.dep             Dif              Fecha            Prom.R.arrival 
##  Min.   : 0.000   Min.   : 0.0000   Min.   :2020-01-02   Min.   :3.823  
##  1st Qu.: 0.000   1st Qu.: 0.0000   1st Qu.:2020-05-06   1st Qu.:3.823  
##  Median : 0.000   Median : 0.0000   Median :2022-02-13   Median :3.823  
##  Mean   : 4.134   Mean   : 0.3344   Mean   :2021-06-23   Mean   :3.823  
##  3rd Qu.: 9.000   3rd Qu.: 0.8000   3rd Qu.:2022-05-09   3rd Qu.:3.823  
##  Max.   :24.500   Max.   :20.0000   Max.   :2022-07-23   Max.   :3.823

Quitar clientes que tengan valor de 0 en la base de datos

bd_limpia1<-bd_limpia1[bd_limpia1$Cle!="MAGNA",]
bd_limpia1<-bd_limpia1[bd_limpia1$Cle!="VARROC",]
summary(bd_limpia1)
##        Cle         Vueltas        P.arrival       R.arrival     
##  MAGNA   :  0   Min.   :1.000   Min.   : 8.00   Min.   : 0.000  
##  MAHLE   :538   1st Qu.:1.000   1st Qu.: 8.25   1st Qu.: 0.000  
##  PRINTEL :180   Median :1.000   Median : 9.00   Median : 8.000  
##  VARROC  :  0   Mean   :1.747   Mean   :13.23   Mean   : 7.603  
##                 3rd Qu.:2.000   3rd Qu.:16.00   3rd Qu.:10.000  
##                 Max.   :3.000   Max.   :20.00   Max.   :23.500  
##      R.dep            Dif              Fecha            Prom.R.arrival 
##  Min.   : 0.00   Min.   : 0.0000   Min.   :2020-01-02   Min.   :3.823  
##  1st Qu.: 0.00   1st Qu.: 0.0000   1st Qu.:2020-05-06   1st Qu.:3.823  
##  Median : 9.00   Median : 0.8000   Median :2022-02-13   Median :3.823  
##  Mean   : 8.28   Mean   : 0.6697   Mean   :2021-06-23   Mean   :3.823  
##  3rd Qu.:11.50   3rd Qu.: 1.0000   3rd Qu.:2022-05-09   3rd Qu.:3.823  
##  Max.   :24.50   Max.   :20.0000   Max.   :2022-07-23   Max.   :3.823

Realizar la grafica con los 2 clientes que eliminamos

ggplot(bd_limpia1,aes(x=Fecha, y=Dif,color=Cle))+
  geom_line()+  geom_hline(yintercept=0.8000,linetype="dashed",color="black")+
  labs(x="Fecha",y="Diferencia por día", color="Legend")+
  ggtitle("Diferencia de entrega por Cliente")

### Nota (Hallazgo): Encontramos gracias a la grafica realizada de la Diferencia de tiempo en la entrega de producto por cliente, que los clientes con mayor Delay son MAHLE Y PRINTEL, al mismo tiempo encontramos que entre estos dos clientes, el que tiene mayor Delay es MAHLE, por lo que sería bueno para la empresa el tener un mayor enfoque, obvio en ambos, pero tambien un poco más en Mahle, para que tenga mejor referencia de este cliente y mayor confianza con la empresa en las entregas.

7. Base de Datos Externa

Prediccion de los datos base de datos externa

Instalar paquetes y llamar librerías

library(psych)
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(ggplot2)
library(GGally)
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
library(TSstudio)
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo

Llamar base de datos

Companies <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd1 csv1.csv")
summary(Companies)
##   Geography           Category          Data.Type             Unit          
##  Length:89          Length:89          Length:89          Length:89         
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Current.Constant       X2016              X2017              X2018         
##  Length:89          Min.   :       0   Min.   :       0   Min.   :       0  
##  Class :character   1st Qu.:     421   1st Qu.:     432   1st Qu.:     527  
##  Mode  :character   Median :    4383   Median :    4804   Median :    5063  
##                     Mean   :  939400   Mean   :  993634   Mean   : 1193476  
##                     3rd Qu.:   37794   3rd Qu.:   38307   3rd Qu.:   40769  
##                     Max.   :25902010   Max.   :27472550   Max.   :35218716  
##      X2019              X2020              X2021         
##  Min.   :       0   Min.   :       0   Min.   :       0  
##  1st Qu.:     529   1st Qu.:     548   1st Qu.:     607  
##  Median :    4849   Median :    5020   Median :    5477  
##  Mean   : 1376491   Mean   : 1554963   Mean   : 1904399  
##  3rd Qu.:   43779   3rd Qu.:   44564   3rd Qu.:   51280  
##  Max.   :39310235   Max.   :41193660   Max.   :63857942

1. Limpieza, Transformación y Organización de Bases de Datos

str(Companies)
## 'data.frame':    89 obs. of  11 variables:
##  $ Geography       : chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Category        : chr  "Corrugated Paper, Paperboard and Containers" "Corrugated Paper, Paperboard and Containers" "Corrugated Paper, Paperboard and Containers" "Corrugated Paper, Paperboard and Containers" ...
##  $ Data.Type       : chr  "Production (turnover) MSP" "Production (turnover) MSP" "Production (turnover) MSP" "Production (turnover) MSP" ...
##  $ Unit            : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ Current.Constant: chr  "Current Prices" "Current Prices" "Current Prices" "Current Prices" ...
##  $ X2016           : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ X2017           : num  44.6 135423.7 257700 301286.2 212.7 ...
##  $ X2018           : num  47.3 156788.3 299500 317612.9 217.5 ...
##  $ X2019           : num  52.2 180445.4 314000 310925.3 216.8 ...
##  $ X2020           : num  51.5 198883.5 281100 312534.7 196.7 ...
##  $ X2021           : num  66.1 222755.3 285994.4 344612.2 191.4 ...
describe(Companies)
## Companies 
## 
##  11  Variables      89  Observations
## --------------------------------------------------------------------------------
## Geography 
##        n  missing distinct 
##       89        0       89 
## 
## lowest : Algeria        Angola         Argentina      Australia      Austria       
## highest: United Kingdom Uruguay        USA            Uzbekistan     Vietnam       
## --------------------------------------------------------------------------------
## Category 
##                                           n 
##                                          89 
##                                     missing 
##                                           0 
##                                    distinct 
##                                           1 
##                                       value 
## Corrugated Paper, Paperboard and Containers 
##                                                       
## Value      Corrugated Paper, Paperboard and Containers
## Frequency                                           89
## Proportion                                          1 
## --------------------------------------------------------------------------------
## Data.Type 
##                         n                   missing                  distinct 
##                        89                         0                         1 
##                     value 
## Production (turnover) MSP 
##                                     
## Value      Production (turnover) MSP
## Frequency                         89
## Proportion                         1
## --------------------------------------------------------------------------------
## Unit 
##        n  missing distinct 
##       89        0       70 
## 
## lowest : AED million AOA million ARS million AUD million AZN million
## highest: UYU million UZS million VND million XAF million ZAR million
## --------------------------------------------------------------------------------
## Current.Constant 
##              n        missing       distinct          value 
##             89              0              1 Current Prices 
##                          
## Value      Current Prices
## Frequency              89
## Proportion              1
## --------------------------------------------------------------------------------
## X2016 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1    939400   1802910 4.024e+01 7.196e+01 
##       .25       .50       .75       .90       .95 
## 4.208e+02 4.383e+03 3.779e+04 2.811e+05 2.444e+06 
## 
## lowest :        0.0       23.5       27.0       35.5       40.0
## highest:  2546890.4  8853225.9 15537060.0 24737853.0 25902010.0
## 
## 0 (61, 0.685), 50000 (10, 0.112), 1e+05 (4, 0.045), 150000 (1, 0.011), 2e+05
## (1, 0.011), 250000 (3, 0.034), 3e+05 (1, 0.011), 450000 (1, 0.011), 9e+05 (1,
## 0.011), 2300000 (1, 0.011), 2550000 (1, 0.011), 8850000 (1, 0.011), 15550000
## (1, 0.011), 24750000 (1, 0.011), 25900000 (1, 0.011)
## 
## For the frequency table, variable is rounded to the nearest 50000
## --------------------------------------------------------------------------------
## X2017 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1    993634   1906261 3.848e+01 8.660e+01 
##       .25       .50       .75       .90       .95 
## 4.318e+02 4.804e+03 3.831e+04 3.074e+05 2.490e+06 
## 
## lowest :        0.0       23.5       24.8       28.8       37.4
## highest:  2544419.2  9234244.0 17719080.0 25006911.1 27472550.0
## 
## 0 (61, 0.685), 50000 (10, 0.112), 1e+05 (3, 0.034), 150000 (2, 0.022), 2e+05
## (2, 0.022), 250000 (1, 0.011), 3e+05 (1, 0.011), 350000 (1, 0.011), 550000 (1,
## 0.011), 1e+06 (1, 0.011), 2400000 (1, 0.011), 2550000 (1, 0.011), 9250000 (1,
## 0.011), 17700000 (1, 0.011), 2.5e+07 (1, 0.011), 27450000 (1, 0.011)
## 
## For the frequency table, variable is rounded to the nearest 50000
## --------------------------------------------------------------------------------
## X2018 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1193476   2294312      43.3      86.7 
##       .25       .50       .75       .90       .95 
##     526.7    5063.1   40769.0  336594.7 2613855.3 
## 
## lowest :        0.0       26.2       28.5       31.7       42.9
## highest:  2629713.5 10416278.4 20330000.0 30247300.0 35218715.9
##                                                                          
## Value             0   100000   200000   300000   400000   700000  1200000
## Frequency        68        6        3        3        1        1        1
## Proportion    0.764    0.067    0.034    0.034    0.011    0.011    0.011
##                                                        
## Value       2600000 10400000 20300000 30200000 35200000
## Frequency         2        1        1        1        1
## Proportion    0.022    0.011    0.011    0.011    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------
## X2019 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1376491   2648876 4.098e+01 8.928e+01 
##       .25       .50       .75       .90       .95 
## 5.293e+02 4.849e+03 4.378e+04 3.325e+05 2.729e+06 
## 
## lowest :        0.0       27.3       32.2       34.6       38.1
## highest:  2751972.0 10231535.7 27384030.0 35183030.0 39310234.8
##                                                                          
## Value             0   100000   200000   300000   400000   900000  1000000
## Frequency        68        6        2        4        1        1        1
## Proportion    0.764    0.067    0.022    0.045    0.011    0.011    0.011
##                                                                 
## Value       2700000  2800000 10200000 27400000 35200000 39300000
## Frequency         1        1        1        1        1        1
## Proportion    0.011    0.011    0.011    0.011    0.011    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------
## X2020 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1554963   2992470 3.546e+01 8.688e+01 
##       .25       .50       .75       .90       .95 
## 5.480e+02 5.020e+03 4.456e+04 3.276e+05 2.613e+06 
## 
## lowest :        0.0       22.8       30.4       30.7       33.3
## highest:  2643726.9 10503145.6 37653180.0 38605278.4 41193660.0
##                                                                          
## Value             0   100000   200000   300000   400000  1000000  1100000
## Frequency        68        5        3        4        1        1        1
## Proportion    0.764    0.056    0.034    0.045    0.011    0.011    0.011
##                                                        
## Value       2600000 10500000 37700000 38600000 41200000
## Frequency         2        1        1        1        1
## Proportion    0.022    0.011    0.011    0.011    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------
## X2021 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1904399   3679670 4.066e+01 9.036e+01 
##       .25       .50       .75       .90       .95 
## 6.074e+02 5.477e+03 5.128e+04 3.774e+05 2.859e+06 
## 
## lowest :        0.0       27.1       31.8       37.0       38.9
## highest:  2933126.1 10586976.2 41570794.1 41644308.6 63857941.8
##                                                                          
## Value             0   100000   200000   300000   400000   500000  1200000
## Frequency        66        7        2        4        1        1        1
## Proportion    0.742    0.079    0.022    0.045    0.011    0.011    0.011
##                                                                 
## Value       1400000  2700000  2900000 10600000 41600000 63900000
## Frequency         1        1        1        1        2        1
## Proportion    0.011    0.011    0.011    0.011    0.022    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------

Nota: Debido a la versión de R, nos deja descargar el paquete “psych”. Sin embargo, no nos deja llamar a la librería “psych”, por lo tanto utilizamos str, para obtener el numero de las variables de la base de datos.

2. Clasificación de variables

Realizamos una tabla para poder clasificar cada una de las variables de la base de Datos bd1

Variable<-c("Geography","Category","Data.Type", "Unit","Current Constant","Years")
Type<-c("Cualitativa", "Cualitativa", "Cualitativa", "Cualitativa", "Cualitativa", "Cuantitativa (Continua)")
table<-data.frame(Variable,Type)
knitr::kable(table)
Variable Type
Geography Cualitativa
Category Cualitativa
Data.Type Cualitativa
Unit Cualitativa
Current Constant Cualitativa
Years Cuantitativa (Continua)

3. Escala de Medición

Realizamos una tabla donde viene clasificado cada variable y agregamos una columna con la escala de medición para cada variable.

Variable<-c("Geography","Category","Data.Type", "Unit","Current Constant","Years")
Type<-c("Cualitativa", "Cualitativa", "Cualitativa", "Cualitativa", "Cualitativa", "Cuantitativa (Continua)")
Escala_de_Medición <- c("Países", "Producto", "Departamento","Tipo de Moneda", "Precio actual", "Ganancia (Razon)")
table<-data.frame(Variable,Type,Escala_de_Medición)
knitr::kable(table)
Variable Type Escala_de_Medición
Geography Cualitativa Países
Category Cualitativa Producto
Data.Type Cualitativa Departamento
Unit Cualitativa Tipo de Moneda
Current Constant Cualitativa Precio actual
Years Cuantitativa (Continua) Ganancia (Razon)

4. Limpieza de datos

La primer tecnica de limpieza que utilizamos fue, eliminar columnas debido a que contabamos con datos los cuales no eran relevantes para el análisis.
La segunda herramienta de limpieza que utilizamos para la visulización de los datos fue implementar una nueva columna como el total de la Producción de las variables que se producen por país.

Remover Valores Irrelevantes

Eliminar columnas

bd1 <- Companies
bd1<-subset(bd1,select=-c(Category,Data.Type,Current.Constant))
str(bd1)
## 'data.frame':    89 obs. of  8 variables:
##  $ Geography: chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Unit     : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ X2016    : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ X2017    : num  44.6 135423.7 257700 301286.2 212.7 ...
##  $ X2018    : num  47.3 156788.3 299500 317612.9 217.5 ...
##  $ X2019    : num  52.2 180445.4 314000 310925.3 216.8 ...
##  $ X2020    : num  51.5 198883.5 281100 312534.7 196.7 ...
##  $ X2021    : num  66.1 222755.3 285994.4 344612.2 191.4 ...

Agregar Columnas

bd1$Total_Produccion<- bd1$X2016+bd1$X2017+bd1$X2018+bd1$X2019+bd1$X2020+bd1$X2021
bd1$Promedio_X2021<- mean(bd1$X2021)

summary(bd1)
##   Geography             Unit               X2016              X2017         
##  Length:89          Length:89          Min.   :       0   Min.   :       0  
##  Class :character   Class :character   1st Qu.:     421   1st Qu.:     432  
##  Mode  :character   Mode  :character   Median :    4383   Median :    4804  
##                                        Mean   :  939400   Mean   :  993634  
##                                        3rd Qu.:   37794   3rd Qu.:   38307  
##                                        Max.   :25902010   Max.   :27472550  
##      X2018              X2019              X2020              X2021         
##  Min.   :       0   Min.   :       0   Min.   :       0   Min.   :       0  
##  1st Qu.:     527   1st Qu.:     529   1st Qu.:     548   1st Qu.:     607  
##  Median :    5063   Median :    4849   Median :    5020   Median :    5477  
##  Mean   : 1193476   Mean   : 1376491   Mean   : 1554963   Mean   : 1904399  
##  3rd Qu.:   40769   3rd Qu.:   43779   3rd Qu.:   44564   3rd Qu.:   51280  
##  Max.   :35218716   Max.   :39310235   Max.   :41193660   Max.   :63857942  
##  Total_Produccion    Promedio_X2021   
##  Min.   :        0   Min.   :1904399  
##  1st Qu.:     3166   1st Qu.:1904399  
##  Median :    30333   Median :1904399  
##  Mean   :  7962363   Mean   :1904399  
##  3rd Qu.:   254492   3rd Qu.:1904399  
##  Max.   :204523302   Max.   :1904399
str(bd1)
## 'data.frame':    89 obs. of  10 variables:
##  $ Geography       : chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Unit            : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ X2016           : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ X2017           : num  44.6 135423.7 257700 301286.2 212.7 ...
##  $ X2018           : num  47.3 156788.3 299500 317612.9 217.5 ...
##  $ X2019           : num  52.2 180445.4 314000 310925.3 216.8 ...
##  $ X2020           : num  51.5 198883.5 281100 312534.7 196.7 ...
##  $ X2021           : num  66.1 222755.3 285994.4 344612.2 191.4 ...
##  $ Total_Produccion: num  302 1009403 1685394 1896358 1247 ...
##  $ Promedio_X2021  : num  1904399 1904399 1904399 1904399 1904399 ...

¿Cuántos NA’s tengo en la base de datos?

sum(is.na(bd1))
## [1] 0

Nota: Se eliminan Category, Data.Type y Current.Constant, ya que no nos sirven, debido a que es el mismo dato para todos los registros y es algo que no nos aporta alguna información.

5. Análisis Exploratorio de las Bases de Datos

describe(bd1)
## bd1 
## 
##  10  Variables      89  Observations
## --------------------------------------------------------------------------------
## Geography 
##        n  missing distinct 
##       89        0       89 
## 
## lowest : Algeria        Angola         Argentina      Australia      Austria       
## highest: United Kingdom Uruguay        USA            Uzbekistan     Vietnam       
## --------------------------------------------------------------------------------
## Unit 
##        n  missing distinct 
##       89        0       70 
## 
## lowest : AED million AOA million ARS million AUD million AZN million
## highest: UYU million UZS million VND million XAF million ZAR million
## --------------------------------------------------------------------------------
## X2016 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1    939400   1802910 4.024e+01 7.196e+01 
##       .25       .50       .75       .90       .95 
## 4.208e+02 4.383e+03 3.779e+04 2.811e+05 2.444e+06 
## 
## lowest :        0.0       23.5       27.0       35.5       40.0
## highest:  2546890.4  8853225.9 15537060.0 24737853.0 25902010.0
## 
## 0 (61, 0.685), 50000 (10, 0.112), 1e+05 (4, 0.045), 150000 (1, 0.011), 2e+05
## (1, 0.011), 250000 (3, 0.034), 3e+05 (1, 0.011), 450000 (1, 0.011), 9e+05 (1,
## 0.011), 2300000 (1, 0.011), 2550000 (1, 0.011), 8850000 (1, 0.011), 15550000
## (1, 0.011), 24750000 (1, 0.011), 25900000 (1, 0.011)
## 
## For the frequency table, variable is rounded to the nearest 50000
## --------------------------------------------------------------------------------
## X2017 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1    993634   1906261 3.848e+01 8.660e+01 
##       .25       .50       .75       .90       .95 
## 4.318e+02 4.804e+03 3.831e+04 3.074e+05 2.490e+06 
## 
## lowest :        0.0       23.5       24.8       28.8       37.4
## highest:  2544419.2  9234244.0 17719080.0 25006911.1 27472550.0
## 
## 0 (61, 0.685), 50000 (10, 0.112), 1e+05 (3, 0.034), 150000 (2, 0.022), 2e+05
## (2, 0.022), 250000 (1, 0.011), 3e+05 (1, 0.011), 350000 (1, 0.011), 550000 (1,
## 0.011), 1e+06 (1, 0.011), 2400000 (1, 0.011), 2550000 (1, 0.011), 9250000 (1,
## 0.011), 17700000 (1, 0.011), 2.5e+07 (1, 0.011), 27450000 (1, 0.011)
## 
## For the frequency table, variable is rounded to the nearest 50000
## --------------------------------------------------------------------------------
## X2018 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1193476   2294312      43.3      86.7 
##       .25       .50       .75       .90       .95 
##     526.7    5063.1   40769.0  336594.7 2613855.3 
## 
## lowest :        0.0       26.2       28.5       31.7       42.9
## highest:  2629713.5 10416278.4 20330000.0 30247300.0 35218715.9
##                                                                          
## Value             0   100000   200000   300000   400000   700000  1200000
## Frequency        68        6        3        3        1        1        1
## Proportion    0.764    0.067    0.034    0.034    0.011    0.011    0.011
##                                                        
## Value       2600000 10400000 20300000 30200000 35200000
## Frequency         2        1        1        1        1
## Proportion    0.022    0.011    0.011    0.011    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------
## X2019 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1376491   2648876 4.098e+01 8.928e+01 
##       .25       .50       .75       .90       .95 
## 5.293e+02 4.849e+03 4.378e+04 3.325e+05 2.729e+06 
## 
## lowest :        0.0       27.3       32.2       34.6       38.1
## highest:  2751972.0 10231535.7 27384030.0 35183030.0 39310234.8
##                                                                          
## Value             0   100000   200000   300000   400000   900000  1000000
## Frequency        68        6        2        4        1        1        1
## Proportion    0.764    0.067    0.022    0.045    0.011    0.011    0.011
##                                                                 
## Value       2700000  2800000 10200000 27400000 35200000 39300000
## Frequency         1        1        1        1        1        1
## Proportion    0.011    0.011    0.011    0.011    0.011    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------
## X2020 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1554963   2992470 3.546e+01 8.688e+01 
##       .25       .50       .75       .90       .95 
## 5.480e+02 5.020e+03 4.456e+04 3.276e+05 2.613e+06 
## 
## lowest :        0.0       22.8       30.4       30.7       33.3
## highest:  2643726.9 10503145.6 37653180.0 38605278.4 41193660.0
##                                                                          
## Value             0   100000   200000   300000   400000  1000000  1100000
## Frequency        68        5        3        4        1        1        1
## Proportion    0.764    0.056    0.034    0.045    0.011    0.011    0.011
##                                                        
## Value       2600000 10500000 37700000 38600000 41200000
## Frequency         2        1        1        1        1
## Proportion    0.022    0.011    0.011    0.011    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------
## X2021 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   1904399   3679670 4.066e+01 9.036e+01 
##       .25       .50       .75       .90       .95 
## 6.074e+02 5.477e+03 5.128e+04 3.774e+05 2.859e+06 
## 
## lowest :        0.0       27.1       31.8       37.0       38.9
## highest:  2933126.1 10586976.2 41570794.1 41644308.6 63857941.8
##                                                                          
## Value             0   100000   200000   300000   400000   500000  1200000
## Frequency        66        7        2        4        1        1        1
## Proportion    0.742    0.079    0.022    0.045    0.011    0.011    0.011
##                                                                 
## Value       1400000  2700000  2900000 10600000 41600000 63900000
## Frequency         1        1        1        1        2        1
## Proportion    0.011    0.011    0.011    0.011    0.022    0.011
## 
## For the frequency table, variable is rounded to the nearest 100000
## --------------------------------------------------------------------------------
## Total_Produccion 
##         n   missing  distinct      Info      Mean       Gmd       .05       .10 
##        89         0        89         1   7962363  15296095 2.333e+02 5.224e+02 
##       .25       .50       .75       .90       .95 
## 3.166e+03 3.033e+04 2.545e+05 1.970e+06 1.570e+07 
## 
## lowest :         0.0       171.5       189.5       194.3       221.3
## highest:  15807772.3  59825405.8 186021771.8 198028864.1 204523301.8
## 
## 0 (66, 0.742), 5e+05 (7, 0.079), 1e+06 (3, 0.034), 1500000 (3, 0.034), 2e+06
## (1, 0.011), 2500000 (1, 0.011), 5e+06 (1, 0.011), 6500000 (1, 0.011), 15500000
## (1, 0.011), 1.6e+07 (1, 0.011), 6e+07 (1, 0.011), 1.86e+08 (1, 0.011), 1.98e+08
## (1, 0.011), 204500000 (1, 0.011)
## 
## For the frequency table, variable is rounded to the nearest 500000
## --------------------------------------------------------------------------------
## Promedio_X2021 
##        n  missing distinct     Info     Mean      Gmd 
##       89        0        1        0  1904399        0 
##                   
## Value      1904399
## Frequency       89
## Proportion       1
## --------------------------------------------------------------------------------

En el análisis descriptivo se muestran los valores promedio del total de producciones de 2016 a 2021.

Tabla de Frecuencia

bd2 <- table(bd1$Unit)
bd2 <- prop.table(bd2)
bd2
## 
## AED million AOA million ARS million AUD million AZN million BDT million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## BGN million BRL million BYR million CAD million CHF million CLP million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## CNY million COP million CRC million CUC million CZK million DKK million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## DOP million DZD million EGP million ETB million EUR million GBP million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.20224719  0.01123596 
## GEL million GHS million HKD million HRK million HuF million IDR million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## ILS million INR million IQD million IRR million ISK million JPY million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## KES million KHR million KRW million KWD million KZT million LKR million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## MAD million MXN million MYR million NGN million NOK million NZD million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## PAB million PEN million PHP million PKR million PLN million QAR million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## RON million RUB million SAR million SEK million SGD million THB million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596  0.01123596 
## TND million TRY million TWD million UAH million USD million UYU million 
##  0.01123596  0.01123596  0.01123596  0.01123596  0.03370787  0.01123596 
## UZS million VND million XAF million ZAR million 
##  0.01123596  0.01123596  0.01123596  0.01123596

Tabla cruzada

table(bd1$Unit, bd1$Promedio_X2021)
##              
##               1904399.38539326
##   AED million                1
##   AOA million                1
##   ARS million                1
##   AUD million                1
##   AZN million                1
##   BDT million                1
##   BGN million                1
##   BRL million                1
##   BYR million                1
##   CAD million                1
##   CHF million                1
##   CLP million                1
##   CNY million                1
##   COP million                1
##   CRC million                1
##   CUC million                1
##   CZK million                1
##   DKK million                1
##   DOP million                1
##   DZD million                1
##   EGP million                1
##   ETB million                1
##   EUR million               18
##   GBP million                1
##   GEL million                1
##   GHS million                1
##   HKD million                1
##   HRK million                1
##   HuF million                1
##   IDR million                1
##   ILS million                1
##   INR million                1
##   IQD million                1
##   IRR million                1
##   ISK million                1
##   JPY million                1
##   KES million                1
##   KHR million                1
##   KRW million                1
##   KWD million                1
##   KZT million                1
##   LKR million                1
##   MAD million                1
##   MXN million                1
##   MYR million                1
##   NGN million                1
##   NOK million                1
##   NZD million                1
##   PAB million                1
##   PEN million                1
##   PHP million                1
##   PKR million                1
##   PLN million                1
##   QAR million                1
##   RON million                1
##   RUB million                1
##   SAR million                1
##   SEK million                1
##   SGD million                1
##   THB million                1
##   TND million                1
##   TRY million                1
##   TWD million                1
##   UAH million                1
##   USD million                3
##   UYU million                1
##   UZS million                1
##   VND million                1
##   XAF million                1
##   ZAR million                1

La tabla nos muestra la cantidad promedio en millones producida en 2021 por cada unidad monetaria. En este caso, vemos que en 2021 se produjo en promedio más de 1MM de “currencies” (no se puede definir una unidad monetaria específica debido a que estamos ponderando distintas monedas internacionales). Conforme se analiza la tabla, vemos que el euro generó 18 veces el promedio de producción de cartón estimado para 2021, es decir, es la moneda internacional que más produjo cartón a nivel internacional en 2021. La siguiente moneda con mayor capacidad de producción fue USD millions.

Gráficas de datos Cualitativas y Cuantitativas

Cualitativa con Unit

barplot(bd2, xlab='Tipo de Moneda',
        ylab='Frecuencia Relativa', las=1)

La gráfica nos muestra que de acuerdo a la frecuencia relativa de producción, Indonesia es la unidad monetaria que más cartón ha entregado.

Cuantitativa con Total_Produccion

bd3 <- bd1
aggregate(x=bd3$Total_Produccion, by=list(bd3$Geography),FUN=sum)
##                 Group.1 sum.bd3$Total_Produccion
## 1               Algeria                  26366.2
## 2                Angola                   4172.7
## 3             Argentina                 757754.2
## 4             Australia                  21642.9
## 5               Austria                  10233.5
## 6            Azerbaijan                    302.3
## 7            Bangladesh                1009403.0
## 8               Belarus                   2931.2
## 9               Belgium                   6339.5
## 10               Brazil                 129369.8
## 11             Bulgaria                   3166.2
## 12             Cambodia                1685394.4
## 13             Cameroon                 197101.1
## 14               Canada                  78979.4
## 15                Chile                6391369.9
## 16                China                1896358.2
## 17             Colombia               15542263.1
## 18           Costa Rica                 967034.3
## 19              Croatia                   8719.9
## 20                 Cuba                    619.6
## 21               Cyprus                    171.5
## 22       Czech Republic                 178808.7
## 23              Denmark                  32238.2
## 24   Dominican Republic                  37293.6
## 25              Ecuador                    949.5
## 26                Egypt                  96033.6
## 27              Estonia                    387.5
## 28             Ethiopia                   5442.2
## 29              Finland                   2612.9
## 30               France                  33450.4
## 31              Georgia                    194.3
## 32              Germany                  77218.5
## 33                Ghana                    673.7
## 34               Greece                   2573.7
## 35     Hong Kong, China                   1247.2
## 36              Hungary                1504747.7
## 37              Iceland                   5561.8
## 38                India                2264525.5
## 39            Indonesia              204523301.8
## 40                 Iran              186021771.8
## 41                 Iraq                  11680.2
## 42              Ireland                   1873.4
## 43               Israel                  22710.5
## 44                Italy                  50972.2
## 45                Japan               15807772.3
## 46           Kazakhstan                 203941.1
## 47                Kenya                 112343.7
## 48               Kuwait                    251.3
## 49               Latvia                    463.0
## 50            Lithuania                   1775.1
## 51           Luxembourg                      0.0
## 52             Malaysia                  23655.6
## 53               Mexico                 738215.0
## 54              Morocco                  16625.1
## 55          Netherlands                  13921.1
## 56          New Zealand                   7644.6
## 57              Nigeria                 206027.0
## 58               Norway                  11525.8
## 59             Pakistan                 628812.7
## 60               Panama                    221.3
## 61                 Peru                   5083.5
## 62          Philippines                 302208.8
## 63               Poland                 118115.9
## 64             Portugal                   5366.3
## 65          Puerto Rico                    537.2
## 66                Qatar                    189.5
## 67              Romania                  16388.7
## 68               Russia                1590911.6
## 69         Saudi Arabia                  36787.1
## 70            Singapore                   3636.7
## 71             Slovakia                   1317.9
## 72             Slovenia                   1137.3
## 73         South Africa                 277898.6
## 74          South Korea               59825405.8
## 75                Spain                  31015.4
## 76            Sri Lanka                 254492.0
## 77               Sweden                  60578.6
## 78          Switzerland                   5331.3
## 79               Taiwan                 615169.6
## 80             Thailand                 201398.4
## 81              Tunisia                   2715.6
## 82               Turkey                 195406.5
## 83              Ukraine                 128095.2
## 84 United Arab Emirates                  12957.3
## 85       United Kingdom                  30332.9
## 86              Uruguay                  83173.7
## 87                  USA                 323594.0
## 88           Uzbekistan                5103054.3
## 89              Vietnam              198028864.1

En la tabla anterior se muestra el total de producción generado por cada país. Haciendo una ponderación de los 5 países que mayor producción de cartón tienen (haciendo conteo histórico de 2016 a 2021), vemos que se destacan Irán, Vietnam, Corea del Sur, Japón e Indonesia.

hist(log(bd1$Total_Produccion), main = "Histograma de Producción Total", xlab="Producción Total", 
     ylab="Frecuencia", col="blue1")

En la gráfica anterior se simboliza la distribución de la muestra respecto a la producción total y la frecuencia de ésta. De acuerdo a la frecuencia total, vemos que se tiene una mayor producción por frecuencia entre 10 y 15, es decir, la producción total es más alta y tiene una frecuencia mayor a 15 que se muestra como el más elevado en el histograma.

Gráficas de Dispersión

Relación Geography con Producción Total

ggplot(bd1, aes(x=Total_Produccion, y=Geography)) + 
  geom_point(shape=19, size=3) + labs(title = "Relación entre los Países y la Producción Total",caption ="Passport_ProducciónCarton",x="Producción_Total", y="Geography") + theme_classic()

En la gráfica anterior se muestra la relación entre los países y la producción total. Se ve que hay una dispersión mayor para los países en el centro de la gráfica. Esto significa que hay más irregularidad en la producción total que han generado.

boxplot=subset(bd1,select = -c(Total_Produccion,Geography))
boxplot(bd1$Total_Produccion, main= "Total de producción")

En la gráfica anterior vemos el total de producción de acuerdo a la geografía. Al igual que la gráfica anterior, hay una correlación mayor acorde al total de producción.

Vol<-ts(boxplot,start=c(2016,1),frequency=12)
ts_plot(Vol,
        title = "Desempeño de la Industria Automotriz: Producción de cartón global de 2016 a 2021",
        Ytitle = "Unidades en miles",
        Xtitle = "Años", 
        slider = TRUE)

En esta gráfica se ve el desempeño de la industria automotriz de 2016 a 2021. En general, se muestra que el total de producción de cartón a nivel global fue mayor en 2021 contra otros años.

Predicción del Desempeño de la Industria Automotriz

Importar base de datos

bd5 <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd2 csv2.csv")
summary(bd5)
##   Geography             Unit                Año         Produccion      
##  Length:534         Length:534         Min.   :2016   Min.   :       0  
##  Class :character   Class :character   1st Qu.:2017   1st Qu.:     501  
##  Mode  :character   Mode  :character   Median :2018   Median :    4826  
##                                        Mean   :2018   Mean   : 1327061  
##                                        3rd Qu.:2020   3rd Qu.:   43907  
##                                        Max.   :2021   Max.   :63857942
sum(is.na(bd5))
## [1] 0
bd5$Total_Produccion<- bd1$X2016+bd1$X2017+bd1$X2018+bd1$X2019+bd1$X2020+bd1$X2021

summary(bd5)
##   Geography             Unit                Año         Produccion      
##  Length:534         Length:534         Min.   :2016   Min.   :       0  
##  Class :character   Class :character   1st Qu.:2017   1st Qu.:     501  
##  Mode  :character   Mode  :character   Median :2018   Median :    4826  
##                                        Mean   :2018   Mean   : 1327061  
##                                        3rd Qu.:2020   3rd Qu.:   43907  
##                                        Max.   :2021   Max.   :63857942  
##  Total_Produccion   
##  Min.   :        0  
##  1st Qu.:     3166  
##  Median :    30333  
##  Mean   :  7962363  
##  3rd Qu.:   254492  
##  Max.   :204523302
str(bd5)
## 'data.frame':    534 obs. of  5 variables:
##  $ Geography       : chr  "Azerbaijan" "Bangladesh" "Cambodia" "China" ...
##  $ Unit            : chr  "AZN million" "BDT million" "KHR million" "CNY million" ...
##  $ Año             : int  2016 2016 2016 2016 2016 2016 2016 2016 2016 2016 ...
##  $ Produccion      : num  40.6 115106.8 247100 309386.9 212.1 ...
##  $ Total_Produccion: num  302 1009403 1685394 1896358 1247 ...
sum(is.na(bd5))
## [1] 0

Modelos de regresión lineal múltiple

Modelos de regresión lineal múltiple: Producción de cartón en 2022 a nivel global

regresion <- lm(Total_Produccion ~ Geography + Unit + Año + Produccion, data=bd5)
summary(regresion)
## 
## Call:
## lm(formula = Total_Produccion ~ Geography + Unit + Año + Produccion, 
##     data = bd5)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -2.765e-06 -9.300e-09  6.000e-10  8.700e-09  3.720e-06 
## 
## Coefficients: (69 not defined because of singularities)
##                                 Estimate Std. Error    t value Pr(>|t|)    
## (Intercept)                    2.637e+04  1.543e-05  1.709e+09  < 2e-16 ***
## GeographyAngola               -2.219e+04  1.719e-07 -1.291e+11  < 2e-16 ***
## GeographyArgentina             7.314e+05  1.719e-07  4.254e+12  < 2e-16 ***
## GeographyAustralia            -4.723e+03  1.719e-07 -2.748e+10  < 2e-16 ***
## GeographyAustria              -1.613e+04  1.719e-07 -9.384e+10  < 2e-16 ***
## GeographyAzerbaijan           -2.606e+04  1.719e-07 -1.516e+11  < 2e-16 ***
## GeographyBangladesh            9.830e+05  1.719e-07  5.718e+12  < 2e-16 ***
## GeographyBelarus              -2.343e+04  1.719e-07 -1.363e+11  < 2e-16 ***
## GeographyBelgium              -2.003e+04  1.719e-07 -1.165e+11  < 2e-16 ***
## GeographyBrazil                1.030e+05  1.719e-07  5.992e+11  < 2e-16 ***
## GeographyBulgaria             -2.320e+04  1.719e-07 -1.350e+11  < 2e-16 ***
## GeographyCambodia              1.659e+06  1.719e-07  9.650e+12  < 2e-16 ***
## GeographyCameroon              1.707e+05  1.719e-07  9.932e+11  < 2e-16 ***
## GeographyCanada                5.261e+04  1.719e-07  3.061e+11  < 2e-16 ***
## GeographyChile                 6.365e+06  1.720e-07  3.700e+13  < 2e-16 ***
## GeographyChina                 1.870e+06  1.719e-07  1.088e+13  < 2e-16 ***
## GeographyColombia              1.552e+07  1.727e-07  8.984e+13  < 2e-16 ***
## GeographyCosta Rica            9.407e+05  1.719e-07  5.472e+12  < 2e-16 ***
## GeographyCroatia              -1.765e+04  1.719e-07 -1.026e+11  < 2e-16 ***
## GeographyCuba                 -2.575e+04  1.719e-07 -1.498e+11  < 2e-16 ***
## GeographyCyprus               -2.619e+04  1.719e-07 -1.524e+11  < 2e-16 ***
## GeographyCzech Republic        1.524e+05  1.719e-07  8.868e+11  < 2e-16 ***
## GeographyDenmark               5.872e+03  1.719e-07  3.416e+10  < 2e-16 ***
## GeographyDominican Republic    1.093e+04  1.719e-07  6.356e+10  < 2e-16 ***
## GeographyEcuador              -2.542e+04  1.719e-07 -1.478e+11  < 2e-16 ***
## GeographyEgypt                 6.967e+04  1.719e-07  4.053e+11  < 2e-16 ***
## GeographyEstonia              -2.598e+04  1.719e-07 -1.511e+11  < 2e-16 ***
## GeographyEthiopia             -2.092e+04  1.719e-07 -1.217e+11  < 2e-16 ***
## GeographyFinland              -2.375e+04  1.719e-07 -1.382e+11  < 2e-16 ***
## GeographyFrance                7.084e+03  1.719e-07  4.121e+10  < 2e-16 ***
## GeographyGeorgia              -2.617e+04  1.719e-07 -1.522e+11  < 2e-16 ***
## GeographyGermany               5.085e+04  1.719e-07  2.958e+11  < 2e-16 ***
## GeographyGhana                -2.569e+04  1.719e-07 -1.495e+11  < 2e-16 ***
## GeographyGreece               -2.379e+04  1.719e-07 -1.384e+11  < 2e-16 ***
## GeographyHong Kong, China     -2.512e+04  1.719e-07 -1.461e+11  < 2e-16 ***
## GeographyHungary               1.478e+06  1.719e-07  8.599e+12  < 2e-16 ***
## GeographyIceland              -2.080e+04  1.719e-07 -1.210e+11  < 2e-16 ***
## GeographyIndia                 2.238e+06  1.719e-07  1.302e+13  < 2e-16 ***
## GeographyIndonesia             2.045e+08  2.788e-07  7.334e+14  < 2e-16 ***
## GeographyIran                  1.860e+08  2.635e-07  7.059e+14  < 2e-16 ***
## GeographyIraq                 -1.469e+04  1.719e-07 -8.543e+10  < 2e-16 ***
## GeographyIreland              -2.449e+04  1.719e-07 -1.425e+11  < 2e-16 ***
## GeographyIsrael               -3.656e+03  1.719e-07 -2.127e+10  < 2e-16 ***
## GeographyItaly                 2.461e+04  1.719e-07  1.431e+11  < 2e-16 ***
## GeographyJapan                 1.578e+07  1.727e-07  9.136e+13  < 2e-16 ***
## GeographyKazakhstan            1.776e+05  1.719e-07  1.033e+12  < 2e-16 ***
## GeographyKenya                 8.598e+04  1.719e-07  5.001e+11  < 2e-16 ***
## GeographyKuwait               -2.611e+04  1.719e-07 -1.519e+11  < 2e-16 ***
## GeographyLatvia               -2.590e+04  1.719e-07 -1.507e+11  < 2e-16 ***
## GeographyLithuania            -2.459e+04  1.719e-07 -1.430e+11  < 2e-16 ***
## GeographyLuxembourg           -2.637e+04  1.719e-07 -1.534e+11  < 2e-16 ***
## GeographyMalaysia             -2.711e+03  1.719e-07 -1.577e+10  < 2e-16 ***
## GeographyMexico                7.118e+05  1.719e-07  4.141e+12  < 2e-16 ***
## GeographyMorocco              -9.741e+03  1.719e-07 -5.666e+10  < 2e-16 ***
## GeographyNetherlands          -1.245e+04  1.719e-07 -7.239e+10  < 2e-16 ***
## GeographyNew Zealand          -1.872e+04  1.719e-07 -1.089e+11  < 2e-16 ***
## GeographyNigeria               1.797e+05  1.719e-07  1.045e+12  < 2e-16 ***
## GeographyNorway               -1.484e+04  1.719e-07 -8.633e+10  < 2e-16 ***
## GeographyPakistan              6.024e+05  1.719e-07  3.504e+12  < 2e-16 ***
## GeographyPanama               -2.614e+04  1.719e-07 -1.521e+11  < 2e-16 ***
## GeographyPeru                 -2.128e+04  1.719e-07 -1.238e+11  < 2e-16 ***
## GeographyPhilippines           2.758e+05  1.719e-07  1.605e+12  < 2e-16 ***
## GeographyPoland                9.175e+04  1.719e-07  5.337e+11  < 2e-16 ***
## GeographyPortugal             -2.100e+04  1.719e-07 -1.222e+11  < 2e-16 ***
## GeographyPuerto Rico          -2.583e+04  1.719e-07 -1.502e+11  < 2e-16 ***
## GeographyQatar                -2.618e+04  1.719e-07 -1.523e+11  < 2e-16 ***
## GeographyRomania              -9.978e+03  1.719e-07 -5.804e+10  < 2e-16 ***
## GeographyRussia                1.565e+06  1.719e-07  9.101e+12  < 2e-16 ***
## GeographySaudi Arabia          1.042e+04  1.719e-07  6.062e+10  < 2e-16 ***
## GeographySingapore            -2.273e+04  1.719e-07 -1.322e+11  < 2e-16 ***
## GeographySlovakia             -2.505e+04  1.719e-07 -1.457e+11  < 2e-16 ***
## GeographySlovenia             -2.523e+04  1.719e-07 -1.468e+11  < 2e-16 ***
## GeographySouth Africa          2.515e+05  1.719e-07  1.463e+12  < 2e-16 ***
## GeographySouth Korea           5.980e+07  1.835e-07  3.259e+14  < 2e-16 ***
## GeographySpain                 4.649e+03  1.719e-07  2.704e+10  < 2e-16 ***
## GeographySri Lanka             2.281e+05  1.719e-07  1.327e+12  < 2e-16 ***
## GeographySweden                3.421e+04  1.719e-07  1.990e+11  < 2e-16 ***
## GeographySwitzerland          -2.103e+04  1.719e-07 -1.224e+11  < 2e-16 ***
## GeographyTaiwan                5.888e+05  1.719e-07  3.425e+12  < 2e-16 ***
## GeographyThailand              1.750e+05  1.719e-07  1.018e+12  < 2e-16 ***
## GeographyTunisia              -2.365e+04  1.719e-07 -1.376e+11  < 2e-16 ***
## GeographyTurkey                1.690e+05  1.719e-07  9.833e+11  < 2e-16 ***
## GeographyUkraine               1.017e+05  1.719e-07  5.918e+11  < 2e-16 ***
## GeographyUnited Arab Emirates -1.341e+04  1.719e-07 -7.800e+10  < 2e-16 ***
## GeographyUnited Kingdom        3.967e+03  1.719e-07  2.307e+10  < 2e-16 ***
## GeographyUruguay               5.681e+04  1.719e-07  3.304e+11  < 2e-16 ***
## GeographyUSA                   2.972e+05  1.719e-07  1.729e+12  < 2e-16 ***
## GeographyUzbekistan            5.077e+06  1.720e-07  2.952e+13  < 2e-16 ***
## GeographyVietnam               1.980e+08  2.734e-07  7.243e+14  < 2e-16 ***
## UnitAOA million                       NA         NA         NA       NA    
## UnitARS million                       NA         NA         NA       NA    
## UnitAUD million                       NA         NA         NA       NA    
## UnitAZN million                       NA         NA         NA       NA    
## UnitBDT million                       NA         NA         NA       NA    
## UnitBGN million                       NA         NA         NA       NA    
## UnitBRL million                       NA         NA         NA       NA    
## UnitBYR million                       NA         NA         NA       NA    
## UnitCAD million                       NA         NA         NA       NA    
## UnitCHF million                       NA         NA         NA       NA    
## UnitCLP million                       NA         NA         NA       NA    
## UnitCNY million                       NA         NA         NA       NA    
## UnitCOP million                       NA         NA         NA       NA    
## UnitCRC million                       NA         NA         NA       NA    
## UnitCUC million                       NA         NA         NA       NA    
## UnitCZK million                       NA         NA         NA       NA    
## UnitDKK million                       NA         NA         NA       NA    
## UnitDOP million                       NA         NA         NA       NA    
## UnitDZD million                       NA         NA         NA       NA    
## UnitEGP million                       NA         NA         NA       NA    
## UnitETB million                       NA         NA         NA       NA    
## UnitEUR million                       NA         NA         NA       NA    
## UnitGBP million                       NA         NA         NA       NA    
## UnitGEL million                       NA         NA         NA       NA    
## UnitGHS million                       NA         NA         NA       NA    
## UnitHKD million                       NA         NA         NA       NA    
## UnitHRK million                       NA         NA         NA       NA    
## UnitHuF million                       NA         NA         NA       NA    
## UnitIDR million                       NA         NA         NA       NA    
## UnitILS million                       NA         NA         NA       NA    
## UnitINR million                       NA         NA         NA       NA    
## UnitIQD million                       NA         NA         NA       NA    
## UnitIRR million                       NA         NA         NA       NA    
## UnitISK million                       NA         NA         NA       NA    
## UnitJPY million                       NA         NA         NA       NA    
## UnitKES million                       NA         NA         NA       NA    
## UnitKHR million                       NA         NA         NA       NA    
## UnitKRW million                       NA         NA         NA       NA    
## UnitKWD million                       NA         NA         NA       NA    
## UnitKZT million                       NA         NA         NA       NA    
## UnitLKR million                       NA         NA         NA       NA    
## UnitMAD million                       NA         NA         NA       NA    
## UnitMXN million                       NA         NA         NA       NA    
## UnitMYR million                       NA         NA         NA       NA    
## UnitNGN million                       NA         NA         NA       NA    
## UnitNOK million                       NA         NA         NA       NA    
## UnitNZD million                       NA         NA         NA       NA    
## UnitPAB million                       NA         NA         NA       NA    
## UnitPEN million                       NA         NA         NA       NA    
## UnitPHP million                       NA         NA         NA       NA    
## UnitPKR million                       NA         NA         NA       NA    
## UnitPLN million                       NA         NA         NA       NA    
## UnitQAR million                       NA         NA         NA       NA    
## UnitRON million                       NA         NA         NA       NA    
## UnitRUB million                       NA         NA         NA       NA    
## UnitSAR million                       NA         NA         NA       NA    
## UnitSEK million                       NA         NA         NA       NA    
## UnitSGD million                       NA         NA         NA       NA    
## UnitTHB million                       NA         NA         NA       NA    
## UnitTND million                       NA         NA         NA       NA    
## UnitTRY million                       NA         NA         NA       NA    
## UnitTWD million                       NA         NA         NA       NA    
## UnitUAH million                       NA         NA         NA       NA    
## UnitUSD million                       NA         NA         NA       NA    
## UnitUYU million                       NA         NA         NA       NA    
## UnitUZS million                       NA         NA         NA       NA    
## UnitVND million                       NA         NA         NA       NA    
## UnitXAF million                       NA         NA         NA       NA    
## UnitZAR million                       NA         NA         NA       NA    
## Año                           -2.623e-10  7.645e-09 -3.400e-02    0.973    
## Produccion                    -2.771e-14  6.441e-15 -4.302e+00 2.08e-05 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.978e-07 on 443 degrees of freedom
## Multiple R-squared:      1,  Adjusted R-squared:      1 
## F-statistic: 8.585e+28 on 90 and 443 DF,  p-value: < 2.2e-16
regresion <- lm(Total_Produccion ~ Año + Produccion, data=bd5)
summary(regresion)
## 
## Call:
## lm(formula = Total_Produccion ~ Año + Produccion, data = bd5)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -156662104   -2346480    -288323     745268   98830383 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.083e+09  5.845e+08   3.563 0.000400 ***
## Año         -1.031e+06  2.896e+05  -3.561 0.000402 ***
## Produccion   5.394e+00  7.845e-02  68.757  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 11410000 on 531 degrees of freedom
## Multiple R-squared:  0.899,  Adjusted R-squared:  0.8986 
## F-statistic:  2364 on 2 and 531 DF,  p-value: < 2.2e-16
bd5 <- data.frame(Año=2022, Produccion= 170000000)
predict(regresion,bd5)
##         1 
## 914196926

De acuerdo a los datos estimados, se ve que las variables de año y producción son igualmente significativas para la variable dependiente. En el caso de año, este tiene un impacto negativo sobre la otra y la producción tiene una estimación positiva. El modelo anterior nos muestra cuánto se estima que se producirá a nivel global en la industria del cartón para 2022. De acuerdo a una producción total aproximada de 170 millones de cartón en 2021, se espera que en 2022 se produzcan 914,196,926. En este caso, el prónostico fue realizado al crear un nuevo ‘data frame’ y al implementar la función de ‘lm’, usada para crear análisis regresivos y predictivos.

Modelos de regresión lineal múltiple: Producción de cartón en 2022 para Estados Unidos y México

Importar base de datos (3)

bd6 <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd3 csv3 (1).csv")
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
sum(is.na(bd6))
## [1] 0
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
str(bd6)
## 'data.frame':    6 obs. of  3 variables:
##  $ Año: int  2016 2017 2018 2019 2020 2021
##  $ USA: num  48847 51672 54006 55387 54651 ...
##  $ MEX: num  103443 112231 120639 128471 129871 ...

Modelo de regresión múltiple: Producción de cartón en 2022: México

regresion3 <- lm(MEX ~ USA + Año, data=bd6)
summary(regresion3)
## 
## Call:
## lm(formula = MEX ~ USA + Año, data = bd6)
## 
## Residuals:
##      1      2      3      4      5      6 
##  574.6 -373.0 -664.0  478.2 -345.3  329.5 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)   
## (Intercept) -7.614e+06  1.010e+06  -7.540  0.00484 **
## USA          2.109e+00  2.749e-01   7.674  0.00460 **
## Año          3.777e+03  5.072e+02   7.446  0.00501 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 675 on 3 degrees of freedom
## Multiple R-squared:  0.9986, Adjusted R-squared:  0.9977 
## F-statistic:  1100 on 2 and 3 DF,  p-value: 5.023e-05
regresion3 <- lm(MEX ~ Año, data=bd6)
summary(regresion3)
## 
## Call:
## lm(formula = MEX ~ Año, data = bd6)
## 
## Residuals:
##       1       2       3       4       5       6 
##  -925.5   395.3  1336.2  1701.6 -4365.0  1857.6 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -1.495e+07  1.281e+06  -11.67 0.000308 ***
## Año          7.467e+03  6.347e+02   11.77 0.000299 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2655 on 4 degrees of freedom
## Multiple R-squared:  0.9719, Adjusted R-squared:  0.9649 
## F-statistic: 138.4 on 1 and 4 DF,  p-value: 0.0002986
bd6 <- data.frame(Año=2022, Produccion= 740000)
predict(regresion3,bd6)
##        1 
## 149170.3
ggplot(bd6, aes(x=Año, y=Produccion))+
  geom_point() +
  geom_line(aes(y=Produccion), color="red", linetype="dashed") +
  geom_line(aes(y=Produccion), color="red", linetype="dashed") +
  geom_smooth(method=lm, formula=y~x, se=TRUE, level=0.95, col='blue', fill='pink2') +
  theme_light()
## geom_path: Each group consists of only one observation. Do you need to adjust
## the group aesthetic?
## geom_path: Each group consists of only one observation. Do you need to adjust
## the group aesthetic?

La predicción anterior nos arroja que hay un impacto positivo y significativo entre la variable Año y la variable dependiente. Esto significa que hay una predicción positiva de crecimiento acorde al año. De acuerdo a la producción total generada por México de 2016 a 2021 (740 M), el modelo pronóstico estima que en 2022 producirá 149,170.3. En la gráfica previa se muestra el punto de predicción. Si analizamos la producción de 2021 contra el pronóstico de 2022, se estima que la producción mexicana disminuirá. Podemos suponer que esto se debe a la deficiencia en la cadena de suministro global, así como factores económicos globales.

Modelos de regresión lineal múltiple: Producción de cartón en 2022 para Estados Unidos y México

Importar base de datos (3)

bd6 <-read.csv("C:\\Users\\danyc\\Downloads\\externa_bd3 csv3 (1).csv")
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
sum(is.na(bd6))
## [1] 0
summary(bd6)
##       Año            USA             MEX        
##  Min.   :2016   Min.   :48847   Min.   :103443  
##  1st Qu.:2017   1st Qu.:52256   1st Qu.:114333  
##  Median :2018   Median :54328   Median :124555  
##  Mean   :2018   Mean   :53932   Mean   :123036  
##  3rd Qu.:2020   3rd Qu.:55203   3rd Qu.:129521  
##  Max.   :2021   Max.   :59031   Max.   :143561
str(bd6)
## 'data.frame':    6 obs. of  3 variables:
##  $ Año: int  2016 2017 2018 2019 2020 2021
##  $ USA: num  48847 51672 54006 55387 54651 ...
##  $ MEX: num  103443 112231 120639 128471 129871 ...

Modelos de regresión lineal múltiple: Producción de cartón en 2022: Estados Unidos

regresion2 <- lm(USA ~ MEX + Año, data=bd6)
summary(regresion2)
## 
## Call:
## lm(formula = USA ~ MEX + Año, data = bd6)
## 
## Residuals:
##       1       2       3       4       5       6 
## -293.67  185.92  345.50 -187.61   63.41 -113.54 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)   
## (Intercept)  3.266e+06  8.915e+05   3.663   0.0352 * 
## MEX          4.511e-01  5.878e-02   7.674   0.0046 **
## Año         -1.619e+03  4.452e+02  -3.636   0.0358 * 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 312.1 on 3 degrees of freedom
## Multiple R-squared:  0.9951, Adjusted R-squared:  0.9918 
## F-statistic: 304.3 on 2 and 3 DF,  p-value: 0.0003435
regresion2 <- lm(USA ~ Año, data=bd6)
summary(regresion2)
## 
## Call:
## lm(formula = USA ~ Año, data = bd6)
## 
## Residuals:
##       1       2       3       4       5       6 
##  -711.2   364.2   948.3   580.0 -1905.7   724.4 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)   
## (Intercept) -3477589.1   592456.5  -5.870  0.00421 **
## Año             1749.6      293.5   5.961  0.00398 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1228 on 4 degrees of freedom
## Multiple R-squared:  0.8988, Adjusted R-squared:  0.8735 
## F-statistic: 35.53 on 1 and 4 DF,  p-value: 0.003977
bd6 <- data.frame(Año=2022, Produccion= 320000)
predict(regresion2,bd6)
##        1 
## 60055.85

Para la predicción de Estados Unidos, vemos que habrá un incremento en la producción de cartón contra 2021. Sin embargo, al analizar la producción total de México contra la producción total de Estados Unidos, vemos que la mexicana es mucho mayor. Podemos suponer que esto se debe debido a la mano de obra económica del mercado mexicano.

De acuerdo a la predicción anterior, se ve un incremento positivo para la variable México con la variable dependiente, a diferencia del año que muestra un impacto menor y negativo, pero igualmente significativo.

Pronostico del desempeño de la industria automotriz y la empresa FORM

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

Pronosticar el desempeño de la industria automotriz (EUA y MEX) para los 3 periodos de tiempo.

#file.choose()
externo<- read.csv("C:\\Users\\danyc\\Downloads\\externa_bd3 csv3.csv")

Crear serie de tiempo

produccion_mexico<- c(externo$MEX)
produccion_usa<- c(externo$USA)
produccionm<-ts(data=produccion_mexico, start=c(2016,1), frequency=1)
produccionu<-ts(data=produccion_usa, start=c(2016,1), frequency=1)
produccionm
## Time Series:
## Start = 2016 
## End = 2021 
## Frequency = 1 
## [1] 103442.8 112230.6 120638.5 128470.9 129871.3 143560.9
produccionu
## Time Series:
## Start = 2016 
## End = 2021 
## Frequency = 1 
## [1] 48847.2 51672.2 54005.8 55387.1 54651.0 59030.7
modelom<- auto.arima(produccionm, D=1)
modelou<- auto.arima(produccionu, D=1)
modelom
## Series: produccionm 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##          drift
##       8023.620
## s.e.  1752.032
## 
## sigma^2 = 19186921:  log likelihood = -48.46
## AIC=100.92   AICc=106.92   BIC=100.14
modelou
## Series: produccionu 
## ARIMA(0,1,0) 
## 
## sigma^2 = 7012061:  log likelihood = -46.5
## AIC=95   AICc=96.34   BIC=94.61
pronosticom <- forecast(modelom, level=c(95), h=4)
pronosticom
##      Point Forecast    Lo 95    Hi 95
## 2022       151584.5 142999.3 160169.7
## 2023       159608.1 147466.8 171749.5
## 2024       167631.8 152761.7 182501.8
## 2025       175655.4 158485.0 192825.8
plot(pronosticom)

pronosticou <- forecast(modelou, level=c(95), h=4)
pronosticou
##      Point Forecast    Lo 95    Hi 95
## 2022        59030.7 53840.66 64220.74
## 2023        59030.7 51690.87 66370.53
## 2024        59030.7 50041.28 68020.12
## 2025        59030.7 48650.61 69410.79
plot(pronosticou)

Pronosticar el desempeño de produccion de Form para los proximos 3 periodos de tiempo.

#file.choose()
formproduccion<- read.csv("C:\\Users\\danyc\\OneDrive - Instituto Tecnologico y de Estudios Superiores de Monterrey\\Desktop\\Form_produccionbaselimpia.csv")

Crear serie de tiempo

produccionform<- c(formproduccion$laminas_procesadas)
produccionf<-ts(data=produccionform, start=c(2022,7), end=c(2025, 12), frequency=12)

produccionf
##      Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
## 2022                           3   2   2   1   1   3
## 2023   2   5   5  10   5   1   5   7  12   4   7   1
## 2024  15   9   9   9  10  18  22  22   9  45  22  11
## 2025  22  11  11  21  11  11  11   6  11  11  11  11
modelof<- auto.arima(produccionf, D=1)

modelof
## Series: produccionf 
## ARIMA(2,1,0)(1,1,0)[12] 
## 
## Coefficients:
##           ar1      ar2     sar1
##       -0.7093  -0.3922  -0.6559
## s.e.   0.1707   0.1731   0.1338
## 
## sigma^2 = 79.45:  log likelihood = -106.7
## AIC=221.39   AICc=223.06   BIC=226.86
pronosticof <- forecast(modelof, level=c(95), h=3)
pronosticof
##          Point Forecast     Lo 95    Hi 95
## Jan 2026       16.15994 -1.310577 33.63046
## Feb 2026       10.94930 -7.244584 29.14318
## Mar 2026       12.23185 -7.267684 31.73139
plot(pronosticof)

Describe los resultados

Realizamos una serie de tiempo tanto para la base de la industria automotriz como para la base de producción de FORM, este es enfocado a las laminas procesadas cada mes y en la industria es por año. Para poder realizar este Analisis de Resultado realizamos una grafica y un modelo de Predicción por medio de la función auto.arima. Gracias a esta función, le especificamos desde que Fecha empezará a obtener datos de la base de Datos y también colocamos la frecuencia, que se refiere a cómo se comporta, en cuestión a si se va a calcular por mes o por año. Así mismo, obtuvimos para la industria tanto en México como en EU, que son los países en los que se enfoca más FORM y obtengan mejor oportunidad de crecimiento. Al realizar este modelo calculamos para los próximos 3 periodos, en este caso para el 2025 y obtuvimos los siguientes resultados: - Industria Automotriz en México:

  1. Partiendo de un margen del 95%, queriendo decir, que este modelo es más preciso por lo que al ver la grafica obtenemos que tendrá un incremento constante en los próximos 3 años, partiendo del 2022.
  2. Este crecimiento de la industria automotriz en México se estima un crecimiento del 16% para 2025, lo que beneficia a FORM para continuar produciendo en el mercado Mexicano.
  • Industria Automotriz en Estados Unidos:

    1. Para 2022 el pronostico es de 59 mil, que este se puede mantener constante en los próximos 3 años hasta 2025
    2. Se obtiene un escenario optimista con la precisión del 95%, lo que quiere decir que para finales del 2025, puede estar igual en 59 mil o aumentar hasta los 69 mil. Esto indicaría que va en aumento año con año y terminaría el 2025 con un aumento del casi 20%. Lo que indicaría algo bueno para FORM, dandole oportunidad a aumentar su cartera de clientes dentro del mercado Estadounidense y teniendo un buen impacto de la industria para los próximos periodos.
  • Empresa FORM:

    1. Se hizo el pronostico por mes y dando un periodo hasta el 2026, partiendo del 2022 con 3 en cuanto a producción de laminas procesadas, se estima que este tenga un aumento constante, ademas de que entre el 2024 y 2025 tenga un punto de pique más alto, que posteriormente volverá a estabilizarse pero que se mantendrá constante entre los 10 a 20 en producción.
    2. Se pronostica que para el 2026 se tenga un 33 en producción del área de laminas procesadas, teniendo una precisión del 95% en un escenario optimista. Así mismo este se puede mantener constante en 10 o aumentar como se comentó anteriormente y este crecimiento a términos del 2026 tomando el escenario optimista, sería de poco mas del 90% lo que sería un gran aumento para FORM. También si fuera sin el 95% para inicios del 2026 serían 16 en producción con el 60% de aumento, lo que seguiría siendo algo importante para FORM.

Listar y describir los principales 5-6 resultados / hallazgos de la actividad.

1.Recursos humanos: Uno de los hallazgos en esta base de datos es que las principales causas de bajas de empleados se debe a tres razones. Bajas por faltas, renuncia voluntaria o término de contrato y nos damos cuenta que el puesto con más rotación en la empresa es el de ayudante general. Por lo tanto podemos observar que existe una mala gestión administrativa o que los empleados no están 100% felices por lo tanto no se están esforzando lo suficiente.

La principal causa de bajas en la empresa es debido a faltas, En numero de bajas por sexo masculino y femenino las mujeres son las que más faltan generando 53 bajas en total,pero lo importante es que para los hombres también es su mayor es la razón de baja, lo cual es por faltas ya que se han presentado 25 bajas. Tomando en cuenta la lejanía de la planta esto puede ser un factor que esté generando bajas. Estos datos nos permiten ver una gráfica de dispersión que nos arroja que los ex-empleados tienen un tiempo de duración más corto a un año.

2.Merma:

-Un hallazgo importante en merma es que se está generando alrededor de 3 toneladas a 4 toneladas de merma cada 4 meses, Por lo tanto nosotros consideramos que es mucha merma la que se está generando.

-Otro punto importante es que se está generando una merma muy irregular por ejemplo de enero a abril fue una merma de 3 toneladas promedio, de abril a julio alrededor de 5 toneladas y llegó hasta generar 6 toneladas y de julio a octubre género 3 toneladas promedio pero en un mes se logró tener menos de 1 tonelada de merma.

-Por lo tanto es importante que la empresa genere menores cantidades de merma y que esta merma sea lo mayor constante posible , sabemos que puede variar dependiendo de la cantidad de pedidos pero pues lograr reducir la cantidad de merma nos ayudará a reducir costos.

3.Scrap:

-Analizando estas variables se confirma que en el área de pre-producción,Es donde se genera la mayoría del scrap en su mayoría se genera casi el 85% de scrap, que generan dentro de la empresa, por lo tanto es algo alarmante por lo tanto se tienen que tomar decisiones importantes para poder realizar cambios en esta área para reducir la cantidad de scrap.

-Un punto importante es que con la ayuda de un gráfica lineal, nos dimos cuenta de cuál fue el día en el mes de agosto que generó más scrap,por lo que se puede decir que en el día que se cometieron más errores fue el día 24 de agosto, por lo tanto debemos de observar que es lo que pasó este día en la planta, o si también este factor se está repitiendo mes con mes.

4.Delivery Plan:

-Nos damos cuenta que en esta área de la empresa que es delivery plan, nos muestra que el cliente potencial es Hella, ya que cuenta con mayores pedidos , el segundo lugar para FORM es TRMX.

-Hella es la empresa que más pedidos tiene para FORM siendo alrededor de 225,000 y TRMX lo sigue con 80,000 pedidos. También se analizó que septiembre es uno de los meses fuertes para la empresa en esta área ya que se incrementaron los pedidos establecidos.

5.Delivery Performance:

-Se encontraron hallazgos importantes en esta base de datos como son, que FORM cuenta con dos clientes con mayor Delay. Estos clientes son MAHLE y PRINTEL. Pero en este caso lo que se analizó es que el cliente con mayor dilación es MAHLE, Por lo tanto nosotros recomendaremos a FORM mantener una mejor logística y eficiencia con el objetivo de generar que la empresa tenga una mejor referencia y mucho más confianza con las entregas.

6.Producción

-La primera observación ene producción que nos llama la atención es saber cuál es el cliente más importante para FORM, por lo que en este análisis nos desarrollo que Stabilus 1, es el cliente potencial de la empresa en el área de producción. Analizando los meses de julio , agosto y septiembre nos dimos cuenta que agosto es el mes con más producción, alrededor de 35,000 piezas programadas.

-Se analizó que en la estación c1 y c2 es la estación con mayor productividad debido a que es la que menos tiempo hace con más procesamiento de láminas. Por lo tanto esto es una ventaja que se podría analizar en esta fase de producción para aplicarla a las demás áreas.

-Un punto relevante de esta investigación que nos demostró un gráfico de dispersión es que si se le dedica tiempo de calidad que se le otorga al cliente, la empresa realiza los procesos de una manera mucho más eficiente y detallada, generando productos de calidad y más pronto.

7.Base de datos externa.

-En esta base de datos externa se analizó una serie de tiempo enfocada principalmente en EUA y México ya que son las principales áreas de interés para la empresa de FORM.

-Un hallazgo es que la industria automotriz en México se mantendrá en constante crecimiento en un lapso de 3 años en un futuro. Con un pronóstico de un 95% lo cual es muy óptimo a que suceda.

-Si se analiza hasta el año 2025, existe un 16% de crecimiento en la industria, por lo que a FORM, le conviene hoy en día continuar con la mano de obra en México y seguir vendiendo a compañías extranjeras.

-Por la parte de EUA, se espera un crecimiento para el 2025 de un 20% , por lo que nos determinó que la industria automotriz estado unidos se mantiene en constante crecimiento año tras año.

-Para la empresa de FORM, se espera que exista un crecimiento en los próximos años en lo que es la producción de láminas procesadas, se espera que este tenga un aumento constante, por lo que sería una ventaja competitiva preparar los procesos de láminas desde este año para que en los próximos años que este proceso de laminado aumente no existan tantos errores buscando perfeccionar el proceso.

Reflexion Final

¿Qué es Business Analytics? Es una combinación de habilidades, tecnologías y prácticas para la exploración e investigación del funcionamiento y los procesos empresariales que se han tenido anteriormente por un empresa, para de ese modo obtener información, poder analizar dicha información que se extrae y así impulsar la planificación estratégica empresarial. Business Analytics puede descubrir patrones y predecir tendencias considerando diferentes factores.

Existen diferentes rubros del “Business Analytics”:

  1. Análisis Descriptivo

  2. Análisis de Diagnóstico

  3. Análisis Predictivo

  4. Análisis Prescriptivo

3 objetivos deL uso de la herramienta de Business Analytics?** 1. Determinar qué conjuntos de datos son significantes y útiles para poder analizar y conocer el desempeño de la empresa y cuáles pueden aumentar los ingresos y disminuir los costos.

  • Ejemplo: productividad y eficencia.
  1. Analizar y transformar los datos en información útil, identificar y anticipar tendencias y resultados. Simplificar información para hacerla más sencilla de entender y visual.

  2. Tomar decisiones empresariales más inteligentes basadas en datos.

  • Ejemplo: Análisis del comportamiento de los clientes, disminución de costo, evitar mermas, aprovechamiento de tiempos y materiales, eficiencia y eficacia.

¿Cuál es la relación entre Business Analytics y Business Intelligence? BI sirve para evaluar, optimizar y coordinar las operaciones internas de una empresa. Trata de aprovechar todo el potencial de los datos que genera una empresa en todas sus actividades diarias y analizar estos datos para obtener información de valor sobre la toma de decisiones.Ayuda para entender el histórico y el como evolucionan los datos. Y como mencionamos anteriormente Business Analytics con el analisis de la información de una empresa logra puede llegar a desubrir patrones, explicaciones del porque de los mismos y predecir tendencias o hechos que pueden llegar a pasar en el negocio.

Estos dos términos tienen una alta relación entre ellas ya que en pocas palabras la Inteligencia de Negocios es el hacer análisis de los datos obtenidos y Analítica de Negocios es predicción a partir de los datos que se obtuvieron con el análisis. Una con lleva a la otra y trabajan juntas para obtener el resultado buscado de un análisis de datos que contenga la información relevante y significativa que nos pueda mostrar predicciones del comportamiento ya sea de la empresa, de la economía, de los ingresos, de los clientes y más. Ambas son necesarias para extraer un buen análisis de la información de una empresa, ya que una analis dos, los organiza y extra aquellos relevantes y la otra puede lograr las pedicciones y análisis.

LS0tDQp0aXRsZTogPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+KipFbnRyZWdhYmxlIDIuNCBGT1JNKioNCmF1dGhvcjogIkVxdWlwbyAyIg0KZGF0ZTogIjIwMjItMTAtMDMiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRoZW1lOiBjb3Ntbw0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCiMgPGltZyBzcmM9ICJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXGxvZ28ucG5nIiAvPg0KDQoNCmBgYHtyfSANCg0Ka25pdHI6OmluY2x1ZGVfdXJsKCJodHRwczovL2Zvcm0uY29tLm14LyIpDQoNCmBgYA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPioqwr9RdWllbiBlcyBGb3JtPyoqKg0KRk9STSBlcyB1bmEgZW1wcmVzYSBtZXhpY2FuYSBkZWRpY2FkYSBhIGdlbmVyYXIgc29sdWNpb25lcyBpbnRlZ3JhbGVzIGRlIGVtcGFxdWUgcGFyYSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpei4gRnVlIGZ1bmRhZGEgZW4gZWwgMjAxMSBwb3IgRmVsaXBlIEZsb3JlcyBHYXJjw61hIHkgaG95IGVuIGTDrWEgY3VlbnRhIGNvbiBtw6FzIGRlIDEzMCBlbXBsZWFkb3MuIEZPUk0gdG9tYSBncmFuIGltcG9ydGFuY2lhIGEgc2VyIHBhcnRlIGRlIHVuIGVudG9ybm8gc29zdGVuaWJsZSwgcG9yIGxvIHF1ZSBkaXNlw7FhIGVtcGFxdWVzIGVjb2zDs2dpY29zIGdlbmVyYW5kbyB1biBpbXBhY3RvIHBvc2l0aXZvIGFsIG1lZGlvIGFtYmllbnRlLCBlcyBwb3IgZWxsbyBxdWUgc3UgcHJpbmNpcGFsIG1hdGVyaWFsIGVzIGVsIGNhcnTDs24sICBjb24gZWwgY3VhbCBvYnRpZW5lbiBlbCA1MCUgZGUgc3VzIGdhbmFuY2lhcyB5IHJlcHJlc2VudGEgZWwgOTAlIGRlIHN1cyBnYXN0b3MgeSBjb3N0b3MuIFBvciBlbGxvIGxhIGltcG9ydGFuY2lhIGRlIHVuYSBidWVuYSBsb2fDrXN0aWNhIHkgY2FkZW5hIGRlIHN1bWluaXN0cm9zIGVuIEZPUk0sIHBhcmEgb3B0aW1pemFyICB5IGVmaWNpZW50aXphciB5IGRlIGVzZSBtb2RvIHRlbmVyIHJlbnRhYmlsaWRhZC4gDQoNCg0KIyAqKkVudHJlZ2FibGUgMi40IEVxdWlwbyAyKioNCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKjEuIFNjcmFwKiogDQoNCiMjIExsYW1hciBiYXNlIGRlIGRhdG9zLg0KDQpgYGB7cn0NCiNmaWxlLmNob29zZSgpDQpTQ1JBUDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXEZPUk0gLSBTY3JhcCBMaW1waWEgLmNzdiIpDQpgYGANCg0KIyMgRW50ZW5kZXIgQmFzZSBkZSBEYXRvcw0KYGBge3J9DQpyZXN1bWVuIDwtIHN1bW1hcnkoU0NSQVApDQpyZXN1bWVuDQpgYGANCg0KIyMgKjEuwr9DdcOhbnRhcyB2YXJpYWJsZXMgeSBjdcOhbnRvcyByZWdpc3Ryb3MgdGllbmUgbGEgYmFzZSBkZSBkYXRvcz8qDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6UmVkIj4gUj0gMjUwIHJlZ2lzdHJvcyB5IDkgdmFyaWFibGVzIDwvY2VudGVyPg0KYGBge3J9DQpzdHIoU0NSQVApDQojbGlicmFyeShwc3ljaCkNCiNpbnN0YWxsLnBhY2thZ2VzKCJwc3ljaCIpDQojZGVzY3JpYmUoRk9STSkNCmBgYA0KDQoqKk5vdGE6KipFbiBlc3RhIGJhc2UgZGUgZGF0b3Mgc2UgZWxpbWluYXJvbiBsYSBjb2x1bWFuYSBxdWUgbm8gZXJhIHJlbGV2YW50ZSBwYXJhIGVsIGFuYWxpc2lzLFNlIGVsaW1pbmFuIFJlZmVyZW5jaWEsIFByb2R1Y3RvLCBVbmlkYWQuZGUubWVkaWRhICwgVWJpY2FjacOzbi5kZS5kZXNlY2hvLCBFc3RhZG8sIGRlYmlkbyBhIHF1ZSBzb24gaXJyZWxldmFudGVzLCBwb3IgcXVlIGVzIGVsIG1pc21vIGRhdG8gcGFyYSB0b2RvcyBsb3MgcmVnaXN0cm9zLlBvciBsbyB0YW50byBlcyBpcnJlbGV2YW50ZS4gDQoNCmBgYHtyfQ0KYmQxPC0gU0NSQVANCmJkMTwtc3Vic2V0KFNDUkFQLHNlbGVjdD0tYyhSZWZlcmVuY2lhLCBVbmlkYWQuZGUubWVkaWRhICwgVWJpY2FjacOzbi5kZS5kZXNlY2hvLCBFc3RhZG8pKQ0Kc3RyKGJkMSkNCnN1bW1hcnkoYmQxKQ0KYGBgDQoNCiMjICoyLiAqUGFyYSBlbCBjYXNvIGRlIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGNvbnNpZGVyYXIgbGEgcG9zaWJpbGlkYWQgZGUgcmVlbXBsYXphciBsYSBwcmVzZW5jaWEgZGUg4oCcbWlzc2luZyB2YWx1ZXPigJ0gY29uIGVzdGFkw61zdGljb3MgZGVzY3JpcHRpdm9zIChwb3IgZWplbXBsbywgbWVkaWEsIG1lZGlhbmEsIG1vZGEpLioNCg0KDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQojaW5zdGFsbC5wYWNrYWdlcygibWlyYWdlIikNCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQpsaWJyYXJ5KGRwbHlyKQ0KI2xpYnJhcnkobWlyYWdlKQ0KDQpgYGANCg0KIyMgVGVjbmljYSA1OlZhbG9yZXMgZmFsdGFudGVzDQojIyMgwr9DdWFudG9zIE4vQSB0ZW5nbyBlbiBtaSBiYXNlIGRlIGRhdG9zPw0KDQojRGViaWRvIGEgcXVlIGVuIGxhIGJhc2UgZGUgZGF0b3Mgbm8gc2UgZW5jdWVudHJhbiBNaXNzaW5nIFZhbHVlcywgZW4gZXN0YSBiYXNlIGRlIGRhdG9zIG5vIHNlIHB1ZWRlbiByZW1wbGF6YXIgdmFsb3JlcyBwb3IgbWVkaWEsIG1lZGlhbmEgeSBtb2RhIHlhIHF1ZSBubyBhcGxpY2EuIA0KYGBge3J9DQoNCiNiZDE8LVNDUkFQDQojYmQxDQoNCnN1bShpcy5uYShiZDEpKQ0Kc3VtKGlzLm5hKFNDUkFQKSkNCnNhcHBseShiZDEsIGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpDQpzYXBwbHkoU0NSQVAsIGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpDQpgYGANCg0KIyMjIENhbWJpYXIgY29sdW1uYXMgeSB2YXJpYWJsZXMgDQoqQ2FtYmlhciBsb3Mgbm9tYnJlcyBkZSBsYXMgY29sdW1uYXMgLyB2YXJpYWJsZXMgYSBub21icmVzIG3DoXMgY29ydG9zIHkgZXNwZWPDrWZpY29zLiBQb3IgZWplbXBsbywgbXVuaWNpcGlvIOKGkiBtcGlvLCBzYWxhcmlvIG3DrW5pbW8gZGlhcmlvIOKGkiBzYWxhcmlvX21pbi4qDQoNCmBgYHtyfQ0KI3NlbGVjY2lvbmFyIGNvbHVtbmFzIC8gdmFyaWFibGVzLg0KYmQxPC1TQ1JBUCAlPiUgc2VsZWN0KG9uZV9vZignRmVjaGEnLCdIb3JhJywnUHJvZHVjdG8nLCdDYW50aWRhZCcsJ1ViaWNhY2nDs24uZGUub3JpZ2VuJykpDQoNCiNSZW5vbWJyYXIgbGFzIGNvbHVtbmFzIC92YXJpYWJsZXMgc2VsZWNjaW9uYWRhcy4gDQpjb2xuYW1lcyhiZDEpIDwtYyAoJ0ZlY2hhJywnSG9yYScsJ1Byb2QuJywnQ2FudC4nLCdPcmlnZW4nKQ0KDQpgYGANCg0KKipOb3RhOioqIFNlIGNhbWJpYXJvbiBsb3Mgbm9tYnJlcyBkZSBsYXMgdmFyaWFibGVzIGEgbm9tYnJlcyBtYXMgY29ydG9zLiBQYXJhIG5vIGNvbnRhciBjb24gbm9tYnJlcyBsYXJnb3MuDQoNCiMjIFRhYmxhIGRlIGVzdGFkw61zdGljb3MgZGVzY3JpcHRpdm9zDQoqQ3JlYXIgdGFibGEgcXVlIG11ZXN0cmUgbG9zIHByaW5jaXBhbGVzIGVzdGFkw61zdGljb3MgZGVzY3JwdGl2b3MgKG1lZGlhLG1lZGlhbmEsIG1vZGEsIGRlc3ZpYWNpw7NuIGVzdGFuZGFyKSBkZSBjYWRhIHVuYSBkZSBsYXMgdmFyaWFibGVzIHBhcmEgY2FkYSBiYXNlIGRlIGRhdG9zLiBDb21lbnRhciBicmV2ZW1lbnRlIGxvcyBwcmluY2lwYWxlcyByZXN1bHRhZG9zIHF1ZSBzZSBtdWVzdHJhbiBlbiBsYSB0YWJsYS4qDQoNCmBgYHtyfQ0KI0RFU0NBUkdBUiBFTCBQQVFVRVRFDQojaW5zdGFsbC5wYWNrYWdlcygia2tibGVFeHRyYSIpIA0KDQoNCiNzdW1tYXJ5KGJkMSkNCiNkZXNjcmliZShiZDEpDQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJzZCIpDQojaW5zdGFsbC5wYWNrYWdlcygibW9kZWVzdCIpDQojbGlicmFyeShtb2RlZXN0KQ0KI3NkKEZPUk1fMSRLaWxvLCBuYS5ybSA9IEZBTFNFKQ0KI2luc3RhbGwucGFja2FnZXMoImRwbHlyIikNCiNsaWJyYXJ5KGRwbHlyKQ0KDQojbGlicmFyeShrYmxlRXh0cmEpDQpzdW1tYXJ5KGJkMSkNCmBgYA0KDQoNCmBgYHtyfQ0Kc2QoYmQxJENhbnRpZGFkLCBuYS5ybT0gVFJVRSkgIA0KDQpWYXJpYWJsZTwtYygiQ2FudC4iKQ0KTWVkaWFuYTwtYygiMi4wMCIpDQpNZWRpYSA8LSBjKCI2LjY5NiIpDQpNb2RhIDwtIGMoIjEiKSAjRVhDRUwgDQpEZXN2aWFjacOzbl9lc3RhbmRhcjwtYygiMTEuODQ4ODUiKQ0KdGFibGUxIDwtIGRhdGEuZnJhbWUgKFZhcmlhYmxlLCBNZWRpYW5hLCBNZWRpYSwgTW9kYSwgRGVzdmlhY2nDs25fZXN0YW5kYXIpDQprbml0cjo6a2FibGUodGFibGUxKQ0KYGBgDQoNCg0KIyNDcmVhciAxLTIg4oCcdGltZSBzZXJpZXMgcGxvdHPigJ0gKGxpbmUgcGxvdCkgcXVlIG11ZXN0cmFuIGxhIGRpc3BlcnNpw7NuIGRlIHZhcmlhYmxlcyBzZWxlY2lvbmFkYXMuDQoNCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KI2luc3RhbGwucGFja2FnZXMoImJhcnBsb3QiKQ0KbGlicmFyeShnZ3Bsb3QyKQ0Kc3VtbWFyeShiZDEpDQpnZ3Bsb3QoYmQxLGFlcyh4PUNhbnQuKSkrDQogIGdlb21fbGluZShhZXMoeT1PcmlnZW4pLGNvbG9yPSJSZWQiKSsNCiAgbGFicyh4PSJDYW50Iix5PSJPcmlnZW4iLCBjb2xvcj0iTGVnZW5kIikrDQogICBnZ3RpdGxlKCJNYXlvcmVzIGNhdGlkYWRlcyBkZSBTY3JhcCBwb3Igb3JpZ2VuIikNCmBgYA0KDQoNCiMjIyAqSW5mcm9tYWPDrW9uIFJlbGV2YW50ZS4qDQoNCkVuIGVzdGEgYWN0aXZpZGFkIGRlIGxhIGxpbXBpYSB5IG9yZ2FuaXphY2nDs24gZGUgbGEgYmFzZSBkZSBkYXRvcyBkZSBTY3JhcC4gTm9zIGRpbW9zIGN1ZW50YXMgcXVlIGxhIGJhc2UgZGUgZGF0b3MgY29udGFiYSBjb24gZGlzdGludGFzIHZhcmlhYmxlcyBxdWUgbm8gZXJhbiB0YW4gcmVsZXZhbnRlcyBwYXJhIGFuYWxpemFyIGxhIGJkIHNjcmFwLiBQb3IgbG8gdGFudG8gZGVjaWRpb21vcyBlbGltaW5hcmxhcyBwYXJhIGNvbnRhciBjb24gbWVub3MgdmFyaWFibGVzIHkgYXNpIHBvZGVyIHJlYWxpemFyIHVuIG1lam9yIGFuYWxpc2lzLiANCg0KRW4gZXN0ZSBhbmFsaXNpcyBub3MgZGltb3MgY3VlbnRhIHF1ZSBsb3MgZGF0b3MgZXN0YWJhbiBvcmduYWl6YWRvcyBlcyBkZWNpciBubyBjb250YWJhbiBjb24gbWlzc2luZyB2YWx1ZXMgcG9yIGxvIHRhbnRvIGVzIGFsZ28gYnVlbm8gcGFyYSBlbCBhbmFsaXNpcywgZGUgdG9kb3MgbW9kb3MgZXMgaW1wb3J0YW50ZSBjb25jaWRlcmFybG9zIHNpIGVzIHJlbGV2YW50ZSBwYXJhIGVsIGFuYWxpc2lzLCBlbiBlc3RlIGNhc28gbm8gc2UgaHViaWVyYW4gZWxpbWluYWRvIHNpIG5vIHF1ZSBzZSBodWJpZXJhbiByZW1wbGF6YWRvIHBvciBsYSBtZWRpYW5hIGRlcGVuZGllbmR0ZSBkZSBsYSB2YXJpYWJsZSBxdWUgZXN0dXZpZXJhbW9zIGFuYWxpc2FuZG8uDQoNCkFuYWxpc2FuZG8gZXN0YXMgdmFyaWFibGVzIHNlIGNvbmZpcm1hIHF1ZSBlbiBlbCBhcmVhIGRlIHByZS1wcm9kdWNjacOzbixlcyBkb25kZSBzZSBnZW5lcmEgbGEgbWF5b3JpYSBkZWwgc2NyYXAgZW4gc3UgbWF5b3JpYSBzZSBnZW5lcmEgY2FzaSBlbCA4NSUgZGUgc2NyYXAsIHF1ZSBnZW5lcmFuIGRlbnRybyBkZSBsYSBlbXByZXNhLCBwb3IgbG8gdGFudG8gZXMgYWxhZ28gYWxhcm1hbnRlIHBvciBsbyB0YW50byBzZSB0aWVuZW4gcXVlIHRvbWFyIGRlY2lzaW9uZXMgaW1wb3J0YW50ZXMgcGFyYSBwb2RlciByZWFsaXphciBjYW1iaW9zIGVuIGVzdGEgYXJlYSBwYXJhIHJlZHVjaXIgbGEgY2FudGlkYWQgZGUgc2NyYXAuIA0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPioqMi4gTWVybWEqKiANCg0KIyMjIExsYW1hciBiYXNlIGRlIGRhdG9zLg0KDQpgYGB7cn0NCiNmaWxlLmNob29zZSgpDQpGT1JNIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXEZPUk0gLSBNZXJtYSBsaW1waWEuY3N2IikNCmBgYA0KDQojIyMgRW50ZW5kZXIgQmFzZSBkZSBEYXRvcw0KYGBge3J9DQpyZXN1bWVuIDwtIHN1bW1hcnkoRk9STSkNCnJlc3VtZW4NCmBgYA0KDQojIyMgKjEuwr9DdcOhbnRhcyB2YXJpYWJsZXMgeSBjdcOhbnRvcyByZWdpc3Ryb3MgdGllbmUgbGEgYmFzZSBkZSBkYXRvcz8qDQo8Y2VudGVyPiA8c3BhbiBzdHlsZT0iY29sb3I6Qmx1ZSI+IFI9IDUyIHJlZ2lzdHJvcyB5IDIgdmFyaWFibGVzIDwvY2VudGVyPg0KYGBge3J9DQpzdHIoRk9STSkNCmxpYnJhcnkocHN5Y2gpDQojaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KZGVzY3JpYmUoRk9STSkNCmBgYA0KDQoqKk5vdGE6KipFbiBlc3RhIGJhc2UgZGUgZGF0b3Mgc2UgZWxpbWluYXJvbiBsYSBjb2x1bWFuYSBxdWUgbm8gZXJhIHJlbGV2YW50ZSBwYXJhIGVsIGFuYWxpc2lzLCBTZSBlbGltaW5hcm9uIGxvcyByZWdpc3Ryb3MgZGUgdG90YWwgZGUgbWVybWEgeSBsYSBjb2x1bW5hIGRlIG1lcyB5YSBxdWUgbm8gZXJhbiBpcnJlbGV2YW50ZXMuIFBvciBsbyB0YW50byBub3MgcXVlZGFtb3MgY29uIDUyIHJlZ2lzdHJvcyB5IDIgdmFyaWFibGVzLiAgDQoNCioyLipQYXJhIGVsIGNhc28gZGUgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgY29uc2lkZXJhciBsYSBwb3NpYmlsaWRhZCBkZSByZWVtcGxhemFyIGxhIHByZXNlbmNpYSBkZSDigJxtaXNzaW5nIHZhbHVlc+KAnSBjb24gZXN0YWTDrXN0aWNvcyBkZXNjcmlwdGl2b3MgKHBvciBlamVtcGxvLCBtZWRpYSwgbWVkaWFuYSwgbW9kYSkuKg0KDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQojaW5zdGFsbC5wYWNrYWdlcygibWVyZ2UpDQpsaWJyYXJ5KGRwbHlyKQ0KI2xpYnJhcnkobWVyZ2UpDQpgYGANCg0KDQpgYGB7cn0NCiNSZW1wbGF6YXIgdmFsb3JlcyBmYWx0YW50ZXMgcG9yIGxhIG1lZGlhbmE6IE5vIHNlIHB1ZWRlbiBjYW1iYWlyIGRlYmlkbyBhIHF1ZSBsb3MgTkHCtFMgZGUgbGEgYmFzZSBkZSBkYXRvcyBubyB0aWVuZW4gaW5mb3JtYWNpw7NuLiBQb3IgbG8gdGFudG8gc2UgdmFuIGEgRWxpbWluYXIuIA0KDQpGT1JNXzE8LUZPUk0NCkZPUk1fMTwtIG5hLm9taXQoRk9STV8xKQ0Kc3VtbWFyeShGT1JNXzEpDQoNCiNzdW1tYXJ5KEZPUk0pIA0KI3N0cihGT1JNKQ0KI0ZPUk0kS2lsb3M8LWFzLm51bWVyaWMoRk9STSRLaWxvcykNCiNGT1JNPC1GT1JNICU+JSBtdXRhdGUoS2lsb3M9aWZfZWxzZShpcy5uYShLaWxvcyksbWVkaWFuKEtpbG9zLG5hLnJtID0gVCksS2lsb3MpKQ0KYGBgDQoNCioqTm90YToqKkVuIGVzdGEgYmFzZSBkZSBkYXRvcyBsYSB1bmljYSB2YXJpYWJsZSBxdWUgc2UgcHVlZGUgcmVtcGxhemFyIHBvciBsYSBtZWRpYW5hIGVzIGxhIGNvbHVtbmEgZGUga2lsb3MuIFlhIHNlIHJlbXBsYXphcm9uIGxvcyB2YWxvcmVzIGZhbHRhbnRlcyBwb3IgbGEgbWVkaWFuYS4gDQoNCg0KIyMgQ2FtYmlhciBub21icmVzIGRlIGNvbHVtbmFzIHkgdmFyaWFibGVzDQoqQ2FtYmlhciBsb3Mgbm9tYnJlcyBkZSBsYXMgY29sdW1uYXMgLyB2YXJpYWJsZXMgYSBub21icmVzIG3DoXMgY29ydG9zIHkgZXNwZWPDrWZpY29zLiBQb3IgZWplbXBsbywgbXVuaWNpcGlvIOKGkiBtcGlvLCBzYWxhcmlvIG3DrW5pbW8gZGlhcmlvIOKGkiBzYWxhcmlvX21pbi4qDQoNCmBgYHtyfQ0KI3NlbGVjY2lvbmFyIGNvbHVtbmFzIC8gdmFyaWFibGVzLg0KI0ZPUk08LUZPUk0gJT4lIHNlbGVjdCgtb25lX29mKCdGZWNoYScsJ0tpbG9zJykpDQoNCiNSZW5vbWJyYXIgbGFzIGNvbHVtbmFzIC92YXJpYWJsZXMgc2VsZWNjaW9uYWRhcy4gDQpjb2xuYW1lcyhGT1JNXzEpIDwtYyAoJ0ZjaGEnLCdLaWxvJykNCmBgYA0KDQoqUmVzcGVjdG8gYSB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzIChwb3IgZWplbXBsbywgZ8OpbmVybywgY2xpZW50ZSxtdW5pY2lwaW8sIGVzdGFkbykgaG9tb2dlbml6YXIgZWwgbm9tYnJlIGRlIGxhcyBkaWZlcmVudGVzIGNhdGVnb3LDrWFzLiAqDQoNCg0KKlJlc3BlY3RvIGEgTGEgYmFzZSBkZSBkYXRvcyBhbmFsaXphZGEgbm8gYXBsaWNhIGVsIHBhc28gZGUgaG9tb2dlbml6YXIgbGFzIHZhcmlhYmxlcyB5YSBxdWUgZW4gZXN0ZSBjYXNvIHNvbG8gc2UgY3VlbnRhIGNvbiBkb3MgdmFyaWFibGVzIGVuIGxhIGJhc2UgZGUgZGF0b3MuKiANCg0KIyMgVGFibGEgZGUgZXN0YWTDrXN0aWNvcyBkZXNjcmlwdGl2b3MNCg0KKkNyZWFyIHRhYmxhIHF1ZSBtdWVzdHJlIGxvcyBwcmluY2lwYWxlcyBlc3RhZMOtc3RpY29zIGRlc2NyaXB0aXZvcyAobWVkaWEsbWVkaWFuYSwgbW9kYSwgZGVzdmlhY2nDs24gZXN0YW5kYXIpIGRlIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMgcGFyYSBjYWRhIGJhc2UgZGUgZGF0b3MuIENvbWVudGFyIGJyZXZlbWVudGUgbG9zIHByaW5jaXBhbGVzIHJlc3VsdGFkb3MgcXVlIHNlIG11ZXN0cmFuIGVuIGxhIHRhYmxhLioNCg0KYGBge3J9DQojREVTQ0FSR0FSIEVMIFBBUVVFVEUgDQojaW5zdGFsbC5wYWNrYWdlcygia2JsZUV4dHJhIikgDQoNCg0KI3N1bW1hcnkoRk9STV8xKQ0KDQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJzZCIpDQojaW5zdGFsbC5wYWNrYWdlcygibW9kZWVzdCIpDQojbGlicmFyeShtb2RlZXN0KQ0KI3NkKEZPUk1fMSRLaWxvLCBuYS5ybSA9IEZBTFNFKQ0KI2luc3RhbGwucGFja2FnZXMoImRwbHlyIikNCiNsaWJyYXJ5KGRwbHlyKQ0KbWVkaWFuKEZPUk1fMSRLaWxvLCBuYS5ybSA9IFRSVUUpDQptZWFuKEZPUk1fMSRLaWxvLCBuYS5ybSA9IFRSVUUpDQpzZChGT1JNXzEkS2lsbywgbmEucm0gPSBGQUxTRSkNCiNtZnYoRk9STV8xJEtpbG8pDQoNCnZhcmlhYmxlPC1jKCInS2lsbyIpDQpNZWRpYW5hPC1jKCI0MDI1IikNCk1lZGlhIDwtIGMoIjQ0MTUiKQ0KTW9kYSA8LSBjKCI0MTkwIikNCkRlc3ZpYWNpw7NuX2VzdGFuZGFyPC1jKCIyNTcxLjc5MyIpDQp0YWJsZTEgPC0gZGF0YS5mcmFtZSAodmFyaWFibGUsIE1lZGlhbmEsIE1lZGlhLCBNb2RhLCBEZXN2aWFjacOzbl9lc3RhbmRhcikNCmtuaXRyOjprYWJsZSh0YWJsZTEpDQpgYGANCg0KIyMgVGltZSBTZXJpZSBQbG90cw0KKkNyZWFyIDEtMiDigJx0aW1lIHNlcmllcyBwbG90c+KAnSAobGluZSBwbG90KSBxdWUgbXVlc3RyYW4gbGEgZGlzcGVyc2nDs24gZGUgdmFyaWFibGVzIHNlbGVjaW9uYWRhcy4qDQoNCmBgYHtyfQ0KDQpGT1JNXzEkRmNoYTwtYXMuRGF0ZShGT1JNXzEkRmNoYSxmb3JtYXQ9IiVkLyVtLyV5IikgDQoNCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCmxpYnJhcnkoZ2dwbG90MikNCnN1bW1hcnkoRk9STV8xKQ0KZ2dwbG90KEZPUk1fMSxhZXMoeD1GY2hhKSkrDQogIGdlb21fbGluZShhZXMoeT1LaWxvKSxjb2xvcj0iYmx1ZSIpKw0KICBsYWJzKHg9IkZjaGEiLHk9IktpbG8iLCBjb2xvcj0iTGVnZW5kIikrDQogICBnZ3RpdGxlKCJLaWxvcyBkZSBtZXJtYSBwb3IgbWVzIikNCmBgYA0KDQojIyAqNy5JbmZvcm1hY2nDs24gUmVsZXZhbnRlICoNCg0KVW5hIHJlZmxleGnDs24gcXVlIHNlIHRvbWEgc29icmUgZXN0YSBhY3RpdmlkYWQgZXMgcXVlIHNvbG8gY29udGFtb3MgY29uIGRvcyB2YXJpYWJsZXMgcmVsZXZhbnRlcyBsYXMgY3VhbCBub3MgcHVlZGUgZGVjaXIgYWxnbywgZW4gZXN0ZSBjYXNvIHNvbG8gc2UgdXRpbGl6byBsYSBkZSBmZWNoYSB5IGxhIGRlIGxvcyBraWxvcyBkZSBtZXJtYS4gDQoNClVuIGRhdG8gaW1wYWN0YW50ZSBlcyBxdWUgbGEgbWF5b3LDrWEgZGUgbGFzIHZlY2VzIGxhIGVtcHJlc2EgdGllbmUgdW5hIG1lcm1hIGNvbnN0YW50ZSwgZXN0YSB2YXJpYSBwZXJvIGNhc2kgdG9kb3MgbG9zIG1lc2VzIGN1ZW50YW4gY29uIGFsIHJlZGVkb3IgZGUgNSB0b25lbGFkYXMgZGUgbWVybWEsIGRlIGFjdWVyZG8gY29uIGxhcyBmZWNoYXMgcXVlIG5vcyBkaWVyb24gZW4gZXN0YSBiYXNlIGRlIGRhdG9zIHNlIGFuYWxpem8gcXVlIGRlIGVuZXJvIGEgbWFyem8gZXhpc3Rpw7MgdW5hIGdyYW4gY2FudGlkYWQgZGUgbWVybWEgcXVlIGxsZWdvIGFsIHJlZGVkb3IgZGUgMTcgdG9uZWxhZGFzIGRlIG1lcm1hLCBwb3IgbG8gdGFudG8gc2UgZGViZSBkZSBhbmFsaXphciBlbiBsYSBlbXByZXNhIHF1ZSBmdWUgbG8gcXVlIHN1Y2VkacOzIGVuIGVzdGUgbGFwc28gZGUgdGllbXBvLCBwdWVkbyBzZXIgcXVlIHVuIGNsaWVudGUgY2FuY2VsYXJhIGFsZ8O6biBwZWRpZG8sIHF1ZSBoYXlhIGdlbmVyYWRvIHVuYSBncmFuIGNhbnRpZGFkIGRlIG1lcm1hLiANCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKjMuIERlbGl2ZXJ5IFBsYW4qKiANCg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpvcmFuZ2UiPioqSW1wb3J0YXIgbGEgYmFzZSBkZSBkYXRvcyoqIA0KYGBge3J9DQojZmlsZS5jaG9vc2UoKQ0KZGVsaXZlcnk8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXERFTElWRVJZLmNzdiIpDQpzdW1tYXJ5KGRlbGl2ZXJ5KQ0KYGBgDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKk9ic2VydmFjaW9uZXMqKiANCg0KMS4qU2UgaGl6byBsaW1waWV6YSBtYW51YWwgZGUgbGEgYmFzZSBkZSBkYXRvcyBwYXJhIGFjb21vZGFyIGxvcyBjbGllbnRlcyBjb21vIHZhcmlhYmxlcyB5IGxhcyBmZWNoYXMgY29tbyByZWdpc3Ryb3MuKiANCg0KMi4qU2Ugc3VzdGl0dXllcm9uIE5BcyBwb3IgY2Vyby4qDQoNCjMuKlNlIGVsaW1pbmFyb24gY29sdW1uYXMgbm8gdXNhZGFzIHkgcXVlIG5vIGFncmVlZ2FuIHZhbG9yIHBhcmEgZWwgYW5hbGlzaXMgcXVlIHNlIGJ1c2NhIGhhY2VyLioNCg0KIyMgKkRlc2NhcmdhciBsaWJyZXLDrWFzIHkgcGFxdWV0ZXMqDQpgYGB7cn0NCmxpYnJhcnkoZm9yZWlnbikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGZvcmNhdHMpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeShuYW5pYXIpDQpsaWJyYXJ5KGRsb29rcikNCmBgYA0KDQojIyAqQ3VhbnRhcyB2YXJpYWJsZXMgeSByZWdpc3Ryb3MgaGF5Kg0KYGBge3J9DQpzdHIoZGVsaXZlcnkpDQpgYGANCipDb250YW1vcyBjb24gMyB2YXJpYWJsZXMgeSAzODAgb2JzZXJ2YWNpb25lcy4qIA0KDQojIyAqQ29udGFyIHRvdGFsIGRlIHBlZGlkb3MgcG9yIGNsaWVudGUqDQpgYGB7cn0NCmRlbGl2ZXJ5U1VNID0gY29sU3VtcyhkZWxpdmVyeVs0XSkNCg0KYXMuZGF0YS5mcmFtZShkZWxpdmVyeVNVTSkNCmBgYA0KKkNvbnRhbW9zIGNvbiA1MiwwMjgxIHBlZGlkb3MqDQoNCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCmRlbGl2ZXJ5Q0xJRU5UUzwtcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcRGVsaXZlcnlDTElFTlRTLnhsc3ggLSBTaGVldDEuY3N2IikNCnN1bW1hcnkoZGVsaXZlcnlDTElFTlRTKQ0KDQpkZWxpdmVyeUNMSUVOVFMgPSBjb2xTdW1zKGRlbGl2ZXJ5Q0xJRU5UU1syOjIxXSkNCmFzLmRhdGEuZnJhbWUoZGVsaXZlcnlDTElFTlRTKQ0KYmFycGxvdC5kZWZhdWx0KGRlbGl2ZXJ5Q0xJRU5UUykNCmBgYA0KDQoqQ29uIGVzdGUgcGxvdCBwb2RlbW9zIHZlciBxdWUgaGF5IG11Y2hvcyBjbGllbnRlcyBjb24gbXV5IHBvY29zIHBlZGlkb3MuKg0KDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOm9yYW5nZSI+KipUw6ljbmljYXMgZGUgTGltcGllemEqKiANCg0KIyMjIFTDqWNuaWNhIDE6IGVsaW1pbmFyIE5Bcw0KKlNlIGRlY2lkacOzIHJlYWxpemFyIGVzdMOhIHTDqWNuaWNhIHBhcmEgYXNlZ3VyYXJub3MgZGUgcXVlIG5vIHNlIHRlbmdhIGZhbHRhIGRlIGRhdG9zIHkgZW4gY2FzbyBkZSB0ZW5lcmxvcyBldml0YXIgcXVlIGVzdGFzIGV2aXRlbiB0ZW5lciB1biBhbmFsaXNpcyBhc2VydGl2byBhbCBubyBhZ3JlZ2FyIHZhbG9yIGEgbGEgYmFzZSBkZSBkYXRvcy4qDQoNCiMjIyMgwr9DdWFudG9zIE5BIHRlbmdvIGVuIGxhIGJhc2UgZGUgZGF0b3M/DQpgYGB7cn0NCnN1bShpcy5uYShkZWxpdmVyeSkpDQpgYGANCg0KIyMjIyBDdWFudG9zIE5BIHRlbmdvIHBvciB2YXJpYWJsZT8NCioqU2FwcGx5OioqIFBhcmEgY29udGFyIGxvcyBOQS4NCmBgYHtyfQ0Kc2FwcGx5KGRlbGl2ZXJ5LCBmdW5jdGlvbih4KSBzdW0oaXMubmEoeCkpKQ0KYGBgDQoqU2UgZW5jb250csOzIHVuIHNvbG8gTkEqDQoNCiMjIyBUw6ljbmljYSAyOiBlbGltaW5hciBmaWxhcyANCipTZSBkZWNpZMOzIHJlYWxpemFyIGVzdMOhIHTDqWNuaWNhIHBhcmEgZWxpbWluYXIgbG9zIGNsaWVudGVzIHF1ZSB0aWVuZW4gbWVub3MgZGUgKio1LDAwMCoqIHBlZGlkb3MuKg0KDQojIyMjIEVsaW1pbmFyIGZpbGFzIGNvbiBlbCBub21icmUgZGUgbG9zIGNsaWVudGVzIHF1ZSBzZSBkZXNlYW4gZWxpbWluYXIuIA0KYGBge3J9DQoNCiNkZWxpdmVyeTEgPC0gc3Vic2V0IChkZWxpdmVyeTEsICBDTElFTlRFID09ICJTVEIzIikgI1BhcmEgY29uc2VydmFyIGNpZXJ0YXMgZmlsYXMNCg0KZGVsaXZlcnkxPC1kZWxpdmVyeQ0KDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IlNUQiAxIiwgXQ0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJZRiBSQU1PUyIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iSU5PQUMgUE9MWVRFQyIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iTUVSSURJQU4iLCBdDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IllBTkZFTkcgc20iLCBdDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IllGIFFSTyIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iU0VHUk9WRSIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iSEFOT04iLCBdDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IkFOVE9MSU4gVE9MVUNBIiwgXQ0KZGVsaXZlcnkxPC1kZWxpdmVyeTFbZGVsaXZlcnkxJENMSUVOVEUhPSJBTlRPTElOIEFSVEVBR0EiLCBdDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IkFCQyBRVUVSRVRBUk8iLCBdDQpkZWxpdmVyeTE8LWRlbGl2ZXJ5MVtkZWxpdmVyeTEkQ0xJRU5URSE9IlVGSSIsIF0NCmRlbGl2ZXJ5MTwtZGVsaXZlcnkxW2RlbGl2ZXJ5MSRDTElFTlRFIT0iSVNSSSIsIF0NCg0Kc3VtbWFyeShkZWxpdmVyeTEpDQpgYGANCg0KIyMgKlRhYmxhIGRlIE1lZGlhLCBNb2RhIHkgTWVkaWFuYQ0KYGBge3J9DQp0YWJsZTM8LWRlc2NyaWJlKGRlbGl2ZXJ5MSkNCmtuaXRyOjprYWJsZSh0YWJsZTMpDQpgYGANCg0KIyMgKklkZW50aWZpY2FyIHZhcmlhYmxlcyogDQoNCioqQ3VhbnRpdGF0aXZhOioqIERpc2NyZXRhLCBDb250aW51YQ0KKipFc2NhbGEgZGUgbWVkaWNpw7NuOioqSW50ZXJ2YWxvLCBSYXrDs24gDQoqKkN1YWxpdGF0aXZhKioNCioqRXNjYWxhIGRlIG1lZGljacOzbjoqKiBOb21pbmFsZXMsIE9yZGluYWxlcw0KDQpgYGB7cn0NClZhcmlhYmxlPC1jKCJGZWNoYSIsIlNUQjMiLCJZRlRPIiwgIlRSTVgiLCAiREVOU08iLCJIRUxMQSIsIlZBUlJPQyIsIlRvdGFsLnBlZGlkb3MubWVzIikNClR5cGU8LWMoIkN1YW50aXRhdGl2YSAoZGlzY3JldGEpIiwgIkN1YWxpdGF0aXZhIiwgIkN1YWxpdGF0aXZhIiwgIkN1YWxpdGF0aXZhIiwiQ3VhbGl0YXRpdmEiLCJDdWFsaXRhdGl2YSIsIkN1YWxpdGF0aXZhIiwiQ3VhbnRpdGF0aXZhIChkaXNjcmV0YSkiKQ0KTWVhc3VyZW1lbnQ8LWMoIlJhesOzbiIsIk5vbWluYWwiLCJOb21pbmFsIiwiTm9taW5hbCIsIk5vbWluYWwiLCJOb21pbmFsIiwiTm9taW5hbCIsIlJhesOzbiIpDQp0YWJsZTI8LWRhdGFfZnJhbWUoVmFyaWFibGUsVHlwZSxNZWFzdXJlbWVudCkNCg0Ka25pdHI6OmthYmxlKHRhYmxlMikNCmBgYA0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKkdyw6FmaWNhIEN1YWxpdGF0aXZhKiogDQoNCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoInBseXIiKQ0KbGlicmFyeShwbHlyKQ0KZGVsaXZlcnkyPC1kZWxpdmVyeTENCg0KZGVsaXZlcnkyPC0gYWdncmVnYXRlKGRlbGl2ZXJ5MiRQZWRpZG9zLCBieT1saXN0KGNhdGVnb3J5PWRlbGl2ZXJ5MiRDTElFTlRFKSwgRlVOPXN1bSkNCnBpZShkZWxpdmVyeTIkeCwgbGFiZWxzID0gZGVsaXZlcnkyJGNhdGVnb3J5KQ0KYGBgDQoNCipDb24gZXN0YSBncsOhZmljYSBwb2RlbW9zIGRhcm5vcyBjdWVudGEgZGUgbG9zIGNsaWVudGVzIHF1ZSB0aWVuZW4gbWF5b3JlcyBwZWRpZG9zIHkgZW4gZXN0ZSBjYXNvIGVzIEhFTExBIGVuIHByaW1lciBsdWdhciB5IFRSTVggZW4gc2VndW5kbyBsdWdhci4qDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPioqR3LDoWZpY2EgQ3VhbnRpdGF0aXZhKiogDQpgYGB7cn0NCmRlbGl2ZXJ5MjwtZGVsaXZlcnkyICU+JSBkcGx5cjo6cmVuYW1lKHBlZGlkb3M9IngiKQ0KZGVsaXZlcnkyPC1kZWxpdmVyeTIgJT4lIGRwbHlyOjpyZW5hbWUoQ2xpZW50ZXM9ImNhdGVnb3J5IikNCg0KZGVsaXZlcnkyJENsaWVudGVzPC1hcy5mYWN0b3IoZGVsaXZlcnkyJENsaWVudGVzKQ0KZ2dwbG90KGRlbGl2ZXJ5MiwgYWVzKHg9Q2xpZW50ZXMsIHk9cGVkaWRvcywgZmlsbD1wZWRpZG9zKSkrDQogICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKw0KICAgICAgICAgdGhlbWVfbWluaW1hbCgpKw0KICAgICAgICAgbGFicyh0aXRsZT0iUGVkaWRvcyBwb3IgY2xpZW50ZSIpDQpgYGANCipFc3RhIGdyw6FmaWNhIHNpcnZlIHBhcmEgdGVuZXIgZGUgbWFuZXJhIG3DoXMgdmlzdWFsIGVsIGltcGFjdG8gcXVlIHRpZW5lIGNhZGEgdW5vIGRlIGxvcyBjbGllbnRlcyBlbiBsYSBlbXByZXNhIEZPUk0uIFBvZGVtb3MgdmVyIHF1ZSBIRUxMQSBlcyBlbCBjbGllbnRlIG3DoXMgc2lnbmlmaWNhdGl2byBjb24gY2FzaSBlbCB0cmlwbGUgZGUgcGVkaWRvcyBxdWUgZWwgc2lndWllbnRlIGNsaWVudGUgY29uIG1heW9yZXMgcGVkaWRvcywgVFJNWC4gRGUgbGFkbyBkZXJlY2hvIHNlIHRpZW5lIHVuIGxlZ2VuZCBxdWUgbXVlc3RyYSBsYSB0b25hbGlkYWQgZGUgbG9zIHBsb3RzIHBhcmEgdmVyIHF1ZSB0YW50b3MgcGVkaWRvcyB0aWVuZSwgcG9yIGVsbG8gSEVMTEFTIHRpZW5lIHVuIGNvbG9yIGF6dWwgY2xhcm8sIHJlcHJlc2VudGFuZG8gbcOhcyBkZSAyNTAsMDAwIHBlZGlkb3MuICogDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPioqQ29tcG9ydGFtaWVudG8gZGUgY2xpZW50ZXMgcG9yIGZlY2hhKiogDQpgYGB7cn0NCnN1bW1hcnkoZGVsaXZlcnkxKQ0KDQpnZ3Bsb3QoZGVsaXZlcnkxLGFlcyh4PUlEX0ZlY2hhLCB5PVBlZGlkb3MsIGdyb3VwPUNMSUVOVEUsY29sb3VyPUNMSUVOVEUpKSsNCiAgZ2VvbV9saW5lKCkrDQogIGdndGl0bGUoIlBlZGlkb3MgcG9yIGNsaWVudGUiKQ0KYGBgDQoqQ29uIGVzdGEgZ3LDoWZpY2EgdXRpbGl6YW1vcyBlbCBJRCBGZWNoYSBwYXJhIGNvbm9jZXIgbG9zIHBlZGlkb3MgcXVlIHNlIHRpZW5lIHBvciBjbGllbnRlIGNhZGEgbWVzIHkgdmVtb3MgdW4gc2lnbmlmaWNhdGl2byBpbmNyZW1lbnRvIGRlIHBlZGlkb3MgZW4gZWwgbWVzIGRlIHNlcHRpZW1icmUgeSBvY3R1YnJlLiBjb250YW1vcyBjb24gdW4gbGVnZW4gcXVlIGluZGljYSBjYWRhIGzDrW5lYSBjb24gdW4gY29sb3IgcGFyYSBub21icmFyIGxhIGluZm9ybWFjacOzbiBkZSBjYWRhIHVubyBkZSBsb3MgY2xpZW50ZXMuICogDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOmRhcmtvcmFuZ2UiPioqR3LDoWZpY2EgQm94cGxvdCoqIA0KYGBge3J9DQpib3hwbG90KGRlbGl2ZXJ5MSRQZWRpZG9zLCBtYWluPSAiUGVkaWRvcyIpDQoNCmRlbGl2ZXJ5MzwtZGVsaXZlcnkxDQpkZWxpdmVyeTMkQ0xJRU5URSA8LWFzLmZhY3RvcihkZWxpdmVyeTMkQ0xJRU5URSkNCmdncGxvdChkZWxpdmVyeTMsIGFlcyh4PUNMSUVOVEUsIHk9UGVkaWRvcykpKw0KICBnZW9tX2JveHBsb3QoY29sb3I9ImJsdWUiLCBmaWxsPSJwdXJwbGUiKQ0KYGBgDQoNCipFbiBlc3RhIGdyw6FmaWNhIHBvZGVtb3MgdmlzdWFsaXphcmN1YW50b3MgcGVkaWRvcyB0aWVuZSBwcm9ncmFtYWRvcyBjYWRhIGNsaWVudGUgeSBsb3MgY2xpZW50ZXMgcXVlIHNvYnJlIHNhbGVuIHNvbiBIRUxMQSB5IFRSTVgsIGFsZ28gbXV5IHJlbGV2YW50ZSBlbiBlc3RhIGdyw6FmaWNhIGVzIHF1ZSBzZSBtdWVzdHJhIGxhIG1vZGEgZGUgY2FkYSB1bm8sIGFzw60gY29tbyB0YW1iacOpbiBsYSBtaW5pbWEgZGUgcGVkaWRvcyB5IGxhIG3DoXhpbWEsIHkgZW4gZXN0ZSBjYXNvIG5vIHNlIHRpZW5lIHVuYSBkaXNwZXJzacOzbiBwb3IgbmluZ3VubyBkZSBsb3MgY2xpZW50ZXMuKiANCg0KIyMgKipDb25jbHVzacOzbiAtIERlbGl2ZXJ5IFBsYW4qKiANClBhcmEgcmVhbGl6YXIgZWwgYW7DoWxpc2lzIGRlIGxhIGJhc2UgZGUgZGF0b3MgZGUgIkRlbGl2ZXJ5IFBsYW4iIGZ1w6kgbmVjZXNhcmlvIHByaW1lcm8gaGFjZXIgdW4gYXJyZWdsbyBkZSBsYSBiYXNlIGRlIGRhdG9zIGRlIG1hbmVyYSBtYW51YWwgZW4gZWwgZXhjZWwuIEVzdMOzIHBhcmEgc2ltcGxpZmljYXIgZWwgdXNvIGRlIGxhIGJhc2UgZGUgZGF0b3MgeSBwZXJtaXRpciBxdWUgUiBwdWVkYSBhbmFsaXphcmxhIHkgZXh0cmFlciBsb3MgZGF0b3MgcGFyYSBnZW5lcmFyIGdyw6FmaWNhcy4gRGVzcHXDqXMgYXBsaWNhbW9zIGRvcyBkaWZlcmVudGVzIGJhc2VzIGRlIGRhdG9zLCBub3MgYXNlZ3VyYW1vcyBkZSBxdWUgbm8gaGF5YSBOQXMgeSBlbGltaW5hbW9zIGZpbGFzIHF1ZSBjb3JyZXNwb25kw61hbiBhIGxvcyBjbGllbnRlcyBxdWUgdGVuw61hbiBtZW5vcyBkZSA1LDAwMCBwZWRpZG9zLiBOb3MgcXVlZGFtb3MgY29uIHVuYSBiYXNlIGRlIGRhdG9zIGNvbiBsb3MgNiBjbGllbnRlcyBtw6FzIHNpZ25pZmljYXRpdm9zIHBhcmEgRk9STS4gQ29udGludWFtb3MgaWRlbnRpZmljYW5kbyBsYXMgdmFyaWFibGVzIGVuIGTDs25kZSA2IGRlIDggdmFyaWFibGVzIGVyYW4gY3VhbGl0YXRpdmFzIGFsIHNlciBsb3MgY2xpZW50ZXMgZGUgRk9STS4gDQoNCkdyYWZpY2Ftb3MgdW5hIGdyw6FmaWNhIGRlIFBpZSBwYXJhIGlkZW50aWZpY2FyIGRlIG1hbmVyYSB2aXN1YWwgbG9zIG1heW9yZXMgY2xpZW50ZXMsIGxvcyBxdWUgdmllbmVuIHNpZW5kbyBIRUxMQSB5IFRSTVguIFRhbWJpw6luIGhpY2ltb3MgdW4gIkJhcnBsb3QiIHBhcmEgbW9zdHJhciBsYSBjYW50aWRhZCBkZSBwZWRpZG9zIHByb2dyYW1hZG9zIHF1ZSB0aWVuZSBjYWRhIGNsaWVudGUsIEhlbGxhIHNpZW5kbyBlbCBjbGllbnRlIGNvbiBtYXlvciBwZWRpZG9zIGNvbiBtw6FzIGRlIDIyNSwwMDAgeSBUUk1YIHNpZ3VpZW5kbyBjb24gODAsMDAwLiBEZWNpZGltb3MgdGFtYmnDqW4gdmlzdWFsaXphciBlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgY2xpZW50ZXMgc2Vnw7puIGxhIGZlY2hhIHkgbm9zIGRpbW9zIGN1ZW50YSBxdWUgZW50cmUgZWwgbWVzIGRlIHNlcHRpZW1icmUgeSBvY3R1YnJlIGh1Ym8gdW4gaW5jcmVtZW50byBkZSBwZWRpZG9zIGVzdGFibGVjaWRvcy4gWSBwb3Igw7psdGltbyBzZSByZWFsaXrDsyBlbCAiQm94cGxvdCIgcGFyYSBkZSBlc2UgbW9kbyB2ZXIgZGUgbWFuZXJhIHByZWNpc2EgbGEgbW9kYSBkZSBjbG9zIHBlZGlkb3MgcXVlIHN1ZWxlIGhhY2VyIGNhZGEgdW5vIGRlIGxvcyBjbGllbnRlcy4gDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+Kio0LiBSZWN1cnNvcyBIdW1hbm9zKiogDQoNCg0KIyMgTGltcGllemEsIFRyYW5zZm9ybWFjacOzbiB5IE9yZ2FuaXphY2nDs24gZGUgQmFzZXMgZGUgRGF0b3MNCg0KYGBge3J9DQojIyBEZXNjYXJnYXIgbGlicmVyw61hcw0KbGlicmFyeShmb3JlaWduKQ0KbGlicmFyeShkcGx5cikgICAgICAgICMgZGF0YSBtYW5pcHVsYXRpb24gDQpsaWJyYXJ5KGZvcmNhdHMpICAgICAgIyB0byB3b3JrIHdpdGggY2F0ZWdvcmljYWwgdmFyaWFibGVzDQpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24NCmxpYnJhcnkocmVhZHIpICAgICAgICAjIHJlYWQgc3BlY2lmaWMgY3N2IGZpbGVzDQpsaWJyYXJ5KGphbml0b3IpICAgICAgIyBkYXRhIGV4cGxvcmF0aW9uIGFuZCBjbGVhbmluZyANCmxpYnJhcnkoSG1pc2MpICAgICAgICAjIHNldmVyYWwgdXNlZnVsIGZ1bmN0aW9ucyBmb3IgZGF0YSBhbmFseXNpcyANCmxpYnJhcnkocHN5Y2gpICAgICAgICAjIGZ1bmN0aW9ucyBmb3IgbXVsdGl2YXJpYXRlIGFuYWx5c2lzIA0KbGlicmFyeShuYW5pYXIpICAgICAgICMgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIE5Bcw0KbGlicmFyeShkbG9va3IpICAgICAgICMgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIE5Bcw0KbGlicmFyeShjb3JycGxvdCkgICAgICMgY29ycmVsYXRpb24gcGxvdHMNCmxpYnJhcnkoanRvb2xzKSAgICAgICAjIHByZXNlbnRhdGlvbiBvZiByZWdyZXNzaW9uIGFuYWx5c2lzIA0KbGlicmFyeShsbXRlc3QpICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyANCmxpYnJhcnkoY2FyKSAgICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMNCmxpYnJhcnkob2xzcnIpICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQpsaWJyYXJ5KGthYmxlRXh0cmEpICAgIyBIVE1MIHRhYmxlIGF0dHJpYnV0ZXMNCmxpYnJhcnkoZ21vZGVscykNCmxpYnJhcnkob3Blbnhsc3gpDQpsaWJyYXJ5KGNyb3NzdGFibGUpDQpgYGANCg0KKk5vdGE6IENvbW8gcGFydGUgZGUgbGEgbGltcGllemEgZGUgZGF0b3MgZGUgYW1ib3MgZG9jdW1lbnRvcywgc2UgcmVhbGl6YXJvbiBsb3MgcHJvbWVkaW9zIGRlIGxvcyB2YWxvcmVzIGZhbHRhbnRlcyBkZSBmb3JtYSBtYW51YWwgZW4gRXhjZWwuDQoNCg0KX19BIHBhcnRpciBkZSBlc3RhIHBhcnRlIGRlbCBkb2N1bWVudG8sIGVsIGFuw6FsaXNpcyBlc3RhcsOhIGRpdmlkaWRvIGVuIGRvcyBwYXJ0ZXMuIEVuIGxhIHByaW1lcmEgc2UgYW5hbGl6YXLDoSBsYSBiYXNlIGRlIGRhdG9zIGNvbiBsYSBpbmZvcm1hY2nDs24gZGUgbG9zIGNvbGFib3JhZG9yZXMgYWN0dWFsZXMgZGUgbGEgZW1wcmVzYSwgbWllbnRyYXMgcXVlIGVuIGxhIHNlZ3VuZGEgc2UgYW5hbGl6YXLDoW4gbG9zIGRhdG9zIGRlIGFxdWVsbG9zIGVtcGxlYWRvcyBxdWUgeWEgZnVlcm9uIGJhamFzIHBvciBtb3Rpdm9zIGRlIGRlc3BpZG8sIHJlbnVuY2lhIHZvbHVudGFyaWEsIGVudHJlIG90cm9zLl9fDQoNCiMjIyBCQVNFIERFIERBVE9TOiBDT0xBQk9SQURPUkVTIERFIFJFQ1VSU09TIEhVTUFOT1MNCmBgYHtyfQ0KIyMgMS4gTsO6bWVybyBkZSByZWdpc3Ryb3MgeSB2YXJpYWJsZXMNCg0KIyMjIEltcG9ydGFyIGJhc2UgZGUgZGF0b3MNCiNmaWxlLmNob29zZSgpDQpkZjEgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxociBjc3YgMS5jc3YiKQ0Kc3VtbWFyeShkZjEpDQpkZXNjcmliZShkZjEpDQpgYGANCg0KDQojIyAyLiBDbGFzaWZpY2FjacOzbiBkZSB2YXJpYWJsZXMNCmBgYHtyfQ0KDQp2YXJpYWJsZTwtYygiTm8uLkRlLkVtcGxlYWRvIiwiQVBFTExJRE9TIiwiTk9NQlJFIiwiRkVDSEEuREUuTkFDSU1JRU5UTyIsIkVEQUQiLCJHRU5FUk8iLCJSRkMiLCJGRUNIQS5ERS5BTFRBIiwiUFJJTUVSLk1FUyIsIkNVQVJUTy5NRVMiLCJCQUpBIiwiUFVFU1RPIiwiREVQQVJUQU1FTlRPIiwiU0FMQVJJTy5ESUFSSU8uSU1TUyIsIkZBQ1RPUi5DUkVELklORk9OQVZJVCIsIk4uLkNSRURJVE8uSU5GT05BVklUIiwiTFVHQVIuREUuTkFDSU1JRU5UTyIsIkNVUlAiLCJDQUxMRSIsIk5VTUVSTy5JTlRFUk5PIiwiQ09MT05JQSIsIk1VTklDSVBJTyIsIkVTVEFETyIsIkNPRElHTy5QT1NUQUwiLCJFU1RBRE8uQ0lWSUwiLCJUQVJKRVRBLkNVRU5UQSIpDQpUeXBlPC1jKA0KICAgICAgICAicXVhbnRpdGF0aXZlIChjb250aW5vdXMpIiwNCiAgICAgICAgInF1YWxpdGF0aXZlIChkaXNjcmV0ZSkiLA0KICAgICAgICAicXVhbGl0YXRpdmUgKGRpc2NyZXRlKSIsDQogICAgICAgICJxdWFsaXRhdGl2ZSAoZGlzY3JldGUpIiwNCiAgICAgICAgInF1YW50aXRhdGl2ZSAoY29udGlub3VzKSIsDQogICAgICAgICJxdWFsaXRhdGl2ZSAoZGlzY3JldGUpIiwNCiAgICAgICAgInF1YWxpdGF0aXZlIChkaXNjcmV0ZSkiLA0KICAgICAgICAicXVhbnRpdGF0aXZlIChjb250aW5vdXMpIiwNCiAgICAgICAgInF1YW50aXRhdGl2ZSAoY29udGlub3VzKSIsDQogICAgICAgICJxdWFudGl0YXRpdmUgKGNvbnRpbm91cykiLA0KICAgICAgICAicXVhbnRpdGF0aXZlIChjb250aW5vdXMpIiwNCiAgICAgICAgInF1YWxpdGF0aXZlIChkaXNjcmV0ZSkiLA0KICAgICAgICAicXVhbGl0YXRpdmUgKGRpc2NyZXRlKSIsDQogICAgICAgICJxdWFudGl0YXRpdmUgKGNvbnRpbm91cykiLA0KICAgICAgICAicXVhbnRpdGF0aXZlIChjb250aW5vdXMpIiwNCiAgICAgICAgInF1YWxpdGF0aXZlIChkaXNjcmV0ZSkiLA0KICAgICAgICAicXVhbGl0YXRpdmUgKGRpc2NyZXRlKSIsDQogICAgICAgICJxdWFsaXRhdGl2ZSAoZGlzY3JldGUpIiwNCiAgICAgICAgInF1YWxpdGF0aXZlIChkaXNjcmV0ZSkiLA0KICAgICAgICAicXVhbnRpdGF0aXZlIChjb250aW5vdXMpIiwNCiAgICAgICAgInF1YWxpdGF0aXZlIChkaXNjcmV0ZSkiLA0KICAgICAgICAicXVhbGl0YXRpdmUgKGRpc2NyZXRlKSIsDQogICAgICAgICJxdWFsaXRhdGl2ZSAoZGlzY3JldGUpIiwNCiAgICAgICAgInF1YW5pdGF0aXZlIChjb250aW5vdXMpIiwNCiAgICAgICAgInF1YWxpdGF0aXZlIChkaXNjcmV0ZSkiLA0KICAgICAgICAicXVhbGl0YXRpdmUgKGRpc2NyZXRlKSINCiAgICAgICAgKQ0KDQp0YWJsZTwtZGF0YS5mcmFtZSh2YXJpYWJsZSxUeXBlKQ0Ka25pdHI6OmthYmxlKHRhYmxlKQ0KDQpgYGANCg0KIyMgMy4gRXNjYWxhcyBkZSBtZWRpY2nDs24NCmBgYHtyfQ0KDQp2YXJpYWJsZXMgPC0gYygNCiAgIk5vLi5EZS5FbXBsZWFkbyIsDQogICJBUEVMTElET1MiLA0KICAiTk9NQlJFIiwNCiAgIkZFQ0hBLkRFLk5BQ0lNSUVOVE8iLA0KICAiRURBRCIsDQogICJHRU5FUk8iLA0KICAiUkZDIiwNCiAgIkZFQ0hBLkRFLkFMVEEiLA0KICAiUFJJTUVSLk1FUyIsDQogICJDVUFSVE8uTUVTIiwNCiAgIkJBSkEiLA0KICAiUFVFU1RPIiwNCiAgIkRFUEFSVEFNRU5UTyIsDQogICJTQUxBUklPLkRJQVJJTy5JTVNTIiwNCiAgIkZBQ1RPUi5DUkVELklORk9OQVZJVCIsDQogICJOLi5DUkVESVRPLklORk9OQVZJVCIsDQogICJMVUdBUi5ERS5OQUNJTUlFTlRPIiwNCiAgIkNVUlAiLA0KICAiQ0FMTEUiLA0KICAiTlVNRVJPLklOVEVSTk8iLA0KICAiQ09MT05JQSIsDQogICJNVU5JQ0lQSU8iLA0KICAiRVNUQURPIiwNCiAgIkNPRElHTy5QT1NUQUwiLA0KICAiRVNUQURPLkNJVklMIiwNCiAgIlRBUkpFVEEuQ1VFTlRBIg0KICApDQoNCnRpcG9zIDwtIGMoDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbnRpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YWxpdGF0aXZvIiwNCiAgICAgICAgICAgICAgIkN1YW50aXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFsaXRhdGl2byIsDQogICAgICAgICAgICAgICJDdWFudGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iLA0KICAgICAgICAgICAgICAiQ3VhbGl0YXRpdm8iDQogICAgICAgICAgICAgICkNCg0KZXNjYWxhcyA8LSBjKA0KICAgICAgICAgICAgIkludGVydmFsbyIsDQogICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICAiSW50ZXJ2YWxvIiwNCiAgICAgICAgICAgICJJbnRlcnZhbG8iLA0KICAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICJSYXrDs24iLA0KICAgICAgICAgICAgIlJhesOzbiIsDQogICAgICAgICAgICAiUmF6w7NuIiwNCiAgICAgICAgICAgICJSYXrDs24iLA0KICAgICAgICAgICAgIk9yZGluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIlJhesOzbiIsDQogICAgICAgICAgICAiUmF6w7NuIiwNCiAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICJOb21pbmFsIiwNCiAgICAgICAgICAgICJSYXrDs24iLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk9yZGluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiLA0KICAgICAgICAgICAgIk5vbWluYWwiDQogICAgICAgICAgICApDQoNCnRhYmxlMSA8LSBkYXRhLmZyYW1lICh2YXJpYWJsZXMsIHRpcG9zLCBlc2NhbGFzKQ0Ka25pdHI6OmthYmxlKHRhYmxlMSkNCg0KYGBgDQoNCmBgYHtyfQ0KI0xhcyBlc2NhbGFzIGRlIG1lZGljacOzbiBwZXJtaXRlbiBvcmdhbml6YXIgZGF0b3MgZW4gb3JkZW4gamVyw6FycXVpY28uIMOJc3RhcyBwdWVkZW4gc2VyIGNsYXNpZmljYWRhcyBkZSBhY3VlcmRvIGEgdW5hIGRlZ3JhZGFjacOzbiBkZSBsYXMgY2FyYWN0ZXLDrXN0aWNhcyBkZSBkaXN0aW50YXMgdmFyaWFibGVzLiBFbnRyZSBsYXMgdmFyaWFibGVzIHVzYWRhcyBlc3TDoW4gbm9taW5hbCAoYXF1ZWxsYXMgcXVlIHNvbiBtdXR1YW1lbnRlIGV4Y2x1eWVudGVzIHkgbm8gYXNpZ25hbiB1biBvcmRlbiBvIGplcmFycXXDrWEpLCBvcmRpbmFsIChlc3RhYmxlY2VuIHVuIG9yZGVuLCBwdWVkZSBzZXIgY3JlY2llbnRlIG8gZGVjcmVjaWVudGUpLCBpbnRlcnZhbG8gKGVzdGFibGVjZW4gdW4gb3JkZW4gZGV0ZXJtaW5hZG8gcG9yIHVuIGludGVydmFsbyBudW3DqXJpY28pIHkgcmF6w7NuIChleGlzdGUgdW4gaW50ZXJ2YWxvIG51bcOpcmljbzsgZWwgY2VybyByZXByZXNlbnRhIGxhIGF1c2VuY2lhIGRlIHZhbG9yOyBlcyB1biBjZXJvIGFic29sdXRvKS4NCmBgYA0KDQojIyA0LiBMaW1waWV6YSBkZSBkYXRvcw0KDQpSZW1vdmVyIHZhbG9yZXMgaXJyZWxldmFudGVzIChlbGltaW5hciByZW5nbG9uZXMgZHVwbGljYWRvcykgeSBjb252ZXJzacOzbiBkZSBkYXRvcyBzb24gdMOpY25pY2FzIGVsZWdpZGFzIHBhcmEgcmVhbGl6YXIgbGEgbGltcGllemEgZGUgZGF0b3MgZGViaWRvIGEgbGFzIG5lY2VzaWRhZGVzIGRlIGxhIGJhc2UgZGUgZGF0b3MgeSBlbCBiZW5lZmljaW8gcXVlIGdlbmVyw7MgcGFyYSBlbCBhbsOhbGlzaXMgZGVzY3JpcHRpdm8sIG9idGVuaWVuZG8gaW5mb3JtYWNpw7NuIG3DoXMgY2xhcmEgeSBjb25jaXNhLg0KDQpgYGB7cn0NCg0KIyMjIEVsaW1pbmFyIHJlbmdsb25lcyBkdXBsaWNhZG9zDQpkZjI8LWRmMQ0KZGYyPC1kaXN0aW5jdChkZjIpDQoNCiMjIyDCv0N1w6FudG9zIE5BJ3MgdGVuZ28gZW4gbGEgYmFzZSBkZSBkYXRvcz8gUHJpbWVyYSBsaW1waWV6YQ0Kc3VtKGlzLm5hKGRmMikpDQoNCiMjIyBFbGltaW5hciBjb2x1bW5hcw0KZGYzPC1kZjINCmRmMyA8LSBzdWJzZXQoZGYzLCBzZWxlY3QgPS1jIChYKSkNCmRmMyA8LSBzdWJzZXQoZGYzLCBzZWxlY3QgPS1jIChYLjEpKQ0KZGYzIDwtIHN1YnNldChkZjMsIHNlbGVjdCA9LWMgKE5PTUJSRSkpDQpkZjMgPC0gc3Vic2V0KGRmMywgc2VsZWN0ID0tYyAoQVBFTExJRE9TKSkNCmRmMyA8LSBzdWJzZXQoZGYzLCBzZWxlY3QgPS1jIChSRkMpKQ0KZGYzIDwtIHN1YnNldChkZjMsIHNlbGVjdCA9LWMgKENVQVJUTy5NRVMpKQ0KZGYzIDwtIHN1YnNldChkZjMsIHNlbGVjdCA9LWMgKEZBQ1RPUi5DUkVELklORk9OQVZJVCkpDQpkZjMgPC0gc3Vic2V0KGRmMywgc2VsZWN0ID0tYyAoQ1VSUCkpDQpkZjMgPC0gc3Vic2V0KGRmMywgc2VsZWN0ID0tYyAoQ0FMTEUpKQ0KZGYzIDwtIHN1YnNldChkZjMsIHNlbGVjdCA9LWMgKE5VTUVSTy5JTlRFUk5PKSkNCmRmMyA8LSBzdWJzZXQoZGYzLCBzZWxlY3QgPS1jIChUQVJKRVRBLkNVRU5UQSkpDQoNCiMjIyDCv0N1w6FudG9zIE5BJ3MgdGVuZ28gZW4gbGEgYmFzZSBkZSBkYXRvcz8gU2VndW5kYSBsaW1waWV6YQ0Kc3VtKGlzLm5hKGRmMykpDQoNCmBgYA0KDQoNCg0KDQojIyA1LiBBbsOhbGlzaXMgRXhwbG9yYXRvcmlvIGRlIGxhcyBCYXNlcyBkZSBEYXRvcw0KTm90YTogU2kgc2FsZW4gbG9zIGNvdW50cyBzaSBzZSBwb25lIHNvbG8gZWwgZG9jdW1lbnRvIGRlIFJILCBzaSBzZSBqdW50YSBjb24gbGFzIG90cmFzLCBzYWxlIGVycm9yLCBwYXJhIG1lam9yIHZpc3VhbGl6YWNpb24gdmVyIGNhbnZhIGFwYXJ0YWRvIFJILg0KYGBge3J9DQoNCmRlc2NyaWJlKGRmMykNCg0KI2NvdW50KGRmMywgR0VORVJPLCBzb3J0ID0gVFJVRSkNCiNjb3VudChkZjMsIFBVRVNUTywgc29ydCA9IFRSVUUpDQojY291bnQoZGYzLCBERVBBUlRBTUVOVE8sIHNvcnQgPSBUUlVFKQ0KI2NvdW50KGRmMywgU0FMQVJJTy5ESUFSSU8uSU1TUywgc29ydCA9IFRSVUUpDQojY291bnQoZGYzLCBMVUdBUi5ERS5OQUNJTUlFTlRPLCBzb3J0ID0gVFJVRSkNCg0KdGliYmxlKGRmMykNCmBgYA0KDQpFbiBlc3RhIHByaW1lcmEgcGFydGUgZGVsIGFuw6FsaXNpcyBlc3RhZMOtc3RpY28gZGVzY3JpcHRpdm8sIHZlbW9zIHF1ZSBlbCBjb250ZW8gdG90YWwgZGUgZW1wbGVhZG9zIGFjdHVhbGVzIGVzIGRlIDExMyB5IGhheSB1biBtYXlvciBuw7ptZXJvIGRlIG11amVyZXMgKDU0JSkgY29udHJhIGVtcGxlYWRvcyBxdWUgc29uIGhvbWJyZXMgKDQ2JSkuDQoNCkVuIGN1YW50byBhIGxvcyBwdWVzdG9zLCB2ZW1vcyBxdWUgZXhpc3RlIHVuYSBncmFuIGNhbnRpZGFkIGRlIGF5dWRhbnRlcyBnZW5lcmFsZXMsIHB1ZXMgZXMgZWwgcHVlc3RvIHF1ZSBvY3VwYSBtYXlvciBjYXBpdGFsIGh1bWFubywgY29udHJhIGFxdWVsbG9zIHF1ZSBvY3VwYW4gbWVub3MgcXVlIHZhbiBkZXNkZSBzZXJ2aWNpbyBhbCBjbGllbnRlIGhhc3RhIG9wZXJhZG9yZXMuDQoNCkVudHJlIGxvcyBkZXBhcnRhbWVudG9zIGNvbiBtYXlvciBjYW50aWRhZCBkZSBlbXBsZWFkb3MsIHZlbW9zIHF1ZSBlc3TDoSB2YXJpb3MgeSBwcm9kdWNjacOzbiByZXRvcm4uIEVsIGRlcGFydGFtZW50byBkZSAiVmFyaW9zIiBmdWUgY3JlYWRvIHBhcmEgY2F0YWxvZ2FyIGEgYXF1ZWxsb3MgZW1wbGVhZG9zIHF1ZSBlbiBsYSBiYXNlIGRlIGRhdG9zIG5vIHRlbsOtYW4gZGVmaW5pZGEgdW4gw6FyZWEgZW4gY29uY3JldG8uDQoNClZlbW9zIHF1ZSBsYSBtYXlvcsOtYSBkZSBsb3MgZW1wbGVhZG9zIGdhbmFuICQxODAuNjggcGVzb3MgZGUgc2FsYXJpbyBkaWFyaW8gcG9yIGVsIElNU1MgeSBkZSB0b2RvcyBsb3MgZW1wbGVhZG9zLCBzZSBjYWxjdWxhIHF1ZSB0aWVuZW4gdW4gcHJvbWVkaW8gZGUgc2FsYXJpbyBkaWFyaW8gZGUgJDIzNi42MiBwZXNvcy4NCg0KRW4gY3VhbnRvIGFsIGx1Z2FyIGRlIG9yaWdlbiwgdmVtb3MgcXVlIGxhIG1heW9yw61hIGRlIGxvcyBlbXBsZWFkb3MgcHJvdmllbmVuIGRlbCBFc3RhZG8gZGUgTnVldm8gTGXDs24gKDcwJSkgeSBWZXJhY3J1eiAoMTElKSwgdmllbmRvIHF1ZSBlbCAxOSUgcmVzdGFudGUgZGUgbG9zIGVtcGxlYWRvcyBzb24gcHJvdmVuaWVudGVzIGRlIFpvbmEgQ2VudHJvIG8gZXN0YWRvcyBjb2xpZGFudGVzIGRlIE51ZXZvIExlw7NuLg0KDQoNCg0KIyMgNS4xIFRhYmxhIGRlIGZyZWN1ZW5jaWEgKDEpDQoNCkxhcyB0YWJsYXMgZGUgZnJlY3VlbmNpYSBzb24gdW5hIG9yZGVuYWNpw7NuIGVuIGZvcm1hIGRlIHRhYmxhIGRlIGxvcyBkYXRvcyBlc3RhZMOtc3RpY29zLCBhc2lnbmFuZG8gYSBjYWRhIGRhdG8gc3UgZnJlY3VlbmNpYSBjb3JyZXNwb25kaWVudGUsIGVzIGRlY2lyLCBlbCBuw7ptZXJvIGRlIHZlY2VzIHF1ZSBhcGFyZWNlIHVuIGRldGVybWluYWRvIHZhbG9yIGVuIHVuIGVzdHVkaW8gZXN0YWTDrXN0aWNvLg0KDQpgYGB7cn0NCg0KIyMjIFRhYmxhIGRlIGZyZWN1ZW5jaWE6IFNhbGFyaW8gZGlhcmlvIGRlIGFjdWVyZG8gYWwgZ8OpbmVybw0KcHJvcG9ydGlvbiA8LSBwcm9wLnRhYmxlKHRhYmxlKGRmMyRHRU5FUk8sZGYzJFNBTEFSSU8uRElBUklPLklNU1MpKQ0KcHJvcG9ydGlvbiAlPiUNCiAga2JsKCkgJT4lDQogIGthYmxlX3N0eWxpbmcoKQ0KYGBgDQoNCkVzdGEgdGFibGEgZGUgZnJlY3VlbmNpYSByZXByZXNlbnRhIGVsIHZhbG9yIGRlY2ltYWwgZGVsIHNhbGFyaW8gZGlhcmlvIGRlIGFjdWVyZG8gYWwgZ8OpbmVybywgZXMgZGVjaXIsIGxhIGNhbnRpZGFkIGRlIGVtcGxlYWRvcyBlbiB2YWxvciBkZWNpbWFsIHF1ZSByZWNpYmVuIGNpZXJ0byBzYWxhcmlvIGRpYXJpbyBkZSBhY3VlcmRvIGEgc3UgZ8OpbmVyby4NCg0KDQojIyMgQkFTRSBERSBEQVRPUzogQkFKQVMgREUgUkVDVVJTT1MgSFVNQU5PUw0KDQpfX0EgcGFydGlyIGRlIGxhIHNpZ3VpZW50ZSBiYXNlIGRlIGRhdG9zLCBzZSBhbmFsaXphcsOhIGVzcGVjw61maWNhbWVudGUgbGEgaW5mb3JtYWNpw7NuIGRlIGFxdWVsbGFzIHBlcnNvbmFzIHF1ZSBzZSBkaWVyb24gZGUgYmFqYSBlbiBhw7FvcyBhbnRlcmlvcmVzIGNvbiBlbCBvYmpldGl2byBkZSBlbnRlbmRlciBsYXMgcHJpbmNpcGFsZXMgcmF6b25lcyBkZSBsYSBhbHRhIHJvdGFjacOzbiBlbiBsYSBlbXByZXNhLl9fDQoNCg0KYGBge3J9DQoNCiMjIyBJbXBvcnRhciBiYXNlIGRlIGRhdG9zDQoNCmRmNCA8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXEhSX0JhamFzIDIuY3N2IikNCnN1bW1hcnkoZGY0KQ0KDQojIyMgwr9DdcOhbnRvcyBOQSdzIHRlbmdvIGVuIGxhIGJhc2UgZGUgZGF0b3M/DQpzdW0oaXMubmEoZGY0KSkNCg0KIyMjIEJvcnJhciB0b2RvcyBsb3MgcmVnaXN0cm9zIE5BJ3MgZGUgdW5hIHRhYmxhDQpkZjU8LWRmNA0KZGY1PC1uYS5vbWl0KGRmNSkNCnN1bW1hcnkoZGY1KQ0KDQojIyMgRWxpbWluYXIgY29sdW1uYXMNCmRmMzwtZGYyDQpkZjMgPC0gc3Vic2V0KGRmMywgc2VsZWN0ID0tYyAoQVBFTExJRE9TKSkNCmRmMyA8LSBzdWJzZXQoZGYzLCBzZWxlY3QgPS1jIChOT01CUkUpKQ0KZGYzIDwtIHN1YnNldChkZjMsIHNlbGVjdCA9LWMgKEZBQ1RPUi5DUkVELklORk9OQVZJVCkpDQpkZjMgPC0gc3Vic2V0KGRmMywgc2VsZWN0ID0tYyAoQ1VSUCkpDQpkZjMgPC0gc3Vic2V0KGRmMywgc2VsZWN0ID0tYyAoQ0FMTEUpKQ0KZGYzIDwtIHN1YnNldChkZjMsIHNlbGVjdCA9LWMgKE5VTUVSTy5JTlRFUk5PKSkNCmRmMyA8LSBzdWJzZXQoZGYzLCBzZWxlY3QgPS1jIChUQVJKRVRBLkNVRU5UQSkpDQoNCg0KIyMjIMK/Q3XDoW50b3MgTkEncyB0ZW5nbyBlbiBsYSBiYXNlIGRlIGRhdG9zPw0Kc3VtKGlzLm5hKGRmNSkpDQoNCiMgQ29uIGxvcyBkYXRvcyBwcmVzZW50YWRvcyBhbnRlcmlvcm1lbnRlLCB2ZW1vcyBxdWUgbGEgZWRhZCBwcm9tZWRpbyBkZSBsb3MgY29sYWJvcmFkb3JlcyBlcyBkZSAzNSBhw7FvcywgYWRlbcOhcyBkZSBxdWUgZ2FuYW4gdW4gcHJvbWVkaW8gZGUgJDE4MCBwZXNvcy4NCg0KYGBgDQoNCiMjIDUuMi4xIFRhYmxhIGNydXphZGEgKDEpDQpgYGB7cn0NCg0KdGFibGUoZGY1JFBVRVNUTywgZGY1JE1PVElWTy5ERS5CQUpBKQ0KYGBgDQoNCkVuIGxhIHRhYmxhIHZlbW9zIHF1ZSBzZSBkZXN0YWNhbiB0cmVzIHJhem9uZXMgcHJpbmNpcGFsZXMgZGUgYmFqYXMgZGUgZW1wbGVhZG9zLCBsYXMgY3VhbGVzIHNvbjogYmFqYXMgcG9yIGZhbHRhcywgcmVudW5jaWEgdm9sdW50YXJpYSBvIHTDqXJtaW5vIGRlIGNvbnRyYXRvLiBFbiBzdSBtYXlvcsOtYSwgaHVibyB1bmEgYmFqYSBwb3IgZmFsdGFzIGRlbCBwdWVzdG8gZGUgYXl1ZGFudGUgZ2VuZXJhbCB5IHJlbnVuY2lhIHZvbHVudGFyaWEgcGFyYSBlbCBtaXNtbyBwdWVzdG8uIEFsIGlndWFsIHF1ZSBlbiBsYSBiYXNlIGRlIGRhdG9zIGFudGVyaW9yLCB2ZW1vcyBxdWUgZWwgcHVlc3RvIGNvbiBtYXlvciByb3RhY2nDs24gYSBuaXZlbCBoaXN0w7NyaWNvIGVzIGRlIGF5dWRhbnRlIGdlbmVyYWwuIEVzdG8gc3VnaWVyZSBxdWUgZXhpc3RlIHVuIGFsdG8gbsO6bWVybyBkZSBjb250cmF0YWNpb25lcyBwYXJhIGVsIHB1ZXN0byBkZWJpZG8gYSB1bmEgbWFsYSBnZXN0acOzbiBhZG1pbmlzdHJhdGl2YSBvIGJham8gcmVuZGltaWVudG8gZGUgbG9zIGVtcGxlYWRvcy4NCg0KIyMgNS4yLjIgVGFibGEgY3J1emFkYSAoMikNCmBgYHtyfQ0KDQp0YWJsZShkZjUkR0VORVJPLCBkZjUkTU9USVZPLkRFLkJBSkEpDQpgYGANCg0KTGEgdGFibGEgY3J1emFkYSBhbnRlcmlvciBub3MgbXVlc3RyYSBsYSByZWxhY2nDs24gZW50cmUgbG9zIG1vdGl2b3MgZGUgYmFqYSBjb250cmEgZWwgZ8OpbmVybywgZXMgZGVjaXIsIGxhcyBwcmluY2lwYWxlcyByYXpvbmVzIGRlIGJhamEgZGUgYWN1ZXJkbyBhbCBnw6luZXJvIGRlIGNhZGEgZW1wbGVhZG8uIFZlbW9zIHF1ZSBodWJvIHVuIHRvdGFsIGRlIDUzIGJhamFzIGRlbCBnw6luZXJvIGZlbWVuaW5vLCBkZXN0YWNhbmRvIGxhcyBiYWphcyBwb3IgZmFsdGFzIChyZXByZXNlbnRhIHVuIDc1JSBkZSBsYXMgYmFqYXMgZmVtZW5pbmFzKS4gUGFyYSBlbCBnw6luZXJvIG1hc2N1bGlubywgaHVibyB1biB0b3RhbCBkZSAyNSBmYWx0YXMsIGRlc3RhY2FuZG8gcHJpbmNpcGFsbWVudGUgbGFzIGJhamFzIHBvciBmYWx0YXMgKHJlcHJlc2VudGEgdW4gNjAlIGRlIGxhcyBiYWphcyBtYXNjdWxpbmFzKS4NCg0KIyMgNS4zIEdyw6FmaWNvcyBkZSBkYXRvcyBjdWFudGl0YXRpdm9zIHkgY3VhbGl0YXRpdm9zICgyKQ0KYGBge3J9DQoNCiMjIDUuMy4xIFBpZSBjaGFydA0KDQojIyMgUGllIGNoYXJ0OiBSZXByZXNlbnRhY2nDs24gZGUgYmFqYXMgYWNvcmRlIGFsIGVzdGFkbyBkZSByZXNpZGVuY2lhDQpwaWUodGFibGUoZGY1JEVTVEFETyksIGNvbD1jKCJvcmFuZ2UiLCJjb3JhbDEiKSwNCiAgICBtYWluPSJSZXByZXNlbnRhY2nDs24gZGUgYmFqYXMgYWNvcmRlIGFsIGVzdGFkbyBkZSByZXNpZGVuY2lhIikNCmBgYA0KDQpMYSBncsOhZmljYSBhbnRlcmlvciBub3MgbXVlc3RyYSBxdWUgaGF5IHVuIG1heW9yIG7Dum1lcm8gZGUgZXgtZW1wbGVhZG9zIHF1ZSB2aXZlbiBlbiBlbCBFc3RhZG8gZGUgTnVldm8gTGXDs24uIFNpbiBlbWJhcmdvLCBoYXkgdW4gcG9yY2VudGFqZSBxdWUgcmVzaWRlIGVuIENvYWh1aWxhLiBFc3RvIHNlIHB1ZWRlIGludGVycHJldGFyIGNvbiBxdWUgaGF5IHVuIGFsdG8gbml2ZWwgZGUgcm90YWNpw7NuIGV4aXN0ZW50ZSBkZWJpZG8gYSBsYSBsZWphbsOtYSBkZSByZXNpZGVuY2lhIGRlIGxvcyBlbXBsZWFkb3MuDQoNCg0KIyMjIFBpZSBjaGFydDogUmVwcmVzZW50YWNpw7NuIGRlIGJhamFzIGFjb3JkZSBhbCBnw6luZXJvDQpgYGB7cn0NCg0KcGllKHRhYmxlKGRmNSRHRU5FUk8pLCBjb2w9Yygib3JhbmdlIiwiY29yYWwxIiksDQogICAgbWFpbj0iUmVwcmVzZW50YWNpw7NuIGRlIGJhamFzIGFjb3JkZSBhbCBnw6luZXJvIikNCg0KYGBgDQoNCkxhIGFudGVyaW9yIGdyw6FmaWNhIGRlIHBhc3RlbCByZWFmaXJtYSBsbyBxdWUgbWVuY2lvbmFtb3MgYW50ZXJpb3JtZW50ZS4gRGUgYWN1ZXJkbyBhIGxhcyBiYWphcyByZWFsaXphZGFzLCBsYSBtYXlvcsOtYSBkZSBsb3MgZXgtZW1wbGVhZG9zIHNvbiBkZWwgZ8OpbmVybyBmZW1lbmluby4NCg0KDQojIyA1LjQgR3LDoWZpY29zIGRlIGRpc3BlcnNpw7NuICgyKQ0KYGBge3J9DQoNCiMjIyBHcsOhZmljYSBkZSBkaXNwZXJzacOzbjogTsO6bWVybyBkZSBiYWphcyBWUy4gRMOtYXMgdHJhYmFqYWRvcw0KcGxvdCh4PSBkZjUkTk8uREUuQkFKQVMsDQogICAgIHk9ZGY1JERJQVMuVFJBQkFKQURPUykNCg0KYGBgDQoNCkxhIGdyw6FmaWNhIGRlIGRpc3BlcnNpw7NuIG5vcyBtdWVzdHJhIGxhIGludGVuc2lkYWQgZGUgcmVsYWNpw7NuIGVudHJlIGxhIHZhcmlhYmxlIGRlIGTDrWFzIHRyYWJhamFkb3MgeSBuw7ptZXJvIGRlIGJhamFzLiBFc3RvIG5vcyBkaWNlIHF1ZSBodWJvIHVuIGFsdG8gbsO6bWVybyBkZSBiYWphcyBkZSBlbXBsZWFkb3MgcXVlIHRyYWJhamFyb24gbWVub3MgZGUgMjAwIGTDrWFzLCBlcyBkZWNpciwgbGEgbWF5b3LDrWEgZGUgbG9zIGV4LWVtcGxlYWRvcyBlc3R1dmllcm9uIGVuIEZPUk0gbWVub3MgZGUgMSBhw7FvLg0KDQpgYGB7cn0NCiMjIyBCb3hwbG90OiBDb3JyZWxhY2nDs24gZW4gYmFqYXMgYWNvcmRlIGEgdmFyaWFibGVzIGRlIGfDqW5lcm8geSBlZGFkDQpnZ3Bsb3QoZGY1LCBhZXMoR0VORVJPLFNBTEFSSU8uRElBUklPLklNU1MsZmlsbD1HRU5FUk8pKSArDQpnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArIGdndGl0bGUoIlNhbGFyaW8gZGlhcmlvIHBvciBnw6luZXJvIikNCmBgYA0KDQpMYSBncsOhZmljYSBhbnRlcmlvciBub3MgbXVlc3RyYSBsYSBjb3JyZWxhY2nDs24gZW50cmUgZWwgZ8OpbmVybyB5IGVsIHNhbGFyaW8gZGlhcmlvIGRlIGxvcyBlbXBsZWFkb3MuIEVuIGVzdGUsIGVudGVuZGVtb3MgcXVlIGVsIGfDqW5lcm8gZmVtZW5pbm8gdGllbmUgdW4gc2FsYXJpbyBkaWFyaW8gdG90YWwgbcOhcyBhbHRvIHF1ZSBsb3MgZGUgZ8OpbmVybyBtYXNjdWxpbm8uDQoNCg0KIyMgNi4gUmVmZXJlbmNpYXMNCiAgQW5hIEthcmVuIEdhcmPDrWEuICgyMDIyLCBTZXB0ZW1iZXIgOCkuIEluZHVzdHJpYSBhdXRvbW90cml6IGFub3RhIHVuIGJ1ZW4gYWdvc3RvOiBjcmVjZW4gcHJvZHVjY2nDs24sIGV4cG9ydGFjaW9uZXMgeSB2ZW50YXMgaW50ZXJuYXMuIEVsIEVjb25vbWlzdGE7IEVsIEVjb25vbWlzdGEuIGh0dHBzOi8vd3d3LmVsZWNvbm9taXN0YS5jb20ubXgvZW1wcmVzYXMvSW5kdXN0cmlhLWF1dG9tb3RyaXotYW5vdGEtdW4tYnVlbi1hZ29zdG8tY3JlY2VuLXByb2R1Y2Npb24tZXhwb3J0YWNpb25lcy15LXZlbnRhcy1pbnRlcm5hcy0yMDIyMDkwNy0wMDMxLmh0bWwNCiAgDQogIEhlcm7DoW5kZXosIEYuLCAmIFVzdWdhLCBPLiAoMjAyMikuIDkgVGFibGFzIGRlIGZyZWN1ZW5jaWEgfCBNYW51YWwgZGUgUi4gUmV0cmlldmVkIDI0IFNlcHRlbWJlciAyMDIyLCBmcm9tIGh0dHBzOi8vZmhlcm5hbmIuZ2l0aHViLmlvL01hbnVhbC1kZS1SL3RhYmxhcy5odG1sI2VqZW1wbG8tdGFibGEtZGUtZnJlY3VlbmNpYS1yZWxhdGl2YS1kZS11bmEtdiVDMyVBRGENCg0KICA5IEVzdGlsb3MgeSBmb3JtYXRvcyBkZSB0YWJsYSB8IFRhYmxhcyB5IGdyYWZpY29zIGNvbiBSIHkgUiBTdHVkaW8uICgyMDIyKS4gUmV0cmlldmVkIDI0IFNlcHRlbWJlciAyMDIyLCBmcm9tIGh0dHBzOi8vdGFibGVzLmludmVzdGlnYW9ubGluZS5jb20vdHNlLWZvcm1hdGVvLmh0bWwNCg0KDQoNCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjpkYXJrb3JhbmdlIj4qKjUuIFByb2R1Y3Rpb24qKiANCg0KIyMgSW1wb3J0YXIgbGlicmVyaWFzDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQpsaWJyYXJ5KGZvcmVpZ24pDQpsaWJyYXJ5KGRwbHlyKSAgICAgICAgIyBkYXRhIG1hbmlwdWxhdGlvbiANCmxpYnJhcnkoZm9yY2F0cykgICAgICAjIHRvIHdvcmsgd2l0aCBjYXRlZ29yaWNhbCB2YXJpYWJsZXMNCmxpYnJhcnkoZ2dwbG90MikgICAgICAjIGRhdGEgdmlzdWFsaXphdGlvbiANCmxpYnJhcnkoamFuaXRvcikgICAgICAjIGRhdGEgZXhwbG9yYXRpb24gYW5kIGNsZWFuaW5nIA0KI2luc3RhbGwucGFja2FnZXMoIkhtaXNjIikNCmxpYnJhcnkoSG1pc2MpICAgICAgICAjIHNldmVyYWwgdXNlZnVsIGZ1bmN0aW9ucyBmb3IgZGF0YSBhbmFseXNpcyANCiNpbnN0YWxsLnBhY2thZ2VzKCJwc3ljaCIpDQpsaWJyYXJ5KHBzeWNoKSAgICAgICAgIyBmdW5jdGlvbnMgZm9yIG11bHRpdmFyaWF0ZSBhbmFseXNpcyANCiNpbnN0YWxsLnBhY2thZ2VzKCJuYW5pYXIiKQ0KbGlicmFyeShuYW5pYXIpICAgICAgICMgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIE5Bcw0KDQojaW5zdGFsbC5wYWNrYWdlcygiZGxvb2tyIikNCmxpYnJhcnkoZGxvb2tyKSAgIyBzdW1tYXJpZXMgYW5kIHZpc3VhbGl6YXRpb24gb2YgbWlzc2luZyB2YWx1ZXMgTkFzDQojaW5zdGFsbC5wYWNrYWdlcygiY29ycnBsb3QiKQ0KbGlicmFyeShjb3JycGxvdCkgICAgICMgY29ycmVsYXRpb24gcGxvdHMNCiNpbnN0YWxsLnBhY2thZ2VzKCJqdG9vbHMiKQ0KbGlicmFyeShqdG9vbHMpICAgICAgICMgcHJlc2VudGF0aW9uIG9mIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQojaW5zdGFsbC5wYWNrYWdlcygibG10ZXN0IikNCmxpYnJhcnkobG10ZXN0KSAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgDQojaW5zdGFsbC5wYWNrYWdlcygiY2FyIikNCmxpYnJhcnkoY2FyKSAgICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMNCiNpbnN0YWxsLnBhY2thZ2VzKCJvbHNyciIpDQpsaWJyYXJ5KG9sc3JyKSAgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzIA0KI2luc3RhbGwucGFja2FnZXMoImthYmxlRXh0cmEiKQ0KbGlicmFyeShrYWJsZUV4dHJhKSAgICMgSFRNTCB0YWJsZSBhdHRyaWJ1dGVzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmBgYA0KDQoNCiMjIEltcG9ydGFyIGJhc2UgZGUgZGF0b3MNCg0KDQpgYGB7cn0NCiNmaWxlLmNob29zZSgpDQpwcm9kdWNjaW9uPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxCYXNlIHByb2R1Y2Npb24gZm9ybSAtIEJhc2UgcHJvZHVjY2lvbiBmb3JtIC0gQmFzZSBwcm9kdWNjaW9uIGZvcm0gLSBCYXNlIHByb2R1Y2Npb24gZm9ybS5jc3YuY3N2LmNzdiIgKQ0KYGBgDQpsaWJyYXJ5KGRwbHlyKQ0KDQoqKlByb2R1Y2Npb24qKg0KKjM5ODggcmVnaXN0cm9zIHkgMTUgdmFyaWFibGVzKiANCg0KIyMgMS4gRW50ZW5kZXIgeSBsaW1waWFyIGxhIGJhc2UgZGUgZGF0b3MgDQpgYGB7cn0NCmRlc2NyaWJlKHByb2R1Y2Npb24pDQpgYGANCg0KDQojIyMgUGFzbyAxLiBEZSBjYXJhY3RlciBhIGZlY2hhIChUZWNuaWNhIDQuIENvbnZlcnRpciB0aXBvcyBkZSBkYXRvcykNCmBgYHtyfQ0KYmRwPC1wcm9kdWNjaW9uDQpiZHAkRmVjaGE8LSBhcy5EYXRlKGJkcCRGZWNoYSwgZm9ybWF0PSAiJWQvJW0vJVkiKQ0Kc3VtbWFyeShiZHApDQp0aWJibGUoYmRwKQ0KYGBgDQoNCg0KIyMjIFBhc28gMi4gRWxpbWluYXIgY29sdW1uYXMgaW5zZXJ2aWJsZXMoVGVjbmljYSAxLiBSZW1vdmVyIHZhbG9yZXMgaXJyZWxldmFudGVzKQ0KYGBge3J9DQpiZHAxPC1iZHANCmJkcDEgPC0gc3Vic2V0KGJkcDEsIHNlbGVjdCA9LWMgKElELkZPUk0pKQ0KYmRwMSA8LSBzdWJzZXQoYmRwMSwgc2VsZWN0ID0tYyAoSU5JQ0lPLlNFUC5VUCxGSU4uSU5JQ0lPLkRFLlNFUC5VUCwgVElFTVBPLk1BVEVSSUFMRVMpKQ0KYmRwMSA8LSBzdWJzZXQoYmRwMSwgc2VsZWN0ID0tYyAoSFIuLkZJTiwgSU5JQ0lPLmRlLlBST0NFU08sIEZJTi5kZS5QUk9DRVNPKSkNCmBgYA0KDQojIyMgQ2FtYmlhciBub21icmVzDQpgYGB7cn0NCmNvbG5hbWVzKGJkcDEpPC1jKCdmZWNoYScsJ2NsaWVudGUnLCdwcm9kdWN0bycsJ3BpZXphc19wcm9nJywndGllbXBvX21pbicsJ2VzdGFfYXJyYW5xdWUnLCdsYW1pbmFzX3Byb2Nlc2FkYXMnLCd0aWVtcG9fY2FsaWRhZCcpDQpgYGANCg0KIyMjIFBhc28gMy4gQ2FtYmlhciBkZSBjYXJhY3RlciBhIE51bWVyaWNvIChUZWNuaWNhIDQuIENvbnZlcnRpciB0aXBvcyBkZSBkYXRvcykgIA0KDQpgYGB7cn0NCmJkcDEkcGllemFzX3Byb2c8LWFzLm51bWVyaWMoYmRwMSRwaWV6YXNfcHJvZykgICAgICAgICAgICAgICANCmJkcDEkdGllbXBvX21pbjwtYXMubnVtZXJpYyhiZHAxJHRpZW1wb19taW4pICAgICAgICAgICAgICAgICANCmJkcDEkbGFtaW5hc19wcm9jZXNhZGFzPC1hcy5udW1lcmljKGJkcDEkbGFtaW5hc19wcm9jZXNhZGFzKSANCmJkcDEkdGllbXBvX2NhbGlkYWQ8LWFzLm51bWVyaWMoYmRwMSR0aWVtcG9fY2FsaWRhZCkgICAgICAgICANCg0KYmRwMjwtYmRwMQ0KYmRwMiR0aWVtcG9fbWluIDwtIHN1YnN0cihiZHAyJHRpZW1wb19taW4sIHN0YXJ0ID0gMSwgc3RvcCA9IDIpDQp0aWJibGUoYmRwMikgIA0KYmRwMiR0aWVtcG9fbWluIDwtIGFzLmludGVnZXIoYmRwMiR0aWVtcG9fbWluKQ0Kc3RyKGJkcDIpICANCg0KYmRwMiRwaWV6YXNfcHJvZyA8LSBzdWJzdHIoYmRwMiRwaWV6YXNfcHJvZywgc3RhcnQgPSAxLCBzdG9wID0gMikNCnRpYmJsZShiZHAyKSAgDQpiZHAyJHBpZXphc19wcm9nIDwtIGFzLmludGVnZXIoYmRwMiRwaWV6YXNfcHJvZykNCnN0cihiZHAyKQ0KDQpiZHAyJGxhbWluYXNfcHJvY2VzYWRhcyA8LSBzdWJzdHIoYmRwMiRsYW1pbmFzX3Byb2Nlc2FkYXMsIHN0YXJ0ID0gMSwgc3RvcCA9IDIpDQp0aWJibGUoYmRwMikgIA0KYmRwMiRsYW1pbmFzX3Byb2Nlc2FkYXMgPC0gYXMuaW50ZWdlcihiZHAyJGxhbWluYXNfcHJvY2VzYWRhcykNCnN0cihiZHAyKSANCmBgYA0KDQoNCiMjIyBQYXNvIDQuIENhbWJpYXIgZGUgTi9BIGEgcHJvbWVkaW9zIA0KYGBge3J9DQpiZHAzIDwtIGJkcDINCmJkcDMkdGllbXBvX21pbltpcy5uYShiZHAzJHRpZW1wb19taW4pXTwtbWVhbihiZHAzJHRpZW1wb19taW4sIG5hLnJtID0gVFJVRSkNCnN1bW1hcnkgKGJkcDMpIA0KYGBgDQoNCg0KIyMjIFBhc28gNS4gQ2FtYmlhciBkZSBOL0EgYSAwDQpgYGB7cn0NCmJkcDQgPC0gYmRwMw0KYmRwNCRsYW1pbmFzX3Byb2Nlc2FkYXNbYmRwNCRsYW1pbmFzX3Byb2Nlc2FkYXMgPCAxXTwtIE5BDQpzdW1tYXJ5IChiZHA0KQ0KYGBgDQoNCg0KIyMjIFBhc28gNi4gQm9ycmEgTi9Bcw0KYGBge3J9DQpiZHA1IDwtIGJkcDQNCmJkcDUgPC0gbmEub21pdChiZHA1KSAgICANCnN0cihiZHA1KQ0KYGBgDQoNCg0KIyMjIFZlcmlmaWNhciBlbGltaW5hY2lvbiBkZSBOQcK0cw0KYGBge3J9DQpjb2xTdW1zKGlzLm5hKGJkcDUpKQ0Kc3VtbWFyeShiZHA1KQ0KDQpzdHIoYmRwNSkNCnN1bW1hcnkoYmRwNSkNCmBgYA0KDQoNCiMjIDIuQ2xhc2lmaWNhIGNhZGEgdmFyaWFibGUgZW4gY3VhbGl0YXRpdmEsIGN1YW50aXRhdGl2YSBkaXNjcmV0YSBvIGN1YW50aXRhdGl2YSBjb250aW51YSB5IEVzY2FsYXMgZGUgTWVkaWNpb24uDQoNCmBgYHtyfQ0KVmFyaWFibGU8LWMoIkZlY2hhICIsImNsaWVudGUiLCJwcm9kdWN0byIsICJQaWV6YXMgcHJvZ3JhbWFkYXMiLCJ0aWVtcG8gbWluIiwiRXN0YWNpb24gZGUgYXJyYW5xdWUiLCJMYW1pbmFzIHByb2Nlc2FkYXMiLCAiVGllbXBvIGRlIGNhbGlkYWQiKQ0KVHlwZTwtYygiQ3VhbGl0YXRpdmEiLCJDdWFsaXRhdGl2YSIsIkN1YWxpdGF0aXZhIiwgIkN1YW50aXRhdGl2YShEaXNjcmV0YSkiLCAiQ3VhbnRpdGF0aXZhKERpc2NyZXRhKSIsIkN1YWxpdGF0aXZhIiwgIkN1YW50aXRhdGl2YShEaXNjcmV0YSkiLCAiQ3VhbnRpdGF0aXZhIGRpc2NyZXRhIikNCk1lZGljaW9uIDwtYygiTm9taW5hbCIsICJOb21pbmFsIiwiTm9taW5hbCIsICJJbnRlcnZhbG8iLCAiSW50ZXJ2YWxvIiwiTm9taW5hbCIsICJJbnRlcnZhbG8iLCAiSW50ZXJ2YWxvIikgDQp0YWJsZTwtZGF0YS5mcmFtZShWYXJpYWJsZSxUeXBlLCBNZWRpY2lvbikNCmtuaXRyOjprYWJsZSh0YWJsZSkNCmBgYA0KDQojIyMgRXhwb3J0YXIgY3N2DQpgYGB7cn0NCndyaXRlLmNzdihiZHA1LCJDOlxcVXNlcnNcXGRhbnljXFxPbmVEcml2ZSAtIEluc3RpdHV0byBUZWNub2xvZ2ljbyB5IGRlIEVzdHVkaW9zIFN1cGVyaW9yZXMgZGUgTW9udGVycmV5XFxEZXNrdG9wXFxGb3JtX3Byb2R1Y2Npb25iYXNlbGltcGlhLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkNCmBgYA0KDQojIyMgSW1wb3J0YXIgYmFzZSBkZSBkYXRvcyBsaW1waWENCg0KYGBge3J9DQpiZGw8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxPbmVEcml2ZSAtIEluc3RpdHV0byBUZWNub2xvZ2ljbyB5IGRlIEVzdHVkaW9zIFN1cGVyaW9yZXMgZGUgTW9udGVycmV5XFxEZXNrdG9wXFxGb3JtX3Byb2R1Y2Npb25iYXNlbGltcGlhLmNzdiIpDQpgYGANCg0KIyMgRGF0b3MgZGVzY3JpcHRpdm9zIA0KIyMgKlRhYmxhIGRlIE1lZGlhLCBNb2RhIHkgTWVkaWFuYQ0KTG9zIGRhdG9zIGFxdWkgbXVlc3RyYW4gdW5hIGRlc3ZpYWNpb24gZXN0YW5kYXIgeSBkYXRvcyBtdXkgYWxlamFkb3MgZW50cmUgbG9zIHB1bnRvcyB2YXJpYWJsZXMgbG8gY3VhbCBub3MgaW5kaWNhIHVuYSBhbHRlcmFjaW9uIGVuIGxhIHVuaWZvcm1pZGFkIGRlIGxvcyBkYXRvcyBsbyBjdWFsIG5vcyBwdWVkZSBpbmRpY2FyIGFsZ3VuYSBmYWxsYSBlbiBsb3MgZGF0b3MgbyBiaWVuIHVuIGRldGFsbGUgZGUgcHJvZHVjdGl2aWRhZC4NCmBgYHtyfQ0KYmQ2PC1iZGwNCnRhYmxhPC1kZXNjcmliZShiZDYpDQoNCmBgYA0KDQoNCg0KDQojIyMgR3JhZmljYXMNCg0KIyMjIyBCYXJwbG90cy0zDQoNClJlY29waWxhbmRvIGxhIGluZm9ybWFjaW9uIG1lIHRvcGUgY29uIGVzdG9zIGRhdG9zIGxvIGN1YWwgbm9zIGluZm9ybWEgYWNlcmNhIGRlIGxvcyBjbGllbnRlcyBtYXMgZGVzdGFjYWRvcyBwYXJhIGZvcm0geSBlbCB0aWVtcG8gbWluaW1vIGRlIHRhcmRhbnphIGVuIGVsIGVuc2FtYmxhamUgZGUgbG9zIHByb2R1Y3RvcywgZW4gZXN0ZSBjYXNvIGVsIHByaW1lciBsdWdhciBjb24gbWFzIGVmaWNpZW5jaWEgcG9yIGNsaWVudGUgZnVlIHN0YWJpbHVzIGVuIGxhIHByaW1lcmEgdnVlbHRhLg0KTm90YTogTEEgdmlzdWFsaXphY2lvbiBubyBzZSBjb21wbGV0YSBlbiBlc3RlIHJtZCwgcGFyYSBtZWpvciB2aXN1YWxpemFjaW9uIHZlciBhcmNoaXZvIGluZGl2aWR1YWwuDQpgYGB7cn0NCiNiZDY8LWJkNiAlPiUgc2VsZWN0KHBpZXphc19wcm9nLHRpZW1wb19taW4sY2xpZW50ZSApICU+JSBncm91cF9ieShjbGllbnRlKSAlPiUgDQogICNzdW1tYXJpc2UocGllemFzX3Byb2c9c3VtKHBpZXphc19wcm9nKSx0aWVtcG9fbWluPXN1bSh0aWVtcG9fbWluKSkgJT4lIGFycmFuZ2UoZGVzYyhwaWV6YXNfcHJvZykpDQoNCiNiZDY8LWJkNlstYyg3LDgsOSksXSANCg0KDQojZ2dwbG90KGJkNixhZXMoeD1yZW9yZGVyKHRpZW1wb19taW4scGllemFzX3Byb2cpLCB5PXBpZXphc19wcm9nLGZpbGw9Y2xpZW50ZSkpICsNCiMgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikNCg0KYGBgDQo8aW1nIHNyYz0gIkM6XFxVc2Vyc1xcZGFueWNcXE9uZURyaXZlXFxQaWN0dXJlc1xcU2NyZWVuc2hvdHNcXENhcHR1cmEgZGUgcGFudGFsbGEgKDMwMCkucG5nIi8+ICANCkRlbnRybyBkZSBlc3RhIHNlZ3VuZGEgdGFibGEgZGUgYmFycmFzIHNlIHB1ZWRlIHZlciBkZXNwbGVnYWRvIGxhIGNhbnRpZGFkIGRlIHBpZXphcyBwcm9ncmFtYWRhcyBxdWUgc2UgdHV2byBwb3IgbWVzIGVuIGxvcyBwZXJpb2RvcyBkZSBsb3MgbWVzZXMganVsaW8sIGFnb3N0byB5IHNlcHRpZW1icmUuIEVzdG8gbm9zIGRpY2UgYWNlcmNhIGRlIGxhIG1heW9yIHByb2R1Y3RpdmlkYWQgZGUgYWdvc3RvLCBwZXJvIHBvcnF1ZSBlcyBlc3RvPw0KYGBge3J9DQpkYXRvc2NvcGlhPC1iZGwNCmRhdG9zY29waWEkYW5vPC1zdHJmdGltZShkYXRvc2NvcGlhJGZlY2hhLCAiJVkiKQ0KZGF0b3Njb3BpYSRtZXM8LXN0cmZ0aW1lKGRhdG9zY29waWEkZmVjaGEsICIlbSIpDQoNCmRhdGFfYWdnPC0gYWdncmVnYXRlKHBpZXphc19wcm9nfm1lcyArIGFubywgZGF0b3Njb3BpYSwgRlVOID0gc3VtKQ0KZGF0YV9hZ2dsYW1pbmE8LSBhZ2dyZWdhdGUobGFtaW5hc19wcm9jZXNhZGFzfm1lcyArIGFubywgZGF0b3Njb3BpYSwgRlVOID0gc3VtKQ0KZ2dwbG90KGRhdGFfYWdnLGFlcyh4PW1lcyx5PXBpZXphc19wcm9nKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KRW4gZXN0YSBncmFmaWNhIHNlIHB1ZWRlIHZpc3VhbGl6YXIgbGEgZGVwZW5kZW5jaWEgZGVsIHRpZW1wbyBtaW5pbW8gZGUgcHJvZHVjY2lvbiBjb24gbGFzIHBpZXphcyBwcm9ncmFtYWRhcyBkZXBlbmRpZW5kbyBkZSBsYSBlc3RhY2lvbiBkZSBhcnJhbnF1ZSwgbGEgbWF5b3IgcHJvZHVjdGl2aWRhZCBnZW5lcmFsIHRpZW5lIHVuYXJlbGFjaW9uIGNvbiBsYSBlc3RhY2lvbiBDMSB5IGxhIEMxeTIgeWEgcXVlIHNlIHZlIHF1ZSBlcyBsYSBxdWUgbWVub3MgdGllbXBvIGhhY2UgY29uIG1hcyBwcm9jZXNhbWllbnRvIGRlIGxhbWluYXMuDQpgYGB7cn0NCmdncGxvdChkYXRvc2NvcGlhLGFlcyh4PXRpZW1wb19taW4sIHk9cGllemFzX3Byb2csZmlsbD1lc3RhX2FycmFucXVlKSkgKw0KICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpDQpgYGANCg0KDQoNCiMjIyMgRGlzcGVyc2lvbi0yDQpFbiBlc3RhIHRhYmxhIHNlIG11ZXN0cmEgdW4gY2xhcm8gZWplbXBsbyBkZSBjb21wYXJhY2lvbiBxdWUgZW50cmUgbWFzIHRpZW1wbyBkZSBjYWxpZGFkIHNlIGxlIGRlIGFsIGNsaWVudGUgc2UgbG9ncmFyYSBoYWNlciB1biB0aWVtcG8gbXVjaG8gbWFzIG1pbmltbyBlZmVjdGl2aXphbmRvIGxvcyBwcm9jZXNvcyB5IHRlcm1pbmFuZG9sb3MgbWFzIHJhcGlkbyBjb21vIGZ1ZSBjb24gbG9zIGNsaWVudGVzIGVuIGF6dWwuDQpgYGB7cn0NCmdncGxvdChkYXRvc2NvcGlhLCBhZXMoeD10aWVtcG9fY2FsaWRhZCwgeT10aWVtcG9fbWluLCBjb2xvcj1jbGllbnRlKSkgKw0KICBnZW9tX3BvaW50KCkgKyBnZW9tX3J1ZygpDQpgYGANCkVuIGVzdGEgZ3JhZmljYSwgc2UgaWVuZSBsYSBpbnRlbmNpb24gZGUgdmVyIGEgbG9zIGNvbXByYWRvcmVzIHByZWRvbWluYW50ZXMgZGVudHJvIGRlIEZPUk0gZHVyYW50ZSBsb3MgdHJlcyBtZXNlcyBwcmVkaWN0aXZvcywgZXN0byBwYXJhIHBvZGVyIGxvZ3JhciB1bmEgYXRlbmNpb24gZXNwZWNpYWxpemFkYSB5IHZlciBtYXMgbyBtZW5vcyBlbCB0aWVtcG8gcXVlIHRvbWFuIHN1cyBwcm9kdWN0b3MgeSBnZW5lcmFyIHVuIHRpcG8gZGUgcHJvY2Vzb3MgbWFzIGZsdWlkby4NCmBgYHtyfQ0KZ2dwbG90KGRhdG9zY29waWEsIGFlcyh4PWNsaWVudGUsIHk9bGFtaW5hc19wcm9jZXNhZGFzLCBjb2xvcj1tZXMpKSArDQogIGdlb21fcG9pbnQoKSArIGdlb21fcnVnKCkNCmBgYA0KDQojIyMgU2VyaWVzIGRlIHRpZW1wby0xDQpBcXVpIHNlIHB1ZWRlIHZlciB1bmEgc2VyaWUgZGUgdGllbXBvIG5vIGxpbmVhbCwgbG8gY3VhbCBub3MgZGljZSBxdWUgbm8gc2UgdGllbmVuIHByb2Nlc29zIGNsYXJvcyB5IGVzdGFibGVzIHBhcmEgbGEgcHJvZHVjY2lvbiBsbyBjdWFsIGxvIGNvbnZpZXJ0ZSBlbiB1biBwcm9jZXNvIHZhcmlhYmxlIHkgY29uIGZhbGxhcyBlbiBsb3MgdGllbXBvcyBkZSBlbnRyZWdhcyBjb21vIHJlc3VsdGFkby4NCmBgYHtyfQ0KZ2dwbG90KGRhdG9zY29waWEsYWVzKHg9ZmVjaGEpKSsNCiAgZ2VvbV9saW5lKGFlcyh5PXBpZXphc19wcm9nKSxjb2xvcj0ib3JhbmdlIikrDQogIGxhYnMoeD0iRmVjaGEiLHk9InBpZXphcyBwcm9ncmFtYWRhcyIsIGNvbG9yPSJvcmFuZ2UiKSsNCiAgZ2d0aXRsZSgiR3JhZmljYSBkZSB0YXNhIGRlIHJlbmRpbWllbnRvIikNCmBgYA0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+Kio2LiBQZXJmb3JtYW5jZSoqIA0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+SW1wb3J0YXIgYmFzZSBkZSBkYXRvcyAgDQoNCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCmJhc2VfZGVfZGF0b3M8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxPbmVEcml2ZSAtIEluc3RpdHV0byBUZWNub2xvZ2ljbyB5IGRlIEVzdHVkaW9zIFN1cGVyaW9yZXMgZGUgTW9udGVycmV5XFxEZXNrdG9wXFxGb3JtXFxGb3JtZGVsaXZlcnlmaW5hbDMuY3N2IiApDQpgYGANCg0KIyMgSW5zdGFsYWNpb24gZGUgcGFxdWV0ZXMgDQoNCmBgYHtyfQ0KDQpsaWJyYXJ5KGZvcmVpZ24pDQpsaWJyYXJ5KGRwbHlyKSAgICAgICAgIyBkYXRhIG1hbmlwdWxhdGlvbiANCmxpYnJhcnkoZm9yY2F0cykgICAgICAjIHRvIHdvcmsgd2l0aCBjYXRlZ29yaWNhbCB2YXJpYWJsZXMNCmxpYnJhcnkoZ2dwbG90MikgICAgICAjIGRhdGEgdmlzdWFsaXphdGlvbiANCmxpYnJhcnkoamFuaXRvcikgICAgICAjIGRhdGEgZXhwbG9yYXRpb24gYW5kIGNsZWFuaW5nIA0KI2luc3RhbGwucGFja2FnZXMoIkhtaXNjIikNCiNsaWJyYXJ5KEhtaXNjKSAgICAgICAgIyBzZXZlcmFsIHVzZWZ1bCBmdW5jdGlvbnMgZm9yIGRhdGEgYW5hbHlzaXMgDQojaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KI2xpYnJhcnkocHN5Y2gpICAgICAgICAjIGZ1bmN0aW9ucyBmb3IgbXVsdGl2YXJpYXRlIGFuYWx5c2lzIA0KI2luc3RhbGwucGFja2FnZXMoIm5hbmlhciIpDQojbGlicmFyeShuYW5pYXIpICAgICAgICMgc3VtbWFyaWVzIGFuZCB2aXN1YWxpemF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIE5Bcw0KI2luc3RhbGwucGFja2FnZXMoImRsb29rciIpDQojbGlicmFyeShkbG9va3IpICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQXMNCiNpbnN0YWxsLnBhY2thZ2VzKCJjb3JycGxvdCIpDQojbGlicmFyeShjb3JycGxvdCkgICAgICMgY29ycmVsYXRpb24gcGxvdHMNCiNpbnN0YWxsLnBhY2thZ2VzKCJqdG9vbHMiKQ0KI2xpYnJhcnkoanRvb2xzKSAgICAgICAjIHByZXNlbnRhdGlvbiBvZiByZWdyZXNzaW9uIGFuYWx5c2lzIA0KI2luc3RhbGwucGFja2FnZXMoImxtdGVzdCIpDQojbGlicmFyeShsbXRlc3QpICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyANCiNpbnN0YWxsLnBhY2thZ2VzKCJjYXIiKQ0KI2xpYnJhcnkoY2FyKSAgICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMNCiNpbnN0YWxsLnBhY2thZ2VzKCJvbHNyciIpDQojbGlicmFyeShvbHNycikgICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyANCiNpbnN0YWxsLnBhY2thZ2VzKCJrYWJsZUV4dHJhIikNCiNsaWJyYXJ5KGthYmxlRXh0cmEpICAgIyBIVE1MIHRhYmxlIGF0dHJpYnV0ZXMNCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJDb2xvcjpvcmFuZ2UiPkVudGVuZGVyIG1pIGJhc2UgZGUgZGF0b3MgDQoxKSDCv0N1w6FudGFzIHZhcmlhYmxlcyB5IGN1YW50b3MgcmVnaXN0cm9zIHRpZW5lIGxhIGJhc2UgZGUgZGF0b3M/DQpTZSBtdWVzdHJhbiA4IHZhcmlhYmxlcyB5IDE0NDAgcmVnaXN0cm9zIGRlbnRybyBkZSBsYSBiYXNlIGRlIGRhdG9zLg0KYGBge3J9DQoNCmJkPC1iYXNlX2RlX2RhdG9zDQpzdW1tYXJ5KGJkKQ0Kc3RyKGJkKQ0KYGBgDQoNCg0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+Q291bnQgZGUgVmFyaWFibGVzIHkgRXNjYWxhcyAgDQoNCjIpIENsYXNpZmljYSBjYWRhIHZhcmlhYmxlIGVuIGN1YWxpdGF0aXZhLCBjdWFudGl0YXRpdmEgZGlzY3JldGEgbyBjdWFudGl0YXRpdmENCmNvbnRpbnVhLg0KDQpgYGB7cn0NClZhcmlhYmxlPC1jKCJgVGFyZ2V0YCIsImBDbGllbnRlYCIsImBWdWVsdGFzYCIsImBQbGFuLmFycml2YWxgIiwiYFJlYWwuYXJyaXZhbGAiLCJgUmVhbC5kZXBhcnR1cmVgIiwiYERpZmVyZW5jZWAiLCJgRmVjaGFgIikNClR5cGU8LWMoInF1YW50aWF0aXZlIChkaXNjcmV0ZSkiLCAicXVhbnRpYXRpdmUgKGNvbnRpbm91cykiLCAicXVhbnRpdGF0aXZlIChjb250aW5vdXMpIiwgInF1YW50aXRhdGl2ZSAoY29udGlub3VzKSIpDQp0YWJsZTwtZGF0YS5mcmFtZShWYXJpYWJsZSxUeXBlKQ0Ka25pdHI6OmthYmxlKHRhYmxlKQ0KYGBgDQoNCjMpIEVsaWdlIGxhIGVzY2FsYSBkZSBtZWRpY2nDs24gZGUgY2FkYSB2YXJpYWJsZS4gDQoNCmBgYHtyfQ0KdmFyaWFibGVzIDwtIGMoImBUYXJnZXRgIiwiYENsaWVudGVgIiwiYFZ1ZWx0YXNgIiwiYFBsYW4uYXJyaXZhbGAiLCJgUmVhbC5hcnJpdmFsYCIsImBSZWFsLmRlcGFydHVyZWAiLCJgRGlmZXJlbmNlYCIsImBGZWNoYWAiKQ0KdGlwb3MgPC0gYygiY3VhbnRpdGF0aXZvIChkaXNjcmV0bykgICIsICJjdWFsaXRhdGl2byAgIiwgImN1YW50aXRhdGl2byAoZGlzY3JldG8pICAiLCAiY3VhbnRpdGF0aXZvIChjb250aW51bykgICIsICJjdWFudGl0YXRpdm8gKGNvbnRpbnVvKSAgIiwgImN1YW50aXRhdGl2byAoY29udGludW8pICAiLCAiY3VhbnRpdGF0aXZvIChjb250aW51bykgICIsICJjdWFsaXRhdGl2byAgIikNCmVzY2FsYXMgPC0gYygiaW50ZXJ2YWxvIiwgIm5vbWluYWwiLCAicmF6b24iLCAicmF6b24iLCAicmF6b24iLCAicmF6b24iLCAicmF6b24iLCAib3JkaW5hbCIpDQp0YWJsZTEgPC0gZGF0YS5mcmFtZSAodmFyaWFibGVzLCB0aXBvcywgZXNjYWxhcykNCmtuaXRyOjprYWJsZSh0YWJsZTEpDQpgYGANCg0KDQoNCiMjIDxzcGFuIHN0eWxlPSJDb2xvcjpvcmFuZ2UiPkxpbXBpZXphIGRlIGJhc2VzIGRlIGRhdG9zIA0KDQo0KSBBcGxpY2EgYWwgbWVub3MgMiB0w6ljbmljYXMgZGUgbGltcGllemEgZGUgYmFzZXMgZGUgZGF0b3MgeSBleHBsw61jYWxhcw0KYnJldmVtZW50ZSwgwr9wb3IgcXXDqSByZWFsaXphc3RlIGVzYXMgdMOpY25pY2FzPyANCg0KTGFzIHTDqWNuaWNhcyBlbGVnaWRhcyBlbiBudWVzdHJhIGxpbXBpYSBkZSBkYXRvcyBzZSBlbGlnaWVyb24gcG9yIGxhcyBuZWNlc2lkYWRlcyBxdWUgcHJlc2VudGFiYSBsYSBiYXNlIHkgbGEgdXRpbGlkYWQgbyBubyBxdWUgdGVuw61hbiBudWVzdHJhcyB2YXJpYWJsZXMgDQoNCiMjIENPTlZFUlNJT04gREUgQ0FSQUNURVIgQSBGRUNIQSAoVEVDTklDQSBERSBDT05WRVJTSU9OIERFIERBVE9TKSAgDQpgYGB7cn0NCmJkMTwtYmQNCmJkMSRGZWNoYTwtIGFzLkRhdGUoYmQxJEZlY2hhLCBmb3JtYXQ9ICIlZC8lbS8leSIpDQpzdW1tYXJ5KGJkMSkNCnRpYmJsZShiZDEpDQpgYGANCg0KDQojIyDCv0N1YW50b3MgTi9BIHRlbmdvIGVuIG1pIGJhc2UgZGUgZGF0b3M/ICANCmBgYHtyfQ0Kc3VtKGlzLm5hKGJkMSkpDQpgYGANCg0KDQojIyBFbGltaW5hciBjb2x1bW5hcyANCg0KYGBge3J9DQpiZDI8LWJkMQ0KYmQyIDwtIHN1YnNldChiZDIsIHNlbGVjdCA9LWMgKFRhcmdldCkpDQpgYGANCiMjIyAqTm90YToqDQogU2UgZWxpbWluYSBlbCB0YXJnZXQgeWEgcXVlIG5vIG5vcyBtdWVzdHJhIHVuYSBpbmZvcm1hY2nDs24gZGV0YWxsYWRhIGFsIGRhcm5vcyBkYXRvcyBudWxvcyBkZSB0ZW5lciB1biAxIGVuIHRvZG9zIGxhZG9zLg0KDQojIyBMSU1QSUVaQSBQT1IgTUVUT0RPIEVTVEFESVNUSUNPIA0KYGBge3J9DQpiZDM8LWJkMg0KYm94cGxvdChiZDMkUGxhbi5hcnJpdmFsLCBob3Jpem9udGFsPVRSVUUpDQpib3hwbG90KGJkMyRSZWFsLmFycml2YWwsIGhvcml6b250YWw9VFJVRSkNCmJveHBsb3QoYmQzJFJlYWwuZGVwYXJ0dXJlLCBob3Jpem9udGFsPVRSVUUpDQpib3hwbG90KGJkMyREaWZlcmVuY2UsIGhvcml6b250YWw9VFJVRSkNCmBgYA0KDQojIyA8c3BhbiBzdHlsZT0iQ29sb3I6b3JhbmdlIj5BZ3JlZ2FyIGNvbHVtbmEgZGUgcHJvbWVkaW8gDQpgYGB7cn0NCmJkMyRQcm9tZWRpb19yZWFsX2Fycml2YWw8LSBtZWFuKGJkMyRSZWFsLmFycml2YWwpDQpgYGANCg0KIyMgQ29udmVydGlyIHZhcmFpYmxlcyBkZSBjYXJhY3RlciBhIG51bWVyaWNvLiANCmBgYHtyfQ0KYmQzJFZ1ZWx0YXM8LWFzLm51bWVyaWMoYmQzJFZ1ZWx0YXMpICAgICAjIyMgbWlzc2luZyB2YWx1ZXMgYXJlIGNvbnZlcnRlZCB0byBOQSdzDQpiZDMkUGxhbi5hcnJpdmFsPC1hcy5udW1lcmljKGJkMyRQbGFuLmFycml2YWwpICANCmJkMyRSZWFsLmFycml2YWw8LWFzLm51bWVyaWMoYmQzJFJlYWwuYXJyaXZhbCkgIA0KYmQzJFJlYWwuZGVwYXJ0dXJlPC1hcy5udW1lcmljKGJkMyRSZWFsLmRlcGFydHVyZSkgIA0KYmQzJERpZmVyZW5jZTwtYXMubnVtZXJpYyhiZDMkRGlmZXJlbmNlKSAgDQpiZDMkUHJvbWVkaW9fcmVhbF9hcnJpdmFsPC1hcy5udW1lcmljKGJkMyRQcm9tZWRpb19yZWFsX2Fycml2YWwpIA0KDQpiZDM8LWFzLmRhdGEuZnJhbWUoYmQzKSANCmJkMyRGZWNoYTwtYXMuRGF0ZShiZDMkRmVjaGEsZm9ybWF0PSIlbS8lZC8lWSIpIA0KYmQzJENsaWVudGU8LWFzLmZhY3RvcihiZDMkQ2xpZW50ZSkgDQoNCnRpYmJsZShiZDMpDQpgYGANCg0KDQojIyMgKk5vdGFzOiogDQogU2UgbXVlc3RyYSBxdWUgbGEgZGlmZXJlbmNpYSBkZSBudWVzdHJvcyBhcnJpdmFscyBubyBlcyBtdWNoYSwgcGVybyBoYWJyw61hIHF1ZSByZXZpc2FyIHNpIGVsIHByb21lZGlvIHRvdGFsIG5vcyBheXVkYXLDrWEuIA0KIHNlIGFncmVnbyB1bmEgY29sdW1uYSBkZSBwcm9tZWRpbyBnZW5lcmFsIGRlIG51ZXN0cm9zIGFycml2YWxzIHJlYWxlcy4NCiANCiMjIFJlbm9tYnJhciB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyB5IGN1YWxpdGF0aXZhcyANCmBgYHtyfQ0KI1NlbGVjY2lvbmFyIHZhcmlhYmxlcw0KYmQ0IDwtIGJkMyAlPiUgc2VsZWN0IChvbmVfb2YoIkNsaWVudGUiLCJWdWVsdGFzIiwiUGxhbi5hcnJpdmFsIiwiUmVhbC5hcnJpdmFsIiwiUmVhbC5kZXBhcnR1cmUiLCAiRGlmZXJlbmNlIiwgIkZlY2hhIiwiUHJvbWVkaW9fcmVhbF9hcnJpdmFsIikpDQojUmVub21icmFyIHZhcmlhYmVzDQpjb2xuYW1lcyhiZDMpPC1jKCJDbGUiLCAiVnVlbHRhcyIsICJQLmFycml2YWwiLCAiUi5hcnJpdmFsIiwgIlIuZGVwIiwgIkRpZiIsICJGZWNoYSIsICJQcm9tLlIuYXJyaXZhbCIpDQoNCmBgYA0KDQojIyA8c3BhbiBzdHlsZT0iQ29sb3I6b3JhbmdlIj5FeHBvcnRhciBiYXNlIGRlIGRhdG9zIA0KYGBge3J9DQpiZF9saW1waWE8LWJkMw0Kd3JpdGUuY3N2KGJkX2xpbXBpYSwgZmlsZT0iZm9ybWJhc2VsaW1waWEuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9IkNvbG9yOm9yYW5nZSI+ICpDb25jbHVzacOzbiogPC9zcGFuPiANCg0KUGFyYSBlc3RhIGFjdGl2aWRhZCwgcHVkaW1vcyBsaW1waWFyIGxhIGJhc2UgZGUgZGF0b3MgcXVlIHRpZW5lIEZvcm0gYWwgbW9kaWZpY2FybGEgYWwgMTAwJSBwYXJhIHBvZGVyIGFjb21vZGFyIGxvcyByZXF1ZXJpbWllbnRvcyBxdWUgdGllbmUgUiBwYXJhIGluc2VydGFyIGxhcyBiYXNlcyB5IHF1ZSBoYWdhbiBzZW50aWRvIGEgbGEgaG9yYSBkZSB0cmFiYWphcmxvLiANCg0KUGFyYSBlc3RhIGJhc2UgZGUgZGF0b3MgYWhvcmEgbG8gcXVlIG5vcyBwZXJtaXRpcsOhIGxvZ3JhciBlcyBoYWNlciBncsOhZmljYXMgeSB0YWJsYXMgcGFyYSBkZXRhbGxhciB5IG1vc3RyYXIgbGEgaW5mb3JtYWNpw7NuICoqaW1wb3J0YW50ZSoqIGRlIG51ZXN0cmEgYmFzZS4NCg0KDQojIyA8c3BhbiBzdHlsZT0iQ29sb3I6b3JhbmdlIj5BbmFsaXNpcyBFeHBsb3JhdG9yaW8gZGUgbGEgQmFzZSBkZSBEYXRvcyANCg0KIyMgRXhwb3J0YXIgbGEgYmFzZSBkZSBkYXRvcw0KYGBge3J9DQojZmlsZS5jaG9vc2UoKQ0KYmRfbGltcGlhPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcT25lRHJpdmUgLSBJbnN0aXR1dG8gVGVjbm9sb2dpY28geSBkZSBFc3R1ZGlvcyBTdXBlcmlvcmVzIGRlIE1vbnRlcnJleVxcRGVza3RvcFxcRm9ybVxcZm9ybWJhc2VsaW1waWEuY3N2IikNCmBgYA0KDQoNCg0KIyMgVGFibGEgcHJpbmNpcGFsZXMgZXN0YWTDrXN0aWNvcyBkZXNjcnB0aXZvcw0KDQpgYGB7cn0NCmJkX2xpbXBpYSA8LSBiZDMNCnN1bW1hcnkoYmRfbGltcGlhKQ0Kc2QoYmRfbGltcGlhJFZ1ZWx0YXMsIG5hLnJtID0gRkFMU0UpDQpzZChiZF9saW1waWEkUC5hcnJpdmFsLCBuYS5ybSA9IEZBTFNFKQ0Kc2QoYmRfbGltcGlhJFIuYXJyaXZhbCwgbmEucm0gPSBGQUxTRSkNCnNkKGJkX2xpbXBpYSRSLmRlcCwgbmEucm0gPSBGQUxTRSkNCnNkKGJkX2xpbXBpYSREaWYsIG5hLnJtID0gRkFMU0UpDQoNClZhcmlhYmxlPC1jKCJWdWVsdGFzIiwiUC5hcnJpdmFsIiwgIlIuYXJyaXZhbCIsICJSLmRlcCIsICJEaWYiKQ0KTWVkaWFuYTwtYygiMS41MCAiLCI0LjAwMCIsIjAuMDAwICIsIjAuMDAwICIsIjAuMDAwMCAiKQ0KTWVkaWEgPC0gYygiMS43NSIsIjYuNjI1IiwiMy44MjMiLCI0LjE0MiIsIjQuMTQyIikNCk1vZGEgPC0gYygiMSIsIjAiLCIwIiwiMCIsIjAiKQ0KRGVzdmlhY2nDs25fZXN0YW5kYXI8LWMoIjAuODI5NDQ0MiIsIiA3LjUwMTU2MyIsIjYuNTA1OTAyIiwiNi45NDg2NjUiLCI2Ljk0ODY2NSIpDQp0YWJsZTEgPC0gZGF0YS5mcmFtZSAoVmFyaWFibGUsIE1lZGlhbmEsIE1lZGlhLCBNb2RhLCBEZXN2aWFjacOzbl9lc3RhbmRhcikNCmtuaXRyOjprYWJsZSh0YWJsZTEpDQpgYGANCiMjIyAqTm90YXM6Kg0KU2Ugb2N1cG8gc3VtbWFyeSBwYXJhIHBvZGVyIG9idGVuZXIgbGEgbW9kYSwgbWVkaWFuYSB5IG1lZGlhIGRlIGxhcyB2YXJpYWJsZXMgeSBwb3N0ZXJpb3JtZW50ZSBzZSBjYWxjdWxhIGxhIGRlc3ZpYWNpw7NuIGVzdGFuZGFyIGNvbiBsYSBmdW5jacOzbiBzZCgpDQoNCiMjIDxzcGFuIHN0eWxlPSJDb2xvcjpvcmFuZ2UiPlRhYmxhIGRlIEZyZWN1ZW5jaWENCg0KYGBge3J9DQojaW5zdGFsbC5wYWNrYWdlcygnZXBpRGlzcGxheScpDQpsaWJyYXJ5KGVwaURpc3BsYXkpDQp0YWIxKGJkX2xpbXBpYSREaWYsIHNvcnQuZ3JvdXAgPSAiZGVjcmVhc2luZyIsIGN1bS5wZXJjZW50ID0gVFJVRSkgDQp0YWIxKGJkX2xpbXBpYSRSLmFycml2YWwsIHNvcnQuZ3JvdXAgPSAiZGVjcmVhc2luZyIsIGN1bS5wZXJjZW50ID0gVFJVRSkNCmBgYA0KIyMjICpOb3RhczoqIA0KVmllbmRvIGVsIGdyw6FmaWNvIGRlIGRpc3RyaWJ1Y2nDs24gc2UgcHVlZGVuIHZlciBsYXMgZnJlY3VlbmNpYXMgZW4gbGFzIGRpZmVyZW5jaWFzLCBzZSB2ZSB1bmEgbWF5b3IgcGFydGUgZW4gZWwgbsO6bWVybyAwLCBsbyBjdWFsIG5vcyBpbmRpY2EgdW4gYnVlbiBkZXNhcnJvbGxvIGVuIGRlbGl2ZXJ5Lg0KDQojIyA8c3BhbiBzdHlsZT0iQ29sb3I6b3JhbmdlIj7igJxUaW1lIHNlcmllcyBwbG90c+KAnSAobGluZSBwbG90KQ0KDQpgYGB7cn0NCiNDaGVjYXIgcXVlIGxhIGJhc2UgZGUgZGF0b3MgZXN0YSBlc3RydWN0dXJhZGEgeSB1biByZXN1bWVuIGRlIGxhIGRlc2NyaXBjacOzbiBlc3RhZGlzdGljYQ0Kc3VtbWFyeShiZF9saW1waWEpDQoNCiNHcmFmaWNhciANCmdncGxvdChiZF9saW1waWEsYWVzKHg9RmVjaGEsIHk9RGlmLGNvbG9yPUNsZSkpKw0KICBnZW9tX2xpbmUoKSsNCiAgbGFicyh4PSJGZWNoYSIseT0iRGVsYXkgaW4gTWludXRlcyIsIGNvbG9yPSJMZWdlbmQiKSsNCiAgZ2d0aXRsZSgiRGVsYXlzIGluIFBlcmZvcm1hbmNlIGJ5IENsaWVudCIpDQoNCmBgYA0KIyMjIENoZWNhciBsYSBwcmVzZW5jaWEgZGUgbWlzc2luZyB2YWx1ZXMNCmBgYHtyfQ0KYmRfbGltcGlhMSA8LSBiZF9saW1waWENCmJkX2xpbXBpYTE8LWJkX2xpbXBpYTFbLWMoMzAwLDI5MiksXSAjIFF1aXRhciBsYXMgZmlsYXMgMzAwIHkgMjkyIHBvciBxdWUgcHJlc2VudGFuIGRhdG9zIG5lZ2F0aXZvcyB5IHF1ZSBubyBzaXJ2ZW4gcGFyYSBlbCBhbmFsaXNpcy4NCnN1bW1hcnkoYmRfbGltcGlhMSkgIyBubyBtaXNzaW5nIHZhbHVlcw0KYGBgDQoNCg0KIyMjIFF1aXRhciBjbGllbnRlcyBxdWUgdGVuZ2FuIHZhbG9yIGRlIDAgZW4gbGEgYmFzZSBkZSBkYXRvcw0KYGBge3J9DQpiZF9saW1waWExPC1iZF9saW1waWExW2JkX2xpbXBpYTEkQ2xlIT0iTUFHTkEiLF0NCmJkX2xpbXBpYTE8LWJkX2xpbXBpYTFbYmRfbGltcGlhMSRDbGUhPSJWQVJST0MiLF0NCnN1bW1hcnkoYmRfbGltcGlhMSkNCmBgYA0KDQojIyMgUmVhbGl6YXIgbGEgZ3JhZmljYSBjb24gbG9zIDIgY2xpZW50ZXMgcXVlIGVsaW1pbmFtb3MNCmBgYHtyfQ0KZ2dwbG90KGJkX2xpbXBpYTEsYWVzKHg9RmVjaGEsIHk9RGlmLGNvbG9yPUNsZSkpKw0KICBnZW9tX2xpbmUoKSsgIGdlb21faGxpbmUoeWludGVyY2VwdD0wLjgwMDAsbGluZXR5cGU9ImRhc2hlZCIsY29sb3I9ImJsYWNrIikrDQogIGxhYnMoeD0iRmVjaGEiLHk9IkRpZmVyZW5jaWEgcG9yIGTDrWEiLCBjb2xvcj0iTGVnZW5kIikrDQogIGdndGl0bGUoIkRpZmVyZW5jaWEgZGUgZW50cmVnYSBwb3IgQ2xpZW50ZSIpDQpgYGANCiMjIyBOb3RhIChIYWxsYXpnbyk6DQpFbmNvbnRyYW1vcyBncmFjaWFzIGEgbGEgZ3JhZmljYSByZWFsaXphZGEgZGUgbGEgRGlmZXJlbmNpYSBkZSB0aWVtcG8gZW4gbGEgZW50cmVnYSBkZSBwcm9kdWN0byBwb3IgY2xpZW50ZSwgcXVlIGxvcyBjbGllbnRlcyBjb24gbWF5b3IgRGVsYXkgc29uIE1BSExFIFkgUFJJTlRFTCwgYWwgbWlzbW8gdGllbXBvIGVuY29udHJhbW9zIHF1ZSBlbnRyZSBlc3RvcyBkb3MgY2xpZW50ZXMsIGVsIHF1ZSB0aWVuZSBtYXlvciBEZWxheSBlcyBNQUhMRSwgcG9yIGxvIHF1ZSBzZXLDrWEgYnVlbm8gcGFyYSBsYSBlbXByZXNhIGVsIHRlbmVyIHVuIG1heW9yIGVuZm9xdWUsIG9idmlvIGVuIGFtYm9zLCBwZXJvIHRhbWJpZW4gdW4gcG9jbyBtw6FzIGVuIE1haGxlLCBwYXJhIHF1ZSB0ZW5nYSBtZWpvciByZWZlcmVuY2lhIGRlIGVzdGUgY2xpZW50ZSB5IG1heW9yIGNvbmZpYW56YSBjb24gbGEgZW1wcmVzYSBlbiBsYXMgZW50cmVnYXMuIA0KDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+Kio3LiBCYXNlIGRlIERhdG9zIEV4dGVybmEqKiANCg0KIyMgUHJlZGljY2lvbiBkZSBsb3MgZGF0b3MgYmFzZSBkZSBkYXRvcyBleHRlcm5hIA0KDQoNCiMjIyBJbnN0YWxhciBwYXF1ZXRlcyB5IGxsYW1hciBsaWJyZXLDrWFzIA0KYGBge3J9DQoNCmxpYnJhcnkocHN5Y2gpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoR0dhbGx5KQ0KbGlicmFyeShUU3N0dWRpbykNCmxpYnJhcnkoZm9yZWNhc3QpDQpgYGANCg0KDQoNCiMjIyBMbGFtYXIgYmFzZSBkZSBkYXRvcyANCmBgYHtyfQ0KDQpDb21wYW5pZXMgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxleHRlcm5hX2JkMSBjc3YxLmNzdiIpDQpzdW1tYXJ5KENvbXBhbmllcykNCmBgYA0KDQoNCiMjIyAxLiBMaW1waWV6YSwgVHJhbnNmb3JtYWNpw7NuIHkgT3JnYW5pemFjacOzbiBkZSBCYXNlcyBkZSBEYXRvcyANCmBgYHtyfQ0Kc3RyKENvbXBhbmllcykNCmRlc2NyaWJlKENvbXBhbmllcykNCmBgYA0KDQogTm90YTogRGViaWRvIGEgbGEgdmVyc2nDs24gZGUgUiwgbm9zIGRlamEgZGVzY2FyZ2FyIGVsIHBhcXVldGUgInBzeWNoIi4gU2luIGVtYmFyZ28sIG5vIG5vcyBkZWphIGxsYW1hciBhIGxhIGxpYnJlcsOtYSAicHN5Y2giLCBwb3IgbG8gdGFudG8gdXRpbGl6YW1vcyBzdHIsIHBhcmEgb2J0ZW5lciBlbCBudW1lcm8gZGUgbGFzIHZhcmlhYmxlcyBkZSBsYSBiYXNlIGRlIGRhdG9zLg0KDQojIyMgMi4gQ2xhc2lmaWNhY2nDs24gZGUgdmFyaWFibGVzIA0KUmVhbGl6YW1vcyB1bmEgdGFibGEgcGFyYSBwb2RlciBjbGFzaWZpY2FyIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMgZGUgbGEgYmFzZSBkZSBEYXRvcyBiZDENCmBgYHtyfQ0KVmFyaWFibGU8LWMoIkdlb2dyYXBoeSIsIkNhdGVnb3J5IiwiRGF0YS5UeXBlIiwgIlVuaXQiLCJDdXJyZW50IENvbnN0YW50IiwiWWVhcnMiKQ0KVHlwZTwtYygiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhIChDb250aW51YSkiKQ0KdGFibGU8LWRhdGEuZnJhbWUoVmFyaWFibGUsVHlwZSkNCmtuaXRyOjprYWJsZSh0YWJsZSkNCmBgYA0KDQoNCg0KIyMjIDMuIEVzY2FsYSBkZSBNZWRpY2nDs24gDQpSZWFsaXphbW9zIHVuYSB0YWJsYSBkb25kZSB2aWVuZSBjbGFzaWZpY2FkbyBjYWRhIHZhcmlhYmxlIHkgYWdyZWdhbW9zIHVuYSBjb2x1bW5hIGNvbiBsYSBlc2NhbGEgZGUgbWVkaWNpw7NuIHBhcmEgY2FkYSB2YXJpYWJsZS4gDQpgYGB7cn0NCg0KVmFyaWFibGU8LWMoIkdlb2dyYXBoeSIsIkNhdGVnb3J5IiwiRGF0YS5UeXBlIiwgIlVuaXQiLCJDdXJyZW50IENvbnN0YW50IiwiWWVhcnMiKQ0KVHlwZTwtYygiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbGl0YXRpdmEiLCAiQ3VhbnRpdGF0aXZhIChDb250aW51YSkiKQ0KRXNjYWxhX2RlX01lZGljacOzbiA8LSBjKCJQYcOtc2VzIiwgIlByb2R1Y3RvIiwgIkRlcGFydGFtZW50byIsIlRpcG8gZGUgTW9uZWRhIiwgIlByZWNpbyBhY3R1YWwiLCAiR2FuYW5jaWEgKFJhem9uKSIpDQp0YWJsZTwtZGF0YS5mcmFtZShWYXJpYWJsZSxUeXBlLEVzY2FsYV9kZV9NZWRpY2nDs24pDQprbml0cjo6a2FibGUodGFibGUpDQpgYGANCg0KDQoNCiMjIyA0LiBMaW1waWV6YSBkZSBkYXRvcyANCiBMYSBwcmltZXIgdGVjbmljYSBkZSBsaW1waWV6YSBxdWUgdXRpbGl6YW1vcyBmdWUsIGVsaW1pbmFyIGNvbHVtbmFzIGRlYmlkbyBhIHF1ZSBjb250YWJhbW9zIGNvbiBkYXRvcyBsb3MgY3VhbGVzIG5vIGVyYW4gcmVsZXZhbnRlcyBwYXJhIGVsIGFuw6FsaXNpcy4gICAgDQogTGEgc2VndW5kYSBoZXJyYW1pZW50YSBkZSBsaW1waWV6YSBxdWUgdXRpbGl6YW1vcyBwYXJhIGxhIHZpc3VsaXphY2nDs24gZGUgbG9zIGRhdG9zIGZ1ZSBpbXBsZW1lbnRhciB1bmEgbnVldmEgY29sdW1uYSBjb21vIGVsIHRvdGFsIGRlIGxhIFByb2R1Y2Npw7NuIGRlIGxhcyB2YXJpYWJsZXMgcXVlIHNlIHByb2R1Y2VuIHBvciBwYcOtcy4NCg0KIyMjIFJlbW92ZXIgVmFsb3JlcyBJcnJlbGV2YW50ZXMgDQoNCiMjIyMgRWxpbWluYXIgY29sdW1uYXMgDQoNCmBgYHtyfQ0KYmQxIDwtIENvbXBhbmllcw0KYmQxPC1zdWJzZXQoYmQxLHNlbGVjdD0tYyhDYXRlZ29yeSxEYXRhLlR5cGUsQ3VycmVudC5Db25zdGFudCkpDQpzdHIoYmQxKQ0KYGBgDQoNCiMjIyMgQWdyZWdhciBDb2x1bW5hcyANCmBgYHtyfQ0KYmQxJFRvdGFsX1Byb2R1Y2Npb248LSBiZDEkWDIwMTYrYmQxJFgyMDE3K2JkMSRYMjAxOCtiZDEkWDIwMTkrYmQxJFgyMDIwK2JkMSRYMjAyMQ0KYmQxJFByb21lZGlvX1gyMDIxPC0gbWVhbihiZDEkWDIwMjEpDQoNCnN1bW1hcnkoYmQxKQ0Kc3RyKGJkMSkNCmBgYA0KDQoNCiMjIyMgwr9DdcOhbnRvcyBOQSdzIHRlbmdvIGVuIGxhIGJhc2UgZGUgZGF0b3M/IA0KDQpgYGB7cn0NCnN1bShpcy5uYShiZDEpKQ0KYGBgDQogTm90YTogU2UgZWxpbWluYW4gQ2F0ZWdvcnksIERhdGEuVHlwZSB5IEN1cnJlbnQuQ29uc3RhbnQsIHlhIHF1ZSBubyBub3Mgc2lydmVuLCBkZWJpZG8gYSBxdWUgZXMgZWwgbWlzbW8gZGF0byBwYXJhIHRvZG9zIGxvcyByZWdpc3Ryb3MgeSBlcyBhbGdvIHF1ZSBubyBub3MgYXBvcnRhIGFsZ3VuYSBpbmZvcm1hY2nDs24uIA0KDQojIyMgNS4gQW7DoWxpc2lzIEV4cGxvcmF0b3JpbyBkZSBsYXMgQmFzZXMgZGUgRGF0b3MgDQpgYGB7cn0NCmRlc2NyaWJlKGJkMSkNCmBgYA0KDQoNCg0KRW4gZWwgYW7DoWxpc2lzIGRlc2NyaXB0aXZvIHNlIG11ZXN0cmFuIGxvcyB2YWxvcmVzIHByb21lZGlvIGRlbCB0b3RhbCBkZSBwcm9kdWNjaW9uZXMgZGUgMjAxNiBhIDIwMjEuDQoNCiMjIyBUYWJsYSBkZSBGcmVjdWVuY2lhIA0KYGBge3J9DQpiZDIgPC0gdGFibGUoYmQxJFVuaXQpDQpiZDIgPC0gcHJvcC50YWJsZShiZDIpDQpiZDINCmBgYA0KDQoNCiMjIyBUYWJsYSBjcnV6YWRhIA0KYGBge3J9DQp0YWJsZShiZDEkVW5pdCwgYmQxJFByb21lZGlvX1gyMDIxKQ0KYGBgDQoNCg0KTGEgdGFibGEgbm9zIG11ZXN0cmEgbGEgY2FudGlkYWQgcHJvbWVkaW8gZW4gbWlsbG9uZXMgcHJvZHVjaWRhIGVuIDIwMjEgcG9yIGNhZGEgdW5pZGFkIG1vbmV0YXJpYS4gRW4gZXN0ZSBjYXNvLCB2ZW1vcyBxdWUgZW4gMjAyMSBzZSBwcm9kdWpvIGVuIHByb21lZGlvIG3DoXMgZGUgMU1NIGRlICJjdXJyZW5jaWVzIiAobm8gc2UgcHVlZGUgZGVmaW5pciB1bmEgdW5pZGFkIG1vbmV0YXJpYSBlc3BlY8OtZmljYSBkZWJpZG8gYSBxdWUgZXN0YW1vcyBwb25kZXJhbmRvIGRpc3RpbnRhcyBtb25lZGFzIGludGVybmFjaW9uYWxlcykuIENvbmZvcm1lIHNlIGFuYWxpemEgbGEgdGFibGEsIHZlbW9zIHF1ZSBlbCBldXJvIGdlbmVyw7MgMTggdmVjZXMgZWwgcHJvbWVkaW8gZGUgcHJvZHVjY2nDs24gZGUgY2FydMOzbiBlc3RpbWFkbyBwYXJhIDIwMjEsIGVzIGRlY2lyLCBlcyBsYSBtb25lZGEgaW50ZXJuYWNpb25hbCBxdWUgbcOhcyBwcm9kdWpvIGNhcnTDs24gYSBuaXZlbCBpbnRlcm5hY2lvbmFsIGVuIDIwMjEuIExhIHNpZ3VpZW50ZSBtb25lZGEgY29uIG1heW9yIGNhcGFjaWRhZCBkZSBwcm9kdWNjacOzbiBmdWUgVVNEIG1pbGxpb25zLiANCg0KIyMjIEdyw6FmaWNhcyBkZSBkYXRvcyBDdWFsaXRhdGl2YXMgeSBDdWFudGl0YXRpdmFzIA0KDQojIyMjIEN1YWxpdGF0aXZhIGNvbiBVbml0IA0KYGBge3J9DQpiYXJwbG90KGJkMiwgeGxhYj0nVGlwbyBkZSBNb25lZGEnLA0KICAgICAgICB5bGFiPSdGcmVjdWVuY2lhIFJlbGF0aXZhJywgbGFzPTEpDQpgYGANCg0KDQpMYSBncsOhZmljYSBub3MgbXVlc3RyYSBxdWUgZGUgYWN1ZXJkbyBhIGxhIGZyZWN1ZW5jaWEgcmVsYXRpdmEgZGUgcHJvZHVjY2nDs24sIEluZG9uZXNpYSBlcyBsYSB1bmlkYWQgbW9uZXRhcmlhIHF1ZSBtw6FzIGNhcnTDs24gaGEgZW50cmVnYWRvLiANCg0KIyMjIyBDdWFudGl0YXRpdmEgY29uIFRvdGFsX1Byb2R1Y2Npb24gDQpgYGB7cn0NCmJkMyA8LSBiZDENCmFnZ3JlZ2F0ZSh4PWJkMyRUb3RhbF9Qcm9kdWNjaW9uLCBieT1saXN0KGJkMyRHZW9ncmFwaHkpLEZVTj1zdW0pDQpgYGANCg0KIEVuIGxhIHRhYmxhIGFudGVyaW9yIHNlIG11ZXN0cmEgZWwgdG90YWwgZGUgcHJvZHVjY2nDs24gZ2VuZXJhZG8gcG9yIGNhZGEgcGHDrXMuIEhhY2llbmRvIHVuYSBwb25kZXJhY2nDs24gZGUgbG9zIDUgcGHDrXNlcyBxdWUgbWF5b3IgcHJvZHVjY2nDs24gZGUgY2FydMOzbiB0aWVuZW4gKGhhY2llbmRvICBjb250ZW8gaGlzdMOzcmljbyBkZSAyMDE2IGEgMjAyMSksIHZlbW9zIHF1ZSBzZSBkZXN0YWNhbiBJcsOhbiwgVmlldG5hbSwgQ29yZWEgZGVsIFN1ciwgSmFww7NuIGUgSW5kb25lc2lhLiANCg0KYGBge3J9DQpoaXN0KGxvZyhiZDEkVG90YWxfUHJvZHVjY2lvbiksIG1haW4gPSAiSGlzdG9ncmFtYSBkZSBQcm9kdWNjacOzbiBUb3RhbCIsIHhsYWI9IlByb2R1Y2Npw7NuIFRvdGFsIiwgDQogICAgIHlsYWI9IkZyZWN1ZW5jaWEiLCBjb2w9ImJsdWUxIikNCmBgYA0KDQoNCiBFbiBsYSBncsOhZmljYSBhbnRlcmlvciBzZSBzaW1ib2xpemEgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSBtdWVzdHJhIHJlc3BlY3RvIGEgbGEgcHJvZHVjY2nDs24gdG90YWwgeSBsYSBmcmVjdWVuY2lhIGRlIMOpc3RhLiBEZSBhY3VlcmRvIGEgbGEgZnJlY3VlbmNpYSB0b3RhbCwgdmVtb3MgcXVlIHNlIHRpZW5lIHVuYSBtYXlvciBwcm9kdWNjacOzbiBwb3IgZnJlY3VlbmNpYSBlbnRyZSAxMCB5IDE1LCBlcyBkZWNpciwgbGEgcHJvZHVjY2nDs24gdG90YWwgZXMgbcOhcyBhbHRhIHkgdGllbmUgdW5hIGZyZWN1ZW5jaWEgbWF5b3IgYSAxNSBxdWUgc2UgbXVlc3RyYSBjb21vIGVsIG3DoXMgZWxldmFkbyBlbiBlbCBoaXN0b2dyYW1hLg0KDQojIyMgR3LDoWZpY2FzIGRlIERpc3BlcnNpw7NuDQoNCiMjIyMgUmVsYWNpw7NuIEdlb2dyYXBoeSBjb24gUHJvZHVjY2nDs24gVG90YWwNCmBgYHtyfQ0KZ2dwbG90KGJkMSwgYWVzKHg9VG90YWxfUHJvZHVjY2lvbiwgeT1HZW9ncmFwaHkpKSArIA0KICBnZW9tX3BvaW50KHNoYXBlPTE5LCBzaXplPTMpICsgbGFicyh0aXRsZSA9ICJSZWxhY2nDs24gZW50cmUgbG9zIFBhw61zZXMgeSBsYSBQcm9kdWNjacOzbiBUb3RhbCIsY2FwdGlvbiA9IlBhc3Nwb3J0X1Byb2R1Y2Npw7NuQ2FydG9uIix4PSJQcm9kdWNjacOzbl9Ub3RhbCIsIHk9Ikdlb2dyYXBoeSIpICsgdGhlbWVfY2xhc3NpYygpDQoNCmBgYA0KDQogRW4gbGEgZ3LDoWZpY2EgYW50ZXJpb3Igc2UgbXVlc3RyYSBsYSByZWxhY2nDs24gZW50cmUgbG9zIHBhw61zZXMgeSBsYSBwcm9kdWNjacOzbiB0b3RhbC4gU2UgdmUgcXVlIGhheSB1bmEgZGlzcGVyc2nDs24gbWF5b3IgcGFyYSBsb3MgcGHDrXNlcyBlbiBlbCBjZW50cm8gZGUgbGEgZ3LDoWZpY2EuIEVzdG8gc2lnbmlmaWNhIHF1ZSBoYXkgbcOhcyBpcnJlZ3VsYXJpZGFkIGVuIGxhIHByb2R1Y2Npw7NuIHRvdGFsIHF1ZSBoYW4gZ2VuZXJhZG8uIA0KDQpgYGB7cn0NCmJveHBsb3Q9c3Vic2V0KGJkMSxzZWxlY3QgPSAtYyhUb3RhbF9Qcm9kdWNjaW9uLEdlb2dyYXBoeSkpDQpib3hwbG90KGJkMSRUb3RhbF9Qcm9kdWNjaW9uLCBtYWluPSAiVG90YWwgZGUgcHJvZHVjY2nDs24iKQ0KYGBgDQoNCg0KRW4gbGEgZ3LDoWZpY2EgYW50ZXJpb3IgdmVtb3MgZWwgdG90YWwgZGUgcHJvZHVjY2nDs24gZGUgYWN1ZXJkbyBhIGxhIGdlb2dyYWbDrWEuIEFsIGlndWFsIHF1ZSBsYSBncsOhZmljYSBhbnRlcmlvciwgaGF5IHVuYSBjb3JyZWxhY2nDs24gbWF5b3IgYWNvcmRlIGFsIHRvdGFsIGRlIHByb2R1Y2Npw7NuLiANCg0KYGBge3J9DQpWb2w8LXRzKGJveHBsb3Qsc3RhcnQ9YygyMDE2LDEpLGZyZXF1ZW5jeT0xMikNCnRzX3Bsb3QoVm9sLA0KICAgICAgICB0aXRsZSA9ICJEZXNlbXBlw7FvIGRlIGxhIEluZHVzdHJpYSBBdXRvbW90cml6OiBQcm9kdWNjacOzbiBkZSBjYXJ0w7NuIGdsb2JhbCBkZSAyMDE2IGEgMjAyMSIsDQogICAgICAgIFl0aXRsZSA9ICJVbmlkYWRlcyBlbiBtaWxlcyIsDQogICAgICAgIFh0aXRsZSA9ICJBw7FvcyIsIA0KICAgICAgICBzbGlkZXIgPSBUUlVFKQ0KYGBgDQoNCg0KIEVuIGVzdGEgZ3LDoWZpY2Egc2UgdmUgZWwgZGVzZW1wZcOxbyBkZSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeiBkZSAyMDE2IGEgMjAyMS4gRW4gZ2VuZXJhbCwgc2UgbXVlc3RyYSBxdWUgZWwgdG90YWwgZGUgcHJvZHVjY2nDs24gZGUgY2FydMOzbiBhIG5pdmVsIGdsb2JhbCBmdWUgbWF5b3IgZW4gMjAyMSBjb250cmEgb3Ryb3MgYcOxb3MuIA0KDQoNCiMjIyBQcmVkaWNjacOzbiBkZWwgRGVzZW1wZcOxbyBkZSBsYSBJbmR1c3RyaWEgQXV0b21vdHJpeiANCg0KIyMjIEltcG9ydGFyIGJhc2UgZGUgZGF0b3MgIA0KYGBge3J9DQpiZDUgPC1yZWFkLmNzdigiQzpcXFVzZXJzXFxkYW55Y1xcRG93bmxvYWRzXFxleHRlcm5hX2JkMiBjc3YyLmNzdiIpDQpzdW1tYXJ5KGJkNSkNCg0Kc3VtKGlzLm5hKGJkNSkpDQoNCmJkNSRUb3RhbF9Qcm9kdWNjaW9uPC0gYmQxJFgyMDE2K2JkMSRYMjAxNytiZDEkWDIwMTgrYmQxJFgyMDE5K2JkMSRYMjAyMCtiZDEkWDIwMjENCg0Kc3VtbWFyeShiZDUpDQpzdHIoYmQ1KQ0KDQpzdW0oaXMubmEoYmQ1KSkNCmBgYA0KDQoNCiMjIyMgTW9kZWxvcyBkZSByZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGUNCg0KIyMjIyBNb2RlbG9zIGRlIHJlZ3Jlc2nDs24gbGluZWFsIG3Dumx0aXBsZTogUHJvZHVjY2nDs24gZGUgY2FydMOzbiBlbiAyMDIyIGEgbml2ZWwgZ2xvYmFsIA0KYGBge3J9DQpyZWdyZXNpb24gPC0gbG0oVG90YWxfUHJvZHVjY2lvbiB+IEdlb2dyYXBoeSArIFVuaXQgKyBBw7FvICsgUHJvZHVjY2lvbiwgZGF0YT1iZDUpDQpzdW1tYXJ5KHJlZ3Jlc2lvbikNCg0KcmVncmVzaW9uIDwtIGxtKFRvdGFsX1Byb2R1Y2Npb24gfiBBw7FvICsgUHJvZHVjY2lvbiwgZGF0YT1iZDUpDQpzdW1tYXJ5KHJlZ3Jlc2lvbikNCg0KYmQ1IDwtIGRhdGEuZnJhbWUoQcOxbz0yMDIyLCBQcm9kdWNjaW9uPSAxNzAwMDAwMDApDQpwcmVkaWN0KHJlZ3Jlc2lvbixiZDUpDQpgYGANCg0KDQpEZSBhY3VlcmRvIGEgbG9zIGRhdG9zIGVzdGltYWRvcywgc2UgdmUgcXVlIGxhcyB2YXJpYWJsZXMgZGUgYcOxbyB5IHByb2R1Y2Npw7NuIHNvbiBpZ3VhbG1lbnRlIHNpZ25pZmljYXRpdmFzIHBhcmEgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUuIEVuIGVsIGNhc28gZGUgYcOxbywgZXN0ZSB0aWVuZSB1biBpbXBhY3RvIG5lZ2F0aXZvIHNvYnJlIGxhIG90cmEgeSBsYSBwcm9kdWNjacOzbiB0aWVuZSB1bmEgZXN0aW1hY2nDs24gcG9zaXRpdmEuIA0KRWwgbW9kZWxvIGFudGVyaW9yIG5vcyBtdWVzdHJhIGN1w6FudG8gc2UgZXN0aW1hIHF1ZSBzZSBwcm9kdWNpcsOhIGEgbml2ZWwgZ2xvYmFsIGVuIGxhIGluZHVzdHJpYSBkZWwgY2FydMOzbiBwYXJhIDIwMjIuIERlIGFjdWVyZG8gYSB1bmEgcHJvZHVjY2nDs24gdG90YWwgYXByb3hpbWFkYSBkZSAxNzAgbWlsbG9uZXMgZGUgY2FydMOzbiBlbiAyMDIxLCBzZSBlc3BlcmEgcXVlIGVuIDIwMjIgc2UgcHJvZHV6Y2FuIDkxNCwxOTYsOTI2LiBFbiBlc3RlIGNhc28sIGVsIHByw7Nub3N0aWNvIGZ1ZSByZWFsaXphZG8gYWwgY3JlYXIgdW4gbnVldm8gJ2RhdGEgZnJhbWUnIHkgYWwgaW1wbGVtZW50YXIgbGEgZnVuY2nDs24gZGUgJ2xtJywgdXNhZGEgcGFyYSBjcmVhciBhbsOhbGlzaXMgcmVncmVzaXZvcyB5IHByZWRpY3Rpdm9zLiANCg0KDQojIyMjIE1vZGVsb3MgZGUgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlOiBQcm9kdWNjacOzbiBkZSBjYXJ0w7NuIGVuIDIwMjIgcGFyYSBFc3RhZG9zIFVuaWRvcyB5IE3DqXhpY28NCg0KIyMjIEltcG9ydGFyIGJhc2UgZGUgZGF0b3MgKDMpDQpgYGB7cn0NCmJkNiA8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXGV4dGVybmFfYmQzIGNzdjMgKDEpLmNzdiIpDQpzdW1tYXJ5KGJkNikNCg0Kc3VtKGlzLm5hKGJkNikpDQoNCnN1bW1hcnkoYmQ2KQ0Kc3RyKGJkNikNCmBgYA0KDQoNCiMjIyBNb2RlbG8gZGUgcmVncmVzacOzbiBtw7psdGlwbGU6IFByb2R1Y2Npw7NuIGRlIGNhcnTDs24gZW4gMjAyMjogTcOpeGljbw0KYGBge3J9DQpyZWdyZXNpb24zIDwtIGxtKE1FWCB+IFVTQSArIEHDsW8sIGRhdGE9YmQ2KQ0Kc3VtbWFyeShyZWdyZXNpb24zKQ0KDQpyZWdyZXNpb24zIDwtIGxtKE1FWCB+IEHDsW8sIGRhdGE9YmQ2KQ0Kc3VtbWFyeShyZWdyZXNpb24zKQ0KDQpiZDYgPC0gZGF0YS5mcmFtZShBw7FvPTIwMjIsIFByb2R1Y2Npb249IDc0MDAwMCkNCnByZWRpY3QocmVncmVzaW9uMyxiZDYpDQoNCmdncGxvdChiZDYsIGFlcyh4PUHDsW8sIHk9UHJvZHVjY2lvbikpKw0KICBnZW9tX3BvaW50KCkgKw0KICBnZW9tX2xpbmUoYWVzKHk9UHJvZHVjY2lvbiksIGNvbG9yPSJyZWQiLCBsaW5ldHlwZT0iZGFzaGVkIikgKw0KICBnZW9tX2xpbmUoYWVzKHk9UHJvZHVjY2lvbiksIGNvbG9yPSJyZWQiLCBsaW5ldHlwZT0iZGFzaGVkIikgKw0KICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIGZvcm11bGE9eX54LCBzZT1UUlVFLCBsZXZlbD0wLjk1LCBjb2w9J2JsdWUnLCBmaWxsPSdwaW5rMicpICsNCiAgdGhlbWVfbGlnaHQoKQ0KYGBgDQoNCg0KIExhIHByZWRpY2Npw7NuIGFudGVyaW9yIG5vcyBhcnJvamEgcXVlIGhheSB1biBpbXBhY3RvIHBvc2l0aXZvIHkgc2lnbmlmaWNhdGl2byBlbnRyZSBsYSB2YXJpYWJsZSBBw7FvIHkgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUuIEVzdG8gc2lnbmlmaWNhIHF1ZSBoYXkgdW5hIHByZWRpY2Npw7NuIHBvc2l0aXZhIGRlIGNyZWNpbWllbnRvIGFjb3JkZSBhbCBhw7FvLg0KIERlIGFjdWVyZG8gYSBsYSBwcm9kdWNjacOzbiB0b3RhbCBnZW5lcmFkYSBwb3IgTcOpeGljbyBkZSAyMDE2IGEgMjAyMSAoNzQwIE0pLCBlbCBtb2RlbG8gcHJvbsOzc3RpY28gZXN0aW1hIHF1ZSBlbiAyMDIyIHByb2R1Y2lyw6EgMTQ5LDE3MC4zLiBFbiBsYSBncsOhZmljYSBwcmV2aWEgc2UgbXVlc3RyYSBlbCBwdW50byBkZSBwcmVkaWNjacOzbi4gU2kgYW5hbGl6YW1vcyBsYSBwcm9kdWNjacOzbiBkZSAyMDIxIGNvbnRyYSBlbCBwcm9uw7NzdGljbyBkZSAyMDIyLCBzZSBlc3RpbWEgcXVlIGxhIHByb2R1Y2Npw7NuIG1leGljYW5hIGRpc21pbnVpcsOhLiBQb2RlbW9zIHN1cG9uZXIgcXVlIGVzdG8gc2UgZGViZSBhIGxhIGRlZmljaWVuY2lhIGVuIGxhIGNhZGVuYSBkZSBzdW1pbmlzdHJvIGdsb2JhbCwgYXPDrSBjb21vIGZhY3RvcmVzIGVjb27Ds21pY29zIGdsb2JhbGVzLiANCg0KDQojIyMjIE1vZGVsb3MgZGUgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlOiBQcm9kdWNjacOzbiBkZSBjYXJ0w7NuIGVuIDIwMjIgcGFyYSBFc3RhZG9zIFVuaWRvcyB5IE3DqXhpY28NCg0KIyMjIEltcG9ydGFyIGJhc2UgZGUgZGF0b3MgKDMpDQpgYGB7cn0NCmJkNiA8LXJlYWQuY3N2KCJDOlxcVXNlcnNcXGRhbnljXFxEb3dubG9hZHNcXGV4dGVybmFfYmQzIGNzdjMgKDEpLmNzdiIpDQpzdW1tYXJ5KGJkNikNCg0Kc3VtKGlzLm5hKGJkNikpDQoNCnN1bW1hcnkoYmQ2KQ0Kc3RyKGJkNikNCmBgYA0KDQoNCiMjIyMgTW9kZWxvcyBkZSByZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGU6IFByb2R1Y2Npw7NuIGRlIGNhcnTDs24gZW4gMjAyMjogRXN0YWRvcyBVbmlkb3MNCmBgYHtyfQ0KcmVncmVzaW9uMiA8LSBsbShVU0EgfiBNRVggKyBBw7FvLCBkYXRhPWJkNikNCnN1bW1hcnkocmVncmVzaW9uMikNCg0KcmVncmVzaW9uMiA8LSBsbShVU0EgfiBBw7FvLCBkYXRhPWJkNikNCnN1bW1hcnkocmVncmVzaW9uMikNCg0KYmQ2IDwtIGRhdGEuZnJhbWUoQcOxbz0yMDIyLCBQcm9kdWNjaW9uPSAzMjAwMDApDQpwcmVkaWN0KHJlZ3Jlc2lvbjIsYmQ2KQ0KYGBgDQoNCg0KUGFyYSBsYSBwcmVkaWNjacOzbiBkZSBFc3RhZG9zIFVuaWRvcywgdmVtb3MgcXVlIGhhYnLDoSB1biBpbmNyZW1lbnRvIGVuIGxhIHByb2R1Y2Npw7NuIGRlIGNhcnTDs24gY29udHJhIDIwMjEuIFNpbiBlbWJhcmdvLCBhbCBhbmFsaXphciBsYSBwcm9kdWNjacOzbiB0b3RhbCBkZSBNw6l4aWNvIGNvbnRyYSBsYSBwcm9kdWNjacOzbiB0b3RhbCBkZSBFc3RhZG9zIFVuaWRvcywgdmVtb3MgcXVlIGxhIG1leGljYW5hIGVzIG11Y2hvIG1heW9yLiBQb2RlbW9zIHN1cG9uZXIgcXVlIGVzdG8gc2UgZGViZSBkZWJpZG8gYSBsYSBtYW5vIGRlIG9icmEgZWNvbsOzbWljYSBkZWwgbWVyY2FkbyBtZXhpY2Fuby4gDQoNCkRlIGFjdWVyZG8gYSBsYSBwcmVkaWNjacOzbiBhbnRlcmlvciwgc2UgdmUgdW4gaW5jcmVtZW50byBwb3NpdGl2byBwYXJhIGxhIHZhcmlhYmxlIE3DqXhpY28gY29uIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlLCBhIGRpZmVyZW5jaWEgZGVsIGHDsW8gcXVlIG11ZXN0cmEgdW4gaW1wYWN0byBtZW5vciB5IG5lZ2F0aXZvLCBwZXJvIGlndWFsbWVudGUgc2lnbmlmaWNhdGl2by4gDQoNCg0KDQojIyBQcm9ub3N0aWNvIGRlbCBkZXNlbXBlw7FvIGRlIGxhIGluZHVzdHJpYSBhdXRvbW90cml6IHkgbGEgZW1wcmVzYSBGT1JNDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJmb3JlY2FzdCIpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KYGBgDQoNCg0KIyMjIFByb25vc3RpY2FyIGVsIGRlc2VtcGXDsW8gZGUgbGEgaW5kdXN0cmlhIGF1dG9tb3RyaXogKEVVQSB5IE1FWCkgcGFyYSBsb3MgMyBwZXJpb2RvcyBkZSB0aWVtcG8uDQpgYGB7cn0NCiNmaWxlLmNob29zZSgpDQpleHRlcm5vPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXERvd25sb2Fkc1xcZXh0ZXJuYV9iZDMgY3N2My5jc3YiKQ0KYGBgDQoNCiMjIyBDcmVhciBzZXJpZSBkZSB0aWVtcG8NCmBgYHtyfQ0KcHJvZHVjY2lvbl9tZXhpY288LSBjKGV4dGVybm8kTUVYKQ0KcHJvZHVjY2lvbl91c2E8LSBjKGV4dGVybm8kVVNBKQ0KYGBgDQoNCmBgYHtyfQ0KcHJvZHVjY2lvbm08LXRzKGRhdGE9cHJvZHVjY2lvbl9tZXhpY28sIHN0YXJ0PWMoMjAxNiwxKSwgZnJlcXVlbmN5PTEpDQpwcm9kdWNjaW9udTwtdHMoZGF0YT1wcm9kdWNjaW9uX3VzYSwgc3RhcnQ9YygyMDE2LDEpLCBmcmVxdWVuY3k9MSkNCnByb2R1Y2Npb25tDQpwcm9kdWNjaW9udQ0KYGBgDQoNCg0KYGBge3J9DQptb2RlbG9tPC0gYXV0by5hcmltYShwcm9kdWNjaW9ubSwgRD0xKQ0KbW9kZWxvdTwtIGF1dG8uYXJpbWEocHJvZHVjY2lvbnUsIEQ9MSkNCm1vZGVsb20NCm1vZGVsb3UNCmBgYA0KDQpgYGB7cn0NCnByb25vc3RpY29tIDwtIGZvcmVjYXN0KG1vZGVsb20sIGxldmVsPWMoOTUpLCBoPTQpDQpwcm9ub3N0aWNvbQ0KcGxvdChwcm9ub3N0aWNvbSkNCmBgYA0KDQpgYGB7cn0NCnByb25vc3RpY291IDwtIGZvcmVjYXN0KG1vZGVsb3UsIGxldmVsPWMoOTUpLCBoPTQpDQpwcm9ub3N0aWNvdQ0KcGxvdChwcm9ub3N0aWNvdSkNCmBgYA0KDQojIyMgUHJvbm9zdGljYXIgZWwgZGVzZW1wZcOxbyBkZSBwcm9kdWNjaW9uIGRlIEZvcm0gcGFyYSBsb3MgcHJveGltb3MgMyBwZXJpb2RvcyBkZSB0aWVtcG8uDQoNCmBgYHtyfQ0KI2ZpbGUuY2hvb3NlKCkNCmZvcm1wcm9kdWNjaW9uPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcZGFueWNcXE9uZURyaXZlIC0gSW5zdGl0dXRvIFRlY25vbG9naWNvIHkgZGUgRXN0dWRpb3MgU3VwZXJpb3JlcyBkZSBNb250ZXJyZXlcXERlc2t0b3BcXEZvcm1fcHJvZHVjY2lvbmJhc2VsaW1waWEuY3N2IikNCmBgYA0KIyMjIENyZWFyIHNlcmllIGRlIHRpZW1wbw0KYGBge3J9DQpwcm9kdWNjaW9uZm9ybTwtIGMoZm9ybXByb2R1Y2Npb24kbGFtaW5hc19wcm9jZXNhZGFzKQ0KDQpgYGANCg0KYGBge3J9DQpwcm9kdWNjaW9uZjwtdHMoZGF0YT1wcm9kdWNjaW9uZm9ybSwgc3RhcnQ9YygyMDIyLDcpLCBlbmQ9YygyMDI1LCAxMiksIGZyZXF1ZW5jeT0xMikNCg0KcHJvZHVjY2lvbmYNCmBgYA0KDQoNCmBgYHtyfQ0KbW9kZWxvZjwtIGF1dG8uYXJpbWEocHJvZHVjY2lvbmYsIEQ9MSkNCg0KbW9kZWxvZg0KDQpgYGANCg0KYGBge3J9DQpwcm9ub3N0aWNvZiA8LSBmb3JlY2FzdChtb2RlbG9mLCBsZXZlbD1jKDk1KSwgaD0zKQ0KcHJvbm9zdGljb2YNCnBsb3QocHJvbm9zdGljb2YpDQpgYGANCg0KIyMjIERlc2NyaWJlIGxvcyByZXN1bHRhZG9zIA0KUmVhbGl6YW1vcyB1bmEgc2VyaWUgZGUgdGllbXBvIHRhbnRvIHBhcmEgbGEgYmFzZSBkZSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeiBjb21vIHBhcmEgbGEgYmFzZSBkZSBwcm9kdWNjacOzbiBkZSBGT1JNLCBlc3RlIGVzIGVuZm9jYWRvIGEgbGFzIGxhbWluYXMgcHJvY2VzYWRhcyBjYWRhIG1lcyB5IGVuIGxhIGluZHVzdHJpYSBlcyBwb3IgYcOxby4gUGFyYSBwb2RlciByZWFsaXphciBlc3RlIEFuYWxpc2lzIGRlIFJlc3VsdGFkbyByZWFsaXphbW9zIHVuYSBncmFmaWNhIHkgdW4gbW9kZWxvIGRlIFByZWRpY2Npw7NuIHBvciBtZWRpbyBkZSBsYSBmdW5jacOzbiBhdXRvLmFyaW1hLiBHcmFjaWFzIGEgZXN0YSBmdW5jacOzbiwgbGUgZXNwZWNpZmljYW1vcyBkZXNkZSBxdWUgRmVjaGEgZW1wZXphcsOhIGEgb2J0ZW5lciBkYXRvcyBkZSBsYSBiYXNlIGRlIERhdG9zIHkgdGFtYmnDqW4gY29sb2NhbW9zIGxhIGZyZWN1ZW5jaWEsIHF1ZSBzZSByZWZpZXJlIGEgY8OzbW8gc2UgY29tcG9ydGEsIGVuIGN1ZXN0acOzbiBhIHNpIHNlIHZhIGEgY2FsY3VsYXIgcG9yIG1lcyBvIHBvciBhw7FvLiBBc8OtIG1pc21vLCBvYnR1dmltb3MgcGFyYSBsYSBpbmR1c3RyaWEgdGFudG8gZW4gTcOpeGljbyBjb21vIGVuIEVVLCBxdWUgc29uIGxvcyBwYcOtc2VzIGVuIGxvcyBxdWUgc2UgZW5mb2NhIG3DoXMgRk9STSB5IG9idGVuZ2FuIG1lam9yIG9wb3J0dW5pZGFkIGRlIGNyZWNpbWllbnRvLiBBbCByZWFsaXphciBlc3RlIG1vZGVsbyBjYWxjdWxhbW9zIHBhcmEgbG9zIHByw7N4aW1vcyAzIHBlcmlvZG9zLCBlbiBlc3RlIGNhc28gcGFyYSBlbCAyMDI1IHkgb2J0dXZpbW9zIGxvcyBzaWd1aWVudGVzIHJlc3VsdGFkb3M6DQotICpJbmR1c3RyaWEgQXV0b21vdHJpeiBlbiBNw6l4aWNvKjogDQoNCiAgMS4gUGFydGllbmRvIGRlIHVuIG1hcmdlbiBkZWwgOTUlLCBxdWVyaWVuZG8gZGVjaXIsIHF1ZSBlc3RlIG1vZGVsbyBlcyBtw6FzIHByZWNpc28gcG9yIGxvIHF1ZSBhbCB2ZXIgbGEgZ3JhZmljYSBvYnRlbmVtb3MgICAgICBxdWUgdGVuZHLDoSB1biBpbmNyZW1lbnRvIGNvbnN0YW50ZSBlbiBsb3MgcHLDs3hpbW9zIDMgYcOxb3MsIHBhcnRpZW5kbyBkZWwgMjAyMi4gDQogIDIuIEVzdGUgY3JlY2ltaWVudG8gZGUgbGEgaW5kdXN0cmlhIGF1dG9tb3RyaXogZW4gTcOpeGljbyBzZSBlc3RpbWEgdW4gY3JlY2ltaWVudG8gZGVsIDE2JSBwYXJhIDIwMjUsIGxvIHF1ZSBiZW5lZmljaWEgYSAgICAgIEZPUk0gcGFyYSBjb250aW51YXIgcHJvZHVjaWVuZG8gZW4gZWwgbWVyY2FkbyBNZXhpY2Fuby4gDQoNCi0gKkluZHVzdHJpYSBBdXRvbW90cml6IGVuIEVzdGFkb3MgVW5pZG9zKjogDQoNCiAgMS4gUGFyYSAyMDIyIGVsIHByb25vc3RpY28gZXMgZGUgNTkgbWlsLCBxdWUgZXN0ZSBzZSBwdWVkZSBtYW50ZW5lciBjb25zdGFudGUgZW4gbG9zIHByw7N4aW1vcyAzIGHDsW9zIGhhc3RhIDIwMjUNCiAgMi4gU2Ugb2J0aWVuZSB1biBlc2NlbmFyaW8gb3B0aW1pc3RhIGNvbiBsYSBwcmVjaXNpw7NuIGRlbCA5NSUsIGxvIHF1ZSBxdWllcmUgZGVjaXIgcXVlIHBhcmEgZmluYWxlcyBkZWwgMjAyNSwgcHVlZGUgZXN0YXIgaWd1YWwgZW4gNTkgbWlsIG8gYXVtZW50YXIgaGFzdGEgbG9zIDY5IG1pbC4gRXN0byBpbmRpY2Fyw61hIHF1ZSB2YSBlbiBhdW1lbnRvIGHDsW8gY29uIGHDsW8geSB0ZXJtaW5hcsOtYSBlbCAyMDI1IGNvbiB1biBhdW1lbnRvIGRlbCBjYXNpIDIwJS4gTG8gcXVlIGluZGljYXLDrWEgYWxnbyBidWVubyBwYXJhIEZPUk0sIGRhbmRvbGUgb3BvcnR1bmlkYWQgYSBhdW1lbnRhciBzdSBjYXJ0ZXJhIGRlIGNsaWVudGVzIGRlbnRybyBkZWwgbWVyY2FkbyBFc3RhZG91bmlkZW5zZSB5IHRlbmllbmRvIHVuIGJ1ZW4gaW1wYWN0byBkZSBsYSBpbmR1c3RyaWEgcGFyYSBsb3MgcHLDs3hpbW9zIHBlcmlvZG9zLiANCiAgDQotICpFbXByZXNhIEZPUk0qOg0KDQogIDEuIFNlIGhpem8gZWwgcHJvbm9zdGljbyBwb3IgbWVzIHkgZGFuZG8gdW4gcGVyaW9kbyBoYXN0YSBlbCAyMDI2LCBwYXJ0aWVuZG8gZGVsIDIwMjIgY29uIDMgZW4gY3VhbnRvIGEgcHJvZHVjY2nDs24gZGUgbGFtaW5hcyBwcm9jZXNhZGFzLCBzZSBlc3RpbWEgcXVlIGVzdGUgdGVuZ2EgdW4gYXVtZW50byBjb25zdGFudGUsIGFkZW1hcyBkZSBxdWUgZW50cmUgZWwgMjAyNCB5IDIwMjUgdGVuZ2EgdW4gcHVudG8gZGUgcGlxdWUgbcOhcyBhbHRvLCBxdWUgcG9zdGVyaW9ybWVudGUgdm9sdmVyw6EgYSBlc3RhYmlsaXphcnNlIHBlcm8gcXVlIHNlIG1hbnRlbmRyw6EgY29uc3RhbnRlIGVudHJlIGxvcyAxMCBhIDIwIGVuIHByb2R1Y2Npw7NuLg0KICAyLiBTZSBwcm9ub3N0aWNhIHF1ZSBwYXJhIGVsIDIwMjYgc2UgdGVuZ2EgdW4gMzMgZW4gcHJvZHVjY2nDs24gZGVsIMOhcmVhIGRlIGxhbWluYXMgcHJvY2VzYWRhcywgdGVuaWVuZG8gdW5hIHByZWNpc2nDs24gZGVsIDk1JSBlbiB1biBlc2NlbmFyaW8gb3B0aW1pc3RhLiBBc8OtIG1pc21vIGVzdGUgc2UgcHVlZGUgbWFudGVuZXIgY29uc3RhbnRlIGVuIDEwIG8gYXVtZW50YXIgY29tbyBzZSBjb21lbnTDsyBhbnRlcmlvcm1lbnRlIHkgZXN0ZSBjcmVjaW1pZW50byBhIHTDqXJtaW5vcyBkZWwgMjAyNiB0b21hbmRvIGVsIGVzY2VuYXJpbyBvcHRpbWlzdGEsIHNlcsOtYSBkZSBwb2NvIG1hcyBkZWwgOTAlIGxvIHF1ZSBzZXLDrWEgdW4gZ3JhbiBhdW1lbnRvIHBhcmEgRk9STS4gVGFtYmnDqW4gc2kgZnVlcmEgc2luIGVsIDk1JSBwYXJhIGluaWNpb3MgZGVsIDIwMjYgc2Vyw61hbiAxNiBlbiBwcm9kdWNjacOzbiBjb24gZWwgNjAlIGRlIGF1bWVudG8sIGxvIHF1ZSBzZWd1aXLDrWEgc2llbmRvIGFsZ28gaW1wb3J0YW50ZSBwYXJhIEZPUk0uDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+KioqTGlzdGFyIHkgZGVzY3JpYmlyIGxvcyBwcmluY2lwYWxlcyA1LTYgcmVzdWx0YWRvcyAvIGhhbGxhemdvcyBkZSBsYSBhY3RpdmlkYWQuKioqDQoxLlJlY3Vyc29zIGh1bWFub3M6IA0KVW5vIGRlIGxvcyBoYWxsYXpnb3MgZW4gZXN0YSBiYXNlIGRlIGRhdG9zIGVzIHF1ZSBsYXMgcHJpbmNpcGFsZXMgY2F1c2FzIGRlIGJhamFzIGRlIGVtcGxlYWRvcyBzZSBkZWJlIGEgdHJlcyByYXpvbmVzLiBCYWphcyBwb3IgZmFsdGFzLCByZW51bmNpYSB2b2x1bnRhcmlhIG8gdMOpcm1pbm8gZGUgY29udHJhdG8geSBub3MgZGFtb3MgY3VlbnRhIHF1ZSBlbCBwdWVzdG8gY29uIG3DoXMgcm90YWNpw7NuIGVuIGxhIGVtcHJlc2EgZXMgZWwgZGUgYXl1ZGFudGUgZ2VuZXJhbC4gUG9yIGxvIHRhbnRvIHBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGV4aXN0ZSB1bmEgbWFsYSBnZXN0acOzbiBhZG1pbmlzdHJhdGl2YSBvIHF1ZSBsb3MgZW1wbGVhZG9zIG5vIGVzdMOhbiAxMDAlIGZlbGljZXMgcG9yIGxvIHRhbnRvIG5vIHNlIGVzdMOhbiBlc2ZvcnphbmRvIGxvIHN1ZmljaWVudGUuIA0KDQpMYSBwcmluY2lwYWwgY2F1c2EgZGUgYmFqYXMgZW4gbGEgZW1wcmVzYSBlcyBkZWJpZG8gYSBmYWx0YXMsIEVuIG51bWVybyBkZSBiYWphcyBwb3Igc2V4byBtYXNjdWxpbm8geSBmZW1lbmlubyBsYXMgbXVqZXJlcyBzb24gbGFzIHF1ZSBtw6FzIGZhbHRhbiBnZW5lcmFuZG8gNTMgYmFqYXMgZW4gdG90YWwscGVybyBsbyBpbXBvcnRhbnRlIGVzIHF1ZSBwYXJhIGxvcyBob21icmVzIHRhbWJpw6luIGVzIHN1IG1heW9yIGVzIGxhIHJhesOzbiBkZSBiYWphLCBsbyBjdWFsIGVzIHBvciBmYWx0YXMgeWEgcXVlIHNlIGhhbiBwcmVzZW50YWRvIDI1IGJhamFzLiBUb21hbmRvIGVuIGN1ZW50YSBsYSBsZWphbsOtYSBkZSBsYSBwbGFudGEgZXN0byBwdWVkZSBzZXIgdW4gZmFjdG9yIHF1ZSBlc3TDqSBnZW5lcmFuZG8gYmFqYXMuIEVzdG9zIGRhdG9zIG5vcyBwZXJtaXRlbiB2ZXIgdW5hIGdyw6FmaWNhIGRlIGRpc3BlcnNpw7NuIHF1ZSBub3MgYXJyb2phIHF1ZSBsb3MgZXgtZW1wbGVhZG9zIHRpZW5lbiB1biB0aWVtcG8gZGUgZHVyYWNpw7NuIG3DoXMgY29ydG8gYSB1biBhw7FvLiANCg0KDQoyLk1lcm1hOiANCg0KLVVuIGhhbGxhemdvIGltcG9ydGFudGUgZW4gbWVybWEgZXMgcXVlIHNlIGVzdMOhIGdlbmVyYW5kbyBhbHJlZGVkb3IgZGUgMyB0b25lbGFkYXMgYSA0IHRvbmVsYWRhcyBkZSBtZXJtYSBjYWRhIDQgbWVzZXMsIFBvciBsbyB0YW50byBub3NvdHJvcyBjb25zaWRlcmFtb3MgcXVlIGVzIG11Y2hhIG1lcm1hIGxhIHF1ZSBzZSBlc3TDoSBnZW5lcmFuZG8uIA0KDQotT3RybyBwdW50byBpbXBvcnRhbnRlIGVzIHF1ZSBzZSBlc3TDoSBnZW5lcmFuZG8gdW5hIG1lcm1hIG11eSBpcnJlZ3VsYXIgcG9yIGVqZW1wbG8gZGUgZW5lcm8gYSBhYnJpbCBmdWUgdW5hIG1lcm1hIGRlIDMgdG9uZWxhZGFzIHByb21lZGlvLCBkZSBhYnJpbCBhIGp1bGlvIGFscmVkZWRvciBkZSA1IHRvbmVsYWRhcyB5IGxsZWfDsyBoYXN0YSBnZW5lcmFyIDYgdG9uZWxhZGFzIHkgZGUganVsaW8gYSBvY3R1YnJlIGfDqW5lcm8gMyB0b25lbGFkYXMgcHJvbWVkaW8gcGVybyBlbiB1biBtZXMgc2UgbG9ncsOzIHRlbmVyIG1lbm9zIGRlIDEgdG9uZWxhZGEgZGUgbWVybWEuIA0KDQotUG9yIGxvIHRhbnRvIGVzIGltcG9ydGFudGUgcXVlIGxhIGVtcHJlc2EgZ2VuZXJlIG1lbm9yZXMgY2FudGlkYWRlcyBkZSBtZXJtYSB5IHF1ZSBlc3RhIG1lcm1hIHNlYSBsbyBtYXlvciBjb25zdGFudGUgcG9zaWJsZSAsIHNhYmVtb3MgcXVlIHB1ZWRlIHZhcmlhciBkZXBlbmRpZW5kbyBkZSBsYSBjYW50aWRhZCBkZSBwZWRpZG9zIHBlcm8gcHVlcyBsb2dyYXIgcmVkdWNpciBsYSBjYW50aWRhZCBkZSBtZXJtYSBub3MgYXl1ZGFyw6EgYSByZWR1Y2lyIGNvc3Rvcy4gDQoNCjMuU2NyYXA6IA0KDQotQW5hbGl6YW5kbyBlc3RhcyB2YXJpYWJsZXMgc2UgY29uZmlybWEgcXVlIGVuIGVsIMOhcmVhIGRlIHByZS1wcm9kdWNjacOzbixFcyBkb25kZSBzZSBnZW5lcmEgbGEgbWF5b3LDrWEgZGVsIHNjcmFwIGVuIHN1IG1heW9yw61hIHNlIGdlbmVyYSBjYXNpIGVsIDg1JSBkZSBzY3JhcCwgcXVlIGdlbmVyYW4gZGVudHJvIGRlIGxhIGVtcHJlc2EsIHBvciBsbyB0YW50byBlcyBhbGdvIGFsYXJtYW50ZSBwb3IgbG8gdGFudG8gc2UgdGllbmVuIHF1ZSB0b21hciBkZWNpc2lvbmVzIGltcG9ydGFudGVzIHBhcmEgcG9kZXIgcmVhbGl6YXIgY2FtYmlvcyBlbiBlc3RhIMOhcmVhIHBhcmEgcmVkdWNpciBsYSBjYW50aWRhZCBkZSBzY3JhcC4NCg0KLVVuIHB1bnRvIGltcG9ydGFudGUgZXMgcXVlIGNvbiBsYSBheXVkYSBkZSB1biBncsOhZmljYSBsaW5lYWwsIG5vcyBkaW1vcyBjdWVudGEgZGUgY3XDoWwgZnVlIGVsIGTDrWEgZW4gZWwgbWVzIGRlIGFnb3N0byBxdWUgZ2VuZXLDsyBtw6FzIHNjcmFwLHBvciBsbyBxdWUgc2UgcHVlZGUgZGVjaXIgcXVlIGVuIGVsIGTDrWEgcXVlIHNlIGNvbWV0aWVyb24gbcOhcyBlcnJvcmVzIGZ1ZSBlbCBkw61hIDI0IGRlIGFnb3N0bywgcG9yIGxvIHRhbnRvIGRlYmVtb3MgZGUgb2JzZXJ2YXIgcXVlIGVzIGxvIHF1ZSBwYXPDsyBlc3RlIGTDrWEgZW4gbGEgcGxhbnRhLCBvIHNpIHRhbWJpw6luIGVzdGUgZmFjdG9yIHNlIGVzdMOhIHJlcGl0aWVuZG8gbWVzIGNvbiBtZXMuDQoNCg0KNC5EZWxpdmVyeSBQbGFuOg0KDQotTm9zIGRhbW9zIGN1ZW50YSBxdWUgZW4gZXN0YSDDoXJlYSBkZSBsYSBlbXByZXNhIHF1ZSBlcyBkZWxpdmVyeSBwbGFuLCBub3MgbXVlc3RyYSBxdWUgZWwgY2xpZW50ZSBwb3RlbmNpYWwgZXMgSGVsbGEsIHlhIHF1ZSBjdWVudGEgY29uIG1heW9yZXMgcGVkaWRvcyAsIGVsIHNlZ3VuZG8gbHVnYXIgcGFyYSBGT1JNIGVzIFRSTVguIA0KDQotSGVsbGEgZXMgbGEgZW1wcmVzYSBxdWUgbcOhcyBwZWRpZG9zIHRpZW5lIHBhcmEgRk9STSBzaWVuZG8gYWxyZWRlZG9yIGRlIDIyNSwwMDAgeSBUUk1YIGxvIHNpZ3VlIGNvbiA4MCwwMDAgcGVkaWRvcy4gVGFtYmnDqW4gc2UgYW5hbGl6w7MgcXVlIHNlcHRpZW1icmUgZXMgdW5vIGRlIGxvcyBtZXNlcyBmdWVydGVzIHBhcmEgbGEgZW1wcmVzYSBlbiBlc3RhIMOhcmVhIHlhIHF1ZSBzZSBpbmNyZW1lbnRhcm9uIGxvcyBwZWRpZG9zIGVzdGFibGVjaWRvcy4gDQoNCg0KDQo1LkRlbGl2ZXJ5IFBlcmZvcm1hbmNlOg0KDQotU2UgZW5jb250cmFyb24gaGFsbGF6Z29zIGltcG9ydGFudGVzIGVuIGVzdGEgYmFzZSBkZSBkYXRvcyBjb21vIHNvbiwgcXVlIEZPUk0gY3VlbnRhIGNvbiBkb3MgY2xpZW50ZXMgY29uIG1heW9yIERlbGF5LiBFc3RvcyBjbGllbnRlcyBzb24gTUFITEUgeSBQUklOVEVMLiBQZXJvIGVuIGVzdGUgY2FzbyBsbyBxdWUgc2UgYW5hbGl6w7MgZXMgcXVlIGVsIGNsaWVudGUgY29uIG1heW9yIGRpbGFjacOzbiBlcyBNQUhMRSwgUG9yIGxvIHRhbnRvIG5vc290cm9zIHJlY29tZW5kYXJlbW9zIGEgRk9STSBtYW50ZW5lciB1bmEgbWVqb3IgbG9nw61zdGljYSB5IGVmaWNpZW5jaWEgY29uIGVsIG9iamV0aXZvIGRlIGdlbmVyYXIgcXVlIGxhIGVtcHJlc2EgdGVuZ2EgdW5hIG1lam9yIHJlZmVyZW5jaWEgeSBtdWNobyBtw6FzIGNvbmZpYW56YSBjb24gbGFzIGVudHJlZ2FzLiANCg0KDQo2LlByb2R1Y2Npw7NuIA0KDQotTGEgcHJpbWVyYSBvYnNlcnZhY2nDs24gZW5lIHByb2R1Y2Npw7NuIHF1ZSBub3MgbGxhbWEgbGEgYXRlbmNpw7NuIGVzIHNhYmVyIGN1w6FsIGVzIGVsIGNsaWVudGUgbcOhcyBpbXBvcnRhbnRlIHBhcmEgRk9STSwgcG9yIGxvIHF1ZSBlbiBlc3RlIGFuw6FsaXNpcyBub3MgZGVzYXJyb2xsbyBxdWUgU3RhYmlsdXMgMSwgZXMgZWwgY2xpZW50ZSBwb3RlbmNpYWwgZGUgbGEgZW1wcmVzYSBlbiBlbCDDoXJlYSBkZSBwcm9kdWNjacOzbi4gQW5hbGl6YW5kbyBsb3MgbWVzZXMgZGUganVsaW8gLCBhZ29zdG8geSBzZXB0aWVtYnJlIG5vcyBkaW1vcyBjdWVudGEgcXVlIGFnb3N0byBlcyBlbCBtZXMgY29uIG3DoXMgcHJvZHVjY2nDs24sIGFscmVkZWRvciBkZSAzNSwwMDAgcGllemFzIHByb2dyYW1hZGFzLiANCg0KLVNlIGFuYWxpesOzIHF1ZSBlbiBsYSBlc3RhY2nDs24gYzEgeSBjMiBlcyBsYSBlc3RhY2nDs24gY29uIG1heW9yIHByb2R1Y3RpdmlkYWQgZGViaWRvIGEgcXVlIGVzIGxhIHF1ZSBtZW5vcyB0aWVtcG8gaGFjZSBjb24gbcOhcyBwcm9jZXNhbWllbnRvIGRlIGzDoW1pbmFzLiBQb3IgbG8gdGFudG8gZXN0byBlcyB1bmEgdmVudGFqYSBxdWUgc2UgcG9kcsOtYSBhbmFsaXphciBlbiBlc3RhIGZhc2UgZGUgcHJvZHVjY2nDs24gcGFyYSBhcGxpY2FybGEgYSBsYXMgZGVtw6FzIMOhcmVhcy4gDQoNCi1VbiBwdW50byByZWxldmFudGUgZGUgZXN0YSBpbnZlc3RpZ2FjacOzbiBxdWUgbm9zIGRlbW9zdHLDsyB1biBncsOhZmljbyBkZSBkaXNwZXJzacOzbiBlcyBxdWUgc2kgc2UgbGUgZGVkaWNhIHRpZW1wbyBkZSBjYWxpZGFkIHF1ZSBzZSBsZSBvdG9yZ2EgYWwgY2xpZW50ZSwgbGEgZW1wcmVzYSByZWFsaXphIGxvcyBwcm9jZXNvcyBkZSB1bmEgbWFuZXJhIG11Y2hvIG3DoXMgZWZpY2llbnRlIHkgZGV0YWxsYWRhLCBnZW5lcmFuZG8gcHJvZHVjdG9zIGRlIGNhbGlkYWQgeSBtw6FzIHByb250by4gDQoNCg0KNy5CYXNlIGRlIGRhdG9zIGV4dGVybmEuDQoNCi1FbiBlc3RhIGJhc2UgZGUgZGF0b3MgZXh0ZXJuYSBzZSBhbmFsaXrDsyB1bmEgc2VyaWUgZGUgdGllbXBvIGVuZm9jYWRhIHByaW5jaXBhbG1lbnRlIGVuIEVVQSB5IE3DqXhpY28geWEgcXVlIHNvbiBsYXMgcHJpbmNpcGFsZXMgw6FyZWFzIGRlIGludGVyw6lzIHBhcmEgbGEgZW1wcmVzYSBkZSBGT1JNLiANCg0KLVVuIGhhbGxhemdvIGVzIHF1ZSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeiBlbiBNw6l4aWNvIHNlIG1hbnRlbmRyw6EgZW4gY29uc3RhbnRlIGNyZWNpbWllbnRvIGVuIHVuIGxhcHNvIGRlIDMgYcOxb3MgZW4gdW4gZnV0dXJvLiBDb24gdW4gcHJvbsOzc3RpY28gZGUgdW4gOTUlIGxvIGN1YWwgZXMgbXV5IMOzcHRpbW8gYSBxdWUgc3VjZWRhLiANCg0KLVNpIHNlIGFuYWxpemEgaGFzdGEgZWwgYcOxbyAyMDI1LCBleGlzdGUgdW4gMTYlIGRlIGNyZWNpbWllbnRvIGVuIGxhIGluZHVzdHJpYSwgcG9yIGxvIHF1ZSBhIEZPUk0sIGxlIGNvbnZpZW5lIGhveSBlbiBkw61hIGNvbnRpbnVhciBjb24gbGEgbWFubyBkZSBvYnJhIGVuIE3DqXhpY28geSBzZWd1aXIgdmVuZGllbmRvIGEgY29tcGHDscOtYXMgZXh0cmFuamVyYXMuIA0KDQotUG9yIGxhIHBhcnRlIGRlIEVVQSwgc2UgZXNwZXJhIHVuIGNyZWNpbWllbnRvIHBhcmEgZWwgMjAyNSBkZSB1biAyMCUgLCBwb3IgbG8gcXVlIG5vcyBkZXRlcm1pbsOzIHF1ZSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeiBlc3RhZG8gdW5pZG9zIHNlIG1hbnRpZW5lIGVuIGNvbnN0YW50ZSBjcmVjaW1pZW50byBhw7FvIHRyYXMgYcOxby4gDQoNCi1QYXJhIGxhIGVtcHJlc2EgZGUgRk9STSwgc2UgZXNwZXJhIHF1ZSBleGlzdGEgdW4gY3JlY2ltaWVudG8gZW4gbG9zIHByw7N4aW1vcyBhw7FvcyBlbiBsbyBxdWUgZXMgbGEgcHJvZHVjY2nDs24gZGUgbMOhbWluYXMgcHJvY2VzYWRhcywgc2UgZXNwZXJhIHF1ZSBlc3RlIHRlbmdhIHVuIGF1bWVudG8gY29uc3RhbnRlLCBwb3IgbG8gcXVlIHNlcsOtYSB1bmEgdmVudGFqYSBjb21wZXRpdGl2YSBwcmVwYXJhciBsb3MgcHJvY2Vzb3MgZGUgbMOhbWluYXMgZGVzZGUgZXN0ZSBhw7FvIHBhcmEgcXVlIGVuIGxvcyBwcsOzeGltb3MgYcOxb3MgcXVlIGVzdGUgcHJvY2VzbyBkZSBsYW1pbmFkbyBhdW1lbnRlIG5vIGV4aXN0YW4gdGFudG9zIGVycm9yZXMgYnVzY2FuZG8gcGVyZmVjY2lvbmFyIGVsIHByb2Nlc28uDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6ZGFya29yYW5nZSI+KioqUmVmbGV4aW9uIEZpbmFsKioqDQoNCg0KKsK/UXXDqSBlcyBCdXNpbmVzcyBBbmFseXRpY3M/Kg0KRXMgdW5hIGNvbWJpbmFjacOzbiBkZSBoYWJpbGlkYWRlcywgdGVjbm9sb2fDrWFzIHkgcHLDoWN0aWNhcyBwYXJhIGxhIGV4cGxvcmFjacOzbiBlIGludmVzdGlnYWNpw7NuIGRlbCBmdW5jaW9uYW1pZW50byB5IGxvcyBwcm9jZXNvcyBlbXByZXNhcmlhbGVzIHF1ZSBzZSBoYW4gdGVuaWRvIGFudGVyaW9ybWVudGUgcG9yIHVuIGVtcHJlc2EsIHBhcmEgZGUgZXNlIG1vZG8gb2J0ZW5lciBpbmZvcm1hY2nDs24sIHBvZGVyIGFuYWxpemFyIGRpY2hhIGluZm9ybWFjacOzbiBxdWUgc2UgZXh0cmFlIHkgYXPDrSBpbXB1bHNhciBsYSBwbGFuaWZpY2FjacOzbiBlc3RyYXTDqWdpY2EgZW1wcmVzYXJpYWwuIEJ1c2luZXNzIEFuYWx5dGljcyBwdWVkZSBkZXNjdWJyaXIgcGF0cm9uZXMgeSBwcmVkZWNpciB0ZW5kZW5jaWFzIGNvbnNpZGVyYW5kbyBkaWZlcmVudGVzIGZhY3RvcmVzLiANCg0KRXhpc3RlbiBkaWZlcmVudGVzIHJ1YnJvcyBkZWwgIkJ1c2luZXNzIEFuYWx5dGljcyI6DQoNCjEuIEFuw6FsaXNpcyBEZXNjcmlwdGl2bw0KDQoyLiBBbsOhbGlzaXMgZGUgRGlhZ27Ds3N0aWNvDQoNCjMuIEFuw6FsaXNpcyBQcmVkaWN0aXZvDQoNCjQuIEFuw6FsaXNpcyBQcmVzY3JpcHRpdm8NCg0KKjMgb2JqZXRpdm9zIGRlTCB1c28gZGUgbGEgaGVycmFtaWVudGEgZGUgKkJ1c2luZXNzIEFuYWx5dGljcz8qKg0KMS4gRGV0ZXJtaW5hciBxdcOpIGNvbmp1bnRvcyBkZSBkYXRvcyBzb24gc2lnbmlmaWNhbnRlcyB5IMO6dGlsZXMgcGFyYSBwb2RlciBhbmFsaXphciB5IGNvbm9jZXIgZWwgZGVzZW1wZcOxbyBkZSBsYSBlbXByZXNhIHkgY3XDoWxlcyBwdWVkZW4gYXVtZW50YXIgbG9zIGluZ3Jlc29zIHkgZGlzbWludWlyIGxvcyBjb3N0b3MuIA0KDQotICpFamVtcGxvOiogcHJvZHVjdGl2aWRhZCB5IGVmaWNlbmNpYS4NCg0KMi4gQW5hbGl6YXIgeSB0cmFuc2Zvcm1hciBsb3MgZGF0b3MgZW4gaW5mb3JtYWNpw7NuIMO6dGlsLCBpZGVudGlmaWNhciB5IGFudGljaXBhciB0ZW5kZW5jaWFzIHkgcmVzdWx0YWRvcy4gU2ltcGxpZmljYXIgaW5mb3JtYWNpw7NuIHBhcmEgaGFjZXJsYSBtw6FzIHNlbmNpbGxhIGRlIGVudGVuZGVyIHkgdmlzdWFsLiAgDQoNCjMuIFRvbWFyIGRlY2lzaW9uZXMgZW1wcmVzYXJpYWxlcyBtw6FzIGludGVsaWdlbnRlcyBiYXNhZGFzIGVuIGRhdG9zLg0KDQotICpFamVtcGxvOiogQW7DoWxpc2lzIGRlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgY2xpZW50ZXMsIGRpc21pbnVjacOzbiBkZSBjb3N0bywgZXZpdGFyIG1lcm1hcywgYXByb3ZlY2hhbWllbnRvIGRlIHRpZW1wb3MgeSBtYXRlcmlhbGVzLCBlZmljaWVuY2lhIHkgZWZpY2FjaWEuIA0KDQoqwr9DdcOhbCBlcyBsYSByZWxhY2nDs24gZW50cmUgQnVzaW5lc3MgQW5hbHl0aWNzIHkgQnVzaW5lc3MgSW50ZWxsaWdlbmNlPyoNCkJJIHNpcnZlIHBhcmEgZXZhbHVhciwgb3B0aW1pemFyIHkgY29vcmRpbmFyIGxhcyBvcGVyYWNpb25lcyBpbnRlcm5hcyBkZSB1bmEgZW1wcmVzYS4gVHJhdGEgZGUgYXByb3ZlY2hhciB0b2RvIGVsIHBvdGVuY2lhbCBkZSBsb3MgZGF0b3MgcXVlIGdlbmVyYSB1bmEgZW1wcmVzYSBlbiB0b2RhcyBzdXMgYWN0aXZpZGFkZXMgZGlhcmlhcyB5IGFuYWxpemFyIGVzdG9zIGRhdG9zIHBhcmEgb2J0ZW5lciBpbmZvcm1hY2nDs24gZGUgdmFsb3Igc29icmUgbGEgdG9tYSBkZSBkZWNpc2lvbmVzLkF5dWRhIHBhcmEgZW50ZW5kZXIgZWwgaGlzdMOzcmljbyB5IGVsIGNvbW8gZXZvbHVjaW9uYW4gbG9zIGRhdG9zLiBZIGNvbW8gbWVuY2lvbmFtb3MgYW50ZXJpb3JtZW50ZSBCdXNpbmVzcyBBbmFseXRpY3MgY29uIGVsIGFuYWxpc2lzIGRlIGxhIGluZm9ybWFjacOzbiBkZSB1bmEgZW1wcmVzYSBsb2dyYSBwdWVkZSBsbGVnYXIgYSBkZXN1YnJpciBwYXRyb25lcywgZXhwbGljYWNpb25lcyBkZWwgcG9ycXVlIGRlIGxvcyBtaXNtb3MgeSBwcmVkZWNpciB0ZW5kZW5jaWFzIG8gaGVjaG9zIHF1ZSBwdWVkZW4gbGxlZ2FyIGEgcGFzYXIgZW4gZWwgbmVnb2Npby4gDQoNCkVzdG9zIGRvcyB0w6lybWlub3MgdGllbmVuIHVuYSBhbHRhIHJlbGFjacOzbiBlbnRyZSBlbGxhcyB5YSBxdWUgZW4gcG9jYXMgcGFsYWJyYXMgbGEgSW50ZWxpZ2VuY2lhIGRlIE5lZ29jaW9zIGVzIGVsIGhhY2VyIGFuw6FsaXNpcyBkZSBsb3MgZGF0b3Mgb2J0ZW5pZG9zIHkgQW5hbMOtdGljYSBkZSBOZWdvY2lvcyBlcyBwcmVkaWNjacOzbiBhIHBhcnRpciBkZSBsb3MgZGF0b3MgcXVlIHNlIG9idHV2aWVyb24gY29uIGVsIGFuw6FsaXNpcy4gVW5hIGNvbiBsbGV2YSBhIGxhIG90cmEgeSB0cmFiYWphbiBqdW50YXMgcGFyYSBvYnRlbmVyIGVsIHJlc3VsdGFkbyBidXNjYWRvIGRlIHVuIGFuw6FsaXNpcyBkZSBkYXRvcyBxdWUgY29udGVuZ2EgbGEgaW5mb3JtYWNpw7NuIHJlbGV2YW50ZSB5IHNpZ25pZmljYXRpdmEgcXVlIG5vcyBwdWVkYSBtb3N0cmFyIHByZWRpY2Npb25lcyBkZWwgY29tcG9ydGFtaWVudG8geWEgc2VhIGRlIGxhIGVtcHJlc2EsIGRlIGxhIGVjb25vbcOtYSwgZGUgbG9zIGluZ3Jlc29zLCBkZSBsb3MgY2xpZW50ZXMgeSBtw6FzLiBBbWJhcyBzb24gbmVjZXNhcmlhcyBwYXJhIGV4dHJhZXIgdW4gYnVlbiBhbsOhbGlzaXMgZGUgbGEgaW5mb3JtYWNpw7NuIGRlIHVuYSBlbXByZXNhLCB5YSBxdWUgdW5hIGFuYWxpcyBkb3MsIGxvcyBvcmdhbml6YSB5IGV4dHJhIGFxdWVsbG9zIHJlbGV2YW50ZXMgeSBsYSBvdHJhIHB1ZWRlIGxvZ3JhciBsYXMgcGVkaWNjaW9uZXMgeSBhbsOhbGlzaXMuDQo=