Limpieza, Transformacion y Organizacion

Recursos Humanos (Colaboradores y Bajas)

#file.choose()

RhColab<-read.csv("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/BaseDatosL RH_Colaboradores.csv")
RhBajas<-read.csv("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/BaseD_Limpia RH_ Bajas .csv")

Tipos de Variables Existentes para RHCOLAB

variable<-c("numero_de_empleado","nombre_completo", "edad", "genero", "fecha_de_alta", "antioguedad", "BAJA", "puesto", "departamento", "mano_de_obra", "salario_diario", "colonia", "municipio")

type<-c("Cualitativo (nominal)","Cualitativo (nominal)", "Cuantitativo(discreta)", "Cualitativo (nominal)", "Cuantitativo(discreta)", "cualitativo (nominal)", "Cualitativo (nominal)", "Cualitativo (nominal)", "Cualitativo (nominal)", "Cualitativo (nominal)", "Cuantitativo (continua)", "Cualitativo (nominal)", "Cualitativo (nominal)")

Escala_de_Medición<-c("Numero", "Fecha", "Departamento", "Salario", "Estado")


table<-data.frame(variable,type)
knitr::kable(table)
variable type
numero_de_empleado Cualitativo (nominal)
nombre_completo Cualitativo (nominal)
edad Cuantitativo(discreta)
genero Cualitativo (nominal)
fecha_de_alta Cuantitativo(discreta)
antioguedad cualitativo (nominal)
BAJA Cualitativo (nominal)
puesto Cualitativo (nominal)
departamento Cualitativo (nominal)
mano_de_obra Cualitativo (nominal)
salario_diario Cuantitativo (continua)
colonia Cualitativo (nominal)
municipio Cualitativo (nominal)

Tipos de Variables Existentes para RHBAJAS

variable<-c ("nombre","edad", "genero", "fecha_alta", "motivo_baja", "dias_de_trabajo", "baja", "puesto_que_desempeña", "salario_imss", "colonia", "municipio", "estado", "estado_civil" )


type<-c ("Cualitativo (nominal)","Cuantitativo(discreta)", "Cualitativo (nominal)", "Cuantitativo(discreta)", "Cualitativo (nominal)", "Cuantitativo(discreta)", "Cuantitativo(discreta)", "Cualitativo (nominal)", "Cuantitativo(Continua)", "Cualitativo (nominal)", "Cualitativo (nominal)", "Cualitativo (nominal)", "Cualitativo (nominal)" )

Escala_de_Medición<-c("Numero", "Fecha", "Departamento", "Salario", "Estado")


table<-data.frame(variable,type)
knitr::kable(table)
variable type
nombre Cualitativo (nominal)
edad Cuantitativo(discreta)
genero Cualitativo (nominal)
fecha_alta Cuantitativo(discreta)
motivo_baja Cualitativo (nominal)
dias_de_trabajo Cuantitativo(discreta)
baja Cuantitativo(discreta)
puesto_que_desempeña Cualitativo (nominal)
salario_imss Cuantitativo(Continua)
colonia Cualitativo (nominal)
municipio Cualitativo (nominal)
estado Cualitativo (nominal)
estado_civil Cualitativo (nominal)

Llamar librerias

library(foreign)
library(dplyr)        # data manipulation 
## 
## 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(forcats)      # to work with categorical variables
library(ggplot2)      # data visualization 
library(janitor)      # data exploration and cleaning 
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
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:dplyr':
## 
##     src, summarize
## The following objects are masked from 'package:base':
## 
##     format.pval, units
library(psych)        # functions for multivariate analysis 
## 
## Attaching package: 'psych'
## The following object is masked from 'package:Hmisc':
## 
##     describe
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
library(naniar)       # summaries and visualization of missing values NAs
library(dlookr)       # summaries and visualization of missing values NAs
## 
## Attaching package: 'dlookr'
## The following object is masked from 'package:psych':
## 
##     describe
## The following object is masked from 'package:Hmisc':
## 
##     describe
## The following object is masked from 'package:base':
## 
##     transform
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

Verificar la estructura de la base de datos

str(RhColab)
## 'data.frame':    999 obs. of  13 variables:
##  $ numero_de_empleado: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ nombre_completo   : chr  "NICOLAS MARTINEZ DE LOERA" "MARIANA DE LEON MORENO" "JOSE LUIS HERNANDEZ CERVANTES" "MARIA CAZARES MORALES" ...
##  $ edad              : int  67 43 73 32 57 38 55 26 27 37 ...
##  $ genero            : chr  "MASCULINO" "FEMENINO" "MASCULINO" "FEMENINO" ...
##  $ fecha_de_alta     : chr  "1/7/2010" "1/7/2011" "22/11/2011" "30/1/2013" ...
##  $ antiguedad        : int  12 11 11 9 8 8 7 6 5 5 ...
##  $ BAJA              : int  NA NA NA NA NA NA NA NA NA NA ...
##  $ puesto            : chr  "Supervisor de Máquin" "Supervisor de pegado" "Externo" "SUPERVISORA" ...
##  $ departamento      : chr  "Produccion Cartón MDL" "Produccion Cartón MDL" "Externo" "Produccion Cartón MC" ...
##  $ mano_de_obra      : chr  "Indirecto" "Indirecto" "Indirecto" "Indirecto" ...
##  $ salario_diario    : num  177 177 177 337 441 ...
##  $ colonia           : chr  "UNIDAD LABORAL" "SANTA TERESITA" "VILLAS DE HUINALA" "PUEBLO NUEVO" ...
##  $ municipio         : chr  "SAN NICOLAS DE LOS G" "APODACA" "APODACA" "APODACA" ...
str(RhBajas)
## 'data.frame':    237 obs. of  13 variables:
##  $ nombre              : chr  "MARIO VALDEZ ORTIZ" "ISABEL BARRIOS MENDEZ" "MARIA ELIZABETH GOMEZ HERNANDEZ" "ALONDRA ABIGAIL ESCARCIA GOMEZ" ...
##  $ edad                : int  32 36 23 21 29 46 29 31 50 19 ...
##  $ genero              : chr  "MASCULINO" "FEMENINO" "FEMENINO" "FEMENINO" ...
##  $ fecha_de_alta       : chr  "9/3/2020" "9/11/2021" "10/11/2021" "10/11/2021" ...
##  $ motivo_de_baja      : chr  "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" ...
##  $ dias_de_trabajo     : int  628 60 59 59 51 37 37 31 18 224 ...
##  $ baja                : chr  "27/11/2021" "8/1/2022" "8/1/2022" "8/1/2022" ...
##  $ puesto_que_desempeña: chr  "DISEÑO" "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" ...
##  $ salario_imss        : num  500 152 152 152 152 ...
##  $ colonia             : chr  "SAN NICOLAS DE LOS G" "COLINAS DEL AEROPÑUERTO" "PUEBLO NUEVO" "PUEBLO NUEVO" ...
##  $ municipio           : chr  "SAN NICOLAS DE LOS G" "PESQUERIA" "APODACA" "APODACA" ...
##  $ estado              : chr  "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" ...
##  $ estado_civil        : chr  "SOLTERO" "UNIÓN LIBRE" "CASADO" "SOLTERO" ...

seleccionar columnas / variables

RhColab1<-RhColab 
RhBajas1<-RhBajas

Limpieza de datos

RhColab1<-RhColab %>% select(-one_of('numero_de_empleado','Fecha_alta' , 'BAJA', 'edad'))



# lets rename the selected columns / variables
summary(RhColab1)
##  nombre_completo       genero          fecha_de_alta        antiguedad    
##  Length:999         Length:999         Length:999         Min.   : 0.000  
##  Class :character   Class :character   Class :character   1st Qu.: 0.000  
##  Mode  :character   Mode  :character   Mode  :character   Median : 0.000  
##                                                           Mean   : 1.425  
##                                                           3rd Qu.: 2.000  
##                                                           Max.   :12.000  
##                                                           NA's   :886     
##     puesto          departamento       mano_de_obra       salario_diario 
##  Length:999         Length:999         Length:999         Min.   :144.4  
##  Class :character   Class :character   Class :character   1st Qu.:176.7  
##  Mode  :character   Mode  :character   Mode  :character   Median :180.7  
##                                                           Mean   :181.4  
##                                                           3rd Qu.:180.7  
##                                                           Max.   :441.4  
##                                                           NA's   :886    
##    colonia           municipio        
##  Length:999         Length:999        
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
##                                       
## 
names(RhColab1)<-c('Nom_Comp', 'Gen', 'Fecha_alta', 'Ant', 'Puesto', 'Dep', 'MDO', 'Sal_Diario', 'Col', 'Mun')
names(RhBajas1)<-c('Nom', 'Edad', 'Gen', 'Fecha_alta', 'MB', 'Días_trab', 'Baja', 'PuestDes', 'Sal_IMSS', 'Col', 'Mun', 'Estado', 'EstCiv')

##lets convert fecha_nacimiento to date format 


RhColab1$Fecha_alta<-as.Date(RhColab$fecha_de_alta, format = "%d/%m/%Y")
RhBajas1$Fecha_alta<-as.Date(RhBajas1$Fecha_alta, format = "%d/%m/%Y")
RhBajas1$Baja<-as.Date(RhBajas1$Baja, format = "%d/%m/%Y")

str(RhColab1)
## 'data.frame':    999 obs. of  10 variables:
##  $ Nom_Comp  : chr  "NICOLAS MARTINEZ DE LOERA" "MARIANA DE LEON MORENO" "JOSE LUIS HERNANDEZ CERVANTES" "MARIA CAZARES MORALES" ...
##  $ Gen       : chr  "MASCULINO" "FEMENINO" "MASCULINO" "FEMENINO" ...
##  $ Fecha_alta: Date, format: "2010-07-01" "2011-07-01" ...
##  $ Ant       : int  12 11 11 9 8 8 7 6 5 5 ...
##  $ Puesto    : chr  "Supervisor de Máquin" "Supervisor de pegado" "Externo" "SUPERVISORA" ...
##  $ Dep       : chr  "Produccion Cartón MDL" "Produccion Cartón MDL" "Externo" "Produccion Cartón MC" ...
##  $ MDO       : chr  "Indirecto" "Indirecto" "Indirecto" "Indirecto" ...
##  $ Sal_Diario: num  177 177 177 337 441 ...
##  $ Col       : chr  "UNIDAD LABORAL" "SANTA TERESITA" "VILLAS DE HUINALA" "PUEBLO NUEVO" ...
##  $ Mun       : chr  "SAN NICOLAS DE LOS G" "APODACA" "APODACA" "APODACA" ...
str(RhBajas1)
## 'data.frame':    237 obs. of  13 variables:
##  $ Nom       : chr  "MARIO VALDEZ ORTIZ" "ISABEL BARRIOS MENDEZ" "MARIA ELIZABETH GOMEZ HERNANDEZ" "ALONDRA ABIGAIL ESCARCIA GOMEZ" ...
##  $ Edad      : int  32 36 23 21 29 46 29 31 50 19 ...
##  $ Gen       : chr  "MASCULINO" "FEMENINO" "FEMENINO" "FEMENINO" ...
##  $ Fecha_alta: Date, format: "2020-03-09" "2021-11-09" ...
##  $ MB        : chr  "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" ...
##  $ Días_trab : int  628 60 59 59 51 37 37 31 18 224 ...
##  $ Baja      : Date, format: "2021-11-27" "2022-01-08" ...
##  $ PuestDes  : chr  "DISEÑO" "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" ...
##  $ Sal_IMSS  : num  500 152 152 152 152 ...
##  $ Col       : chr  "SAN NICOLAS DE LOS G" "COLINAS DEL AEROPÑUERTO" "PUEBLO NUEVO" "PUEBLO NUEVO" ...
##  $ Mun       : chr  "SAN NICOLAS DE LOS G" "PESQUERIA" "APODACA" "APODACA" ...
##  $ Estado    : chr  "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" ...
##  $ EstCiv    : chr  "SOLTERO" "UNIÓN LIBRE" "CASADO" "SOLTERO" ...
# Eliminar NA's y sustituir con 0's

sum(is.na(RhColab1))
## [1] 2658
sum(is.na(RhBajas1))
## [1] 0
summary(RhColab1)
##    Nom_Comp             Gen              Fecha_alta              Ant        
##  Length:999         Length:999         Min.   :2010-07-01   Min.   : 0.000  
##  Class :character   Class :character   1st Qu.:2020-08-28   1st Qu.: 0.000  
##  Mode  :character   Mode  :character   Median :2022-02-23   Median : 0.000  
##                                        Mean   :2021-01-16   Mean   : 1.425  
##                                        3rd Qu.:2022-07-05   3rd Qu.: 2.000  
##                                        Max.   :2022-08-23   Max.   :12.000  
##                                        NA's   :886          NA's   :886     
##     Puesto              Dep                MDO              Sal_Diario   
##  Length:999         Length:999         Length:999         Min.   :144.4  
##  Class :character   Class :character   Class :character   1st Qu.:176.7  
##  Mode  :character   Mode  :character   Mode  :character   Median :180.7  
##                                                           Mean   :181.4  
##                                                           3rd Qu.:180.7  
##                                                           Max.   :441.4  
##                                                           NA's   :886    
##      Col                Mun           
##  Length:999         Length:999        
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
##                                       
## 
summary(RhBajas1)
##      Nom                 Edad           Gen              Fecha_alta        
##  Length:237         Min.   : 0.00   Length:237         Min.   :2016-10-12  
##  Class :character   1st Qu.:23.00   Class :character   1st Qu.:2022-01-19  
##  Mode  :character   Median :29.00   Mode  :character   Median :2022-04-04  
##                     Mean   :30.52                      Mean   :2022-02-10  
##                     3rd Qu.:37.00                      3rd Qu.:2022-06-14  
##                     Max.   :61.00                      Max.   :2022-08-17  
##       MB              Días_trab            Baja              PuestDes        
##  Length:237         Min.   :   0.00   Min.   :2021-11-27   Length:237        
##  Class :character   1st Qu.:   9.00   1st Qu.:2022-03-01   Class :character  
##  Mode  :character   Median :  21.00   Median :2022-05-06   Mode  :character  
##                     Mean   :  83.42   Mean   :2022-05-05                     
##                     3rd Qu.:  49.00   3rd Qu.:2022-07-07                     
##                     Max.   :1966.00   Max.   :2022-08-25                     
##     Sal_IMSS         Col                Mun               Estado         
##  Min.   :144.4   Length:237         Length:237         Length:237        
##  1st Qu.:180.7   Class :character   Class :character   Class :character  
##  Median :180.7   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :178.6                                                           
##  3rd Qu.:180.7                                                           
##  Max.   :500.0                                                           
##     EstCiv         
##  Length:237        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
RhColab1 <- na.omit(RhColab1)
RhBajas1 <- na.omit(RhBajas1)


summary(RhColab1)
##    Nom_Comp             Gen              Fecha_alta              Ant        
##  Length:113         Length:113         Min.   :2010-07-01   Min.   : 0.000  
##  Class :character   Class :character   1st Qu.:2020-08-28   1st Qu.: 0.000  
##  Mode  :character   Mode  :character   Median :2022-02-23   Median : 0.000  
##                                        Mean   :2021-01-16   Mean   : 1.425  
##                                        3rd Qu.:2022-07-05   3rd Qu.: 2.000  
##                                        Max.   :2022-08-23   Max.   :12.000  
##     Puesto              Dep                MDO              Sal_Diario   
##  Length:113         Length:113         Length:113         Min.   :144.4  
##  Class :character   Class :character   Class :character   1st Qu.:176.7  
##  Mode  :character   Mode  :character   Mode  :character   Median :180.7  
##                                                           Mean   :181.4  
##                                                           3rd Qu.:180.7  
##                                                           Max.   :441.4  
##      Col                Mun           
##  Length:113         Length:113        
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
## 
summary(RhBajas1)  
##      Nom                 Edad           Gen              Fecha_alta        
##  Length:237         Min.   : 0.00   Length:237         Min.   :2016-10-12  
##  Class :character   1st Qu.:23.00   Class :character   1st Qu.:2022-01-19  
##  Mode  :character   Median :29.00   Mode  :character   Median :2022-04-04  
##                     Mean   :30.52                      Mean   :2022-02-10  
##                     3rd Qu.:37.00                      3rd Qu.:2022-06-14  
##                     Max.   :61.00                      Max.   :2022-08-17  
##       MB              Días_trab            Baja              PuestDes        
##  Length:237         Min.   :   0.00   Min.   :2021-11-27   Length:237        
##  Class :character   1st Qu.:   9.00   1st Qu.:2022-03-01   Class :character  
##  Mode  :character   Median :  21.00   Median :2022-05-06   Mode  :character  
##                     Mean   :  83.42   Mean   :2022-05-05                     
##                     3rd Qu.:  49.00   3rd Qu.:2022-07-07                     
##                     Max.   :1966.00   Max.   :2022-08-25                     
##     Sal_IMSS         Col                Mun               Estado         
##  Min.   :144.4   Length:237         Length:237         Length:237        
##  1st Qu.:180.7   Class :character   Class :character   Class :character  
##  Median :180.7   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :178.6                                                           
##  3rd Qu.:180.7                                                           
##  Max.   :500.0                                                           
##     EstCiv         
##  Length:237        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
str(RhColab1)
## 'data.frame':    113 obs. of  10 variables:
##  $ Nom_Comp  : chr  "NICOLAS MARTINEZ DE LOERA" "MARIANA DE LEON MORENO" "JOSE LUIS HERNANDEZ CERVANTES" "MARIA CAZARES MORALES" ...
##  $ Gen       : chr  "MASCULINO" "FEMENINO" "MASCULINO" "FEMENINO" ...
##  $ Fecha_alta: Date, format: "2010-07-01" "2011-07-01" ...
##  $ Ant       : int  12 11 11 9 8 8 7 6 5 5 ...
##  $ Puesto    : chr  "Supervisor de Máquin" "Supervisor de pegado" "Externo" "SUPERVISORA" ...
##  $ Dep       : chr  "Produccion Cartón MDL" "Produccion Cartón MDL" "Externo" "Produccion Cartón MC" ...
##  $ MDO       : chr  "Indirecto" "Indirecto" "Indirecto" "Indirecto" ...
##  $ Sal_Diario: num  177 177 177 337 441 ...
##  $ Col       : chr  "UNIDAD LABORAL" "SANTA TERESITA" "VILLAS DE HUINALA" "PUEBLO NUEVO" ...
##  $ Mun       : chr  "SAN NICOLAS DE LOS G" "APODACA" "APODACA" "APODACA" ...
##  - attr(*, "na.action")= 'omit' Named int [1:886] 114 115 116 117 118 119 120 121 122 123 ...
##   ..- attr(*, "names")= chr [1:886] "114" "115" "116" "117" ...
str(RhBajas1)
## 'data.frame':    237 obs. of  13 variables:
##  $ Nom       : chr  "MARIO VALDEZ ORTIZ" "ISABEL BARRIOS MENDEZ" "MARIA ELIZABETH GOMEZ HERNANDEZ" "ALONDRA ABIGAIL ESCARCIA GOMEZ" ...
##  $ Edad      : int  32 36 23 21 29 46 29 31 50 19 ...
##  $ Gen       : chr  "MASCULINO" "FEMENINO" "FEMENINO" "FEMENINO" ...
##  $ Fecha_alta: Date, format: "2020-03-09" "2021-11-09" ...
##  $ MB        : chr  "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" ...
##  $ Días_trab : int  628 60 59 59 51 37 37 31 18 224 ...
##  $ Baja      : Date, format: "2021-11-27" "2022-01-08" ...
##  $ PuestDes  : chr  "DISEÑO" "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" ...
##  $ Sal_IMSS  : num  500 152 152 152 152 ...
##  $ Col       : chr  "SAN NICOLAS DE LOS G" "COLINAS DEL AEROPÑUERTO" "PUEBLO NUEVO" "PUEBLO NUEVO" ...
##  $ Mun       : chr  "SAN NICOLAS DE LOS G" "PESQUERIA" "APODACA" "APODACA" ...
##  $ Estado    : chr  "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" ...
##  $ EstCiv    : chr  "SOLTERO" "UNIÓN LIBRE" "CASADO" "SOLTERO" ...

Calcular la variable “año” en años para realizar caracteristicas adicionales de los colaboradores

library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
edad<-trunc((RhColab1$Fecha_alta %--% RhColab1$Fecha_alta) / years(1)) # %--% creates a time interval based on as.date() format
RhColab1$edad<-edad

edad<-trunc((RhBajas1$Fecha_alta %--% RhBajas1$Fecha_alta) / years(1))
edad<-trunc((RhBajas1$Baja %--% RhBajas1$Baja) / years(1))

Convertir las variables a factor para poder crear graficas descriptivas

###  Colab1
RhColab1$Gen<-as.factor(RhColab1$Gen)
RhColab1$Puesto<-as.factor(RhColab1$Puesto)
RhColab1$Dep<-as.factor(RhColab1$Dep)
RhColab1$Mun<-as.factor(RhColab1$Mun)
RhColab1$Col<-as.factor(RhColab1$Col)


###  Bajas1 

RhBajas1$Gen<-as.factor(RhBajas1$Gen)
RhBajas1$MB<-as.factor(RhBajas1$MB)
RhBajas1$Días_trab<-as.factor(RhBajas1$Días_trab)
RhBajas1$PuestDes<-as.factor(RhBajas1$PuestDes)
RhBajas1$Col<-as.factor(RhBajas1$Col)
RhBajas1$Mun<-as.factor(RhBajas1$Mun)
RhBajas1$Estado<-as.factor(RhBajas1$Estado)
RhBajas1$EstCiv<-as.factor(RhBajas1$EstCiv)

Verificar la estructura de las bases de datos RhColab1 y RhBajas1

str(RhColab1)
## 'data.frame':    113 obs. of  11 variables:
##  $ Nom_Comp  : chr  "NICOLAS MARTINEZ DE LOERA" "MARIANA DE LEON MORENO" "JOSE LUIS HERNANDEZ CERVANTES" "MARIA CAZARES MORALES" ...
##  $ Gen       : Factor w/ 2 levels "FEMENINO","MASCULINO": 2 1 2 1 1 2 1 2 2 1 ...
##  $ Fecha_alta: Date, format: "2010-07-01" "2011-07-01" ...
##  $ Ant       : int  12 11 11 9 8 8 7 6 5 5 ...
##  $ Puesto    : Factor w/ 29 levels "AY. GENERAL",..: 27 28 10 29 29 8 7 4 3 7 ...
##  $ Dep       : Factor w/ 22 levels "","Ay.flexo",..: 18 18 13 17 8 4 8 19 4 10 ...
##  $ MDO       : chr  "Indirecto" "Indirecto" "Indirecto" "Indirecto" ...
##  $ Sal_Diario: num  177 177 177 337 441 ...
##  $ Col       : Factor w/ 73 levels "ALAMOS DEL PARQUE",..: 64 61 69 51 56 18 1 52 14 5 ...
##  $ Mun       : Factor w/ 9 levels "APODACA","CAÑADA BLANCA",..: 9 1 1 1 1 8 1 1 8 9 ...
##  $ edad      : num  0 0 0 0 0 0 0 0 0 0 ...
##  - attr(*, "na.action")= 'omit' Named int [1:886] 114 115 116 117 118 119 120 121 122 123 ...
##   ..- attr(*, "names")= chr [1:886] "114" "115" "116" "117" ...
summary(RhColab1)
##    Nom_Comp                Gen       Fecha_alta              Ant        
##  Length:113         FEMENINO :61   Min.   :2010-07-01   Min.   : 0.000  
##  Class :character   MASCULINO:52   1st Qu.:2020-08-28   1st Qu.: 0.000  
##  Mode  :character                  Median :2022-02-23   Median : 0.000  
##                                    Mean   :2021-01-16   Mean   : 1.425  
##                                    3rd Qu.:2022-07-05   3rd Qu.: 2.000  
##                                    Max.   :2022-08-23   Max.   :12.000  
##                                                                         
##               Puesto                      Dep         MDO           
##  AYUDANTE GENERAL:59                        :40   Length:113        
##  COSTURERA       :10   Producción Retorn    :10   Class :character  
##  AY. GENERAL     : 7   Costura              : 7   Mode  :character  
##  SOLDADOR        : 5   Produccion Cartón MDL: 7                     
##  CHOFER          : 4   Stabilus             : 7                     
##  RESIDENTE       : 4   Cedis                : 6                     
##  (Other)         :24   (Other)              :36                     
##    Sal_Diario                      Col            Mun          edad  
##  Min.   :144.4   PUEBLO NUEVO        :27   APODACA  :72   Min.   :0  
##  1st Qu.:176.7   CANTORAL            : 4   JUAREZ   :10   1st Qu.:0  
##  Median :180.7   CAÑADA BLANCA       : 3   PESQUERIA: 9   Median :0  
##  Mean   :181.4   MISION SAN PABLO    : 3   GUADALUPE: 6   Mean   :0  
##  3rd Qu.:180.7   PORTAL DE HUINALA   : 3   SALTILLO : 5   3rd Qu.:0  
##  Max.   :441.4   VALLE DE SANTA MARIA: 3   MONTERREY: 4   Max.   :0  
##                  (Other)             :70   (Other)  : 7
str(RhBajas1)
## 'data.frame':    237 obs. of  13 variables:
##  $ Nom       : chr  "MARIO VALDEZ ORTIZ" "ISABEL BARRIOS MENDEZ" "MARIA ELIZABETH GOMEZ HERNANDEZ" "ALONDRA ABIGAIL ESCARCIA GOMEZ" ...
##  $ Edad      : int  32 36 23 21 29 46 29 31 50 19 ...
##  $ Gen       : Factor w/ 2 levels "FEMENINO","MASCULINO": 2 1 1 1 1 1 1 2 2 2 ...
##  $ Fecha_alta: Date, format: "2020-03-09" "2021-11-09" ...
##  $ MB        : Factor w/ 5 levels "ABANDONO","BAJA POR FALTAS",..: 4 4 4 4 4 2 2 2 2 4 ...
##  $ Días_trab : Factor w/ 95 levels "0","1","2","3",..: 88 53 52 52 48 37 37 31 19 79 ...
##  $ Baja      : Date, format: "2021-11-27" "2022-01-08" ...
##  $ PuestDes  : Factor w/ 31 levels "ANALISTA DE NOMINAS /AUX DE R.H.",..: 15 9 9 9 9 9 9 9 9 4 ...
##  $ Sal_IMSS  : num  500 152 152 152 152 ...
##  $ Col       : Factor w/ 98 levels "ACANTO RESIDENCIAL",..: 82 18 72 72 73 28 72 48 15 80 ...
##  $ Mun       : Factor w/ 13 levels "APODACA","CADEREYTA",..: 10 7 1 1 1 1 1 5 4 1 ...
##  $ Estado    : Factor w/ 3 levels "COAHUILA","NUEVO LEÓN",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ EstCiv    : Factor w/ 5 levels "CASADO","DIVORCIADO",..: 3 5 1 3 3 3 5 5 3 3 ...
summary(RhBajas1)
##      Nom                 Edad              Gen        Fecha_alta        
##  Length:237         Min.   : 0.00   FEMENINO :140   Min.   :2016-10-12  
##  Class :character   1st Qu.:23.00   MASCULINO: 97   1st Qu.:2022-01-19  
##  Mode  :character   Median :29.00                   Median :2022-04-04  
##                     Mean   :30.52                   Mean   :2022-02-10  
##                     3rd Qu.:37.00                   3rd Qu.:2022-06-14  
##                     Max.   :61.00                   Max.   :2022-08-17  
##                                                                         
##                    MB        Días_trab        Baja           
##  ABANDONO           :  1   15     : 11   Min.   :2021-11-27  
##  BAJA POR FALTAS    :141   1      :  9   1st Qu.:2022-03-01  
##  JUBILACION         :  1   6      :  9   Median :2022-05-06  
##  RENUNCIA VOLUNTARIA: 86   9      :  8   Mean   :2022-05-05  
##  TERMINO DE CONTRATO:  8   0      :  7   3rd Qu.:2022-07-07  
##                            8      :  7   Max.   :2022-08-25  
##                            (Other):186                       
##                   PuestDes      Sal_IMSS                       Col     
##  AYUDANTE GENERAL     :173   Min.   :144.4   PUEBLO NUEVO        : 67  
##  SOLDADOR             : 11   1st Qu.:180.7   VALLE DE SANTA MARIA: 15  
##  COSTURERA            : 10   Median :180.7   CANTORAL            : 10  
##  MONTACARGUISTA       :  5   Mean   :178.6   PORTAL DE HUINALA   :  6  
##  AY. GENERAL          :  4   3rd Qu.:180.7   SAN ISIDRO          :  6  
##  AUXILIAR DE EMBARQUES:  3   Max.   :500.0   BOSQUES DE HUINALA  :  4  
##  (Other)              : 31                   (Other)             :129  
##                        Mun             Estado            EstCiv   
##  APODACA                 :162   COAHUILA  :  9   CASADO     : 64  
##  PESQUERIA               : 32   NUEVO LEÓN:227   DIVORCIADO :  3  
##  JUAREZ                  : 15   SALTILLO  :  1   SOLTERO    :110  
##  GUADALUPE               : 10                    Unión libre:  1  
##  RAMOS ARIZPE            :  8                    UNIÓN LIBRE: 59  
##  SAN NICOLAS DE LOS GARZA:  3                                     
##  (Other)                 :  7

Mostrar tablas de visualización para identificar perspectivas relevantes de las bases de datos RhColab1 y RhBajas1

## Colaboradores


tapply(RhColab1$Sal_Diario,
       list(RhColab1$Gen,RhColab1$Puesto), mean)
##           AY. GENERAL AYUDANTE DE MANTENIMIENTO Ayudante general
## FEMENINO       151.61                        NA               NA
## MASCULINO      151.61                    180.68           176.72
##           AYUDANTE GENERAL CHOFER CHOFER GESTOR COSTURERA CUSTOMER SERVICE INF
## FEMENINO          177.4222     NA            NA  191.7533                   NA
## MASCULINO         176.2268 177.71        180.68  176.7200               176.72
##           ENFERMERA Externo EXTERNO GESTOR GUARDIA DE SEGURIDAD
## FEMENINO     176.72      NA      NA     NA                   NA
## MASCULINO        NA  176.72  151.67 176.72               180.68
##           INSPECTOR DE CALIDAD INSPECTORA DE CALIDAD  LIDER LIMPIEZA
## FEMENINO                208.65                180.68 144.45   176.72
## MASCULINO                   NA                    NA     NA       NA
##           MANTENIMIENTO MONTACARGUISTA   MOZO OP. FLEXO-RANURADORA-REFILADORA
## FEMENINO             NA             NA     NA                              NA
## MASCULINO        279.61         180.68 180.68                          176.72
##           OPERADOR SIERRA PINTOR RECIBO RESIDENTE SOLDADOR Supervisor de Máquin
## FEMENINO               NA     NA 176.72        NA       NA                   NA
## MASCULINO          180.68 176.72     NA    177.71  179.888               176.72
##           Supervisor de pegado SUPERVISORA
## FEMENINO                176.72      389.21
## MASCULINO                   NA          NA
tapply(RhColab1$Sal_Diario,
       list(RhColab1$Gen,RhColab1$Dep), mean)
##                    Ay.flexo Calidad  Cedis  CEDIS Celdas CORTADORAS Costura
## FEMENINO  178.7544       NA 194.665     NA     NA 180.68         NA 245.375
## MASCULINO 176.5400   180.68      NA 176.72 180.68     NA     180.68 176.720
##           COSTURA Costura T2     EHS Embarques Externo Limpieza Materiales
## FEMENINO   151.61     152.86 176.720        NA      NA   176.72     176.72
## MASCULINO      NA         NA 230.145    177.71 164.195       NA         NA
##           Paileria Produccion Cartón MC Produccion Cartón MDL Producción Retorn
## FEMENINO        NA              194.405              156.0975          161.3000
## MASCULINO    178.7              151.670              168.3700          183.8443
##           Rotativa Stabilus Troquel
## FEMENINO        NA   180.68  180.68
## MASCULINO   151.61   180.68  180.68
## Bajas

tapply(RhBajas1$Sal_IMSS,RhBajas1$Gen,mean)
##  FEMENINO MASCULINO 
##  177.3126  180.5544

Reemplazar el valor atípico de salario_diario con la mediana

RhColab1$Sal_Diario<-replace(RhColab1$Sal_Diario,RhColab1$Sal_Diario>1000000,181)

Mostrar gráficos de visualización de datos para que podamos identificar información relevante de nuestro conjunto de datos RHColab y RHBajas

tapply(RhColab1$Sal_Diario,
       list(RhColab1$Gen,RhColab1$Dep), mean)
##                    Ay.flexo Calidad  Cedis  CEDIS Celdas CORTADORAS Costura
## FEMENINO  178.7544       NA 194.665     NA     NA 180.68         NA 245.375
## MASCULINO 176.5400   180.68      NA 176.72 180.68     NA     180.68 176.720
##           COSTURA Costura T2     EHS Embarques Externo Limpieza Materiales
## FEMENINO   151.61     152.86 176.720        NA      NA   176.72     176.72
## MASCULINO      NA         NA 230.145    177.71 164.195       NA         NA
##           Paileria Produccion Cartón MC Produccion Cartón MDL Producción Retorn
## FEMENINO        NA              194.405              156.0975          161.3000
## MASCULINO    178.7              151.670              168.3700          183.8443
##           Rotativa Stabilus Troquel
## FEMENINO        NA   180.68  180.68
## MASCULINO   151.61   180.68  180.68
hist(RhBajas1$Edad, freq=TRUE, col='orange', main="Histograma de Edad",xlab="Edad en Años")

ggplot(RhBajas1, aes(x=Gen, y=Edad, fill=Gen)) + 
  geom_boxplot() 

ggplot(RhColab1, aes(x=Gen, y=Sal_Diario, fill=Gen)) + 
  geom_boxplot() 

ggplot(RhColab1, aes(Gen,Sal_Diario,fill=Gen)) +                                    
  geom_bar(stat = "identity") +
  scale_fill_brewer(palette = "Set2") + ggtitle("Salario Diario por Genero")

ggplot(RhBajas1, aes(x=Gen, y=Sal_IMSS, fill=Gen)) + 
  geom_bar(stat="identity") + 
  facet_grid(~EstCiv) + scale_fill_brewer(palette = "Set1")

Tecnicas Utilizadas

Tecnicas de Limpieza: Las tecnicas que se utilizaron con el fin de poder obtener una mejor visualizacion de los datos fueron: Cambiar el nombre de las variables. Se cambio el nombre de las variables de forma que se pudiera obtener mejor comprension de la variable analizada.

Tecnica 2: Se cambio la avriable de fecha_nacimiento a date format

Tecnica 3: Se eliminaron NAs los cuales se sustituyeron con 0s.

Variables: 122 Registros:28

2 propuestas concretas:

Analisis Exploratorio En promedio la mayor parte de los colaboradores de Form tienen una edad de entre 20 y 30 años, hay empleadas que tienen un máximo de 56 años mientras que hay un empleado que pasa ya de los 60 años de edad. Entre hombres y mujeres están en un rango de 20 a 40 años de edad

El saldo promedio tanto para hombres como para mujeres ronda en un monto de 170 y 180 pesos, pero hay una empleada que llega a un salario diario de 441 pesos, duplicando el saldo promedio de la mayor parte de los empleados de la compañía.

Las mujeres tienen un sueldo mas elevado que los hombres

Delivery Plan

Descargar librerias

#library(data.table)
library(dplyr)
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:Hmisc':
## 
##     is.discrete, summarize
## The following objects are masked from 'package:dplyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
library(ggplot2)
library(naniar)
library(Hmisc)         
#library(psych)
library(tidyverse)
## Registered S3 methods overwritten by 'broom':
##   method            from  
##   tidy.glht         jtools
##   tidy.summary.glht jtools
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ tibble  3.1.8     ✔ purrr   0.3.4
## ✔ tidyr   1.2.1     ✔ stringr 1.4.1
## ✔ readr   2.1.3     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ psych::%+%()             masks ggplot2::%+%()
## ✖ psych::alpha()           masks ggplot2::alpha()
## ✖ plyr::arrange()          masks dplyr::arrange()
## ✖ lubridate::as.difftime() masks base::as.difftime()
## ✖ purrr::compact()         masks plyr::compact()
## ✖ plyr::count()            masks dplyr::count()
## ✖ lubridate::date()        masks base::date()
## ✖ tidyr::extract()         masks dlookr::extract()
## ✖ plyr::failwith()         masks dplyr::failwith()
## ✖ dplyr::filter()          masks stats::filter()
## ✖ kableExtra::group_rows() masks dplyr::group_rows()
## ✖ plyr::id()               masks dplyr::id()
## ✖ lubridate::intersect()   masks base::intersect()
## ✖ dplyr::lag()             masks stats::lag()
## ✖ plyr::mutate()           masks dplyr::mutate()
## ✖ car::recode()            masks dplyr::recode()
## ✖ plyr::rename()           masks dplyr::rename()
## ✖ lubridate::setdiff()     masks base::setdiff()
## ✖ purrr::some()            masks car::some()
## ✖ Hmisc::src()             masks dplyr::src()
## ✖ plyr::summarise()        masks dplyr::summarise()
## ✖ plyr::summarize()        masks Hmisc::summarize(), dplyr::summarize()
## ✖ lubridate::union()       masks base::union()
library(janitor)
library(knitr)
library(pollster)
## 
## Attaching package: 'pollster'
## 
## The following object is masked from 'package:janitor':
## 
##     crosstab
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:lmtest':
## 
##     lrtest
## 
## The following object is masked from 'package:jtools':
## 
##     summ
## 
## The following objects are masked from 'package:psych':
## 
##     alpha, cs, lookup
## 
## The following object is masked from 'package:lattice':
## 
##     dotplot
## 
## The following object is masked from 'package:ggplot2':
## 
##     alpha
library(descr)
## 
## Attaching package: 'descr'
## 
## The following object is masked from 'package:pollster':
## 
##     crosstab
## 
## The following object is masked from 'package:janitor':
## 
##     crosstab
library(tidyr)

Limpieza

Importar base de datos

del_plan <-read.csv ("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/DP_1.csv")
del_plan <- read.csv ("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/DP_1.csv")

Convertir meses en una columna

del_plan <- clean_names(del_plan)
del_plan<-del_plan %>% dplyr::rename(jun_21=junio,
                               jul_21=julio,
                               ago_21=agosto, sep_21=septiembre, oct_21= octubre, nov_21=noviembre, dic_21=diciembre, oct_22=octubre_22)
del_plan<-pivot_longer(del_plan, cols=5:16, names_to = "mes", values_to = "unidades")

del_plan <- dplyr::select(del_plan, -c(5:15))

Eliminar columnas no necesarias

del_plan <- dplyr::select(del_plan, -c(2:4))

Formato de las variables

str(del_plan)
## tibble [2,772 × 3] (S3: tbl_df/tbl/data.frame)
##  $ cliente_planta: chr [1:2772] "STB3" "STB3" "STB3" "STB3" ...
##  $ mes           : chr [1:2772] "jun_21" "jul_21" "ago_21" "sep_21" ...
##  $ unidades      : int [1:2772] 0 140 530 0 200 0 150 230 500 0 ...

NA’s y valores atipicos

del_plan <- filter(del_plan, unidades>0)
sum(is.na(del_plan))
## [1] 0

Exportar la base de datos

del_plan_limpia<-del_plan
write.csv(del_plan_limpia,file = "CLEANDBDeliveryPlan.csv", row.names = FALSE)

Tecnicas Utilizadas: Tecnicas de Limpieza: Convertir meses en una columna: Esta tecnica se implemento para poder tener un manejo optimo de las unidades de produccion mensual debido a que en la base original estan registradas por meses lo cual dificulta a la hora de hacer un analisis.

Eliminar columnas: Se eliminaron las columnas “ID” “ODOO” “Proyecto” e “Item” ya que no eran de gran relevancia para este analisis

Eliminar NA’s y Valores atipicos: No se encontraron NA’s ni valores atipicos en la base asi que se eliminaron los registros que tienen 0 unidades programadas.

Registros: 231 Variables:27

Graficas

Tabla estadisticas

tabla_estadisticos <- describe(del_plan)
tabla_estadisticos
## # A tibble: 1 × 26
##   described_…¹     n    na  mean    sd se_mean   IQR skewn…² kurto…³   p00   p01
##   <chr>        <int> <int> <dbl> <dbl>   <dbl> <dbl>   <dbl>   <dbl> <dbl> <dbl>
## 1 unidades       733     0  406. 1337.    49.4   270    8.38    85.8     1     1
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

Bar plots

library(dplyr)
str(del_plan)
## tibble [733 × 3] (S3: tbl_df/tbl/data.frame)
##  $ cliente_planta: chr [1:733] "STB3" "STB3" "STB3" "STB3" ...
##  $ mes           : chr [1:733] "jul_21" "ago_21" "oct_21" "dic_21" ...
##  $ unidades      : int [1:733] 140 530 200 150 230 500 184 125 55 55 ...
del_plan$cliente_planta<-as.factor(del_plan$cliente_planta)
del_plan$unidades<-as.numeric(del_plan$unidades) 

del_plan2<-aggregate(unidades~cliente_planta, data = del_plan,sum)%>% arrange(desc(unidades))
del_plan3<-filter(del_plan2, unidades>4000)

ggplot(del_plan3, aes(x=reorder(cliente_planta,unidades), y=unidades)) +
  geom_bar(stat="identity")+
  coord_flip()

### Dispersion

del_plan2$unidades<-as.numeric(del_plan2$unidades)

ggplot(del_plan, aes(x=cliente_planta, y=unidades, fill=cliente_planta)) + 
  geom_boxplot() 

boxplot(del_plan3$cliente_planta,del_plan3$unidades)

class(del_plan2$unidades)
## [1] "numeric"

Time series plot

del_plan4<-aggregate(unidades~cliente_planta+mes, data = del_plan,sum)%>% arrange(desc(unidades))
del_plan5<-filter(del_plan4, cliente_planta=="HELLA" & cliente_planta=="TRMX" & cliente_planta=="VARROC" & cliente_planta=="DENSO")
ggplot(del_plan,aes(x=mes, y=unidades,color=cliente_planta))+
  geom_line()+
  labs(x="Fecha",y="Delay in Minutes", color="Legend")+
  ggtitle("Delays in Performance by Client")

Analisis exploratorio

Bar Plot: Las funciones utilizadas para la realizacion de este bar plot fueron: as.factor y as.numeric de esta forma volviendo los datos cualitativos a cuantitativos lo cual los hace mas manejables. El resultado de la grafica mostro a los clientes con mayor numero de unidades en orden descendiente.

Box Plot: Se utilizo la funcion as.numeric. Un hallazgo importante obtenido fue que “Hella” es el cliente con mayor cantidad de unidades y cuenta con algunos outliers por encima de la media, seguido por TRMX el cual no cuenta con outliers.

Time Series Plot: Para la realizacion de esta grafica fue nnecesario introducir la variable de tiempo mes. Un hallazgo importante fue que en la segunda mitad del año se nota un incremento considerable y un decremento justo a finalizar el segundo semestre

Delivery Performance

#file.choose()
bd<-read.csv ("/Users/andreapaolasosa/Desktop/DELIVERYPERORMANCE 2.csv") 
bdclientes<-read.csv ("/Users/andreapaolasosa/Desktop/DeliveryPerformancefinal1.csv")

Instalar Librerias

library (tidyverse)
library (janitor)
library (dplyr)
#install.packages ("ggplot2")
library (ggplot2)
library (Hmisc)

Analizar base de datos

summary (bd)
##     fecha             cliente               dif       
##  Length:52          Length:52          Min.   : 0.00  
##  Class :character   Class :character   1st Qu.: 0.00  
##  Mode  :character   Mode  :character   Median : 0.00  
##                                        Mean   :16.07  
##                                        3rd Qu.:29.38  
##                                        Max.   :71.25
str (bd)
## 'data.frame':    52 obs. of  3 variables:
##  $ fecha  : chr  "31/07/21" "31/07/21" "31/07/21" "31/07/21" ...
##  $ cliente: chr  "PRINTEL " "MAHLE" "MAGNA" "VARROC" ...
##  $ dif    : num  4.9 15.7 0 0 27.7 ...
names(bd)<-c('FECHA', 'CLIENTE', 'DIFERENCIA' )

Tipos de variables

Variable<-c("FECHA","CLIENTE","DIFERENCIA")
Type<-c("qualitative (ordinal)", "qualitative(nominal)", "quantitative (continuous)")  
table<-data.frame(Variable,Type)
knitr::kable(table)
Variable Type
FECHA qualitative (ordinal)
CLIENTE qualitative(nominal)
DIFERENCIA quantitative (continuous)

Limpieza de base de datos

Eliminar NA’s y sustituir con 0’s

sum(is.na(bd))
## [1] 0
bd[is.na(bd)]<-0


bd1<-bd
bd1<-as.data.frame(bd1) 
bd1$FECHA<-as.Date(bd1$FECHA,format="%d/%m/%Y") 
bd1$CLIENTE<-as.factor(bd1$CLIENTE) 
tabyl(bd1, FECHA, CLIENTE)
##       FECHA MAGNA MAHLE PRINTEL  VARROC
##  0021-07-31     1     1        1      1
##  0021-08-31     1     1        1      1
##  0021-09-30     1     1        1      1
##  0021-10-31     1     1        1      1
##  0021-11-30     1     1        1      1
##  0021-12-31     1     1        1      1
##  0022-01-31     1     1        1      1
##  0022-02-28     1     1        1      1
##  0022-03-31     1     1        1      1
##  0022-04-30     1     1        1      1
##  0022-05-31     1     1        1      1
##  0022-06-30     1     1        1      1
##  0022-07-31     1     1        1      1
tabyl(bd1, FECHA, DIFERENCIA)
##       FECHA 0 1.6 10.92 15.7 18.41 27.7 28.77 31.21 33.24 4.9 41.65 46.27 50.65
##  0021-07-31 2   0     0    1     0    0     0     0     0   1     0     0     0
##  0021-08-31 2   0     0    0     0    1     0     0     0   0     0     0     0
##  0021-09-30 2   0     0    0     0    0     0     0     0   0     0     0     0
##  0021-10-31 3   0     0    0     0    0     0     0     0   0     0     0     0
##  0021-11-30 2   0     1    0     0    0     0     0     0   0     0     0     0
##  0021-12-31 2   0     0    0     1    0     0     0     0   0     0     1     0
##  0022-01-31 2   0     0    0     0    0     1     0     0   0     0     0     0
##  0022-02-28 2   0     0    0     0    0     0     1     0   0     0     0     0
##  0022-03-31 3   0     0    0     0    0     0     0     0   0     0     0     0
##  0022-04-30 3   0     0    0     0    0     0     0     0   0     0     0     1
##  0022-05-31 3   0     0    0     0    0     0     0     0   0     0     0     0
##  0022-06-30 3   0     0    0     0    0     0     0     0   0     1     0     0
##  0022-07-31 2   1     0    0     0    0     0     0     1   0     0     0     0
##  56.82 60.1 62.63 63.68 66.44 67.31 67.98 71.25 8.6
##      0    0     0     0     0     0     0     0   0
##      0    0     0     0     0     1     0     0   0
##      1    0     0     0     0     0     0     0   1
##      0    0     0     0     0     0     1     0   0
##      0    1     0     0     0     0     0     0   0
##      0    0     0     0     0     0     0     0   0
##      0    0     0     0     1     0     0     0   0
##      0    0     0     0     0     0     0     1   0
##      0    0     0     1     0     0     0     0   0
##      0    0     0     0     0     0     0     0   0
##      0    0     1     0     0     0     0     0   0
##      0    0     0     0     0     0     0     0   0
##      0    0     0     0     0     0     0     0   0
tibble(bd1)
## # A tibble: 52 × 3
##    FECHA      CLIENTE    DIFERENCIA
##    <date>     <fct>           <dbl>
##  1 0021-07-31 "PRINTEL "        4.9
##  2 0021-07-31 "MAHLE"          15.7
##  3 0021-07-31 "MAGNA"           0  
##  4 0021-07-31 "VARROC"          0  
##  5 0021-08-31 "PRINTEL "       27.7
##  6 0021-08-31 "MAHLE"          67.3
##  7 0021-08-31 "MAGNA"           0  
##  8 0021-08-31 "VARROC"          0  
##  9 0021-09-30 "PRINTEL "        8.6
## 10 0021-09-30 "MAHLE"          56.8
## # … with 42 more rows

Limpieza bdclientes2

bdclientes2<-bdclientes
bdclientes2<-as.data.frame(bdclientes2)
bdclientes2$FECHA<-as.Date(bdclientes2$FECHA,format="%m/%d/%Y")
bdclientes2$PRINTEL<-as.factor(bdclientes2$PRINTEL)
tabyl(bdclientes2, FECHA, PRINTEL)
##       FECHA 0 1.6 4.9 8.6 10.92 18.41 27.7 28.77 31.21
##  2021-01-07 0   0   1   0     0     0    0     0     0
##  2021-01-08 0   0   0   0     0     0    1     0     0
##  2021-01-09 0   0   0   1     0     0    0     0     0
##  2021-01-10 1   0   0   0     0     0    0     0     0
##  2021-01-11 0   0   0   0     1     0    0     0     0
##  2021-01-12 0   0   0   0     0     1    0     0     0
##  2022-01-01 0   0   0   0     0     0    0     1     0
##  2022-01-02 0   0   0   0     0     0    0     0     1
##  2022-01-03 1   0   0   0     0     0    0     0     0
##  2022-01-04 1   0   0   0     0     0    0     0     0
##  2022-01-05 1   0   0   0     0     0    0     0     0
##  2022-01-06 1   0   0   0     0     0    0     0     0
##  2022-01-07 0   1   0   0     0     0    0     0     0
tabyl(bdclientes2, FECHA, MAHLE)
##       FECHA 15.7 33.24 41.65 46.27 50.65 56.82 60.1 62.63 63.68 66.44 67.31
##  2021-01-07    1     0     0     0     0     0    0     0     0     0     0
##  2021-01-08    0     0     0     0     0     0    0     0     0     0     1
##  2021-01-09    0     0     0     0     0     1    0     0     0     0     0
##  2021-01-10    0     0     0     0     0     0    0     0     0     0     0
##  2021-01-11    0     0     0     0     0     0    1     0     0     0     0
##  2021-01-12    0     0     0     1     0     0    0     0     0     0     0
##  2022-01-01    0     0     0     0     0     0    0     0     0     1     0
##  2022-01-02    0     0     0     0     0     0    0     0     0     0     0
##  2022-01-03    0     0     0     0     0     0    0     0     1     0     0
##  2022-01-04    0     0     0     0     1     0    0     0     0     0     0
##  2022-01-05    0     0     0     0     0     0    0     1     0     0     0
##  2022-01-06    0     0     1     0     0     0    0     0     0     0     0
##  2022-01-07    0     1     0     0     0     0    0     0     0     0     0
##  67.98 71.25
##      0     0
##      0     0
##      0     0
##      1     0
##      0     0
##      0     0
##      0     0
##      0     1
##      0     0
##      0     0
##      0     0
##      0     0
##      0     0
tibble(bdclientes2)
## # A tibble: 13 × 5
##    FECHA      PRINTEL MAHLE MAGNA VARROC
##    <date>     <fct>   <dbl> <int>  <int>
##  1 2021-01-07 4.9      15.7     0      0
##  2 2021-01-08 27.7     67.3     0      0
##  3 2021-01-09 8.6      56.8     0      0
##  4 2021-01-10 0        68.0     0      0
##  5 2021-01-11 10.92    60.1     0      0
##  6 2021-01-12 18.41    46.3     0      0
##  7 2022-01-01 28.77    66.4     0      0
##  8 2022-01-02 31.21    71.2     0      0
##  9 2022-01-03 0        63.7     0      0
## 10 2022-01-04 0        50.6     0      0
## 11 2022-01-05 0        62.6     0      0
## 12 2022-01-06 0        41.6     0      0
## 13 2022-01-07 1.6      33.2     0      0

Tecnicas de Limpieza 1. Eliminar NA’s y sustituir con 0s: Se reemplazaron los NA’s con 0s para poder facilitar el analisis y obtener resultados mas precisos.

2.Se cambio el formato de la fecha a mes/dia/año

Analisis Profundo de la Base de datos

media_bd <- mean(bd$DIFERENCIA)
media_bd
## [1] 16.07365
median_bd <- median(bd$DIFERENCIA)
median_bd
## [1] 0
mode_bd <- mode(bd$DIFERENCIA)
mode_bd
## [1] "numeric"
hist(bd1$DIFERENCIA) 

Analisis Profundo de la Base de datos BDCLIENTES

media_bdclientes <- mean(bdclientes$PRINTEL)
media_bdclientes
## [1] 10.16231
median_bdclientes <- median(bdclientes$PRINTEL)
median_bdclientes
## [1] 4.9
mode_bdclientes <- mode(bdclientes$PRINTEL)
mode_bdclientes
## [1] "numeric"
media_bdclientes <- mean(bdclientes$MAHLE)
media_bdclientes
## [1] 54.13231
median_bdclientes <- median(bdclientes$MAHLE)
median_bdclientes
## [1] 60.1
mode_bdclientes <- mode(bdclientes$MAHLE)
mode_bdclientes
## [1] "numeric"
bdclientes3 <-bdclientes
bdclientes3 <- subset (bdclientes3, select = -c (MAGNA,VARROC))


hist(bdclientes3$PRINTEL)

hist(bdclientes3$MAHLE)

Graficas

Clientes con los Retrasos mas Altos

ggplot(bd,aes(x=FECHA, y=DIFERENCIA,fill=CLIENTE))+
  geom_bar(stat="identity")+
  geom_hline(yintercept=33,linetype="dashed",color="black")+
  labs(x="Fecha",y="Retraso en Minutos", color="Legend")+
  ggtitle("Retraso en Desempeño de los Clientes")

Analisis Exploratorio Utilizando la moda, media y promedio se pudo realizar un analisis con los clientes Printel y Mahle. En el histograma representando Printel se puede observar que en la clase de 0 a 5 se encuentra que se tuvo mayor frecuencia, siendo la clase que más se repite, esto quiere decir que… De los 12 meses, en 7 se tuvo una diferencia de tiempo de entre 0 y 5 minutos, siendo esta baja pero con un sesgo a la izquierda. En cuanto a Mahle este histograma tiene un sesgo hacia la derecha, se tiene una tendencia a tener un mayor retraso en la clase de 60 a 70 minutos aproximadamente con este cliente, esto en un aproximado de 6 meses de los 12 tomados en cuenta.

En la ultima grafica la cual representa el retraso en desempeño, se puede observar que Mahle es el cliente que representa un mayor retraso mientras que Printel se mantiene con los tiempos mas bajos, en este caso siempre debajo de los 30 minutos.

Produccion

Limpieza de Datos

Importar la base de datos producción de la empresa FORM

producciontotal <- read.csv ("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/BD Producción csv.csv")

Entender la base de datos

str(producciontotal)
## 'data.frame':    5410 obs. of  17 variables:
##  $ Fecha               : chr  "15/07/22" "15/07/22" "15/07/22" "15/07/22" ...
##  $ No.                 : chr  "1" "2" "3" "4" ...
##  $ CLIENTE             : chr  "STABILUS 1" "STABILUS 1" "STABILUS 1" "STABILUS 1" ...
##  $ ID.FORM             : chr  "" "N.A." "CORTE." "ST-026-13892" ...
##  $ PRODUCTO            : chr  "STABOMAT 643920. CAJA IMP. CORTE. AZUL.PC0011. ( 2 Pza/Caja)." "KR55006. CAJA IMP. AZUL. CORTE. ( 1 pieza)." "241B KIT. EXPORT. INSERTO CON INSERTO. CORTE para Troquel." "MOPAR GDE. 754549. CAJA IMP. NEGRA. PC0022. ( PC0043: solo si autoriza Calidad). ( 1 Pieza). CORTE." ...
##  $ PIEZAS.PROG.        : chr  "200" "100" "216" "100" ...
##  $ TMO..MIN.           : chr  "20" "15" "20" "10" ...
##  $ HR..FIN             : chr  "9:20" "9:35" "9:55" "10:05" ...
##  $ ESTACION.ARRANQUE   : chr  "C1" "C1" "C1" "C1" ...
##  $ Laminas.procesadas  : chr  "402" "134" "110" "100" ...
##  $ INICIO.SEP.UP       : chr  "9:05" "10:05" "9:40" "11.2" ...
##  $ FIN.INICIO.DE.SEP.UP: chr  "9.1" "10:16" "9:43" "11:26" ...
##  $ INICIO.de.PROCESO   : chr  "9:12" "10.17" "9:45" "11:30" ...
##  $ FIN.de.PROCESO      : chr  "10:04" "11:05" "9.57" "11:49" ...
##  $ TIEMPO.CALIDAD      : chr  "1" "1" "1" "1" ...
##  $ TIEMPO.MATERIALES   : int  NA NA NA 7 NA NA NA NA NA NA ...
##  $ MERMAS.Maquinas.    : chr  "" "" "" "" ...

Eliminar columnas irrelevantes para el análisis

producciontotal <- subset (producciontotal,select = -c(No. , ID.FORM , PRODUCTO,  HR..FIN , ESTACION.ARRANQUE , INICIO.SEP.UP ,FIN.INICIO.DE.SEP.UP , INICIO.de.PROCESO , TIEMPO.MATERIALES , MERMAS.Maquinas. ))
summary (producciontotal)
##     Fecha             CLIENTE          PIEZAS.PROG.        TMO..MIN.        
##  Length:5410        Length:5410        Length:5410        Length:5410       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##  Laminas.procesadas FIN.de.PROCESO     TIEMPO.CALIDAD    
##  Length:5410        Length:5410        Length:5410       
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character

Instalar librerias necesarias

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

Cambiar a entero las variables cuantitativas

producciontotal$PIEZAS.PROG. <- substr(producciontotal$PIEZAS.PROG., start = 1, stop = 2)
tibble (producciontotal)
## # A tibble: 5,410 × 7
##    Fecha    CLIENTE    PIEZAS.PROG. TMO..MIN. Laminas.procesadas FIN.d…¹ TIEMP…²
##    <chr>    <chr>      <chr>        <chr>     <chr>              <chr>   <chr>  
##  1 15/07/22 STABILUS 1 20           20        402                10:04   1      
##  2 15/07/22 STABILUS 1 10           15        134                11:05   1      
##  3 15/07/22 STABILUS 1 21           20        110                9.57    1      
##  4 15/07/22 STABILUS 1 10           10        100                11:49   1      
##  5 15/07/22 YANFENG    20           10        51                 12:31   1      
##  6 15/07/22 TRMX       20           20        402                2:00    1      
##  7 15/07/22 STABILUS 1 10           10        22                 2.44    1      
##  8 15/07/22 YANFENG    12           10        13                 3:00    1      
##  9 15/07/22 YANFENG    32           10        33                 2:12    1      
## 10 15/07/22 YANFENG    50           60        501/501            10:59   2      
## # … with 5,400 more rows, and abbreviated variable names ¹​FIN.de.PROCESO,
## #   ²​TIEMPO.CALIDAD
producciontotal$PIEZAS.PROG. <- as.integer(producciontotal$PIEZAS.PROG.)
str(producciontotal)    
## 'data.frame':    5410 obs. of  7 variables:
##  $ Fecha             : chr  "15/07/22" "15/07/22" "15/07/22" "15/07/22" ...
##  $ CLIENTE           : chr  "STABILUS 1" "STABILUS 1" "STABILUS 1" "STABILUS 1" ...
##  $ PIEZAS.PROG.      : int  20 10 21 10 20 20 10 12 32 50 ...
##  $ TMO..MIN.         : chr  "20" "15" "20" "10" ...
##  $ Laminas.procesadas: chr  "402" "134" "110" "100" ...
##  $ FIN.de.PROCESO    : chr  "10:04" "11:05" "9.57" "11:49" ...
##  $ TIEMPO.CALIDAD    : chr  "1" "1" "1" "1" ...
producciontotal$TMO..MIN. <- substr(producciontotal$TMO..MIN., start = 1, stop = 2)
tibble (producciontotal)
## # A tibble: 5,410 × 7
##    Fecha    CLIENTE    PIEZAS.PROG. TMO..MIN. Laminas.procesadas FIN.d…¹ TIEMP…²
##    <chr>    <chr>             <int> <chr>     <chr>              <chr>   <chr>  
##  1 15/07/22 STABILUS 1           20 20        402                10:04   1      
##  2 15/07/22 STABILUS 1           10 15        134                11:05   1      
##  3 15/07/22 STABILUS 1           21 20        110                9.57    1      
##  4 15/07/22 STABILUS 1           10 10        100                11:49   1      
##  5 15/07/22 YANFENG              20 10        51                 12:31   1      
##  6 15/07/22 TRMX                 20 20        402                2:00    1      
##  7 15/07/22 STABILUS 1           10 10        22                 2.44    1      
##  8 15/07/22 YANFENG              12 10        13                 3:00    1      
##  9 15/07/22 YANFENG              32 10        33                 2:12    1      
## 10 15/07/22 YANFENG              50 60        501/501            10:59   2      
## # … with 5,400 more rows, and abbreviated variable names ¹​FIN.de.PROCESO,
## #   ²​TIEMPO.CALIDAD
producciontotal$TMO..MIN. <- as.integer(producciontotal$TMO..MIN.)
str(producciontotal)  
## 'data.frame':    5410 obs. of  7 variables:
##  $ Fecha             : chr  "15/07/22" "15/07/22" "15/07/22" "15/07/22" ...
##  $ CLIENTE           : chr  "STABILUS 1" "STABILUS 1" "STABILUS 1" "STABILUS 1" ...
##  $ PIEZAS.PROG.      : int  20 10 21 10 20 20 10 12 32 50 ...
##  $ TMO..MIN.         : int  20 15 20 10 10 20 10 10 10 60 ...
##  $ Laminas.procesadas: chr  "402" "134" "110" "100" ...
##  $ FIN.de.PROCESO    : chr  "10:04" "11:05" "9.57" "11:49" ...
##  $ TIEMPO.CALIDAD    : chr  "1" "1" "1" "1" ...
producciontotal$Laminas.procesadas <- substr(producciontotal$Laminas.procesadas, start = 1, stop = 2)
tibble (producciontotal)
## # A tibble: 5,410 × 7
##    Fecha    CLIENTE    PIEZAS.PROG. TMO..MIN. Laminas.procesadas FIN.d…¹ TIEMP…²
##    <chr>    <chr>             <int>     <int> <chr>              <chr>   <chr>  
##  1 15/07/22 STABILUS 1           20        20 40                 10:04   1      
##  2 15/07/22 STABILUS 1           10        15 13                 11:05   1      
##  3 15/07/22 STABILUS 1           21        20 11                 9.57    1      
##  4 15/07/22 STABILUS 1           10        10 10                 11:49   1      
##  5 15/07/22 YANFENG              20        10 51                 12:31   1      
##  6 15/07/22 TRMX                 20        20 40                 2:00    1      
##  7 15/07/22 STABILUS 1           10        10 22                 2.44    1      
##  8 15/07/22 YANFENG              12        10 13                 3:00    1      
##  9 15/07/22 YANFENG              32        10 33                 2:12    1      
## 10 15/07/22 YANFENG              50        60 50                 10:59   2      
## # … with 5,400 more rows, and abbreviated variable names ¹​FIN.de.PROCESO,
## #   ²​TIEMPO.CALIDAD
producciontotal$Laminas.procesadas <- as.integer(producciontotal$Laminas.procesadas)
str(producciontotal) 
## 'data.frame':    5410 obs. of  7 variables:
##  $ Fecha             : chr  "15/07/22" "15/07/22" "15/07/22" "15/07/22" ...
##  $ CLIENTE           : chr  "STABILUS 1" "STABILUS 1" "STABILUS 1" "STABILUS 1" ...
##  $ PIEZAS.PROG.      : int  20 10 21 10 20 20 10 12 32 50 ...
##  $ TMO..MIN.         : int  20 15 20 10 10 20 10 10 10 60 ...
##  $ Laminas.procesadas: int  40 13 11 10 51 40 22 13 33 50 ...
##  $ FIN.de.PROCESO    : chr  "10:04" "11:05" "9.57" "11:49" ...
##  $ TIEMPO.CALIDAD    : chr  "1" "1" "1" "1" ...
producciontotal$TIEMPO.CALIDAD <- substr(producciontotal$TIEMPO.CALIDAD, start = 1, stop = 2)
tibble (producciontotal)
## # A tibble: 5,410 × 7
##    Fecha    CLIENTE    PIEZAS.PROG. TMO..MIN. Laminas.procesadas FIN.d…¹ TIEMP…²
##    <chr>    <chr>             <int>     <int>              <int> <chr>   <chr>  
##  1 15/07/22 STABILUS 1           20        20                 40 10:04   1      
##  2 15/07/22 STABILUS 1           10        15                 13 11:05   1      
##  3 15/07/22 STABILUS 1           21        20                 11 9.57    1      
##  4 15/07/22 STABILUS 1           10        10                 10 11:49   1      
##  5 15/07/22 YANFENG              20        10                 51 12:31   1      
##  6 15/07/22 TRMX                 20        20                 40 2:00    1      
##  7 15/07/22 STABILUS 1           10        10                 22 2.44    1      
##  8 15/07/22 YANFENG              12        10                 13 3:00    1      
##  9 15/07/22 YANFENG              32        10                 33 2:12    1      
## 10 15/07/22 YANFENG              50        60                 50 10:59   2      
## # … with 5,400 more rows, and abbreviated variable names ¹​FIN.de.PROCESO,
## #   ²​TIEMPO.CALIDAD
producciontotal$TIEMPO.CALIDAD <- as.integer(producciontotal$TIEMPO.CALIDAD)
str(producciontotal) 
## 'data.frame':    5410 obs. of  7 variables:
##  $ Fecha             : chr  "15/07/22" "15/07/22" "15/07/22" "15/07/22" ...
##  $ CLIENTE           : chr  "STABILUS 1" "STABILUS 1" "STABILUS 1" "STABILUS 1" ...
##  $ PIEZAS.PROG.      : int  20 10 21 10 20 20 10 12 32 50 ...
##  $ TMO..MIN.         : int  20 15 20 10 10 20 10 10 10 60 ...
##  $ Laminas.procesadas: int  40 13 11 10 51 40 22 13 33 50 ...
##  $ FIN.de.PROCESO    : chr  "10:04" "11:05" "9.57" "11:49" ...
##  $ TIEMPO.CALIDAD    : int  1 1 1 1 1 1 1 1 1 2 ...

Convertir formato de la fecha

producciontotal$Fecha <- as.Date(producciontotal$Fecha, format = "%d/%m/%Y")
tibble(producciontotal)
## # A tibble: 5,410 × 7
##    Fecha      CLIENTE    PIEZAS.PROG. TMO..MIN. Laminas.proces…¹ FIN.d…² TIEMP…³
##    <date>     <chr>             <int>     <int>            <int> <chr>     <int>
##  1 0022-07-15 STABILUS 1           20        20               40 10:04         1
##  2 0022-07-15 STABILUS 1           10        15               13 11:05         1
##  3 0022-07-15 STABILUS 1           21        20               11 9.57          1
##  4 0022-07-15 STABILUS 1           10        10               10 11:49         1
##  5 0022-07-15 YANFENG              20        10               51 12:31         1
##  6 0022-07-15 TRMX                 20        20               40 2:00          1
##  7 0022-07-15 STABILUS 1           10        10               22 2.44          1
##  8 0022-07-15 YANFENG              12        10               13 3:00          1
##  9 0022-07-15 YANFENG              32        10               33 2:12          1
## 10 0022-07-15 YANFENG              50        60               50 10:59         2
## # … with 5,400 more rows, and abbreviated variable names ¹​Laminas.procesadas,
## #   ²​FIN.de.PROCESO, ³​TIEMPO.CALIDAD

Convertir variable “Cliente” para análisis descriptivo

producciontotal$CLIENTE<-as.factor(producciontotal$CLIENTE)  
str(producciontotal)
## 'data.frame':    5410 obs. of  7 variables:
##  $ Fecha             : Date, format: "0022-07-15" "0022-07-15" ...
##  $ CLIENTE           : Factor w/ 12 levels "","DENSO","HANON SYSTEMS",..: 6 6 6 6 12 8 6 12 12 12 ...
##  $ PIEZAS.PROG.      : int  20 10 21 10 20 20 10 12 32 50 ...
##  $ TMO..MIN.         : int  20 15 20 10 10 20 10 10 10 60 ...
##  $ Laminas.procesadas: int  40 13 11 10 51 40 22 13 33 50 ...
##  $ FIN.de.PROCESO    : chr  "10:04" "11:05" "9.57" "11:49" ...
##  $ TIEMPO.CALIDAD    : int  1 1 1 1 1 1 1 1 1 2 ...

Identificar valores faltantes

sum(is.na(producciontotal))
## [1] 4283

¿Cuántos NA tengo por variable?

sapply(producciontotal, function(x) sum (is.na(x)))
##              Fecha            CLIENTE       PIEZAS.PROG.          TMO..MIN. 
##                  0                  1                117               1528 
## Laminas.procesadas     FIN.de.PROCESO     TIEMPO.CALIDAD 
##               1227                  0               1410

Reemplazar los registros NA de la tabla con la mediana

Instalar paquetes y librerias necesarias

# install.packages("dplyr")
library(dplyr)
producciontotal<-producciontotal %>% mutate(PIEZAS.PROG.=ifelse(is.na(PIEZAS.PROG.),median(PIEZAS.PROG.,na.rm=T),PIEZAS.PROG.))
producciontotal<-producciontotal %>% mutate(TMO..MIN.=ifelse(is.na(TMO..MIN.),median(TMO..MIN.,na.rm=T),TMO..MIN.))
producciontotal<-producciontotal %>% mutate(laminas_procesadas=ifelse(is.na(Laminas.procesadas),median(Laminas.procesadas,na.rm=T),Laminas.procesadas))
producciontotal<-producciontotal %>% mutate(TIEMPO.CALIDAD=ifelse(is.na(TIEMPO.CALIDAD),median(TIEMPO.CALIDAD,na.rm=T),TIEMPO.CALIDAD))

Verificar la suma de NAs

sum(is.na(producciontotal))
sapply(producciontotal, function(x) sum (is.na(x)))

Omitir los valores irrelevantes identificados

producciontotal <- na.omit(producciontotal)
summary(producciontotal)   
##      Fecha                  CLIENTE      PIEZAS.PROG.    TMO..MIN. 
##  Min.   :0022-07-15   STABILUS 1:1354   Min.   : 1.0   Min.   : 0  
##  1st Qu.:0022-08-03   TRMX      : 704   1st Qu.:14.0   1st Qu.:15  
##  Median :0022-08-19   STABILUS 3: 642   Median :20.0   Median :20  
##  Mean   :0022-08-19   YANFENG   : 506   Mean   :27.8   Mean   :22  
##  3rd Qu.:0022-09-05   DENSO     : 414   3rd Qu.:40.0   3rd Qu.:25  
##  Max.   :0022-09-21   VARROC    : 315   Max.   :99.0   Max.   :90  
##                       (Other)   : 247                              
##  Laminas.procesadas FIN.de.PROCESO     TIEMPO.CALIDAD    laminas_procesadas
##  Min.   : 0.00      Length:4182        Min.   : 0.0000   Min.   : 0.00     
##  1st Qu.: 0.00      Class :character   1st Qu.: 1.0000   1st Qu.: 0.00     
##  Median :20.00      Mode  :character   Median : 1.0000   Median :20.00     
##  Mean   :21.87                         Mean   : 0.9173   Mean   :21.87     
##  3rd Qu.:33.00                         3rd Qu.: 1.0000   3rd Qu.:33.00     
##  Max.   :98.00                         Max.   :25.0000   Max.   :98.00     
## 
sum(is.na(producciontotal))
## [1] 0

Tecnicas Utilizadas Las tecnicas de limpieza utilizadas fueron eliminar columnas irrelevantes para el análisis, cambiar a entero las variables cuantitativas,convertir formato de la fecha, convertir variable “Cliente” para análisis descriptivo, Reemplazar los registros NA de la tabla con la mediana , Verificar la suma de NAs, Omitir los valores irrelevantes identificados.

Exportar base de datos

write.csv(producciontotal,"producciontotal.csv", row.names=FALSE)

En las tablas anteriores se puede observar como el cliente que más piezas programadas tiene, “YANFENG” se le dedica un tiempo de calidad de 1.1 minuto, siendo casi el tiempo mínimo de dedicación. Mientras que el cliente VL-017-1486 es el cliente el cual tiene casi la mitad de piezas programadas que YANFENG sin embargo al que más tiempo se le dedica. Por lo que se puede inferir que sus piezas pudieran ser de mucho márgen de error.

Prediccion de Desempeño de la industria automotriz

Modelo predictivo

Importar la base de datos y entenderla

externa <- read.csv("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/us_motor_production_and_domestic_sales.csv")
summary(externa)
##       Year      Total_Production Production_Passenger_Cars
##  Min.   :2007   Min.   : 5710    Min.   :1924             
##  1st Qu.:2010   1st Qu.: 8709    1st Qu.:2745             
##  Median :2014   Median :10823    Median :3382             
##  Mean   :2014   Mean   :10077    Mean   :3326             
##  3rd Qu.:2017   3rd Qu.:11268    3rd Qu.:4061             
##  Max.   :2020   Max.   :12179    Max.   :4369             
##  NA's   :8      NA's   :8        NA's   :8                
##  Production_Commercial_Vehicles Domestic_Sales  Sales_Passenger_Cars
##  Min.   :3514                   Min.   : 7868   Min.   :2560        
##  1st Qu.:5820                   1st Qu.:10474   1st Qu.:3865        
##  Median :6891                   Median :12583   Median :4542        
##  Mean   :6751                   Mean   :11996   Mean   :4491        
##  3rd Qu.:8095                   3rd Qu.:13669   3rd Qu.:5184        
##  Max.   :8512                   Max.   :14128   Max.   :5610        
##  NA's   :8                      NA's   :8       NA's   :8           
##  Sales_Commercial_Vehicles US_Unemployment US_Consumer_Confidence
##  Min.   : 4309             Min.   :3.680   Min.   :63.75         
##  1st Qu.: 6088             1st Qu.:4.685   1st Qu.:73.02         
##  Median : 7634             Median :5.980   Median :82.83         
##  Mean   : 7505             Mean   :6.430   Mean   :82.29         
##  3rd Qu.: 8964             3rd Qu.:8.088   3rd Qu.:92.67         
##  Max.   :10133             Max.   :9.610   Max.   :98.37         
##  NA's   :8                 NA's   :8       NA's   :8             
##  US_Min_Hour_Wage
##  Min.   :5.500   
##  1st Qu.:7.250   
##  Median :7.250   
##  Mean   :7.025   
##  3rd Qu.:7.250   
##  Max.   :7.250   
##  NA's   :8

Instalar librerias necesarias

library(jtools)       
library(lmtest)      
library(car)          
library(olsrr) 

Realizar regresión 1

regresion <- lm(Production_Commercial_Vehicles ~ US_Unemployment + US_Consumer_Confidence + US_Min_Hour_Wage , data=externa)
summary(regresion)
## 
## Call:
## lm(formula = Production_Commercial_Vehicles ~ US_Unemployment + 
##     US_Consumer_Confidence + US_Min_Hour_Wage, data = externa)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1198.1  -257.4   109.0   286.7   623.0 
## 
## Coefficients:
##                        Estimate Std. Error t value Pr(>|t|)  
## (Intercept)            -2217.25    2387.79  -0.929   0.3750  
## US_Unemployment         -226.91     159.03  -1.427   0.1841  
## US_Consumer_Confidence    82.82      28.06   2.952   0.0145 *
## US_Min_Hour_Wage         514.11     387.30   1.327   0.2139  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 525.3 on 10 degrees of freedom
##   (8 observations deleted due to missingness)
## Multiple R-squared:  0.9082, Adjusted R-squared:  0.8807 
## F-statistic: 32.99 on 3 and 10 DF,  p-value: 1.692e-05

Analizar el comportamiento de las variables independientes en la regresión

effect_plot(regresion,pred=US_Consumer_Confidence,interval=TRUE)

effect_plot(regresion,pred=US_Unemployment,interval=TRUE)

effect_plot(regresion,pred=US_Min_Hour_Wage,interval=TRUE)

Analisis Exploratorio Siendo la Producción de Autos Comerciales la variable dependiente, se puede ver como el salario, la confianza del consumidor y el desempleo generan cambios en ella. Es decir, se observa que la que mayor impacto tiene es la confianza del consumidor debido a que valor p esta abajo del 10%, e incluso se observa su comportamiento en la gráfica como si la producción sube, la confianza del consumidor igual aumenta.

Realizar regresión 2

regresion2 <- lm(Production_Passenger_Cars ~ US_Unemployment + US_Consumer_Confidence + US_Min_Hour_Wage , data=externa)
summary(regresion2)
## 
## Call:
## lm(formula = Production_Passenger_Cars ~ US_Unemployment + US_Consumer_Confidence + 
##     US_Min_Hour_Wage, data = externa)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1096.8  -600.5  -162.9   763.0  1154.1 
## 
## Coefficients:
##                        Estimate Std. Error t value Pr(>|t|)
## (Intercept)            6399.886   4071.397   1.572    0.147
## US_Unemployment        -194.101    271.160  -0.716    0.490
## US_Consumer_Confidence  -22.272     47.840  -0.466    0.652
## US_Min_Hour_Wage          1.058    660.387   0.002    0.999
## 
## Residual standard error: 895.7 on 10 degrees of freedom
##   (8 observations deleted due to missingness)
## Multiple R-squared:  0.09057,    Adjusted R-squared:  -0.1823 
## F-statistic: 0.3319 on 3 and 10 DF,  p-value: 0.8026

Analizar el comportamiento de las variables independientes en la regresión

effect_plot(regresion2,pred=US_Consumer_Confidence,interval=TRUE)

effect_plot(regresion2,pred=US_Unemployment,interval=TRUE)

effect_plot(regresion2,pred=US_Min_Hour_Wage,interval=TRUE)

Analisis Exploratorio A diferencia de la primera variable dependiente, se observa como la producción de autos de pasajero tiene coeficientes negativos en las variables independientes del desempleo y confianza del consumidor por lo tanto su comportamiento en las gráficas a pesar de que exista una producción alta su tendencia va para abajo.

Merma

Importar base de datos

bd <-read.csv ("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/FORM - Merma limpia2.csv")

Analizar base de datos.

summary(bd)
##     Fecha              ENERO             KilosEnero      Fecha1         
##  Length:10          Length:10          Min.   :2680   Length:10         
##  Class :character   Class :character   1st Qu.:2912   Class :character  
##  Mode  :character   Mode  :character   Median :3400   Mode  :character  
##                                        Mean   :3640                     
##                                        3rd Qu.:4128                     
##                                        Max.   :5080                     
##                                        NA's   :6                        
##    FEBRERO           KilosFebrero     Fecha2             MARZO          
##  Length:10          Min.   :3410   Length:10          Length:10         
##  Class :character   1st Qu.:3605   Class :character   Class :character  
##  Mode  :character   Median :3760   Mode  :character   Mode  :character  
##                     Mean   :3805                                        
##                     3rd Qu.:3915                                        
##                     Max.   :4380                                        
##                     NA's   :4                                           
##    KilosMarzo      Fecha3             ABRIL             KilosAbril  
##  Min.   :2980   Length:10          Length:10          Min.   :2950  
##  1st Qu.:3420   Class :character   Class :character   1st Qu.:3690  
##  Median :3905   Mode  :character   Mode  :character   Median :3940  
##  Mean   :3745                                         Mean   :3764  
##  3rd Qu.:4142                                         3rd Qu.:4050  
##  Max.   :4200                                         Max.   :4190  
##  NA's   :4                                            NA's   :5     
##     Fecha4              MAYO             KilosMayo       Fecha5         
##  Length:10          Length:10          Min.   :3680   Length:10         
##  Class :character   Class :character   1st Qu.:4310   Class :character  
##  Mode  :character   Mode  :character   Median :4510   Mode  :character  
##                                        Mean   :4682                     
##                                        3rd Qu.:4770                     
##                                        Max.   :6140                     
##                                        NA's   :5                        
##     JUNIO             KilosJunio      Fecha6             JULIO          
##  Length:10          Min.   :4260   Length:10          Length:10         
##  Class :character   1st Qu.:4312   Class :character   Class :character  
##  Mode  :character   Median :4505   Mode  :character   Mode  :character  
##                     Mean   :4570                                        
##                     3rd Qu.:4762                                        
##                     Max.   :5010                                        
##                     NA's   :6                                           
##    KilosJulio      Fecha7             AGOSTO           KilosAgosto  
##  Min.   :2130   Length:10          Length:10          Min.   :1040  
##  1st Qu.:3920   Class :character   Class :character   1st Qu.:3140  
##  Median :3960   Mode  :character   Mode  :character   Median :3780  
##  Mean   :3874                                         Mean   :3567  
##  3rd Qu.:4130                                         3rd Qu.:4210  
##  Max.   :5230                                         Max.   :5080  
##  NA's   :5                                            NA's   :1     
##     Fecha8           SEPTIEMBRE        KilosSeptiembre
##  Length:10          Length:10          Min.   :2830   
##  Class :character   Class :character   1st Qu.:2995   
##  Mode  :character   Mode  :character   Median :3394   
##                                        Mean   :3396   
##                                        3rd Qu.:3796   
##                                        Max.   :3967   
##                                        NA's   :6
str(bd)
## 'data.frame':    10 obs. of  27 variables:
##  $ Fecha          : chr  "11/01/22" "11/01/22" "22/01/22" "22/01/22" ...
##  $ ENERO          : chr  "Enero" "Enero" "Enero" "Enero" ...
##  $ KilosEnero     : int  5080 3810 2990 2680 NA NA NA NA NA NA
##  $ Fecha1         : chr  "18/02/22" "18/02/22" "18/02/22" "18/02/22" ...
##  $ FEBRERO        : chr  "Febrero" "Febrero" "Febrero" "Febrero" ...
##  $ KilosFebrero   : int  3650 4380 3870 3590 3410 3930 NA NA NA NA
##  $ Fecha2         : chr  "03/03/22" "08/03/22" "11/03/22" "16/03/22" ...
##  $ MARZO          : chr  "Marzo" "Marzo" "Marzo" "Marzo" ...
##  $ KilosMarzo     : int  4000 4190 2980 3290 4200 3810 NA NA NA NA
##  $ Fecha3         : chr  "04/04/22" "11/04/22" "14/04/22" "21/04/22" ...
##  $ ABRIL          : chr  "Abril" "Abril" "Abril" "Abril" ...
##  $ KilosAbril     : int  3940 4190 2950 3690 4050 NA NA NA NA NA
##  $ Fecha4         : chr  "02/05/22" "09/05/22" "14/05/22" "24/05/22" ...
##  $ MAYO           : chr  "Mayo" "Mayo" "Mayo" "Mayo" ...
##  $ KilosMayo      : int  4310 4770 3680 6140 4510 NA NA NA NA NA
##  $ Fecha5         : chr  "07/06/22" "15/06/22" "20/06/22" "27/06/22" ...
##  $ JUNIO          : chr  "Junio" "Junio" "Junio" "Junio" ...
##  $ KilosJunio     : int  4680 4330 5010 4260 NA NA NA NA NA NA
##  $ Fecha6         : chr  "04/07/22" "11/07/22" "16/07/22" "21/07/22" ...
##  $ JULIO          : chr  "Julio" "Julio" "Julio" "Julio" ...
##  $ KilosJulio     : int  5230 2130 4130 3920 3960 NA NA NA NA NA
##  $ Fecha7         : chr  "08/08/22" "10/08/22" "11/08/22" "13/08/22" ...
##  $ AGOSTO         : chr  "Agosto" "Agosto" "Agosto" "Agosto" ...
##  $ KilosAgosto    : int  3140 4210 3140 3780 4240 4200 5080 1040 3270 NA
##  $ Fecha8         : chr  "05/09/22" "07/09/22" "15/09/22" "21/09/22" ...
##  $ SEPTIEMBRE     : chr  "Septiembre" "Septiembre" "Septiembre" "Septiembre" ...
##  $ KilosSeptiembre: int  3050 2830 3967 3739 NA NA NA NA NA NA
describe(bd)
## # A tibble: 9 × 26
##   described_…¹     n    na  mean    sd se_mean   IQR skewn…² kurto…³   p00   p01
##   <chr>        <int> <int> <dbl> <dbl>   <dbl> <dbl>   <dbl>   <dbl> <dbl> <dbl>
## 1 KilosEnero       4     6 3640  1072.    536. 1215   0.992  -0.0431  2680 2689.
## 2 KilosFebrero     6     4 3805   340.    139.  310   0.896   0.938   3410 3419 
## 3 KilosMarzo       6     4 3745   503.    205.  722. -0.806  -1.10    2980 2996.
## 4 KilosAbril       5     5 3764   490.    219.  360  -1.53    2.36    2950 2980.
## 5 KilosMayo        5     5 4682   909.    407.  460   1.13    2.15    3680 3705.
## 6 KilosJunio       4     6 4570   346.    173.  450   0.690  -1.85    4260 4262.
## 7 KilosJulio       5     5 3874  1113.    498.  210  -0.844   2.29    2130 2202.
## 8 KilosAgosto      9     1 3567. 1142.    381. 1070  -1.29    2.76    1040 1208 
## 9 KilosSeptie…     4     6 3396.  543.    271.  801   0.0102 -4.39    2830 2837.
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

Instalar librerias

# install.packages("tidyverse")
#library(tidyverse)
# install.packages("janitor")
#library(janitor)
#library(dplyr)
#library(ggplot2)

Tipos de Variables

Variable<-c("Fecha","ENERO","KilosEnero","Fecha1","FEBRERO","KilosFebrero","Fecha2","MARZO","KilosMarzo","Fecha3","ABRIL","KilosAbril","Fecha4","MAYO","KilosMayo","Fecha5","JUNIO","KilosJunio","Fecha6","JULIO","KilosJulio","Fecha7","AGOSTO","KilosAgosto","Fecha8","SEPTIEMBRE","KilosSeptiembre")
Type<-c("qualitative (nominal)", "qualitative (ordinal)", "quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)","qualitative (nominal)","qualitative (ordinal)","quantitative (discrete)")
table<-data.frame(Variable,Type)
knitr::kable(table)
Variable Type
Fecha qualitative (nominal)
ENERO qualitative (ordinal)
KilosEnero quantitative (discrete)
Fecha1 qualitative (nominal)
FEBRERO qualitative (ordinal)
KilosFebrero quantitative (discrete)
Fecha2 qualitative (nominal)
MARZO qualitative (ordinal)
KilosMarzo quantitative (discrete)
Fecha3 qualitative (nominal)
ABRIL qualitative (ordinal)
KilosAbril quantitative (discrete)
Fecha4 qualitative (nominal)
MAYO qualitative (ordinal)
KilosMayo quantitative (discrete)
Fecha5 qualitative (nominal)
JUNIO qualitative (ordinal)
KilosJunio quantitative (discrete)
Fecha6 qualitative (nominal)
JULIO qualitative (ordinal)
KilosJulio quantitative (discrete)
Fecha7 qualitative (nominal)
AGOSTO qualitative (ordinal)
KilosAgosto quantitative (discrete)
Fecha8 qualitative (nominal)
SEPTIEMBRE qualitative (ordinal)
KilosSeptiembre quantitative (discrete)

Eliminar NA’s y sustituir con 0’s

sum(is.na(bd))
## [1] 42
bd[is.na(bd)]<-0

Eliminar duplicados

bd[duplicated(bd), ]
##  [1] Fecha           ENERO           KilosEnero      Fecha1         
##  [5] FEBRERO         KilosFebrero    Fecha2          MARZO          
##  [9] KilosMarzo      Fecha3          ABRIL           KilosAbril     
## [13] Fecha4          MAYO            KilosMayo       Fecha5         
## [17] JUNIO           KilosJunio      Fecha6          JULIO          
## [21] KilosJulio      Fecha7          AGOSTO          KilosAgosto    
## [25] Fecha8          SEPTIEMBRE      KilosSeptiembre
## <0 rows> (or 0-length row.names)
sum(duplicated(bd))
## [1] 0

Eliminar negativos con cero

bd1<-bd
bd1[bd1 <0] <-0
summary(bd1)
##     Fecha              ENERO             KilosEnero      Fecha1         
##  Length:10          Length:10          Min.   :   0   Length:10         
##  Class :character   Class :character   1st Qu.:   0   Class :character  
##  Mode  :character   Mode  :character   Median :   0   Mode  :character  
##                                        Mean   :1456                     
##                                        3rd Qu.:2912                     
##                                        Max.   :5080                     
##    FEBRERO           KilosFebrero     Fecha2             MARZO          
##  Length:10          Min.   :   0   Length:10          Length:10         
##  Class :character   1st Qu.:   0   Class :character   Class :character  
##  Mode  :character   Median :3500   Mode  :character   Mode  :character  
##                     Mean   :2283                                        
##                     3rd Qu.:3815                                        
##                     Max.   :4380                                        
##    KilosMarzo      Fecha3             ABRIL             KilosAbril  
##  Min.   :   0   Length:10          Length:10          Min.   :   0  
##  1st Qu.:   0   Class :character   Class :character   1st Qu.:   0  
##  Median :3135   Mode  :character   Mode  :character   Median :1475  
##  Mean   :2247                                         Mean   :1882  
##  3rd Qu.:3952                                         3rd Qu.:3878  
##  Max.   :4200                                         Max.   :4190  
##     Fecha4              MAYO             KilosMayo       Fecha5         
##  Length:10          Length:10          Min.   :   0   Length:10         
##  Class :character   Class :character   1st Qu.:   0   Class :character  
##  Mode  :character   Mode  :character   Median :1840   Mode  :character  
##                                        Mean   :2341                     
##                                        3rd Qu.:4460                     
##                                        Max.   :6140                     
##     JUNIO             KilosJunio      Fecha6             JULIO          
##  Length:10          Min.   :   0   Length:10          Length:10         
##  Class :character   1st Qu.:   0   Class :character   Class :character  
##  Mode  :character   Median :   0   Mode  :character   Mode  :character  
##                     Mean   :1828                                        
##                     3rd Qu.:4312                                        
##                     Max.   :5010                                        
##    KilosJulio      Fecha7             AGOSTO           KilosAgosto  
##  Min.   :   0   Length:10          Length:10          Min.   :   0  
##  1st Qu.:   0   Class :character   Class :character   1st Qu.:3140  
##  Median :1065   Mode  :character   Mode  :character   Median :3525  
##  Mean   :1937                                         Mean   :3210  
##  3rd Qu.:3950                                         3rd Qu.:4208  
##  Max.   :5230                                         Max.   :5080  
##     Fecha8           SEPTIEMBRE        KilosSeptiembre
##  Length:10          Length:10          Min.   :   0   
##  Class :character   Class :character   1st Qu.:   0   
##  Mode  :character   Mode  :character   Median :   0   
##                                        Mean   :1359   
##                                        3rd Qu.:2995   
##                                        Max.   :3967

Analisis Profundo de la Base de datos

media_bd5 <- mean(bd$KilosMayo)
media_bd5
## [1] 2341
median_bd5 <- median(bd$KilosMayo)
median_bd5
## [1] 1840
mode_bd5 <- mode(bd$KilosMayo)
mode_bd5
## [1] "numeric"
media_bd8 <- mean(bd$KilosAgosto)
media_bd8
## [1] 3210
median_bd8 <- median(bd$KilosAgosto)
median_bd8
## [1] 3525
mode_bd8 <- mode(bd$KilosAgosto)
mode_bd8
## [1] "numeric"

Grafica Frecuencia (Fecha)

bd$Fecha7<- as.Date(bd$Fecha7,format = "%d/%m/%Y")
plot(bd$Fecha7, bd$KilosAgosto)

Eliminar columnas

bd2 <-bd
bd2 <- subset (bd2, select = -c (Fecha))

Grafica de Mayo & Agosto (Mayor cantidad de merma y registros)

ggplot(bd, aes(x= Fecha4, y= KilosMayo)) + geom_bar(stat="identity", fill="blue") + scale_fill_grey() + labs(title = "Kilos de merma Agosto", x = "Fecha")

ggplot(bd, aes(x= Fecha7, y= KilosAgosto)) + geom_bar(stat="identity", fill="blue") + scale_fill_grey() + labs(title = "Kilos de merma Agosto", x = "Fecha")
## Warning: Removed 1 rows containing missing values (position_stack).

Pronostico de la Industria Automotriz

Instalar paquetes y llamar librerias

#install.packages("forecast")
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo

Sumar el Total de KilosxMes

sum(bd$KilosEnero)
## [1] 14560
sum(bd$KilosFebrero)
## [1] 22830
sum(bd$KilosMarzo)
## [1] 22470
sum(bd$KilosAbril)
## [1] 18820
sum(bd$KilosMayo)
## [1] 23410
sum(bd$KilosJunio)
## [1] 18280
sum(bd$KilosJulio)
## [1] 19370
sum(bd$KilosAgosto)
## [1] 32100
sum(bd$KilosSeptiembre)
## [1] 13586

Crear serie de tiempo

merma <- c(14560,22830,22470,18820,23410,18280,19370,32100,13586)

produccion_st <- ts(data = merma, start = c(2022,1), frequency = 12)
produccion_st
##        Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep
## 2022 14560 22830 22470 18820 23410 18280 19370 32100 13586

Graficar Pronostico

modelo <- auto.arima(produccion_st)
modelo
## Series: produccion_st 
## ARIMA(0,0,0) with non-zero mean 
## 
## Coefficients:
##            mean
##       20602.889
## s.e.   1736.893
## 
## sigma^2 = 30544665:  log likelihood = -89.8
## AIC=183.59   AICc=185.59   BIC=183.99
pronostico <- forecast(modelo, level=c(95), h=3)
pronostico
##          Point Forecast    Lo 95    Hi 95
## Oct 2022       20602.89 9770.711 31435.07
## Nov 2022       20602.89 9770.711 31435.07
## Dec 2022       20602.89 9770.711 31435.07
plot(pronostico)

Tecnicas Utilizadas Para la elaboracion de este analisis fue necesario utilizar ciertas tecnicas de limpieza antes, como ser, Eliminar NA’s y sustituir con 0’s, Eliminar duplicados,Eliminar negativos con cero, Eliminar columnas. Todas las tecnicas mencionadas anteriormente son utilizadas para poder obtener un analisis mas preciso eliminando informacion que no aporta a la realizacion de este.

Como se puede obervar en la grafica de pronostico,

Scrap

Importar base de datos

bd <- read.csv ("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/FORM - Scrap Limpia  (2).csv")

Tipos de Variables Existentes

variable<-c("Referencia","Fecha", "Hora", "Producto", "Cantidad", "Unidad.de.medida", "Ubicación.de.origen", "Ubicación.de.desecho", "Estado")

type<-c("Cualitativo (nominal)","Cuantitativo (disccreta)", "Cuantitativo (discreta)", "Cualitativo (nominal)","Cuantitativo (Continua)", "Cualitativo (nominal)", "Cualitativo (nominal)","Cualitativo (nominal)","Cualitativo (nominal)")

Escala_de_Medición<-c("Numero", "Fecha", "Categoría", "Kg", "Medición", "Posición", "Posición", "Estado")


table<-data.frame(variable,type)
knitr::kable(table)
variable type
Referencia Cualitativo (nominal)
Fecha Cuantitativo (disccreta)
Hora Cuantitativo (discreta)
Producto Cualitativo (nominal)
Cantidad Cuantitativo (Continua)
Unidad.de.medida Cualitativo (nominal)
Ubicación.de.origen Cualitativo (nominal)
Ubicación.de.desecho Cualitativo (nominal)
Estado Cualitativo (nominal)

Cantidad de productos por día

bd$Fecha<- as.Date(bd$Fecha,format = "%d/%m/%Y")
plot(bd$Fecha, bd$Cantidad)

summary(bd)
##   Referencia            Fecha                Hora             Producto        
##  Length:250         Min.   :2022-08-01   Length:250         Length:250        
##  Class :character   1st Qu.:2022-08-11   Class :character   Class :character  
##  Mode  :character   Median :2022-08-19   Mode  :character   Mode  :character  
##                     Mean   :2022-08-17                                        
##                     3rd Qu.:2022-08-25                                        
##                     Max.   :2022-08-31                                        
##     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  
##                    
##                    
## 
#library(tidyverse)
#library(janitor)

Número de variables y registros en base de datos

#install.packages("psych")
library(psych)
#describe(bd)
str(bd)
## 'data.frame':    250 obs. of  9 variables:
##  $ Referencia          : chr  "SP/08731" "SP/08730" "SP/08729" "SP/08728" ...
##  $ Fecha               : Date, format: "2022-08-31" "2022-08-31" ...
##  $ 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" ...
#tabyl(bd, Producto, Ubicación.de.origen)

Tipos de Variables Existentes

variable<-c("Referencia","Fecha", "Hora", "Producto", "Cantidad", "Unidad.de.medida", "Ubicación.de.origen", "Ubicación.de.desecho")

type<-c("Cualitativo (nominal)","Cuantitativo (disccreta)", "Cuantitativo (discreta)", "Cualitativo (nominal)","Cuantitativo (Continua)", "Cualitativo (nominal)", "Cualitativo (nominal)","Cualitativo (nominal)")

table<-data.frame(variable,type)
knitr::kable(table)
variable type
Referencia Cualitativo (nominal)
Fecha Cuantitativo (disccreta)
Hora Cuantitativo (discreta)
Producto Cualitativo (nominal)
Cantidad Cuantitativo (Continua)
Unidad.de.medida Cualitativo (nominal)
Ubicación.de.origen Cualitativo (nominal)
Ubicación.de.desecho Cualitativo (nominal)

Limpieza de datos

## Eliminar columnas que no se usan  

bd1 <- bd
bd1<- subset(bd1, select = -c (Referencia, Producto, Unidad.de.medida, Hora, Ubicación.de.desecho, Estado))

## Borrar N/A's 

Tecnicas Utilizadas Eliminar columnas innecesarias para facilitar el analisis con datos relevantes. Borrar NA’s ya que no dicen informacion relevante para el analisis.

bd2 <- bd
bd2<- subset(bd2, select = -c (Referencia, Producto, Unidad.de.medida, Hora, Ubicación.de.desecho, Estado))

media <- mean(bd2$Cantidad)

mediana <- median(bd2$Cantidad)

mode <- function (x) {
  ux <- unique(x)
  ux [which.max(tabulate(match(x,ux)))]
}

mode <- mode(bd2$Cantidad)
mode
## [1] 1
hist(bd2$Cantidad)

ggplot(bd2, aes(x=media, y= Ubicación.de.origen)) +
  geom_bar(stat="identity", fill="red") + scale_fill_grey() + # Add bars to the plot
  labs(title = "Scrap empresa FORM", # Add a title
       subtitle = "", # Add a subtitle
       caption = "Relación", # Add a caption
       x = "Toneladas")

Analisis Exploratorio A traves de analisis realizado, se peude obervar en el grafico que el área donde más se genera desperdicio es en SAB/Pre-Production con al rededor de 1200 toneladas. Este es un insight muy interesante ya que se logra identificar de donde viene la mayoria de desperdicio y se puede realizar un contraste con las otras areas las cuales es muy significativa la diferencia. A raiz de esto se pueden comenzar a pensar estrategias para implementar dentro del area de SAB/Pre-Production las cuales beneficiarian a Form con la disminucion de desperdicio.

Seccion 3: K-means clustering

Definición de conceptos Conceptos que contribuyen a la identificación de clusters usando analítica de datos.

I. K- Means Clustering
K- means clustering tiene como objetivo agrupar datos con características similares en el mismo cluster. Uno de los beneficios más grandes de la herramienta es que se pueden resumir datos de gran dimensión.

II. Unsupervised Learning
No se asignan etiquetas al algoritmo de aprendizaje, dejándolo solo para encontrar la estructura en su entrada. El aprendizaje no supervisado puede ser un fin en sí mismo (descubrir patrones ocultos en los datos) o un medio para un fin (aprendizaje de funciones).

III. Eucliedean Distance
La distancia Euclidiana es el cálculo de distancia comúnmente utilizado para medir la distancia entre dos puntos de datos.

K-means Clusters

Instalar librerias

library(foreign)
library(dplyr)        # data manipulation 
library(ggplot2)      # data visualization 
#install.packages("psych")
library(psych)        # functions for multivariate analysis 
library(corrplot)     # correlation plots
#install.packages("jtools")
library(jtools)       # presentation of regression analysis 
library(lmtest)       # diagnostic checks - linear regression analysis 
library(car)          # diagnostic checks - linear regression analysis
library(factoextra)   # provides functions to extract and visualize the output of exploratory multivariate data analyses
#install.packages("ggfortify")
library(ggfortify)    # data visualization tools for statistical analysis results
library(plyr)
library(base)
library(tibble)

Cluster edad y salario diario Leer la base de datos

bajasdata <-read.csv("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/RHBAJASLIMPIA1.csv")
summary(bajasdata)
##     nombre               edad          genero           fecha_alta       
##  Length:237         Min.   : 0.00   Length:237         Length:237        
##  Class :character   1st Qu.:23.00   Class :character   Class :character  
##  Mode  :character   Median :29.00   Mode  :character   Mode  :character  
##                     Mean   :30.52                                        
##                     3rd Qu.:37.00                                        
##                     Max.   :61.00                                        
##  motivo_baja        dias_laborados     fecha_baja           puesto         
##  Length:237         Min.   :   0.00   Length:237         Length:237        
##  Class :character   1st Qu.:   9.00   Class :character   Class :character  
##  Mode  :character   Median :  21.00   Mode  :character   Mode  :character  
##                     Mean   :  83.42                                        
##                     3rd Qu.:  49.00                                        
##                     Max.   :1966.00                                        
##     sal_imss       colonia           municipio            estado         
##  Min.   :144.4   Length:237         Length:237         Length:237        
##  1st Qu.:180.7   Class :character   Class :character   Class :character  
##  Median :180.7   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :178.6                                                           
##  3rd Qu.:180.7                                                           
##  Max.   :500.0                                                           
##  estado_civil      
##  Length:237        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Limpieza. Seleccionar variables relevantes

bajasdata1<-bajasdata
bajasdata1<-subset(bajasdata,select = -c(genero,fecha_alta,motivo_baja,puesto,estado,nombre,colonia,municipio,motivo_baja, estado_civil, dias_laborados, fecha_baja))
summary(bajasdata1)
##       edad          sal_imss    
##  Min.   : 0.00   Min.   :144.4  
##  1st Qu.:23.00   1st Qu.:180.7  
##  Median :29.00   Median :180.7  
##  Mean   :30.52   Mean   :178.6  
##  3rd Qu.:37.00   3rd Qu.:180.7  
##  Max.   :61.00   Max.   :500.0

Limpieza. Eliminar edad 0

bajasdata2 <- bajasdata1
bajasdata2<-bajasdata1[-c(97,149),]

Normalizar la base de datos

bajas_data_norm <- scale(bajasdata2[1:2])

Identificar número de clusters

fviz_nbclust(bajas_data_norm, kmeans, method="wss")+ 
  geom_vline(xintercept=4, linetype=2)+           
  labs(subtitle = "Elbow method")    

Visualizar el cluster

edad_cluster1<-kmeans(bajas_data_norm,3)
edad_cluster1
## K-means clustering with 3 clusters of sizes 69, 121, 45
## 
## Cluster means:
##         edad   sal_imss
## 1  0.2811317  0.2784633
## 2 -0.7792176 -0.1288413
## 3  1.6641609 -0.0805373
## 
## Clustering vector:
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
##   1   1   2   2   2   3   2   2   3   2   2   1   2   1   1   2   2   2   2   2 
##  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40 
##   2   3   2   1   3   2   1   2   2   2   1   2   2   2   1   2   2   2   1   2 
##  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60 
##   2   2   2   2   2   2   2   2   3   3   3   3   1   3   2   2   3   2   2   3 
##  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 
##   2   2   1   2   2   3   2   2   2   2   2   2   1   2   1   2   1   2   2   3 
##  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  98  99 100 101 
##   2   2   2   2   3   2   3   2   2   2   1   3   3   2   2   2   3   2   2   1 
## 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 
##   2   2   3   1   2   2   1   2   1   1   2   1   1   2   1   1   1   3   3   3 
## 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 
##   2   2   2   2   2   1   2   1   3   2   1   2   3   2   2   2   1   3   1   3 
## 142 143 144 145 146 147 148 150 151 152 153 154 155 156 157 158 159 160 161 162 
##   1   1   1   3   3   2   1   1   1   2   2   2   1   3   3   2   1   2   1   3 
## 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 
##   3   3   3   1   3   2   2   1   2   2   3   1   3   2   3   1   1   3   1   1 
## 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 
##   2   2   2   1   3   3   1   2   2   1   1   1   1   1   1   1   1   2   1   2 
## 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 
##   1   1   2   1   3   1   2   2   2   3   2   2   2   1   1   2   2   1   1   1 
## 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 
##   2   2   1   2   2   2   2   3   1   3   2   2   2   2   2 
## 
## Within cluster sum of squares by cluster:
## [1] 204.19421  35.55499  17.05330
##  (between_SS / total_SS =  45.1 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
fviz_cluster(edad_cluster1,data=bajas_data_norm)

Analisis Profundo del Cluster

bajasdata3<- bajasdata2
bajasdata3$Clusters<-edad_cluster1$cluster
bajasdata4<-bajasdata3 %>% group_by(Clusters) %>% summarise(edad=max(edad)) %>% arrange(desc(edad))
bajasdata3$Cluster_Names<-factor(bajasdata3$Clusters,levels = c(1,2,3), 
                                 labels=c("Jubilación", "Joven", "Adulto"))
bajasdata5 <- bajasdata3 %>% dplyr:: group_by(Cluster_Names) %>% dplyr:: summarize(edad_anos=max(edad), 
                                                             sal_imss=mean(sal_imss),
                                                             count=n())
clusters<-as.data.frame(bajasdata5)
clusters
##   Cluster_Names edad_anos sal_imss count
## 1    Jubilación        40 185.7365    69
## 2         Joven        32 175.3303   121
## 3        Adulto        61 176.5644    45

Gráfico de barras de las bajas con edad máxima de cluster

ggplot(bajasdata5, aes(x=Cluster_Names,y=edad_anos,fill= Cluster_Names,label=round(edad_anos,digits=2))) + 
  geom_col() + 
  geom_text()

Gráfico de barras de las bajas con su salario

ggplot(bajasdata5,aes(x=Cluster_Names,y=sal_imss ,fill= Cluster_Names,label=round(sal_imss,digits=2))) + 
  geom_col() +  
  geom_text()

Dispersión de la edad

ggplot(bajasdata3, aes(x=Cluster_Names, y=edad, fill=Cluster_Names)) +
  geom_boxplot()+
  ggtitle("Dispersion of 'Edad' by Clusters Names")

Dispersión del salario diario

ggplot(bajasdata3, aes(x=Cluster_Names, y=sal_imss, fill=Cluster_Names)) +
  geom_boxplot()+
  ggtitle("Dispersion of 'Salario_Diario' by Clusters Names")

Cluster edad y días laborados

RHBAJAS <-read.csv("/Users/andreapaolasosa/Library/CloudStorage/OneDrive-InstitutoTecnologicoydeEstudiosSuperioresdeMonterrey/RHBAJASLIMPIA1.csv")

Analizar base de datos

summary(RHBAJAS)
##     nombre               edad          genero           fecha_alta       
##  Length:237         Min.   : 0.00   Length:237         Length:237        
##  Class :character   1st Qu.:23.00   Class :character   Class :character  
##  Mode  :character   Median :29.00   Mode  :character   Mode  :character  
##                     Mean   :30.52                                        
##                     3rd Qu.:37.00                                        
##                     Max.   :61.00                                        
##  motivo_baja        dias_laborados     fecha_baja           puesto         
##  Length:237         Min.   :   0.00   Length:237         Length:237        
##  Class :character   1st Qu.:   9.00   Class :character   Class :character  
##  Mode  :character   Median :  21.00   Mode  :character   Mode  :character  
##                     Mean   :  83.42                                        
##                     3rd Qu.:  49.00                                        
##                     Max.   :1966.00                                        
##     sal_imss       colonia           municipio            estado         
##  Min.   :144.4   Length:237         Length:237         Length:237        
##  1st Qu.:180.7   Class :character   Class :character   Class :character  
##  Median :180.7   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :178.6                                                           
##  3rd Qu.:180.7                                                           
##  Max.   :500.0                                                           
##  estado_civil      
##  Length:237        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 
str(RHBAJAS)
## 'data.frame':    237 obs. of  13 variables:
##  $ nombre        : chr  "MARIO VALDEZ ORTIZ" "ISABEL BARRIOS MENDEZ" "MARIA ELIZABETH GOMEZ HERNANDEZ" "ALONDRA ABIGAIL ESCARCIA GOMEZ" ...
##  $ edad          : int  32 36 23 21 29 46 29 31 50 19 ...
##  $ genero        : chr  "MASCULINO" "FEMENINO" "FEMENINO" "FEMENINO" ...
##  $ fecha_alta    : chr  "09/03/20" "09/11/21" "10/11/21" "10/11/21" ...
##  $ motivo_baja   : chr  "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" "RENUNCIA VOLUNTARIA" ...
##  $ dias_laborados: int  628 60 59 59 51 37 37 31 18 224 ...
##  $ fecha_baja    : chr  "27/11/21" "08/01/22" "08/01/22" "08/01/22" ...
##  $ puesto        : chr  "DISEÑO" "AYUDANTE GENERAL" "AYUDANTE GENERAL" "AYUDANTE GENERAL" ...
##  $ sal_imss      : num  500 152 152 152 152 ...
##  $ colonia       : chr  "SAN NICOLAS DE LOS G" "COLINAS DEL AEROPÑUERTO" "PUEBLO NUEVO" "PUEBLO NUEVO" ...
##  $ municipio     : chr  "SAN NICOLAS DE LOS G" "PESQUERIA" "APODACA" "APODACA" ...
##  $ estado        : chr  "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" "NUEVO LEÓN" ...
##  $ estado_civil  : chr  "SOLTERO" "UNIÓN LIBRE" "CASADO" "SOLTERO" ...
describe(RHBAJAS)
## # A tibble: 3 × 26
##   described_…¹     n    na  mean    sd se_mean   IQR skewn…² kurto…³   p00   p01
##   <chr>        <int> <int> <dbl> <dbl>   <dbl> <dbl>   <dbl>   <dbl> <dbl> <dbl>
## 1 edad           237     0  30.5  10.0   0.651    14   0.541   0.216    0    18 
## 2 dias_labora…   237     0  83.4 227.   14.7      40   5.40   33.2      0     0 
## 3 sal_imss       237     0 179.   25.4   1.65      0   9.51  115.     144.  152.
## # … with 15 more variables: p05 <dbl>, p10 <dbl>, p20 <dbl>, p25 <dbl>,
## #   p30 <dbl>, p40 <dbl>, p50 <dbl>, p60 <dbl>, p70 <dbl>, p75 <dbl>,
## #   p80 <dbl>, p90 <dbl>, p95 <dbl>, p99 <dbl>, p100 <dbl>, and abbreviated
## #   variable names ¹​described_variables, ²​skewness, ³​kurtosis

Edad vs dias laborados-Clusters

RHBAJAS1<-RHBAJAS
RHBAJAS1<-subset(RHBAJAS1,select = -c(genero,fecha_alta,motivo_baja,puesto,estado,nombre,colonia,municipio,fecha_baja))
summary(RHBAJAS1)
##       edad       dias_laborados       sal_imss     estado_civil      
##  Min.   : 0.00   Min.   :   0.00   Min.   :144.4   Length:237        
##  1st Qu.:23.00   1st Qu.:   9.00   1st Qu.:180.7   Class :character  
##  Median :29.00   Median :  21.00   Median :180.7   Mode  :character  
##  Mean   :30.52   Mean   :  83.42   Mean   :178.6                     
##  3rd Qu.:37.00   3rd Qu.:  49.00   3rd Qu.:180.7                     
##  Max.   :61.00   Max.   :1966.00   Max.   :500.0

Eliminar renglones Eliminamos dos reglones que tenian como edad (0)

RHBAJAS2 <- RHBAJAS1
RHBAJAS2 <- RHBAJAS2 [RHBAJAS2$edad> min(1), ]
summary(RHBAJAS2)
##       edad       dias_laborados       sal_imss     estado_civil      
##  Min.   :18.00   Min.   :   0.00   Min.   :144.4   Length:235        
##  1st Qu.:23.00   1st Qu.:   9.50   1st Qu.:180.7   Class :character  
##  Median :29.00   Median :  21.00   Median :180.7   Mode  :character  
##  Mean   :30.78   Mean   :  84.07   Mean   :178.6                     
##  3rd Qu.:37.00   3rd Qu.:  49.50   3rd Qu.:180.7                     
##  Max.   :61.00   Max.   :1966.00   Max.   :500.0

Normalizar la base de datos

RH_EDAD_NORM<-scale(RHBAJAS2[1:2])

Se visualizan el # correcto de clusters a realizar

fviz_nbclust(RH_EDAD_NORM, kmeans, method="wss")+ 
  geom_vline(xintercept=4, linetype=2)+         
  labs(subtitle = "Elbow method") 

Visualizar el cluster

RHEDAD_Cluster1<-kmeans(RH_EDAD_NORM,4)
RHEDAD_Cluster1
## K-means clustering with 4 clusters of sizes 43, 107, 5, 80
## 
## Cluster means:
##         edad dias_laborados
## 1  1.6031879    -0.11611923
## 2 -0.8512555    -0.17238996
## 3  1.2245019     5.86438920
## 4  0.2003094    -0.07353867
## 
## Clustering vector:
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
##   4   4   2   2   4   1   4   4   1   2   2   4   2   4   4   2   2   2   2   2 
##  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40 
##   4   3   2   4   1   2   4   2   2   2   4   2   2   2   4   2   2   4   4   2 
##  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60 
##   2   2   2   2   2   2   2   2   1   1   1   1   4   1   2   2   1   2   2   3 
##  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 
##   2   2   4   2   2   1   2   2   4   2   2   2   4   2   4   2   4   2   2   1 
##  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  98  99 100 101 
##   3   2   2   4   1   2   1   2   2   2   4   1   1   2   2   4   1   4   2   4 
## 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 
##   2   2   1   4   2   2   4   3   4   4   2   4   4   2   4   4   4   1   1   1 
## 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 
##   2   2   2   2   2   4   2   4   1   2   4   2   1   2   4   2   4   1   4   1 
## 142 143 144 145 146 147 148 150 151 152 153 154 155 156 157 158 159 160 161 162 
##   4   4   1   1   1   2   4   4   4   2   2   2   4   1   1   2   4   2   4   1 
## 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 
##   1   1   1   4   1   2   2   4   2   2   1   4   1   2   1   4   4   1   4   4 
## 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 
##   2   2   2   4   1   3   4   2   2   4   4   4   4   4   4   4   4   2   4   4 
## 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 
##   4   4   2   4   1   4   2   2   2   1   2   2   2   4   4   2   2   4   4   4 
## 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 
##   2   2   4   2   2   2   4   1   4   1   2   2   2   2   2 
## 
## Within cluster sum of squares by cluster:
## [1] 19.40753 15.18543 18.67351 39.82387
##  (between_SS / total_SS =  80.1 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"
fviz_cluster(RHEDAD_Cluster1,data=RH_EDAD_NORM)

RHEDAD_Cluster1<-kmeans(RH_EDAD_NORM,4)
RHEDAD_Cluster1
## K-means clustering with 4 clusters of sizes 9, 111, 42, 73
## 
## Cluster means:
##         edad dias_laborados
## 1  0.9666914      4.3546434
## 2 -0.8318852     -0.1350561
## 3  1.5964199     -0.1776331
## 4  0.2272521     -0.2293147
## 
## Clustering vector:
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
##   1   4   2   2   4   3   4   4   3   2   2   4   2   4   4   2   2   2   2   2 
##  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40 
##   4   1   2   4   3   2   4   2   2   2   4   2   2   2   4   2   2   2   4   2 
##  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60 
##   2   2   2   2   2   2   2   2   3   3   3   3   1   3   2   2   3   2   2   1 
##  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 
##   2   2   4   2   2   3   2   2   2   2   2   2   4   2   4   2   4   2   2   3 
##  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  98  99 100 101 
##   1   2   2   2   3   2   3   2   2   2   4   3   3   2   2   4   3   4   2   4 
## 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 
##   2   2   3   4   2   2   4   1   4   4   2   4   4   2   4   4   4   3   3   3 
## 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 
##   2   2   2   2   2   4   2   4   3   2   4   2   1   2   2   2   4   3   4   3 
## 142 143 144 145 146 147 148 150 151 152 153 154 155 156 157 158 159 160 161 162 
##   4   4   3   3   3   2   4   4   4   2   2   2   4   3   3   2   4   2   4   3 
## 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 
##   3   3   3   4   3   2   2   4   2   2   3   4   3   2   3   4   4   3   4   4 
## 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 
##   2   2   2   4   3   1   4   2   2   4   4   4   4   4   1   4   4   2   4   4 
## 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 
##   4   4   2   4   3   4   2   2   2   3   2   2   2   4   4   2   2   4   4   4 
## 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 
##   2   2   4   2   2   2   4   3   4   3   2   2   2   2   2 
## 
## Within cluster sum of squares by cluster:
## [1] 47.52052 21.82479 12.49099 12.27335
##  (between_SS / total_SS =  79.9 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Visualizacion del Cluster

fviz_cluster(RHEDAD_Cluster1,data=RH_EDAD_NORM)

Analisis Profundo del Cluster

RHBAJAS3 <- RHBAJAS2
RHBAJAS3$Clusters<-RHEDAD_Cluster1$cluster
RHBAJAS4<-RHBAJAS3 %>% group_by(Clusters) %>% summarise(edad=max(edad)) %>% arrange(desc(edad))
RHBAJAS3$Cluster_Names<-factor(RHBAJAS3$Clusters,levels = c(1,2,3,4), 
                                 labels=c("Adulto", "Principiante", "Mayor", "Juvenil"))
RHBAJAS6 <- RHBAJAS3 %>% group_by(Cluster_Names) %>% dplyr:: summarize(edad_anos=max(edad), 
dias_laborados=mean(dias_laborados),
Count=n())
clusters<-as.data.frame(RHBAJAS6)
clusters
##   Cluster_Names edad_anos dias_laborados Count
## 1        Adulto        61     1075.77778     9
## 2  Principiante        28       53.31532   111
## 3         Mayor        57       43.61905    42
## 4       Juvenil        39       31.84932    73

Analisis de Datos del cluster expresados por graficas

ggplot(RHBAJAS6,aes(x=reorder(Cluster_Names,Count),y=Count,fill=Cluster_Names)) +
  geom_bar(stat="identity")

Edades (maximas), al igual se puede realizar con un (barplot)

ggplot(RHBAJAS6, aes(x=Cluster_Names,y=edad_anos,fill= Cluster_Names,label=round(edad_anos,digits=2))) + 
  geom_col() + 
  geom_text()

Dias laborados (Maximos)

ggplot(RHBAJAS6,aes(x=Cluster_Names,y=dias_laborados,fill= Cluster_Names,label=round(dias_laborados,digits=2))) + 
  geom_col() + 
  geom_text()

Grafica de Boxplot (Analisis de las edades de los 4 grupos.)

ggplot(RHBAJAS3, aes(x=Cluster_Names, y=edad, fill=Cluster_Names)) +
  geom_boxplot()+
  ggtitle("Edad (Dispersion)")

Hallazgos identificacos K-Means

Durante esta actividad realizamos un análisis en la base de datos de Recursos Humanos, enfocados en las variables de Edad, Salario y Días Trabajados, por lo que se decidió definir varios pasos a seguir para llegar al objetivo deseado que era finalmente llegar a la construcción de los clusters.

Tomando en cuenta los hallazgos de la edad y el salario diario, se llego a la conclusión de lo siguiente:

  1. Hay más bajas de adultos con el rango de edades de 41 a 61, el cuál se identifico como jubilación.

  2. Los adultos de 33-40 años ganan más con un sueldo diario de 186.16 en promedio.

De igual manera podemos observar cuatro Clusters que toman en cuenta la edad y los días laborados:

  1. El Cluster Rojo “Adulto” es un grupo en el cual se observa que son las personas de edad alta y con una característica en común que es que duran poco tiempo laborando en la empresa.
  2. El Cluster Azul “Mayor” es el Cluster que más se aparta de los demás Clusters debido a que son personas con mayor rango de edad y la mayor parte de los empleados cuentan con esta edad.
  3. El Cluster Morado “Juvenil” donde se encuentran las personas con un rango de edad de entre 30 y 36 años, habiendo más personas en el rango de los 30 a 32 años,
  4. El Cluster Verde “Principiante” es el grupo de personas más jóvenes en la empresa, con un rango de entre 20 y 30 años.

El grupo que cuenta con más días laborados es el de edad máxima, siendo los adultos, de igual manera estos cuentan con un salario mayor.
Por último podemos observar que en los gráficos que se analizan con estas variables tenemos los siguientes puntos a consideración:
- Edad Máxima
- Días Laborados Máximos
- Recuento de los grupos que presentan mayor actividad en la empresa.
- La dispersión de edad que existe entre cada uno de los grupos.

Seccion 4

A partir del análisis de las bases de datos de las diferentes áreas de la empresa FORM, identificar y describir los principales 6-8 hallazgos (meaningful insights). A través de los diferentes análisis realizados en las diferentes bases de datos se pudieron obtener hallazgos importantes entre ellos, algunos importantes a destacar son: Analizando la base de datos de RH se pudo observar que hay una alta rotación de personal. Esto es importante mencionar ya que puede afectar a la productividad de la empresa, es por eso que se debe ver con más detalle esta observación y analizar la raíz de lo que está causando la rotación. En la base de datos de delivery plan se pudo obtener cuál fue el cliente con mayor importancia que en este caso fue “Hella” ya que cuenta con el mayor número de unidades y outliers por encima de la media. En cuanto a la base de delivery performance, se pudieron obtener ciertos hallazgos de gran interés. Por ejemplo, Mahle es el cliente con mayores retrasos en cuanto a los tiempos de entrega. Printel es el cliente con el cual siempre se mantienen dentro de los tiempos deseables, que en este caso sería, debajo de los 30 minutos. En la base de producción se identificó que el cliente “Yanfeng” es al cual se le dedica menos tiempo en calidad, lo cual podría ser un riesgo para Form ya que da espacio a un margen más elevado de error. Se identificó que hay una alta cantidad de desperdicio que podría ser utilizada para una nueva fuente de ingreso. Este insight puede ser transformado en una estrategia ya que uno de los principales objetivos es darle un nuevo uso a la merma.

A partir del análisis de las bases de datos de las diferentes áreas de laempresa FORM, describir 3 sugerencias que le permitan al socio formador mejorar su proceso de captura, organización, y analítica de datos. Contar con bases de datos más organizadas y con formato. Esto para facilitar el análisis de los datos y poder obtener muchos más insights de los que se podrían obtener con sus bases actuales y de manera más rápida.

Poner atencion a la parte de Recursos Humanos y la alta rotacion de empleados y tambien que la mayoria son empleados jovenes. Investigar si estos dos factores se relacionan y emplear acciones de retencion de capital humano.

Abrir un departamento de business analytics e intelligence y tener a una persona que se dedique a realizar pronosticos y predicciones que pueden ayudar a determinar comportamientos a futuro. Esto puede ser de gran utilidad para Form para ayudar a identificar areas de mejora y oportunidades de crecimiento y ahorro. Asi mismo puede ayudar a prevenir errores a futuro.

Describir con tus propias palabras los términos Business Analytics and Business Intelligence. Así también, identificar y describir 3 principales diferencias entre Business Analytics y Business Intelligence. Ambas herramientas son utilizadas para el procesamiento de datos y para poder llevar a cabo análisis estadísticos, sin embargo existe una diferencia entre los dos conceptos aunque puedan sonar similares. Business analytics hace referencia a las herramientas que se utilizan al momento de realizar ciertas actividades como el análisis predictivo, facilitando realizar predicciones utilizando como estructura principal los datos analizados. Ayuda a la toma de decisiones dentro de una organización. Business Intelligence, se aplica al análisis de datos y negocios lo cual facilita la toma de decisiones dentro de una empresa. Gracias a Business Intelligence se pueden crear objetivos orientados a las necesidades primordiales de la empresa, siendo mucho más precisas y basadas en datos concretos y no en suposiciones.

3 Diferencias: La diferencia principal entre estas dos herramientas se basa en el enfoque que tiene cada una. Business Analytics es mas análisis estadístico, modelos predictivos y tendencias para poder desarrollar pronósticos de comportamientos a futuro.

Business Intelligence se encarga más de analizar la información y a partir de ella poder tomar decisiones.

Business Analytics se encarga de resolver problemas dentro de una organización antes de que estos ocurran, previniendo pérdidas.

Describir con tus propias palabras el concepto de Indicador Clave de Rendimiento / Key Performance Indicators Los Kpis son indicadores dentro de una empresa que facilitan medir el desempeño de los colaboradores y de la organización. Indica el nivel de rendimiento que se está obteniendo y ayuda a identificar en qué áreas se debe reforzar el enfoque.

A partir del análisis de las bases de datos de las diferentes áreas de la empresa FORM, proponer y describir 3 posibles KPIs que permitan evaluar el desempeño de algunas de sus áreas tasa de pedidos entregados a tiempo(30 min): medir que todos los pedidos sean entregados dentro del tiempo establecido es decir 30 minnutos y prestar atencion a los que estan causando retrasos e investigar la causa de ellos. Esto aumentaria la cantidad de entregas por dia lo cual generaria mayor rentabilidad. tasa de rotación de empleados: medir la tasa de rotacion de empelados y analizar de que manera se puede crear mayor retencion. Impartir capacitaciones tasa de desperdicio: Medir la cantidad de desperdicio generada, de esta manera con los datos precisos, poder buscar alternativas de que se puede hacer con la materia sobrante.

Bibliografia: Escobar, J. (2021, October 26). Business Analytics vs Business Intelligence ¿cuál es la diferencia? Egade.tec.mx; EGADE Insights. https://blog.egade.tec.mx/business-analytics-vs-business-intelligence-diferencias

Grupo Bit. (2022). ¿Cuál es la diferencia entre Business Intelligence y Business Analytics? Grupobit.net. https://business-intelligence.grupobit.net/blog/cual-es-la-diferencia-entre-business-intelligence-y-business-analytics

LS0tCnRpdGxlOiAiRXZpZGVuY2lhIDIiCmF1dGhvcjogIkFuZHJlYSBQYW9sYSBTb3NhIEEwMDgyNzM1OSIKZGF0ZTogIjIwMjItMTAtMTIiCm91dHB1dDoKICAgIGh0bWxfZG9jdW1lbnQ6CiAgICAgIHRvYzogdHJ1ZQogICAgICB0b2NfZmxvYXQ6IHRydWUgCiAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgo8aW1nIHNyYz0gIi9Vc2Vycy9hbmRyZWFwYW9sYXNvc2EvRG93bmxvYWRzL2Zvcm1mb3RvLnBuZyI+CgojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOm9yYW5nZSI+IExpbXBpZXphLCBUcmFuc2Zvcm1hY2lvbiB5IE9yZ2FuaXphY2lvbgoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOm9yYW5nZSI+ICoqUmVjdXJzb3MgSHVtYW5vcyAoQ29sYWJvcmFkb3JlcyB5ICBCYWphcykqKgpgYGB7cn0KI2ZpbGUuY2hvb3NlKCkKClJoQ29sYWI8LXJlYWQuY3N2KCIvVXNlcnMvYW5kcmVhcGFvbGFzb3NhL0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLUluc3RpdHV0b1RlY25vbG9naWNveWRlRXN0dWRpb3NTdXBlcmlvcmVzZGVNb250ZXJyZXkvQmFzZURhdG9zTCBSSF9Db2xhYm9yYWRvcmVzLmNzdiIpClJoQmFqYXM8LXJlYWQuY3N2KCIvVXNlcnMvYW5kcmVhcGFvbGFzb3NhL0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLUluc3RpdHV0b1RlY25vbG9naWNveWRlRXN0dWRpb3NTdXBlcmlvcmVzZGVNb250ZXJyZXkvQmFzZURfTGltcGlhIFJIXyBCYWphcyAuY3N2IikKYGBgCioqVGlwb3MgZGUgVmFyaWFibGVzIEV4aXN0ZW50ZXMgcGFyYSBSSENPTEFCKioKYGBge3J9CnZhcmlhYmxlPC1jKCJudW1lcm9fZGVfZW1wbGVhZG8iLCJub21icmVfY29tcGxldG8iLCAiZWRhZCIsICJnZW5lcm8iLCAiZmVjaGFfZGVfYWx0YSIsICJhbnRpb2d1ZWRhZCIsICJCQUpBIiwgInB1ZXN0byIsICJkZXBhcnRhbWVudG8iLCAibWFub19kZV9vYnJhIiwgInNhbGFyaW9fZGlhcmlvIiwgImNvbG9uaWEiLCAibXVuaWNpcGlvIikKCnR5cGU8LWMoIkN1YWxpdGF0aXZvIChub21pbmFsKSIsIkN1YWxpdGF0aXZvIChub21pbmFsKSIsICJDdWFudGl0YXRpdm8oZGlzY3JldGEpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIsICJDdWFudGl0YXRpdm8oZGlzY3JldGEpIiwgImN1YWxpdGF0aXZvIChub21pbmFsKSIsICJDdWFsaXRhdGl2byAobm9taW5hbCkiLCAiQ3VhbGl0YXRpdm8gKG5vbWluYWwpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIsICJDdWFsaXRhdGl2byAobm9taW5hbCkiLCAiQ3VhbnRpdGF0aXZvIChjb250aW51YSkiLCAiQ3VhbGl0YXRpdm8gKG5vbWluYWwpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIpCgpFc2NhbGFfZGVfTWVkaWNpw7NuPC1jKCJOdW1lcm8iLCAiRmVjaGEiLCAiRGVwYXJ0YW1lbnRvIiwgIlNhbGFyaW8iLCAiRXN0YWRvIikKCgp0YWJsZTwtZGF0YS5mcmFtZSh2YXJpYWJsZSx0eXBlKQprbml0cjo6a2FibGUodGFibGUpCmBgYAoqKlRpcG9zIGRlIFZhcmlhYmxlcyBFeGlzdGVudGVzIHBhcmEgUkhCQUpBUyoqCmBgYHtyfQp2YXJpYWJsZTwtYyAoIm5vbWJyZSIsImVkYWQiLCAiZ2VuZXJvIiwgImZlY2hhX2FsdGEiLCAibW90aXZvX2JhamEiLCAiZGlhc19kZV90cmFiYWpvIiwgImJhamEiLCAicHVlc3RvX3F1ZV9kZXNlbXBlw7FhIiwgInNhbGFyaW9faW1zcyIsICJjb2xvbmlhIiwgIm11bmljaXBpbyIsICJlc3RhZG8iLCAiZXN0YWRvX2NpdmlsIiApCgoKdHlwZTwtYyAoIkN1YWxpdGF0aXZvIChub21pbmFsKSIsIkN1YW50aXRhdGl2byhkaXNjcmV0YSkiLCAiQ3VhbGl0YXRpdm8gKG5vbWluYWwpIiwgIkN1YW50aXRhdGl2byhkaXNjcmV0YSkiLCAiQ3VhbGl0YXRpdm8gKG5vbWluYWwpIiwgIkN1YW50aXRhdGl2byhkaXNjcmV0YSkiLCAiQ3VhbnRpdGF0aXZvKGRpc2NyZXRhKSIsICJDdWFsaXRhdGl2byAobm9taW5hbCkiLCAiQ3VhbnRpdGF0aXZvKENvbnRpbnVhKSIsICJDdWFsaXRhdGl2byAobm9taW5hbCkiLCAiQ3VhbGl0YXRpdm8gKG5vbWluYWwpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIsICJDdWFsaXRhdGl2byAobm9taW5hbCkiICkKCkVzY2FsYV9kZV9NZWRpY2nDs248LWMoIk51bWVybyIsICJGZWNoYSIsICJEZXBhcnRhbWVudG8iLCAiU2FsYXJpbyIsICJFc3RhZG8iKQoKCnRhYmxlPC1kYXRhLmZyYW1lKHZhcmlhYmxlLHR5cGUpCmtuaXRyOjprYWJsZSh0YWJsZSkKYGBgCioqTGxhbWFyIGxpYnJlcmlhcyAqKgpgYGB7cn0KbGlicmFyeShmb3JlaWduKQpsaWJyYXJ5KGRwbHlyKSAgICAgICAgIyBkYXRhIG1hbmlwdWxhdGlvbiAKbGlicmFyeShmb3JjYXRzKSAgICAgICMgdG8gd29yayB3aXRoIGNhdGVnb3JpY2FsIHZhcmlhYmxlcwpsaWJyYXJ5KGdncGxvdDIpICAgICAgIyBkYXRhIHZpc3VhbGl6YXRpb24gCmxpYnJhcnkoamFuaXRvcikgICAgICAjIGRhdGEgZXhwbG9yYXRpb24gYW5kIGNsZWFuaW5nIApsaWJyYXJ5KEhtaXNjKSAgICAgICAgIyBzZXZlcmFsIHVzZWZ1bCBmdW5jdGlvbnMgZm9yIGRhdGEgYW5hbHlzaXMgCmxpYnJhcnkocHN5Y2gpICAgICAgICAjIGZ1bmN0aW9ucyBmb3IgbXVsdGl2YXJpYXRlIGFuYWx5c2lzIApsaWJyYXJ5KG5hbmlhcikgICAgICAgIyBzdW1tYXJpZXMgYW5kIHZpc3VhbGl6YXRpb24gb2YgbWlzc2luZyB2YWx1ZXMgTkFzCmxpYnJhcnkoZGxvb2tyKSAgICAgICAjIHN1bW1hcmllcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBtaXNzaW5nIHZhbHVlcyBOQXMKbGlicmFyeShjb3JycGxvdCkgICAgICMgY29ycmVsYXRpb24gcGxvdHMKbGlicmFyeShqdG9vbHMpICAgICAgICMgcHJlc2VudGF0aW9uIG9mIHJlZ3Jlc3Npb24gYW5hbHlzaXMgCmxpYnJhcnkobG10ZXN0KSAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMgCmxpYnJhcnkoY2FyKSAgICAgICAgICAjIGRpYWdub3N0aWMgY2hlY2tzIC0gbGluZWFyIHJlZ3Jlc3Npb24gYW5hbHlzaXMKbGlicmFyeShvbHNycikgICAgICAgICMgZGlhZ25vc3RpYyBjaGVja3MgLSBsaW5lYXIgcmVncmVzc2lvbiBhbmFseXNpcyAKbGlicmFyeShrYWJsZUV4dHJhKSAgICMgSFRNTCB0YWJsZSBhdHRyaWJ1dGVzCmBgYAoqKlZlcmlmaWNhciBsYSBlc3RydWN0dXJhIGRlIGxhIGJhc2UgZGUgZGF0b3MqKgpgYGB7cn0Kc3RyKFJoQ29sYWIpCnN0cihSaEJhamFzKQpgYGAKKipzZWxlY2Npb25hciBjb2x1bW5hcyAvIHZhcmlhYmxlcyoqCmBgYHtyfQpSaENvbGFiMTwtUmhDb2xhYiAKUmhCYWphczE8LVJoQmFqYXMKYGBgCioqTGltcGllemEgZGUgZGF0b3MqKiAKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KUmhDb2xhYjE8LVJoQ29sYWIgJT4lIHNlbGVjdCgtb25lX29mKCdudW1lcm9fZGVfZW1wbGVhZG8nLCdGZWNoYV9hbHRhJyAsICdCQUpBJywgJ2VkYWQnKSkKCgoKIyBsZXRzIHJlbmFtZSB0aGUgc2VsZWN0ZWQgY29sdW1ucyAvIHZhcmlhYmxlcwpzdW1tYXJ5KFJoQ29sYWIxKQpuYW1lcyhSaENvbGFiMSk8LWMoJ05vbV9Db21wJywgJ0dlbicsICdGZWNoYV9hbHRhJywgJ0FudCcsICdQdWVzdG8nLCAnRGVwJywgJ01ETycsICdTYWxfRGlhcmlvJywgJ0NvbCcsICdNdW4nKQpuYW1lcyhSaEJhamFzMSk8LWMoJ05vbScsICdFZGFkJywgJ0dlbicsICdGZWNoYV9hbHRhJywgJ01CJywgJ0TDrWFzX3RyYWInLCAnQmFqYScsICdQdWVzdERlcycsICdTYWxfSU1TUycsICdDb2wnLCAnTXVuJywgJ0VzdGFkbycsICdFc3RDaXYnKQoKIyNsZXRzIGNvbnZlcnQgZmVjaGFfbmFjaW1pZW50byB0byBkYXRlIGZvcm1hdCAKCgpSaENvbGFiMSRGZWNoYV9hbHRhPC1hcy5EYXRlKFJoQ29sYWIkZmVjaGFfZGVfYWx0YSwgZm9ybWF0ID0gIiVkLyVtLyVZIikKUmhCYWphczEkRmVjaGFfYWx0YTwtYXMuRGF0ZShSaEJhamFzMSRGZWNoYV9hbHRhLCBmb3JtYXQgPSAiJWQvJW0vJVkiKQpSaEJhamFzMSRCYWphPC1hcy5EYXRlKFJoQmFqYXMxJEJhamEsIGZvcm1hdCA9ICIlZC8lbS8lWSIpCgpzdHIoUmhDb2xhYjEpCnN0cihSaEJhamFzMSkKCgoKCiMgRWxpbWluYXIgTkEncyB5IHN1c3RpdHVpciBjb24gMCdzCgpzdW0oaXMubmEoUmhDb2xhYjEpKQpzdW0oaXMubmEoUmhCYWphczEpKQoKCnN1bW1hcnkoUmhDb2xhYjEpCnN1bW1hcnkoUmhCYWphczEpCgpSaENvbGFiMSA8LSBuYS5vbWl0KFJoQ29sYWIxKQpSaEJhamFzMSA8LSBuYS5vbWl0KFJoQmFqYXMxKQoKCnN1bW1hcnkoUmhDb2xhYjEpCnN1bW1hcnkoUmhCYWphczEpICAKCnN0cihSaENvbGFiMSkKc3RyKFJoQmFqYXMxKQpgYGAKKipDYWxjdWxhciBsYSB2YXJpYWJsZSAiYcOxbyIgZW4gYcOxb3MgcGFyYSByZWFsaXphciBjYXJhY3RlcmlzdGljYXMgYWRpY2lvbmFsZXMgZGUgbG9zIGNvbGFib3JhZG9yZXMqKgpgYGB7cn0KbGlicmFyeShsdWJyaWRhdGUpCgoKZWRhZDwtdHJ1bmMoKFJoQ29sYWIxJEZlY2hhX2FsdGEgJS0tJSBSaENvbGFiMSRGZWNoYV9hbHRhKSAvIHllYXJzKDEpKSAjICUtLSUgY3JlYXRlcyBhIHRpbWUgaW50ZXJ2YWwgYmFzZWQgb24gYXMuZGF0ZSgpIGZvcm1hdApSaENvbGFiMSRlZGFkPC1lZGFkCgplZGFkPC10cnVuYygoUmhCYWphczEkRmVjaGFfYWx0YSAlLS0lIFJoQmFqYXMxJEZlY2hhX2FsdGEpIC8geWVhcnMoMSkpCmVkYWQ8LXRydW5jKChSaEJhamFzMSRCYWphICUtLSUgUmhCYWphczEkQmFqYSkgLyB5ZWFycygxKSkKYGBgCioqQ29udmVydGlyIGxhcyB2YXJpYWJsZXMgYSBmYWN0b3IgcGFyYSBwb2RlciBjcmVhciBncmFmaWNhcyBkZXNjcmlwdGl2YXMqKgpgYGB7cn0KIyMjICBDb2xhYjEKUmhDb2xhYjEkR2VuPC1hcy5mYWN0b3IoUmhDb2xhYjEkR2VuKQpSaENvbGFiMSRQdWVzdG88LWFzLmZhY3RvcihSaENvbGFiMSRQdWVzdG8pClJoQ29sYWIxJERlcDwtYXMuZmFjdG9yKFJoQ29sYWIxJERlcCkKUmhDb2xhYjEkTXVuPC1hcy5mYWN0b3IoUmhDb2xhYjEkTXVuKQpSaENvbGFiMSRDb2w8LWFzLmZhY3RvcihSaENvbGFiMSRDb2wpCgoKIyMjICBCYWphczEgCgpSaEJhamFzMSRHZW48LWFzLmZhY3RvcihSaEJhamFzMSRHZW4pClJoQmFqYXMxJE1CPC1hcy5mYWN0b3IoUmhCYWphczEkTUIpClJoQmFqYXMxJETDrWFzX3RyYWI8LWFzLmZhY3RvcihSaEJhamFzMSREw61hc190cmFiKQpSaEJhamFzMSRQdWVzdERlczwtYXMuZmFjdG9yKFJoQmFqYXMxJFB1ZXN0RGVzKQpSaEJhamFzMSRDb2w8LWFzLmZhY3RvcihSaEJhamFzMSRDb2wpClJoQmFqYXMxJE11bjwtYXMuZmFjdG9yKFJoQmFqYXMxJE11bikKUmhCYWphczEkRXN0YWRvPC1hcy5mYWN0b3IoUmhCYWphczEkRXN0YWRvKQpSaEJhamFzMSRFc3RDaXY8LWFzLmZhY3RvcihSaEJhamFzMSRFc3RDaXYpCmBgYAoqKlZlcmlmaWNhciBsYSBlc3RydWN0dXJhIGRlIGxhcyBiYXNlcyBkZSBkYXRvcyBSaENvbGFiMSB5IFJoQmFqYXMxKiogIApgYGB7cn0Kc3RyKFJoQ29sYWIxKQpzdW1tYXJ5KFJoQ29sYWIxKQoKc3RyKFJoQmFqYXMxKQpzdW1tYXJ5KFJoQmFqYXMxKQpgYGAKKipNb3N0cmFyIHRhYmxhcyBkZSB2aXN1YWxpemFjacOzbiBwYXJhIGlkZW50aWZpY2FyIHBlcnNwZWN0aXZhcyByZWxldmFudGVzIGRlIGxhcyBiYXNlcyBkZSBkYXRvcyBSaENvbGFiMSB5IFJoQmFqYXMxKiogCmBgYHtyfQojIyBDb2xhYm9yYWRvcmVzCgoKdGFwcGx5KFJoQ29sYWIxJFNhbF9EaWFyaW8sCiAgICAgICBsaXN0KFJoQ29sYWIxJEdlbixSaENvbGFiMSRQdWVzdG8pLCBtZWFuKQoKdGFwcGx5KFJoQ29sYWIxJFNhbF9EaWFyaW8sCiAgICAgICBsaXN0KFJoQ29sYWIxJEdlbixSaENvbGFiMSREZXApLCBtZWFuKQoKIyMgQmFqYXMKCnRhcHBseShSaEJhamFzMSRTYWxfSU1TUyxSaEJhamFzMSRHZW4sbWVhbikKYGBgCioqUmVlbXBsYXphciBlbCB2YWxvciBhdMOtcGljbyBkZSBzYWxhcmlvX2RpYXJpbyBjb24gbGEgbWVkaWFuYSoqCmBgYHtyfQpSaENvbGFiMSRTYWxfRGlhcmlvPC1yZXBsYWNlKFJoQ29sYWIxJFNhbF9EaWFyaW8sUmhDb2xhYjEkU2FsX0RpYXJpbz4xMDAwMDAwLDE4MSkKYGBgCioqTW9zdHJhciBncsOhZmljb3MgZGUgdmlzdWFsaXphY2nDs24gZGUgZGF0b3MgcGFyYSBxdWUgcG9kYW1vcyBpZGVudGlmaWNhciBpbmZvcm1hY2nDs24gcmVsZXZhbnRlIGRlIG51ZXN0cm8gY29uanVudG8gZGUgZGF0b3MgUkhDb2xhYiB5IFJIQmFqYXMqKgpgYGB7cn0KCnRhcHBseShSaENvbGFiMSRTYWxfRGlhcmlvLAogICAgICAgbGlzdChSaENvbGFiMSRHZW4sUmhDb2xhYjEkRGVwKSwgbWVhbikKCmhpc3QoUmhCYWphczEkRWRhZCwgZnJlcT1UUlVFLCBjb2w9J29yYW5nZScsIG1haW49Ikhpc3RvZ3JhbWEgZGUgRWRhZCIseGxhYj0iRWRhZCBlbiBBw7FvcyIpCgpnZ3Bsb3QoUmhCYWphczEsIGFlcyh4PUdlbiwgeT1FZGFkLCBmaWxsPUdlbikpICsgCiAgZ2VvbV9ib3hwbG90KCkgCgpnZ3Bsb3QoUmhDb2xhYjEsIGFlcyh4PUdlbiwgeT1TYWxfRGlhcmlvLCBmaWxsPUdlbikpICsgCiAgZ2VvbV9ib3hwbG90KCkgCgpnZ3Bsb3QoUmhDb2xhYjEsIGFlcyhHZW4sU2FsX0RpYXJpbyxmaWxsPUdlbikpICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsgZ2d0aXRsZSgiU2FsYXJpbyBEaWFyaW8gcG9yIEdlbmVybyIpCgoKZ2dwbG90KFJoQmFqYXMxLCBhZXMoeD1HZW4sIHk9U2FsX0lNU1MsIGZpbGw9R2VuKSkgKyAKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgCiAgZmFjZXRfZ3JpZCh+RXN0Q2l2KSArIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCmBgYAoKCioqVGVjbmljYXMgVXRpbGl6YWRhcyoqCgpUZWNuaWNhcyBkZSBMaW1waWV6YTogTGFzIHRlY25pY2FzIHF1ZSBzZSB1dGlsaXphcm9uIGNvbiBlbCBmaW4gZGUgcG9kZXIgb2J0ZW5lciB1bmEgbWVqb3IgdmlzdWFsaXphY2lvbiBkZSBsb3MgZGF0b3MgZnVlcm9uOiBDYW1iaWFyIGVsIG5vbWJyZSBkZSBsYXMgdmFyaWFibGVzLiBTZSBjYW1iaW8gZWwgbm9tYnJlIGRlIGxhcyB2YXJpYWJsZXMgZGUgZm9ybWEgcXVlIHNlIHB1ZGllcmEgb2J0ZW5lciBtZWpvciBjb21wcmVuc2lvbiBkZSBsYSB2YXJpYWJsZSBhbmFsaXphZGEuCgpUZWNuaWNhIDI6IFNlIGNhbWJpbyBsYSBhdnJpYWJsZSBkZSBmZWNoYV9uYWNpbWllbnRvIGEgZGF0ZSBmb3JtYXQKClRlY25pY2EgMzogU2UgZWxpbWluYXJvbiBOQXMgbG9zIGN1YWxlcyBzZSBzdXN0aXR1eWVyb24gY29uIDBzLiAKClZhcmlhYmxlczogMTIyClJlZ2lzdHJvczoyOAoKMiBwcm9wdWVzdGFzIGNvbmNyZXRhczoKCioqQW5hbGlzaXMgRXhwbG9yYXRvcmlvKioKIEVuIHByb21lZGlvIGxhIG1heW9yIHBhcnRlIGRlIGxvcyBjb2xhYm9yYWRvcmVzIGRlIEZvcm0gdGllbmVuIHVuYSBlZGFkIGRlIGVudHJlIDIwIHkgMzAgYcOxb3MsIGhheSBlbXBsZWFkYXMgcXVlIHRpZW5lbiB1biBtw6F4aW1vIGRlIDU2IGHDsW9zIG1pZW50cmFzIHF1ZSBoYXkgdW4gZW1wbGVhZG8gcXVlIHBhc2EgeWEgZGUgbG9zIDYwIGHDsW9zIGRlIGVkYWQuIEVudHJlIGhvbWJyZXMgeSBtdWplcmVzIGVzdMOhbiBlbiB1biByYW5nbyBkZSAyMCBhIDQwIGHDsW9zIGRlIGVkYWQKCkVsIHNhbGRvIHByb21lZGlvIHRhbnRvIHBhcmEgaG9tYnJlcyBjb21vIHBhcmEgbXVqZXJlcyByb25kYSBlbiB1biBtb250byBkZSAxNzAgeSAxODAgcGVzb3MsIHBlcm8gaGF5IHVuYSBlbXBsZWFkYSBxdWUgbGxlZ2EgYSB1biBzYWxhcmlvIGRpYXJpbyBkZSA0NDEgcGVzb3MsIGR1cGxpY2FuZG8gZWwgc2FsZG8gcHJvbWVkaW8gZGUgbGEgbWF5b3IgcGFydGUgZGUgbG9zIGVtcGxlYWRvcyBkZSBsYSBjb21wYcOxw61hLiAKCkxhcyBtdWplcmVzIHRpZW5lbiB1biBzdWVsZG8gbWFzIGVsZXZhZG8gcXVlIGxvcyBob21icmVzCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIj4gKkRlbGl2ZXJ5IFBsYW4qCgojIyMgRGVzY2FyZ2FyIGxpYnJlcmlhcwpgYGB7cn0KI2xpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkobmFuaWFyKQpsaWJyYXJ5KEhtaXNjKSAgICAgICAgIAojbGlicmFyeShwc3ljaCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoamFuaXRvcikKbGlicmFyeShrbml0cikKbGlicmFyeShwb2xsc3RlcikKbGlicmFyeShlcGlEaXNwbGF5KQpsaWJyYXJ5KGRlc2NyKQpsaWJyYXJ5KHRpZHlyKQpgYGAKIyMjIExpbXBpZXphCgojIyMgSW1wb3J0YXIgYmFzZSBkZSBkYXRvcwpgYGB7cn0KZGVsX3BsYW4gPC1yZWFkLmNzdiAoIi9Vc2Vycy9hbmRyZWFwYW9sYXNvc2EvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtSW5zdGl0dXRvVGVjbm9sb2dpY295ZGVFc3R1ZGlvc1N1cGVyaW9yZXNkZU1vbnRlcnJleS9EUF8xLmNzdiIpCmRlbF9wbGFuIDwtIHJlYWQuY3N2ICgiL1VzZXJzL2FuZHJlYXBhb2xhc29zYS9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1JbnN0aXR1dG9UZWNub2xvZ2ljb3lkZUVzdHVkaW9zU3VwZXJpb3Jlc2RlTW9udGVycmV5L0RQXzEuY3N2IikKYGBgCiMjIyBDb252ZXJ0aXIgbWVzZXMgZW4gdW5hIGNvbHVtbmEKYGBge3J9CmRlbF9wbGFuIDwtIGNsZWFuX25hbWVzKGRlbF9wbGFuKQpkZWxfcGxhbjwtZGVsX3BsYW4gJT4lIGRwbHlyOjpyZW5hbWUoanVuXzIxPWp1bmlvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAganVsXzIxPWp1bGlvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdvXzIxPWFnb3N0bywgc2VwXzIxPXNlcHRpZW1icmUsIG9jdF8yMT0gb2N0dWJyZSwgbm92XzIxPW5vdmllbWJyZSwgZGljXzIxPWRpY2llbWJyZSwgb2N0XzIyPW9jdHVicmVfMjIpCmRlbF9wbGFuPC1waXZvdF9sb25nZXIoZGVsX3BsYW4sIGNvbHM9NToxNiwgbmFtZXNfdG8gPSAibWVzIiwgdmFsdWVzX3RvID0gInVuaWRhZGVzIikKCmRlbF9wbGFuIDwtIGRwbHlyOjpzZWxlY3QoZGVsX3BsYW4sIC1jKDU6MTUpKQpgYGAKCgojIyMgRWxpbWluYXIgY29sdW1uYXMgbm8gbmVjZXNhcmlhcwpgYGB7cn0KZGVsX3BsYW4gPC0gZHBseXI6OnNlbGVjdChkZWxfcGxhbiwgLWMoMjo0KSkKYGBgCgojIyMgRm9ybWF0byBkZSBsYXMgdmFyaWFibGVzCmBgYHtyfQpzdHIoZGVsX3BsYW4pCmBgYAoKIyMjIE5BJ3MgeSB2YWxvcmVzIGF0aXBpY29zCmBgYHtyfQpkZWxfcGxhbiA8LSBmaWx0ZXIoZGVsX3BsYW4sIHVuaWRhZGVzPjApCnN1bShpcy5uYShkZWxfcGxhbikpCmBgYAoKIyMjIEV4cG9ydGFyIGxhIGJhc2UgZGUgZGF0b3MKYGBge3J9CmRlbF9wbGFuX2xpbXBpYTwtZGVsX3BsYW4Kd3JpdGUuY3N2KGRlbF9wbGFuX2xpbXBpYSxmaWxlID0gIkNMRUFOREJEZWxpdmVyeVBsYW4uY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoqKlRlY25pY2FzIFV0aWxpemFkYXMqKjoKVGVjbmljYXMgZGUgTGltcGllemE6CkNvbnZlcnRpciBtZXNlcyBlbiB1bmEgY29sdW1uYTogRXN0YSB0ZWNuaWNhIHNlIGltcGxlbWVudG8gcGFyYSBwb2RlciB0ZW5lciB1biBtYW5lam8gb3B0aW1vIGRlIGxhcyB1bmlkYWRlcyBkZSBwcm9kdWNjaW9uIG1lbnN1YWwgZGViaWRvIGEgcXVlIGVuIGxhIGJhc2Ugb3JpZ2luYWwgZXN0YW4gcmVnaXN0cmFkYXMgcG9yIG1lc2VzIGxvIGN1YWwgZGlmaWN1bHRhIGEgbGEgaG9yYSBkZSBoYWNlciB1biBhbmFsaXNpcy4KCkVsaW1pbmFyIGNvbHVtbmFzOiBTZSBlbGltaW5hcm9uIGxhcyBjb2x1bW5hcyAiSUQiICJPRE9PIiAiUHJveWVjdG8iIGUgIkl0ZW0iIHlhIHF1ZSBubyBlcmFuIGRlIGdyYW4gcmVsZXZhbmNpYSBwYXJhIGVzdGUgYW5hbGlzaXMKCkVsaW1pbmFyIE5BJ3MgeSBWYWxvcmVzIGF0aXBpY29zOiBObyBzZSBlbmNvbnRyYXJvbiBOQSdzIG5pIHZhbG9yZXMgYXRpcGljb3MgZW4gbGEgYmFzZSBhc2kgcXVlIHNlIGVsaW1pbmFyb24gbG9zIHJlZ2lzdHJvcyBxdWUgdGllbmVuIDAgdW5pZGFkZXMgcHJvZ3JhbWFkYXMuCgpSZWdpc3Ryb3M6IDIzMQpWYXJpYWJsZXM6MjcKCiMjIyBHcmFmaWNhcwoKIyMjIFRhYmxhIGVzdGFkaXN0aWNhcyAKYGBge3J9CnRhYmxhX2VzdGFkaXN0aWNvcyA8LSBkZXNjcmliZShkZWxfcGxhbikKdGFibGFfZXN0YWRpc3RpY29zCmBgYAoKIyMjIEJhciBwbG90cwpgYGB7cn0KbGlicmFyeShkcGx5cikKc3RyKGRlbF9wbGFuKQpkZWxfcGxhbiRjbGllbnRlX3BsYW50YTwtYXMuZmFjdG9yKGRlbF9wbGFuJGNsaWVudGVfcGxhbnRhKQpkZWxfcGxhbiR1bmlkYWRlczwtYXMubnVtZXJpYyhkZWxfcGxhbiR1bmlkYWRlcykgCgpkZWxfcGxhbjI8LWFnZ3JlZ2F0ZSh1bmlkYWRlc35jbGllbnRlX3BsYW50YSwgZGF0YSA9IGRlbF9wbGFuLHN1bSklPiUgYXJyYW5nZShkZXNjKHVuaWRhZGVzKSkKZGVsX3BsYW4zPC1maWx0ZXIoZGVsX3BsYW4yLCB1bmlkYWRlcz40MDAwKQoKZ2dwbG90KGRlbF9wbGFuMywgYWVzKHg9cmVvcmRlcihjbGllbnRlX3BsYW50YSx1bmlkYWRlcyksIHk9dW5pZGFkZXMpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSsKICBjb29yZF9mbGlwKCkKYGBgCiMjIyBEaXNwZXJzaW9uCmBgYHtyfQpkZWxfcGxhbjIkdW5pZGFkZXM8LWFzLm51bWVyaWMoZGVsX3BsYW4yJHVuaWRhZGVzKQoKZ2dwbG90KGRlbF9wbGFuLCBhZXMoeD1jbGllbnRlX3BsYW50YSwgeT11bmlkYWRlcywgZmlsbD1jbGllbnRlX3BsYW50YSkpICsgCiAgZ2VvbV9ib3hwbG90KCkgCgpib3hwbG90KGRlbF9wbGFuMyRjbGllbnRlX3BsYW50YSxkZWxfcGxhbjMkdW5pZGFkZXMpCmNsYXNzKGRlbF9wbGFuMiR1bmlkYWRlcykKYGBgCiMjIyBUaW1lIHNlcmllcyBwbG90CmBgYHtyfQpkZWxfcGxhbjQ8LWFnZ3JlZ2F0ZSh1bmlkYWRlc35jbGllbnRlX3BsYW50YSttZXMsIGRhdGEgPSBkZWxfcGxhbixzdW0pJT4lIGFycmFuZ2UoZGVzYyh1bmlkYWRlcykpCmRlbF9wbGFuNTwtZmlsdGVyKGRlbF9wbGFuNCwgY2xpZW50ZV9wbGFudGE9PSJIRUxMQSIgJiBjbGllbnRlX3BsYW50YT09IlRSTVgiICYgY2xpZW50ZV9wbGFudGE9PSJWQVJST0MiICYgY2xpZW50ZV9wbGFudGE9PSJERU5TTyIpCmdncGxvdChkZWxfcGxhbixhZXMoeD1tZXMsIHk9dW5pZGFkZXMsY29sb3I9Y2xpZW50ZV9wbGFudGEpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IkZlY2hhIix5PSJEZWxheSBpbiBNaW51dGVzIiwgY29sb3I9IkxlZ2VuZCIpKwogIGdndGl0bGUoIkRlbGF5cyBpbiBQZXJmb3JtYW5jZSBieSBDbGllbnQiKQpgYGAKKipBbmFsaXNpcyBleHBsb3JhdG9yaW8qKiAKCkJhciBQbG90OiBMYXMgZnVuY2lvbmVzIHV0aWxpemFkYXMgcGFyYSBsYSByZWFsaXphY2lvbiBkZSBlc3RlIGJhciBwbG90IGZ1ZXJvbjogYXMuZmFjdG9yIHkgYXMubnVtZXJpYyBkZSBlc3RhIGZvcm1hIHZvbHZpZW5kbyBsb3MgZGF0b3MgY3VhbGl0YXRpdm9zIGEgY3VhbnRpdGF0aXZvcyBsbyBjdWFsIGxvcyBoYWNlIG1hcyBtYW5lamFibGVzLiBFbCByZXN1bHRhZG8gZGUgbGEgZ3JhZmljYSBtb3N0cm8gYSBsb3MgY2xpZW50ZXMgY29uIG1heW9yIG51bWVybyBkZSB1bmlkYWRlcyBlbiBvcmRlbiBkZXNjZW5kaWVudGUuCgpCb3ggUGxvdDogU2UgdXRpbGl6byBsYSBmdW5jaW9uIGFzLm51bWVyaWMuIApVbiBoYWxsYXpnbyBpbXBvcnRhbnRlIG9idGVuaWRvIGZ1ZSBxdWUgIkhlbGxhIiBlcyBlbCBjbGllbnRlIGNvbiBtYXlvciBjYW50aWRhZCBkZSB1bmlkYWRlcyB5IGN1ZW50YSBjb24gYWxndW5vcyBvdXRsaWVycyBwb3IgZW5jaW1hIGRlIGxhIG1lZGlhLCBzZWd1aWRvIHBvciBUUk1YIGVsIGN1YWwgbm8gY3VlbnRhIGNvbiBvdXRsaWVycy4KClRpbWUgU2VyaWVzIFBsb3Q6IFBhcmEgbGEgcmVhbGl6YWNpb24gZGUgZXN0YSBncmFmaWNhIGZ1ZSBubmVjZXNhcmlvIGludHJvZHVjaXIgbGEgdmFyaWFibGUgZGUgdGllbXBvIG1lcy4gVW4gaGFsbGF6Z28gaW1wb3J0YW50ZSBmdWUgcXVlIGVuIGxhIHNlZ3VuZGEgIG1pdGFkIGRlbCBhw7FvIHNlIG5vdGEgdW4gaW5jcmVtZW50byBjb25zaWRlcmFibGUgeSB1biBkZWNyZW1lbnRvIGp1c3RvIGEgZmluYWxpemFyIGVsIHNlZ3VuZG8gc2VtZXN0cmUKCgoKIyMgIDxzcGFuIHN0eWxlPSJjb2xvcjpvcmFuZ2UiPiAqRGVsaXZlcnkgUGVyZm9ybWFuY2UqCmBgYHtyfQojZmlsZS5jaG9vc2UoKQpiZDwtcmVhZC5jc3YgKCIvVXNlcnMvYW5kcmVhcGFvbGFzb3NhL0Rlc2t0b3AvREVMSVZFUllQRVJPUk1BTkNFIDIuY3N2IikgCmJkY2xpZW50ZXM8LXJlYWQuY3N2ICgiL1VzZXJzL2FuZHJlYXBhb2xhc29zYS9EZXNrdG9wL0RlbGl2ZXJ5UGVyZm9ybWFuY2VmaW5hbDEuY3N2IikKYGBgCgojIyMjIEluc3RhbGFyIExpYnJlcmlhcwpgYGB7cn0KbGlicmFyeSAodGlkeXZlcnNlKQpsaWJyYXJ5IChqYW5pdG9yKQpsaWJyYXJ5IChkcGx5cikKI2luc3RhbGwucGFja2FnZXMgKCJnZ3Bsb3QyIikKbGlicmFyeSAoZ2dwbG90MikKbGlicmFyeSAoSG1pc2MpCmBgYAoKCiMjIyBBbmFsaXphciBiYXNlIGRlIGRhdG9zCmBgYHtyfQpzdW1tYXJ5IChiZCkKc3RyIChiZCkKCgpuYW1lcyhiZCk8LWMoJ0ZFQ0hBJywgJ0NMSUVOVEUnLCAnRElGRVJFTkNJQScgKQpgYGAKCiMjIyBUaXBvcyBkZSB2YXJpYWJsZXMKYGBge3J9ClZhcmlhYmxlPC1jKCJGRUNIQSIsIkNMSUVOVEUiLCJESUZFUkVOQ0lBIikKVHlwZTwtYygicXVhbGl0YXRpdmUgKG9yZGluYWwpIiwgInF1YWxpdGF0aXZlKG5vbWluYWwpIiwgInF1YW50aXRhdGl2ZSAoY29udGludW91cykiKSAgCnRhYmxlPC1kYXRhLmZyYW1lKFZhcmlhYmxlLFR5cGUpCmtuaXRyOjprYWJsZSh0YWJsZSkKYGBgCgojIyMjIExpbXBpZXphIGRlIGJhc2UgZGUgZGF0b3MKIyMjICBFbGltaW5hciBOQSdzIHkgc3VzdGl0dWlyIGNvbiAwJ3MKYGBge3J9CnN1bShpcy5uYShiZCkpCmJkW2lzLm5hKGJkKV08LTAKCgpiZDE8LWJkCmJkMTwtYXMuZGF0YS5mcmFtZShiZDEpIApiZDEkRkVDSEE8LWFzLkRhdGUoYmQxJEZFQ0hBLGZvcm1hdD0iJWQvJW0vJVkiKSAKYmQxJENMSUVOVEU8LWFzLmZhY3RvcihiZDEkQ0xJRU5URSkgCnRhYnlsKGJkMSwgRkVDSEEsIENMSUVOVEUpCnRhYnlsKGJkMSwgRkVDSEEsIERJRkVSRU5DSUEpCnRpYmJsZShiZDEpCmBgYAoKIyMjIExpbXBpZXphIGJkY2xpZW50ZXMyCmBgYHtyfQpiZGNsaWVudGVzMjwtYmRjbGllbnRlcwpiZGNsaWVudGVzMjwtYXMuZGF0YS5mcmFtZShiZGNsaWVudGVzMikKYmRjbGllbnRlczIkRkVDSEE8LWFzLkRhdGUoYmRjbGllbnRlczIkRkVDSEEsZm9ybWF0PSIlbS8lZC8lWSIpCmJkY2xpZW50ZXMyJFBSSU5URUw8LWFzLmZhY3RvcihiZGNsaWVudGVzMiRQUklOVEVMKQp0YWJ5bChiZGNsaWVudGVzMiwgRkVDSEEsIFBSSU5URUwpCnRhYnlsKGJkY2xpZW50ZXMyLCBGRUNIQSwgTUFITEUpCnRpYmJsZShiZGNsaWVudGVzMikKYGBgCgoqKlRlY25pY2FzIGRlIExpbXBpZXphKioKMS4gRWxpbWluYXIgTkEncyB5IHN1c3RpdHVpciBjb24gMHM6IFNlIHJlZW1wbGF6YXJvbiBsb3MgTkEncyBjb24gMHMgcGFyYSBwb2RlciBmYWNpbGl0YXIgZWwgYW5hbGlzaXMgeSBvYnRlbmVyIHJlc3VsdGFkb3MgbWFzIHByZWNpc29zLgoKMi5TZSBjYW1iaW8gZWwgZm9ybWF0byBkZSBsYSBmZWNoYSBhIG1lcy9kaWEvYcOxbwoKIyMjIEFuYWxpc2lzIFByb2Z1bmRvIGRlIGxhIEJhc2UgZGUgZGF0b3MKYGBge3J9Cm1lZGlhX2JkIDwtIG1lYW4oYmQkRElGRVJFTkNJQSkKbWVkaWFfYmQKCm1lZGlhbl9iZCA8LSBtZWRpYW4oYmQkRElGRVJFTkNJQSkKbWVkaWFuX2JkCgptb2RlX2JkIDwtIG1vZGUoYmQkRElGRVJFTkNJQSkKbW9kZV9iZAoKCgpoaXN0KGJkMSRESUZFUkVOQ0lBKSAKYGBgCgojIyMgQW5hbGlzaXMgUHJvZnVuZG8gZGUgbGEgQmFzZSBkZSBkYXRvcyBCRENMSUVOVEVTCmBgYHtyfQptZWRpYV9iZGNsaWVudGVzIDwtIG1lYW4oYmRjbGllbnRlcyRQUklOVEVMKQptZWRpYV9iZGNsaWVudGVzCgptZWRpYW5fYmRjbGllbnRlcyA8LSBtZWRpYW4oYmRjbGllbnRlcyRQUklOVEVMKQptZWRpYW5fYmRjbGllbnRlcwoKbW9kZV9iZGNsaWVudGVzIDwtIG1vZGUoYmRjbGllbnRlcyRQUklOVEVMKQptb2RlX2JkY2xpZW50ZXMKCm1lZGlhX2JkY2xpZW50ZXMgPC0gbWVhbihiZGNsaWVudGVzJE1BSExFKQptZWRpYV9iZGNsaWVudGVzCgptZWRpYW5fYmRjbGllbnRlcyA8LSBtZWRpYW4oYmRjbGllbnRlcyRNQUhMRSkKbWVkaWFuX2JkY2xpZW50ZXMKCm1vZGVfYmRjbGllbnRlcyA8LSBtb2RlKGJkY2xpZW50ZXMkTUFITEUpCm1vZGVfYmRjbGllbnRlcwoKYmRjbGllbnRlczMgPC1iZGNsaWVudGVzCmJkY2xpZW50ZXMzIDwtIHN1YnNldCAoYmRjbGllbnRlczMsIHNlbGVjdCA9IC1jIChNQUdOQSxWQVJST0MpKQoKCmhpc3QoYmRjbGllbnRlczMkUFJJTlRFTCkKaGlzdChiZGNsaWVudGVzMyRNQUhMRSkKYGBgCgojIyMgR3JhZmljYXMKIyMjIENsaWVudGVzIGNvbiBsb3MgUmV0cmFzb3MgbWFzIEFsdG9zCmBgYHtyfQpnZ3Bsb3QoYmQsYWVzKHg9RkVDSEEsIHk9RElGRVJFTkNJQSxmaWxsPUNMSUVOVEUpKSsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdD0zMyxsaW5ldHlwZT0iZGFzaGVkIixjb2xvcj0iYmxhY2siKSsKICBsYWJzKHg9IkZlY2hhIix5PSJSZXRyYXNvIGVuIE1pbnV0b3MiLCBjb2xvcj0iTGVnZW5kIikrCiAgZ2d0aXRsZSgiUmV0cmFzbyBlbiBEZXNlbXBlw7FvIGRlIGxvcyBDbGllbnRlcyIpCmBgYAoqKkFuYWxpc2lzIEV4cGxvcmF0b3JpbyoqClV0aWxpemFuZG8gbGEgbW9kYSwgbWVkaWEgeSBwcm9tZWRpbyBzZSBwdWRvIHJlYWxpemFyIHVuIGFuYWxpc2lzIGNvbiBsb3MgY2xpZW50ZXMgUHJpbnRlbCB5IE1haGxlLiBFbiBlbCBoaXN0b2dyYW1hIHJlcHJlc2VudGFuZG8gUHJpbnRlbCBzZSBwdWVkZSBvYnNlcnZhciBxdWUgZW4gbGEgY2xhc2UgZGUgMCBhIDUgc2UgZW5jdWVudHJhIHF1ZSBzZSB0dXZvIG1heW9yIGZyZWN1ZW5jaWEsIHNpZW5kbyBsYSBjbGFzZSBxdWUgbcOhcyBzZSByZXBpdGUsIGVzdG8gcXVpZXJlIGRlY2lyIHF1ZeKApiAKRGUgbG9zIDEyIG1lc2VzLCBlbiA3IHNlIHR1dm8gdW5hIGRpZmVyZW5jaWEgZGUgdGllbXBvIGRlIGVudHJlIDAgeSA1IG1pbnV0b3MsIHNpZW5kbyBlc3RhIGJhamEgcGVybyBjb24gdW4gc2VzZ28gYSBsYSBpenF1aWVyZGEuIApFbiBjdWFudG8gYSBNYWhsZSBlc3RlIGhpc3RvZ3JhbWEgdGllbmUgdW4gc2VzZ28gaGFjaWEgbGEgZGVyZWNoYSwgc2UgdGllbmUgdW5hIHRlbmRlbmNpYSBhIHRlbmVyIHVuIG1heW9yIHJldHJhc28gZW4gbGEgY2xhc2UgZGUgNjAgYSA3MCBtaW51dG9zIGFwcm94aW1hZGFtZW50ZSBjb24gZXN0ZSBjbGllbnRlLCBlc3RvIGVuIHVuIGFwcm94aW1hZG8gZGUgNiBtZXNlcyBkZSBsb3MgMTIgdG9tYWRvcyBlbiBjdWVudGEuCgpFbiBsYSB1bHRpbWEgZ3JhZmljYSBsYSBjdWFsIHJlcHJlc2VudGEgZWwgcmV0cmFzbyBlbiBkZXNlbXBlw7FvLCBzZSBwdWVkZSBvYnNlcnZhciBxdWUgTWFobGUgZXMgZWwgY2xpZW50ZSBxdWUgcmVwcmVzZW50YSB1biBtYXlvciByZXRyYXNvIG1pZW50cmFzIHF1ZSBQcmludGVsIHNlIG1hbnRpZW5lIGNvbiBsb3MgdGllbXBvcyBtYXMgYmFqb3MsIGVuIGVzdGUgY2FzbyBzaWVtcHJlIGRlYmFqbyBkZSBsb3MgMzAgbWludXRvcy4KCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpvcmFuZ2UiPiAqUHJvZHVjY2lvbioKCiMjIyBMaW1waWV6YSBkZSBEYXRvcwoKIyMjIEltcG9ydGFyIGxhICBiYXNlIGRlIGRhdG9zIHByb2R1Y2Npw7NuIGRlIGxhIGVtcHJlc2EgRk9STQpgYGB7cn0KcHJvZHVjY2lvbnRvdGFsIDwtIHJlYWQuY3N2ICgiL1VzZXJzL2FuZHJlYXBhb2xhc29zYS9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1JbnN0aXR1dG9UZWNub2xvZ2ljb3lkZUVzdHVkaW9zU3VwZXJpb3Jlc2RlTW9udGVycmV5L0JEIFByb2R1Y2Npb8yBbiBjc3YuY3N2IikKYGBgCgojIyMgRW50ZW5kZXIgbGEgYmFzZSBkZSBkYXRvcwpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzdHIocHJvZHVjY2lvbnRvdGFsKQoKYGBgCgojIyMgRWxpbWluYXIgY29sdW1uYXMgaXJyZWxldmFudGVzIHBhcmEgZWwgYW7DoWxpc2lzCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnByb2R1Y2Npb250b3RhbCA8LSBzdWJzZXQgKHByb2R1Y2Npb250b3RhbCxzZWxlY3QgPSAtYyhOby4gLCBJRC5GT1JNICwgUFJPRFVDVE8sICBIUi4uRklOICwgRVNUQUNJT04uQVJSQU5RVUUgLCBJTklDSU8uU0VQLlVQICxGSU4uSU5JQ0lPLkRFLlNFUC5VUCAsIElOSUNJTy5kZS5QUk9DRVNPICwgVElFTVBPLk1BVEVSSUFMRVMgLCBNRVJNQVMuTWFxdWluYXMuICkpCnN1bW1hcnkgKHByb2R1Y2Npb250b3RhbCkKCmBgYAoKIyMjIEluc3RhbGFyIGxpYnJlcmlhcyBuZWNlc2FyaWFzCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgaW5zdGFsbC5wYWNrYWdlcygidGliYmxlIikKbGlicmFyeSh0aWJibGUpCmBgYAoKIyMjIENhbWJpYXIgYSBlbnRlcm8gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIApgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwcm9kdWNjaW9udG90YWwkUElFWkFTLlBST0cuIDwtIHN1YnN0cihwcm9kdWNjaW9udG90YWwkUElFWkFTLlBST0cuLCBzdGFydCA9IDEsIHN0b3AgPSAyKQp0aWJibGUgKHByb2R1Y2Npb250b3RhbCkKcHJvZHVjY2lvbnRvdGFsJFBJRVpBUy5QUk9HLiA8LSBhcy5pbnRlZ2VyKHByb2R1Y2Npb250b3RhbCRQSUVaQVMuUFJPRy4pCnN0cihwcm9kdWNjaW9udG90YWwpICAgIAoKcHJvZHVjY2lvbnRvdGFsJFRNTy4uTUlOLiA8LSBzdWJzdHIocHJvZHVjY2lvbnRvdGFsJFRNTy4uTUlOLiwgc3RhcnQgPSAxLCBzdG9wID0gMikKdGliYmxlIChwcm9kdWNjaW9udG90YWwpCnByb2R1Y2Npb250b3RhbCRUTU8uLk1JTi4gPC0gYXMuaW50ZWdlcihwcm9kdWNjaW9udG90YWwkVE1PLi5NSU4uKQpzdHIocHJvZHVjY2lvbnRvdGFsKSAgCgpwcm9kdWNjaW9udG90YWwkTGFtaW5hcy5wcm9jZXNhZGFzIDwtIHN1YnN0cihwcm9kdWNjaW9udG90YWwkTGFtaW5hcy5wcm9jZXNhZGFzLCBzdGFydCA9IDEsIHN0b3AgPSAyKQp0aWJibGUgKHByb2R1Y2Npb250b3RhbCkKcHJvZHVjY2lvbnRvdGFsJExhbWluYXMucHJvY2VzYWRhcyA8LSBhcy5pbnRlZ2VyKHByb2R1Y2Npb250b3RhbCRMYW1pbmFzLnByb2Nlc2FkYXMpCnN0cihwcm9kdWNjaW9udG90YWwpIAoKcHJvZHVjY2lvbnRvdGFsJFRJRU1QTy5DQUxJREFEIDwtIHN1YnN0cihwcm9kdWNjaW9udG90YWwkVElFTVBPLkNBTElEQUQsIHN0YXJ0ID0gMSwgc3RvcCA9IDIpCnRpYmJsZSAocHJvZHVjY2lvbnRvdGFsKQpwcm9kdWNjaW9udG90YWwkVElFTVBPLkNBTElEQUQgPC0gYXMuaW50ZWdlcihwcm9kdWNjaW9udG90YWwkVElFTVBPLkNBTElEQUQpCnN0cihwcm9kdWNjaW9udG90YWwpIApgYGAKCgojIyMgQ29udmVydGlyIGZvcm1hdG8gZGUgbGEgZmVjaGEKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcHJvZHVjY2lvbnRvdGFsJEZlY2hhIDwtIGFzLkRhdGUocHJvZHVjY2lvbnRvdGFsJEZlY2hhLCBmb3JtYXQgPSAiJWQvJW0vJVkiKQp0aWJibGUocHJvZHVjY2lvbnRvdGFsKQpgYGAKCiMjIyBDb252ZXJ0aXIgdmFyaWFibGUgIkNsaWVudGUiIHBhcmEgYW7DoWxpc2lzIGRlc2NyaXB0aXZvIApgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwcm9kdWNjaW9udG90YWwkQ0xJRU5URTwtYXMuZmFjdG9yKHByb2R1Y2Npb250b3RhbCRDTElFTlRFKSAgCnN0cihwcm9kdWNjaW9udG90YWwpCmBgYAoKIyMjIElkZW50aWZpY2FyIHZhbG9yZXMgZmFsdGFudGVzIApgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzdW0oaXMubmEocHJvZHVjY2lvbnRvdGFsKSkKYGBgCgoqKsK/Q3XDoW50b3MgTkEgdGVuZ28gcG9yIHZhcmlhYmxlPyoqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnNhcHBseShwcm9kdWNjaW9udG90YWwsIGZ1bmN0aW9uKHgpIHN1bSAoaXMubmEoeCkpKQpgYGAKCiMjIyBSZWVtcGxhemFyIGxvcyByZWdpc3Ryb3MgTkEgZGUgbGEgdGFibGEgY29uIGxhIG1lZGlhbmEgCioqSW5zdGFsYXIgcGFxdWV0ZXMgeSBsaWJyZXJpYXMgbmVjZXNhcmlhcyoqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQpsaWJyYXJ5KGRwbHlyKQpgYGAKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcHJvZHVjY2lvbnRvdGFsPC1wcm9kdWNjaW9udG90YWwgJT4lIG11dGF0ZShQSUVaQVMuUFJPRy49aWZlbHNlKGlzLm5hKFBJRVpBUy5QUk9HLiksbWVkaWFuKFBJRVpBUy5QUk9HLixuYS5ybT1UKSxQSUVaQVMuUFJPRy4pKQpwcm9kdWNjaW9udG90YWw8LXByb2R1Y2Npb250b3RhbCAlPiUgbXV0YXRlKFRNTy4uTUlOLj1pZmVsc2UoaXMubmEoVE1PLi5NSU4uKSxtZWRpYW4oVE1PLi5NSU4uLG5hLnJtPVQpLFRNTy4uTUlOLikpCnByb2R1Y2Npb250b3RhbDwtcHJvZHVjY2lvbnRvdGFsICU+JSBtdXRhdGUobGFtaW5hc19wcm9jZXNhZGFzPWlmZWxzZShpcy5uYShMYW1pbmFzLnByb2Nlc2FkYXMpLG1lZGlhbihMYW1pbmFzLnByb2Nlc2FkYXMsbmEucm09VCksTGFtaW5hcy5wcm9jZXNhZGFzKSkKcHJvZHVjY2lvbnRvdGFsPC1wcm9kdWNjaW9udG90YWwgJT4lIG11dGF0ZShUSUVNUE8uQ0FMSURBRD1pZmVsc2UoaXMubmEoVElFTVBPLkNBTElEQUQpLG1lZGlhbihUSUVNUE8uQ0FMSURBRCxuYS5ybT1UKSxUSUVNUE8uQ0FMSURBRCkpCmBgYAoKIyMjIFZlcmlmaWNhciBsYSBzdW1hIGRlIE5BcwpgYGB7cm1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnN1bShpcy5uYShwcm9kdWNjaW9udG90YWwpKQpzYXBwbHkocHJvZHVjY2lvbnRvdGFsLCBmdW5jdGlvbih4KSBzdW0gKGlzLm5hKHgpKSkKYGBgCgojIyMgT21pdGlyIGxvcyB2YWxvcmVzIGlycmVsZXZhbnRlcyBpZGVudGlmaWNhZG9zCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnByb2R1Y2Npb250b3RhbCA8LSBuYS5vbWl0KHByb2R1Y2Npb250b3RhbCkKc3VtbWFyeShwcm9kdWNjaW9udG90YWwpICAgCnN1bShpcy5uYShwcm9kdWNjaW9udG90YWwpKQpgYGAKCioqVGVjbmljYXMgVXRpbGl6YWRhcyoqCkxhcyB0ZWNuaWNhcyBkZSBsaW1waWV6YSB1dGlsaXphZGFzIGZ1ZXJvbiBlbGltaW5hciBjb2x1bW5hcyBpcnJlbGV2YW50ZXMgcGFyYSBlbCBhbsOhbGlzaXMsIGNhbWJpYXIgYSBlbnRlcm8gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzLGNvbnZlcnRpciBmb3JtYXRvIGRlIGxhIGZlY2hhLCBjb252ZXJ0aXIgdmFyaWFibGUgIkNsaWVudGUiIHBhcmEgYW7DoWxpc2lzIGRlc2NyaXB0aXZvLCBSZWVtcGxhemFyIGxvcyByZWdpc3Ryb3MgTkEgZGUgbGEgdGFibGEgY29uIGxhIG1lZGlhbmEgLCBWZXJpZmljYXIgbGEgc3VtYSBkZSBOQXMsIE9taXRpciBsb3MgdmFsb3JlcyBpcnJlbGV2YW50ZXMgaWRlbnRpZmljYWRvcy4KCgojIyMgRXhwb3J0YXIgYmFzZSBkZSBkYXRvcwpgYGB7cn0Kd3JpdGUuY3N2KHByb2R1Y2Npb250b3RhbCwicHJvZHVjY2lvbnRvdGFsLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkKYGBgCgoqKkVuIGxhcyB0YWJsYXMgYW50ZXJpb3JlcyBzZSBwdWVkZSBvYnNlcnZhciBjb21vIGVsIGNsaWVudGUgcXVlIG3DoXMgcGllemFzIHByb2dyYW1hZGFzIHRpZW5lLCAiWUFORkVORyIgc2UgbGUgZGVkaWNhIHVuIHRpZW1wbyBkZSBjYWxpZGFkIGRlIDEuMSBtaW51dG8sIHNpZW5kbyBjYXNpIGVsIHRpZW1wbyBtw61uaW1vIGRlIGRlZGljYWNpw7NuLiBNaWVudHJhcyBxdWUgZWwgY2xpZW50ZSBWTC0wMTctMTQ4NiBlcyBlbCBjbGllbnRlIGVsIGN1YWwgdGllbmUgY2FzaSBsYSBtaXRhZCBkZSBwaWV6YXMgcHJvZ3JhbWFkYXMgcXVlIFlBTkZFTkcgc2luIGVtYmFyZ28gYWwgcXVlIG3DoXMgdGllbXBvIHNlIGxlIGRlZGljYS4gUG9yIGxvIHF1ZSBzZSBwdWVkZSBpbmZlcmlyIHF1ZSBzdXMgcGllemFzIHB1ZGllcmFuIHNlciBkZSBtdWNobyBtw6FyZ2VuIGRlIGVycm9yLioqCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIj4gKlByZWRpY2Npb24gZGUgRGVzZW1wZcOxbyBkZSBsYSBpbmR1c3RyaWEgYXV0b21vdHJpeioKIyMjIE1vZGVsbyBwcmVkaWN0aXZvIAoKIyMjIEltcG9ydGFyIGxhIGJhc2UgZGUgZGF0b3MgeSBlbnRlbmRlcmxhCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmV4dGVybmEgPC0gcmVhZC5jc3YoIi9Vc2Vycy9hbmRyZWFwYW9sYXNvc2EvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtSW5zdGl0dXRvVGVjbm9sb2dpY295ZGVFc3R1ZGlvc1N1cGVyaW9yZXNkZU1vbnRlcnJleS91c19tb3Rvcl9wcm9kdWN0aW9uX2FuZF9kb21lc3RpY19zYWxlcy5jc3YiKQpzdW1tYXJ5KGV4dGVybmEpCmBgYAoKIyMjIEluc3RhbGFyIGxpYnJlcmlhcyBuZWNlc2FyaWFzCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoanRvb2xzKSAgICAgICAKbGlicmFyeShsbXRlc3QpICAgICAgCmxpYnJhcnkoY2FyKSAgICAgICAgICAKbGlicmFyeShvbHNycikgCmBgYAoKIyMjIFJlYWxpemFyIHJlZ3Jlc2nDs24gMQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpyZWdyZXNpb24gPC0gbG0oUHJvZHVjdGlvbl9Db21tZXJjaWFsX1ZlaGljbGVzIH4gVVNfVW5lbXBsb3ltZW50ICsgVVNfQ29uc3VtZXJfQ29uZmlkZW5jZSArIFVTX01pbl9Ib3VyX1dhZ2UgLCBkYXRhPWV4dGVybmEpCnN1bW1hcnkocmVncmVzaW9uKQpgYGAKCioqQW5hbGl6YXIgZWwgY29tcG9ydGFtaWVudG8gZGUgbGFzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcyBlbiBsYSByZWdyZXNpw7NuKioKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZWZmZWN0X3Bsb3QocmVncmVzaW9uLHByZWQ9VVNfQ29uc3VtZXJfQ29uZmlkZW5jZSxpbnRlcnZhbD1UUlVFKQpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmVmZmVjdF9wbG90KHJlZ3Jlc2lvbixwcmVkPVVTX1VuZW1wbG95bWVudCxpbnRlcnZhbD1UUlVFKQpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmVmZmVjdF9wbG90KHJlZ3Jlc2lvbixwcmVkPVVTX01pbl9Ib3VyX1dhZ2UsaW50ZXJ2YWw9VFJVRSkKYGBgCioqQW5hbGlzaXMgRXhwbG9yYXRvcmlvKioKU2llbmRvIGxhIFByb2R1Y2Npw7NuIGRlIEF1dG9zIENvbWVyY2lhbGVzIGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlLCBzZSBwdWVkZSB2ZXIgIGNvbW8gZWwgc2FsYXJpbywgbGEgY29uZmlhbnphIGRlbCBjb25zdW1pZG9yIHkgZWwgZGVzZW1wbGVvIGdlbmVyYW4gY2FtYmlvcyBlbiBlbGxhLiBFcyBkZWNpciwgc2Ugb2JzZXJ2YSBxdWUgbGEgcXVlIG1heW9yIGltcGFjdG8gdGllbmUgZXMgbGEgY29uZmlhbnphIGRlbCBjb25zdW1pZG9yIGRlYmlkbyBhIHF1ZSB2YWxvciBwIGVzdGEgYWJham8gZGVsIDEwJSwgZSBpbmNsdXNvIHNlIG9ic2VydmEgc3UgY29tcG9ydGFtaWVudG8gZW4gbGEgZ3LDoWZpY2EgY29tbyBzaSBsYSBwcm9kdWNjacOzbiBzdWJlLCBsYSBjb25maWFuemEgZGVsIGNvbnN1bWlkb3IgaWd1YWwgYXVtZW50YS4gCgoKIyMjIFJlYWxpemFyIHJlZ3Jlc2nDs24gMiAKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcmVncmVzaW9uMiA8LSBsbShQcm9kdWN0aW9uX1Bhc3Nlbmdlcl9DYXJzIH4gVVNfVW5lbXBsb3ltZW50ICsgVVNfQ29uc3VtZXJfQ29uZmlkZW5jZSArIFVTX01pbl9Ib3VyX1dhZ2UgLCBkYXRhPWV4dGVybmEpCnN1bW1hcnkocmVncmVzaW9uMikKYGBgCgoqKkFuYWxpemFyIGVsIGNvbXBvcnRhbWllbnRvIGRlIGxhcyB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMgZW4gbGEgcmVncmVzacOzbioqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmVmZmVjdF9wbG90KHJlZ3Jlc2lvbjIscHJlZD1VU19Db25zdW1lcl9Db25maWRlbmNlLGludGVydmFsPVRSVUUpCmBgYAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZWZmZWN0X3Bsb3QocmVncmVzaW9uMixwcmVkPVVTX1VuZW1wbG95bWVudCxpbnRlcnZhbD1UUlVFKQpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmVmZmVjdF9wbG90KHJlZ3Jlc2lvbjIscHJlZD1VU19NaW5fSG91cl9XYWdlLGludGVydmFsPVRSVUUpCmBgYAoqKkFuYWxpc2lzIEV4cGxvcmF0b3JpbyoqCkEgZGlmZXJlbmNpYSBkZSBsYSBwcmltZXJhIHZhcmlhYmxlIGRlcGVuZGllbnRlLCBzZSBvYnNlcnZhIGNvbW8gbGEgcHJvZHVjY2nDs24gZGUgYXV0b3MgZGUgcGFzYWplcm8gdGllbmUgY29lZmljaWVudGVzIG5lZ2F0aXZvcyBlbiBsYXMgdmFyaWFibGVzIGluZGVwZW5kaWVudGVzIGRlbCBkZXNlbXBsZW8geSBjb25maWFuemEgZGVsIGNvbnN1bWlkb3IgcG9yIGxvIHRhbnRvIHN1IGNvbXBvcnRhbWllbnRvIGVuIGxhcyBncsOhZmljYXMgYSBwZXNhciBkZSBxdWUgZXhpc3RhIHVuYSBwcm9kdWNjacOzbiBhbHRhIHN1IHRlbmRlbmNpYSB2YSBwYXJhIGFiYWpvLgoKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpvcmFuZ2UiPiAqTWVybWEqCgojIyMgSW1wb3J0YXIgYmFzZSBkZSBkYXRvcwpgYGB7cn0KYmQgPC1yZWFkLmNzdiAoIi9Vc2Vycy9hbmRyZWFwYW9sYXNvc2EvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtSW5zdGl0dXRvVGVjbm9sb2dpY295ZGVFc3R1ZGlvc1N1cGVyaW9yZXNkZU1vbnRlcnJleS9GT1JNIC0gTWVybWEgbGltcGlhMi5jc3YiKQpgYGAKIyMjIEFuYWxpemFyIGJhc2UgZGUgZGF0b3MuCmBgYHtyfQpzdW1tYXJ5KGJkKQpzdHIoYmQpCmRlc2NyaWJlKGJkKQpgYGAKIyMjIEluc3RhbGFyIGxpYnJlcmlhcyAKYGBge3J9CiMgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKI2xpYnJhcnkodGlkeXZlcnNlKQojIGluc3RhbGwucGFja2FnZXMoImphbml0b3IiKQojbGlicmFyeShqYW5pdG9yKQojbGlicmFyeShkcGx5cikKI2xpYnJhcnkoZ2dwbG90MikKYGBgCiMjIyBUaXBvcyBkZSBWYXJpYWJsZXMKYGBge3J9ClZhcmlhYmxlPC1jKCJGZWNoYSIsIkVORVJPIiwiS2lsb3NFbmVybyIsIkZlY2hhMSIsIkZFQlJFUk8iLCJLaWxvc0ZlYnJlcm8iLCJGZWNoYTIiLCJNQVJaTyIsIktpbG9zTWFyem8iLCJGZWNoYTMiLCJBQlJJTCIsIktpbG9zQWJyaWwiLCJGZWNoYTQiLCJNQVlPIiwiS2lsb3NNYXlvIiwiRmVjaGE1IiwiSlVOSU8iLCJLaWxvc0p1bmlvIiwiRmVjaGE2IiwiSlVMSU8iLCJLaWxvc0p1bGlvIiwiRmVjaGE3IiwiQUdPU1RPIiwiS2lsb3NBZ29zdG8iLCJGZWNoYTgiLCJTRVBUSUVNQlJFIiwiS2lsb3NTZXB0aWVtYnJlIikKVHlwZTwtYygicXVhbGl0YXRpdmUgKG5vbWluYWwpIiwgInF1YWxpdGF0aXZlIChvcmRpbmFsKSIsICJxdWFudGl0YXRpdmUgKGRpc2NyZXRlKSIsInF1YWxpdGF0aXZlIChub21pbmFsKSIsInF1YWxpdGF0aXZlIChvcmRpbmFsKSIsInF1YW50aXRhdGl2ZSAoZGlzY3JldGUpIiwicXVhbGl0YXRpdmUgKG5vbWluYWwpIiwicXVhbGl0YXRpdmUgKG9yZGluYWwpIiwicXVhbnRpdGF0aXZlIChkaXNjcmV0ZSkiLCJxdWFsaXRhdGl2ZSAobm9taW5hbCkiLCJxdWFsaXRhdGl2ZSAob3JkaW5hbCkiLCJxdWFudGl0YXRpdmUgKGRpc2NyZXRlKSIsInF1YWxpdGF0aXZlIChub21pbmFsKSIsInF1YWxpdGF0aXZlIChvcmRpbmFsKSIsInF1YW50aXRhdGl2ZSAoZGlzY3JldGUpIiwicXVhbGl0YXRpdmUgKG5vbWluYWwpIiwicXVhbGl0YXRpdmUgKG9yZGluYWwpIiwicXVhbnRpdGF0aXZlIChkaXNjcmV0ZSkiLCJxdWFsaXRhdGl2ZSAobm9taW5hbCkiLCJxdWFsaXRhdGl2ZSAob3JkaW5hbCkiLCJxdWFudGl0YXRpdmUgKGRpc2NyZXRlKSIsInF1YWxpdGF0aXZlIChub21pbmFsKSIsInF1YWxpdGF0aXZlIChvcmRpbmFsKSIsInF1YW50aXRhdGl2ZSAoZGlzY3JldGUpIiwicXVhbGl0YXRpdmUgKG5vbWluYWwpIiwicXVhbGl0YXRpdmUgKG9yZGluYWwpIiwicXVhbnRpdGF0aXZlIChkaXNjcmV0ZSkiKQp0YWJsZTwtZGF0YS5mcmFtZShWYXJpYWJsZSxUeXBlKQprbml0cjo6a2FibGUodGFibGUpCmBgYAojIyMgRWxpbWluYXIgTkEncyB5IHN1c3RpdHVpciBjb24gMCdzCmBgYHtyfQpzdW0oaXMubmEoYmQpKQpiZFtpcy5uYShiZCldPC0wCmBgYAojIyMgRWxpbWluYXIgZHVwbGljYWRvcwpgYGB7cn0KYmRbZHVwbGljYXRlZChiZCksIF0Kc3VtKGR1cGxpY2F0ZWQoYmQpKQpgYGAKIyMjIEVsaW1pbmFyIG5lZ2F0aXZvcyBjb24gY2VybwpgYGB7cn0KYmQxPC1iZApiZDFbYmQxIDwwXSA8LTAKc3VtbWFyeShiZDEpCmBgYAojIyMgQW5hbGlzaXMgUHJvZnVuZG8gZGUgbGEgQmFzZSBkZSBkYXRvcwpgYGB7cn0KbWVkaWFfYmQ1IDwtIG1lYW4oYmQkS2lsb3NNYXlvKQptZWRpYV9iZDUKbWVkaWFuX2JkNSA8LSBtZWRpYW4oYmQkS2lsb3NNYXlvKQptZWRpYW5fYmQ1Cm1vZGVfYmQ1IDwtIG1vZGUoYmQkS2lsb3NNYXlvKQptb2RlX2JkNQoKbWVkaWFfYmQ4IDwtIG1lYW4oYmQkS2lsb3NBZ29zdG8pCm1lZGlhX2JkOAptZWRpYW5fYmQ4IDwtIG1lZGlhbihiZCRLaWxvc0Fnb3N0bykKbWVkaWFuX2JkOAptb2RlX2JkOCA8LSBtb2RlKGJkJEtpbG9zQWdvc3RvKQptb2RlX2JkOApgYGAKIyMjIEdyYWZpY2EgRnJlY3VlbmNpYSAoRmVjaGEpCmBgYHtyfQpiZCRGZWNoYTc8LSBhcy5EYXRlKGJkJEZlY2hhNyxmb3JtYXQgPSAiJWQvJW0vJVkiKQpwbG90KGJkJEZlY2hhNywgYmQkS2lsb3NBZ29zdG8pCmBgYAoKIyMjIEVsaW1pbmFyIGNvbHVtbmFzCmBgYHtyfQpiZDIgPC1iZApiZDIgPC0gc3Vic2V0IChiZDIsIHNlbGVjdCA9IC1jIChGZWNoYSkpCmBgYAoKIyMjIEdyYWZpY2EgZGUgTWF5byAmIEFnb3N0byAoTWF5b3IgY2FudGlkYWQgZGUgbWVybWEgeSByZWdpc3Ryb3MpCmBgYHtyfQpnZ3Bsb3QoYmQsIGFlcyh4PSBGZWNoYTQsIHk9IEtpbG9zTWF5bykpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsPSJibHVlIikgKyBzY2FsZV9maWxsX2dyZXkoKSArIGxhYnModGl0bGUgPSAiS2lsb3MgZGUgbWVybWEgQWdvc3RvIiwgeCA9ICJGZWNoYSIpCgpnZ3Bsb3QoYmQsIGFlcyh4PSBGZWNoYTcsIHk9IEtpbG9zQWdvc3RvKSkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGw9ImJsdWUiKSArIHNjYWxlX2ZpbGxfZ3JleSgpICsgbGFicyh0aXRsZSA9ICJLaWxvcyBkZSBtZXJtYSBBZ29zdG8iLCB4ID0gIkZlY2hhIikKYGBgCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIj4gKlByb25vc3RpY28gZGUgbGEgSW5kdXN0cmlhIEF1dG9tb3RyaXoqCgojIyMgSW5zdGFsYXIgcGFxdWV0ZXMgeSBsbGFtYXIgbGlicmVyaWFzCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygiZm9yZWNhc3QiKQpsaWJyYXJ5KGZvcmVjYXN0KQpgYGAKCiMjIyBTdW1hciBlbCBUb3RhbCBkZSBLaWxvc3hNZXMKYGBge3J9CnN1bShiZCRLaWxvc0VuZXJvKQpzdW0oYmQkS2lsb3NGZWJyZXJvKQpzdW0oYmQkS2lsb3NNYXJ6bykKc3VtKGJkJEtpbG9zQWJyaWwpCnN1bShiZCRLaWxvc01heW8pCnN1bShiZCRLaWxvc0p1bmlvKQpzdW0oYmQkS2lsb3NKdWxpbykKc3VtKGJkJEtpbG9zQWdvc3RvKQpzdW0oYmQkS2lsb3NTZXB0aWVtYnJlKQpgYGAKCiMjIyBDcmVhciBzZXJpZSBkZSB0aWVtcG8KYGBge3J9Cm1lcm1hIDwtIGMoMTQ1NjAsMjI4MzAsMjI0NzAsMTg4MjAsMjM0MTAsMTgyODAsMTkzNzAsMzIxMDAsMTM1ODYpCgpwcm9kdWNjaW9uX3N0IDwtIHRzKGRhdGEgPSBtZXJtYSwgc3RhcnQgPSBjKDIwMjIsMSksIGZyZXF1ZW5jeSA9IDEyKQpwcm9kdWNjaW9uX3N0CmBgYAoKCiMjIyBHcmFmaWNhciBQcm9ub3N0aWNvCmBgYHtyfQptb2RlbG8gPC0gYXV0by5hcmltYShwcm9kdWNjaW9uX3N0KQptb2RlbG8KCnByb25vc3RpY28gPC0gZm9yZWNhc3QobW9kZWxvLCBsZXZlbD1jKDk1KSwgaD0zKQpwcm9ub3N0aWNvCgpwbG90KHByb25vc3RpY28pCmBgYAoqKlRlY25pY2FzIFV0aWxpemFkYXMqKgpQYXJhIGxhIGVsYWJvcmFjaW9uIGRlIGVzdGUgYW5hbGlzaXMgZnVlIG5lY2VzYXJpbyB1dGlsaXphciBjaWVydGFzIHRlY25pY2FzIGRlIGxpbXBpZXphIGFudGVzLCBjb21vIHNlciwgRWxpbWluYXIgTkEncyB5IHN1c3RpdHVpciBjb24gMCdzLCBFbGltaW5hciBkdXBsaWNhZG9zLEVsaW1pbmFyIG5lZ2F0aXZvcyBjb24gY2VybywgRWxpbWluYXIgY29sdW1uYXMuIFRvZGFzIGxhcyB0ZWNuaWNhcyBtZW5jaW9uYWRhcyBhbnRlcmlvcm1lbnRlIHNvbiB1dGlsaXphZGFzIHBhcmEgcG9kZXIgb2J0ZW5lciB1biBhbmFsaXNpcyBtYXMgcHJlY2lzbyBlbGltaW5hbmRvIGluZm9ybWFjaW9uIHF1ZSBubyBhcG9ydGEgYSBsYSByZWFsaXphY2lvbiBkZSBlc3RlLgoKQ29tbyBzZSBwdWVkZSBvYmVydmFyIGVuIGxhIGdyYWZpY2EgZGUgcHJvbm9zdGljbywKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpvcmFuZ2UiPiAqU2NyYXAqCgojIyMgIEltcG9ydGFyIGJhc2UgZGUgZGF0b3MKYGBge3J9CmJkIDwtIHJlYWQuY3N2ICgiL1VzZXJzL2FuZHJlYXBhb2xhc29zYS9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1JbnN0aXR1dG9UZWNub2xvZ2ljb3lkZUVzdHVkaW9zU3VwZXJpb3Jlc2RlTW9udGVycmV5L0ZPUk0gLSBTY3JhcCBMaW1waWEgICgyKS5jc3YiKQpgYGAKCiMjIyAgVGlwb3MgZGUgVmFyaWFibGVzIEV4aXN0ZW50ZXMKYGBge3J9CnZhcmlhYmxlPC1jKCJSZWZlcmVuY2lhIiwiRmVjaGEiLCAiSG9yYSIsICJQcm9kdWN0byIsICJDYW50aWRhZCIsICJVbmlkYWQuZGUubWVkaWRhIiwgIlViaWNhY2nDs24uZGUub3JpZ2VuIiwgIlViaWNhY2nDs24uZGUuZGVzZWNobyIsICJFc3RhZG8iKQoKdHlwZTwtYygiQ3VhbGl0YXRpdm8gKG5vbWluYWwpIiwiQ3VhbnRpdGF0aXZvIChkaXNjY3JldGEpIiwgIkN1YW50aXRhdGl2byAoZGlzY3JldGEpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIsIkN1YW50aXRhdGl2byAoQ29udGludWEpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIsICJDdWFsaXRhdGl2byAobm9taW5hbCkiLCJDdWFsaXRhdGl2byAobm9taW5hbCkiLCJDdWFsaXRhdGl2byAobm9taW5hbCkiKQoKRXNjYWxhX2RlX01lZGljacOzbjwtYygiTnVtZXJvIiwgIkZlY2hhIiwgIkNhdGVnb3LDrWEiLCAiS2ciLCAiTWVkaWNpw7NuIiwgIlBvc2ljacOzbiIsICJQb3NpY2nDs24iLCAiRXN0YWRvIikKCgp0YWJsZTwtZGF0YS5mcmFtZSh2YXJpYWJsZSx0eXBlKQprbml0cjo6a2FibGUodGFibGUpCmBgYAoKIyMjIENhbnRpZGFkIGRlIHByb2R1Y3RvcyBwb3IgZMOtYSAKYGBge3J9CmJkJEZlY2hhPC0gYXMuRGF0ZShiZCRGZWNoYSxmb3JtYXQgPSAiJWQvJW0vJVkiKQpwbG90KGJkJEZlY2hhLCBiZCRDYW50aWRhZCkKCnN1bW1hcnkoYmQpCgojbGlicmFyeSh0aWR5dmVyc2UpCiNsaWJyYXJ5KGphbml0b3IpCmBgYAoKIyMjIE7Dum1lcm8gZGUgdmFyaWFibGVzIHkgcmVnaXN0cm9zIGVuIGJhc2UgZGUgZGF0b3MKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJwc3ljaCIpCmxpYnJhcnkocHN5Y2gpCiNkZXNjcmliZShiZCkKc3RyKGJkKQoKI3RhYnlsKGJkLCBQcm9kdWN0bywgVWJpY2FjacOzbi5kZS5vcmlnZW4pCmBgYAoKIyMjIFRpcG9zIGRlIFZhcmlhYmxlcyBFeGlzdGVudGVzCmBgYHtyfQp2YXJpYWJsZTwtYygiUmVmZXJlbmNpYSIsIkZlY2hhIiwgIkhvcmEiLCAiUHJvZHVjdG8iLCAiQ2FudGlkYWQiLCAiVW5pZGFkLmRlLm1lZGlkYSIsICJVYmljYWNpw7NuLmRlLm9yaWdlbiIsICJVYmljYWNpw7NuLmRlLmRlc2VjaG8iKQoKdHlwZTwtYygiQ3VhbGl0YXRpdm8gKG5vbWluYWwpIiwiQ3VhbnRpdGF0aXZvIChkaXNjY3JldGEpIiwgIkN1YW50aXRhdGl2byAoZGlzY3JldGEpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIsIkN1YW50aXRhdGl2byAoQ29udGludWEpIiwgIkN1YWxpdGF0aXZvIChub21pbmFsKSIsICJDdWFsaXRhdGl2byAobm9taW5hbCkiLCJDdWFsaXRhdGl2byAobm9taW5hbCkiKQoKdGFibGU8LWRhdGEuZnJhbWUodmFyaWFibGUsdHlwZSkKa25pdHI6OmthYmxlKHRhYmxlKQpgYGAKCiMjIyBMaW1waWV6YSBkZSBkYXRvcyAKYGBge3J9CiMjIEVsaW1pbmFyIGNvbHVtbmFzIHF1ZSBubyBzZSB1c2FuICAKCmJkMSA8LSBiZApiZDE8LSBzdWJzZXQoYmQxLCBzZWxlY3QgPSAtYyAoUmVmZXJlbmNpYSwgUHJvZHVjdG8sIFVuaWRhZC5kZS5tZWRpZGEsIEhvcmEsIFViaWNhY2nDs24uZGUuZGVzZWNobywgRXN0YWRvKSkKCiMjIEJvcnJhciBOL0EncyAKYGBgCgoqKlRlY25pY2FzIFV0aWxpemFkYXMqKgpFbGltaW5hciBjb2x1bW5hcyBpbm5lY2VzYXJpYXMgcGFyYSBmYWNpbGl0YXIgZWwgYW5hbGlzaXMgY29uIGRhdG9zIHJlbGV2YW50ZXMuCkJvcnJhciBOQSdzIHlhIHF1ZSBubyBkaWNlbiBpbmZvcm1hY2lvbiByZWxldmFudGUgcGFyYSBlbCBhbmFsaXNpcy4KCgpgYGB7cn0KYmQyIDwtIGJkCmJkMjwtIHN1YnNldChiZDIsIHNlbGVjdCA9IC1jIChSZWZlcmVuY2lhLCBQcm9kdWN0bywgVW5pZGFkLmRlLm1lZGlkYSwgSG9yYSwgVWJpY2FjacOzbi5kZS5kZXNlY2hvLCBFc3RhZG8pKQoKbWVkaWEgPC0gbWVhbihiZDIkQ2FudGlkYWQpCgptZWRpYW5hIDwtIG1lZGlhbihiZDIkQ2FudGlkYWQpCgptb2RlIDwtIGZ1bmN0aW9uICh4KSB7CiAgdXggPC0gdW5pcXVlKHgpCiAgdXggW3doaWNoLm1heCh0YWJ1bGF0ZShtYXRjaCh4LHV4KSkpXQp9Cgptb2RlIDwtIG1vZGUoYmQyJENhbnRpZGFkKQptb2RlCgpoaXN0KGJkMiRDYW50aWRhZCkKYGBgCgpgYGB7cn0KCmdncGxvdChiZDIsIGFlcyh4PW1lZGlhLCB5PSBVYmljYWNpw7NuLmRlLm9yaWdlbikpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGZpbGw9InJlZCIpICsgc2NhbGVfZmlsbF9ncmV5KCkgKyAjIEFkZCBiYXJzIHRvIHRoZSBwbG90CiAgbGFicyh0aXRsZSA9ICJTY3JhcCBlbXByZXNhIEZPUk0iLCAjIEFkZCBhIHRpdGxlCiAgICAgICBzdWJ0aXRsZSA9ICIiLCAjIEFkZCBhIHN1YnRpdGxlCiAgICAgICBjYXB0aW9uID0gIlJlbGFjacOzbiIsICMgQWRkIGEgY2FwdGlvbgogICAgICAgeCA9ICJUb25lbGFkYXMiKQoKYGBgCioqQW5hbGlzaXMgRXhwbG9yYXRvcmlvKioKQSB0cmF2ZXMgZGUgYW5hbGlzaXMgcmVhbGl6YWRvLCBzZSBwZXVkZSBvYmVydmFyIGVuIGVsIGdyYWZpY28gcXVlIGVsIMOhcmVhIGRvbmRlIG3DoXMgc2UgZ2VuZXJhIGRlc3BlcmRpY2lvIGVzIGVuIFNBQi9QcmUtUHJvZHVjdGlvbiBjb24gYWwgcmVkZWRvciBkZSAxMjAwIHRvbmVsYWRhcy4gRXN0ZSBlcyB1biBpbnNpZ2h0IG11eSBpbnRlcmVzYW50ZSB5YSBxdWUgc2UgbG9ncmEgaWRlbnRpZmljYXIgZGUgZG9uZGUgdmllbmUgbGEgbWF5b3JpYSBkZSBkZXNwZXJkaWNpbyB5IHNlIHB1ZWRlIHJlYWxpemFyIHVuIGNvbnRyYXN0ZSBjb24gbGFzIG90cmFzIGFyZWFzIGxhcyBjdWFsZXMgZXMgbXV5IHNpZ25pZmljYXRpdmEgbGEgZGlmZXJlbmNpYS4KQSByYWl6IGRlIGVzdG8gc2UgcHVlZGVuIGNvbWVuemFyIGEgcGVuc2FyIGVzdHJhdGVnaWFzIHBhcmEgaW1wbGVtZW50YXIgZGVudHJvIGRlbCBhcmVhIGRlIFNBQi9QcmUtUHJvZHVjdGlvbiBsYXMgY3VhbGVzIGJlbmVmaWNpYXJpYW4gYSBGb3JtIGNvbiBsYSBkaXNtaW51Y2lvbiBkZSBkZXNwZXJkaWNpby4KCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIj4gU2VjY2lvbiAzOiBLLW1lYW5zIGNsdXN0ZXJpbmcKKipEZWZpbmljacOzbiBkZSBjb25jZXB0b3MqKiAKQ29uY2VwdG9zIHF1ZSBjb250cmlidXllbiBhIGxhIGlkZW50aWZpY2FjacOzbiBkZSBjbHVzdGVycyB1c2FuZG8gYW5hbMOtdGljYSBkZSBkYXRvcy4gCgoqKkkuIEstIE1lYW5zIENsdXN0ZXJpbmcqKiAgCkstIG1lYW5zIGNsdXN0ZXJpbmcgdGllbmUgY29tbyBvYmpldGl2byBhZ3J1cGFyIGRhdG9zIGNvbiBjYXJhY3RlcsOtc3RpY2FzIHNpbWlsYXJlcyBlbiBlbCBtaXNtbyBjbHVzdGVyLiBVbm8gZGUgbG9zIGJlbmVmaWNpb3MgbcOhcyBncmFuZGVzIGRlIGxhIGhlcnJhbWllbnRhIGVzIHF1ZSBzZSBwdWVkZW4gcmVzdW1pciBkYXRvcyBkZSBncmFuIGRpbWVuc2nDs24uICAKCgoqKklJLiBVbnN1cGVydmlzZWQgTGVhcm5pbmcqKiAgCk5vIHNlIGFzaWduYW4gZXRpcXVldGFzIGFsIGFsZ29yaXRtbyBkZSBhcHJlbmRpemFqZSwgZGVqw6FuZG9sbyBzb2xvIHBhcmEgZW5jb250cmFyIGxhIGVzdHJ1Y3R1cmEgZW4gc3UgZW50cmFkYS4gIEVsIGFwcmVuZGl6YWplIG5vIHN1cGVydmlzYWRvIHB1ZWRlIHNlciB1biBmaW4gZW4gc8OtIG1pc21vIChkZXNjdWJyaXIgcGF0cm9uZXMgb2N1bHRvcyBlbiBsb3MgZGF0b3MpIG8gdW4gbWVkaW8gcGFyYSB1biBmaW4gKGFwcmVuZGl6YWplIGRlIGZ1bmNpb25lcykuICAKCioqSUlJLiBFdWNsaWVkZWFuIERpc3RhbmNlKiogIApMYSBkaXN0YW5jaWEgRXVjbGlkaWFuYSBlcyBlbCBjw6FsY3VsbyBkZSBkaXN0YW5jaWEgY29tw7pubWVudGUgdXRpbGl6YWRvIHBhcmEgbWVkaXIgbGEgZGlzdGFuY2lhIGVudHJlIGRvcyBwdW50b3MgZGUgZGF0b3MuIAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOm9yYW5nZSI+IEstbWVhbnMgQ2x1c3RlcnMKKipJbnN0YWxhciBsaWJyZXJpYXMqKgpgYGB7ciAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShmb3JlaWduKQpsaWJyYXJ5KGRwbHlyKSAgICAgICAgIyBkYXRhIG1hbmlwdWxhdGlvbiAKbGlicmFyeShnZ3Bsb3QyKSAgICAgICMgZGF0YSB2aXN1YWxpemF0aW9uIAojaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQpsaWJyYXJ5KHBzeWNoKSAgICAgICAgIyBmdW5jdGlvbnMgZm9yIG11bHRpdmFyaWF0ZSBhbmFseXNpcyAKbGlicmFyeShjb3JycGxvdCkgICAgICMgY29ycmVsYXRpb24gcGxvdHMKI2luc3RhbGwucGFja2FnZXMoImp0b29scyIpCmxpYnJhcnkoanRvb2xzKSAgICAgICAjIHByZXNlbnRhdGlvbiBvZiByZWdyZXNzaW9uIGFuYWx5c2lzIApsaWJyYXJ5KGxtdGVzdCkgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzIApsaWJyYXJ5KGNhcikgICAgICAgICAgIyBkaWFnbm9zdGljIGNoZWNrcyAtIGxpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzCmxpYnJhcnkoZmFjdG9leHRyYSkgICAjIHByb3ZpZGVzIGZ1bmN0aW9ucyB0byBleHRyYWN0IGFuZCB2aXN1YWxpemUgdGhlIG91dHB1dCBvZiBleHBsb3JhdG9yeSBtdWx0aXZhcmlhdGUgZGF0YSBhbmFseXNlcwojaW5zdGFsbC5wYWNrYWdlcygiZ2dmb3J0aWZ5IikKbGlicmFyeShnZ2ZvcnRpZnkpICAgICMgZGF0YSB2aXN1YWxpemF0aW9uIHRvb2xzIGZvciBzdGF0aXN0aWNhbCBhbmFseXNpcyByZXN1bHRzCmxpYnJhcnkocGx5cikKbGlicmFyeShiYXNlKQpsaWJyYXJ5KHRpYmJsZSkKYGBgCgoqKkNsdXN0ZXIgZWRhZCB5IHNhbGFyaW8gZGlhcmlvKioKKipMZWVyIGxhIGJhc2UgZGUgZGF0b3MqKiAKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KYmFqYXNkYXRhIDwtcmVhZC5jc3YoIi9Vc2Vycy9hbmRyZWFwYW9sYXNvc2EvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtSW5zdGl0dXRvVGVjbm9sb2dpY295ZGVFc3R1ZGlvc1N1cGVyaW9yZXNkZU1vbnRlcnJleS9SSEJBSkFTTElNUElBMS5jc3YiKQpzdW1tYXJ5KGJhamFzZGF0YSkKYGBgCgoqKkxpbXBpZXphLiBTZWxlY2Npb25hciB2YXJpYWJsZXMgcmVsZXZhbnRlcyoqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmJhamFzZGF0YTE8LWJhamFzZGF0YQpiYWphc2RhdGExPC1zdWJzZXQoYmFqYXNkYXRhLHNlbGVjdCA9IC1jKGdlbmVybyxmZWNoYV9hbHRhLG1vdGl2b19iYWphLHB1ZXN0byxlc3RhZG8sbm9tYnJlLGNvbG9uaWEsbXVuaWNpcGlvLG1vdGl2b19iYWphLCBlc3RhZG9fY2l2aWwsIGRpYXNfbGFib3JhZG9zLCBmZWNoYV9iYWphKSkKc3VtbWFyeShiYWphc2RhdGExKQpgYGAKCioqTGltcGllemEuIEVsaW1pbmFyIGVkYWQgMCoqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmJhamFzZGF0YTIgPC0gYmFqYXNkYXRhMQpiYWphc2RhdGEyPC1iYWphc2RhdGExWy1jKDk3LDE0OSksXQpgYGAKCioqTm9ybWFsaXphciBsYSBiYXNlIGRlIGRhdG9zKioKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KYmFqYXNfZGF0YV9ub3JtIDwtIHNjYWxlKGJhamFzZGF0YTJbMToyXSkKYGBgCgoqKklkZW50aWZpY2FyIG7Dum1lcm8gZGUgY2x1c3RlcnMqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpmdml6X25iY2x1c3QoYmFqYXNfZGF0YV9ub3JtLCBrbWVhbnMsIG1ldGhvZD0id3NzIikrIAogIGdlb21fdmxpbmUoeGludGVyY2VwdD00LCBsaW5ldHlwZT0yKSsgICAgICAgICAgIAogIGxhYnMoc3VidGl0bGUgPSAiRWxib3cgbWV0aG9kIikgICAgCmBgYAoKKipWaXN1YWxpemFyIGVsIGNsdXN0ZXIqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQplZGFkX2NsdXN0ZXIxPC1rbWVhbnMoYmFqYXNfZGF0YV9ub3JtLDMpCmVkYWRfY2x1c3RlcjEKYGBgCmBgYHtyfQpmdml6X2NsdXN0ZXIoZWRhZF9jbHVzdGVyMSxkYXRhPWJhamFzX2RhdGFfbm9ybSkKYGBgCioqQW5hbGlzaXMgUHJvZnVuZG8gZGVsIENsdXN0ZXIqKgpgYGB7ciAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KYmFqYXNkYXRhMzwtIGJhamFzZGF0YTIKYmFqYXNkYXRhMyRDbHVzdGVyczwtZWRhZF9jbHVzdGVyMSRjbHVzdGVyCmJhamFzZGF0YTQ8LWJhamFzZGF0YTMgJT4lIGdyb3VwX2J5KENsdXN0ZXJzKSAlPiUgc3VtbWFyaXNlKGVkYWQ9bWF4KGVkYWQpKSAlPiUgYXJyYW5nZShkZXNjKGVkYWQpKQpiYWphc2RhdGEzJENsdXN0ZXJfTmFtZXM8LWZhY3RvcihiYWphc2RhdGEzJENsdXN0ZXJzLGxldmVscyA9IGMoMSwyLDMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIkp1YmlsYWNpw7NuIiwgIkpvdmVuIiwgIkFkdWx0byIpKQpgYGAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmJhamFzZGF0YTUgPC0gYmFqYXNkYXRhMyAlPiUgZHBseXI6OiBncm91cF9ieShDbHVzdGVyX05hbWVzKSAlPiUgZHBseXI6OiBzdW1tYXJpemUoZWRhZF9hbm9zPW1heChlZGFkKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxfaW1zcz1tZWFuKHNhbF9pbXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50PW4oKSkKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpjbHVzdGVyczwtYXMuZGF0YS5mcmFtZShiYWphc2RhdGE1KQpjbHVzdGVycwpgYGAKKipHcsOhZmljbyBkZSBiYXJyYXMgZGUgbGFzIGJhamFzIGNvbiBlZGFkIG3DoXhpbWEgZGUgY2x1c3RlcioqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmdncGxvdChiYWphc2RhdGE1LCBhZXMoeD1DbHVzdGVyX05hbWVzLHk9ZWRhZF9hbm9zLGZpbGw9IENsdXN0ZXJfTmFtZXMsbGFiZWw9cm91bmQoZWRhZF9hbm9zLGRpZ2l0cz0yKSkpICsgCiAgZ2VvbV9jb2woKSArIAogIGdlb21fdGV4dCgpCmBgYAoqKkdyw6FmaWNvIGRlIGJhcnJhcyBkZSBsYXMgYmFqYXMgY29uIHN1IHNhbGFyaW8qKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3Bsb3QoYmFqYXNkYXRhNSxhZXMoeD1DbHVzdGVyX05hbWVzLHk9c2FsX2ltc3MgLGZpbGw9IENsdXN0ZXJfTmFtZXMsbGFiZWw9cm91bmQoc2FsX2ltc3MsZGlnaXRzPTIpKSkgKyAKICBnZW9tX2NvbCgpICsgIAogIGdlb21fdGV4dCgpCmBgYAoqKkRpc3BlcnNpw7NuIGRlIGxhIGVkYWQqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3Bsb3QoYmFqYXNkYXRhMywgYWVzKHg9Q2x1c3Rlcl9OYW1lcywgeT1lZGFkLCBmaWxsPUNsdXN0ZXJfTmFtZXMpKSArCiAgZ2VvbV9ib3hwbG90KCkrCiAgZ2d0aXRsZSgiRGlzcGVyc2lvbiBvZiAnRWRhZCcgYnkgQ2x1c3RlcnMgTmFtZXMiKQpgYGAKKipEaXNwZXJzacOzbiBkZWwgc2FsYXJpbyBkaWFyaW8qKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3Bsb3QoYmFqYXNkYXRhMywgYWVzKHg9Q2x1c3Rlcl9OYW1lcywgeT1zYWxfaW1zcywgZmlsbD1DbHVzdGVyX05hbWVzKSkgKwogIGdlb21fYm94cGxvdCgpKwogIGdndGl0bGUoIkRpc3BlcnNpb24gb2YgJ1NhbGFyaW9fRGlhcmlvJyBieSBDbHVzdGVycyBOYW1lcyIpCmBgYAoqKkNsdXN0ZXIgZWRhZCB5IGTDrWFzIGxhYm9yYWRvcyoqCmBgYHtyfQpSSEJBSkFTIDwtcmVhZC5jc3YoIi9Vc2Vycy9hbmRyZWFwYW9sYXNvc2EvTGlicmFyeS9DbG91ZFN0b3JhZ2UvT25lRHJpdmUtSW5zdGl0dXRvVGVjbm9sb2dpY295ZGVFc3R1ZGlvc1N1cGVyaW9yZXNkZU1vbnRlcnJleS9SSEJBSkFTTElNUElBMS5jc3YiKQpgYGAKKipBbmFsaXphciBiYXNlIGRlIGRhdG9zKioKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kc3VtbWFyeShSSEJBSkFTKQpzdHIoUkhCQUpBUykKZGVzY3JpYmUoUkhCQUpBUykKYGBgCgoqKkVkYWQgdnMgZGlhcyBsYWJvcmFkb3MtQ2x1c3RlcnMqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpSSEJBSkFTMTwtUkhCQUpBUwpSSEJBSkFTMTwtc3Vic2V0KFJIQkFKQVMxLHNlbGVjdCA9IC1jKGdlbmVybyxmZWNoYV9hbHRhLG1vdGl2b19iYWphLHB1ZXN0byxlc3RhZG8sbm9tYnJlLGNvbG9uaWEsbXVuaWNpcGlvLGZlY2hhX2JhamEpKQpzdW1tYXJ5KFJIQkFKQVMxKQpgYGAKKipFbGltaW5hciByZW5nbG9uZXMqKiAKKipFbGltaW5hbW9zIGRvcyByZWdsb25lcyBxdWUgdGVuaWFuIGNvbW8gZWRhZCAoMCkqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpSSEJBSkFTMiA8LSBSSEJBSkFTMQpSSEJBSkFTMiA8LSBSSEJBSkFTMiBbUkhCQUpBUzIkZWRhZD4gbWluKDEpLCBdCnN1bW1hcnkoUkhCQUpBUzIpCmBgYAoqKk5vcm1hbGl6YXIgbGEgYmFzZSBkZSBkYXRvcyoqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9ClJIX0VEQURfTk9STTwtc2NhbGUoUkhCQUpBUzJbMToyXSkKYGBgCioqU2UgdmlzdWFsaXphbiBlbCAjIGNvcnJlY3RvIGRlIGNsdXN0ZXJzIGEgcmVhbGl6YXIqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpmdml6X25iY2x1c3QoUkhfRURBRF9OT1JNLCBrbWVhbnMsIG1ldGhvZD0id3NzIikrIAogIGdlb21fdmxpbmUoeGludGVyY2VwdD00LCBsaW5ldHlwZT0yKSsgICAgICAgICAKICBsYWJzKHN1YnRpdGxlID0gIkVsYm93IG1ldGhvZCIpIApgYGAKCioqVmlzdWFsaXphciBlbCBjbHVzdGVyKioKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KUkhFREFEX0NsdXN0ZXIxPC1rbWVhbnMoUkhfRURBRF9OT1JNLDQpClJIRURBRF9DbHVzdGVyMQpmdml6X2NsdXN0ZXIoUkhFREFEX0NsdXN0ZXIxLGRhdGE9UkhfRURBRF9OT1JNKQpgYGAKCmBgYHtyfQpSSEVEQURfQ2x1c3RlcjE8LWttZWFucyhSSF9FREFEX05PUk0sNCkKUkhFREFEX0NsdXN0ZXIxCmBgYAoKKipWaXN1YWxpemFjaW9uIGRlbCBDbHVzdGVyKioKYGBge3J9CmZ2aXpfY2x1c3RlcihSSEVEQURfQ2x1c3RlcjEsZGF0YT1SSF9FREFEX05PUk0pCmBgYAoKKipBbmFsaXNpcyBQcm9mdW5kbyBkZWwgQ2x1c3RlcioqCmBgYHtyfQpSSEJBSkFTMyA8LSBSSEJBSkFTMgpSSEJBSkFTMyRDbHVzdGVyczwtUkhFREFEX0NsdXN0ZXIxJGNsdXN0ZXIKUkhCQUpBUzQ8LVJIQkFKQVMzICU+JSBncm91cF9ieShDbHVzdGVycykgJT4lIHN1bW1hcmlzZShlZGFkPW1heChlZGFkKSkgJT4lIGFycmFuZ2UoZGVzYyhlZGFkKSkKUkhCQUpBUzMkQ2x1c3Rlcl9OYW1lczwtZmFjdG9yKFJIQkFKQVMzJENsdXN0ZXJzLGxldmVscyA9IGMoMSwyLDMsNCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQWR1bHRvIiwgIlByaW5jaXBpYW50ZSIsICJNYXlvciIsICJKdXZlbmlsIikpCmBgYAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KUkhCQUpBUzYgPC0gUkhCQUpBUzMgJT4lIGdyb3VwX2J5KENsdXN0ZXJfTmFtZXMpICU+JSBkcGx5cjo6IHN1bW1hcml6ZShlZGFkX2Fub3M9bWF4KGVkYWQpLCAKZGlhc19sYWJvcmFkb3M9bWVhbihkaWFzX2xhYm9yYWRvcyksCkNvdW50PW4oKSkKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpjbHVzdGVyczwtYXMuZGF0YS5mcmFtZShSSEJBSkFTNikKY2x1c3RlcnMKYGBgCioqQW5hbGlzaXMgZGUgRGF0b3MgZGVsIGNsdXN0ZXIgZXhwcmVzYWRvcyBwb3IgZ3JhZmljYXMqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3Bsb3QoUkhCQUpBUzYsYWVzKHg9cmVvcmRlcihDbHVzdGVyX05hbWVzLENvdW50KSx5PUNvdW50LGZpbGw9Q2x1c3Rlcl9OYW1lcykpICsKICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpCmBgYAoqKkVkYWRlcyAobWF4aW1hcyksIGFsIGlndWFsIHNlIHB1ZWRlIHJlYWxpemFyIGNvbiB1biAoYmFycGxvdCkqKgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3Bsb3QoUkhCQUpBUzYsIGFlcyh4PUNsdXN0ZXJfTmFtZXMseT1lZGFkX2Fub3MsZmlsbD0gQ2x1c3Rlcl9OYW1lcyxsYWJlbD1yb3VuZChlZGFkX2Fub3MsZGlnaXRzPTIpKSkgKyAKICBnZW9tX2NvbCgpICsgCiAgZ2VvbV90ZXh0KCkKYGBgCioqRGlhcyBsYWJvcmFkb3MgKE1heGltb3MpKioKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZ2dwbG90KFJIQkFKQVM2LGFlcyh4PUNsdXN0ZXJfTmFtZXMseT1kaWFzX2xhYm9yYWRvcyxmaWxsPSBDbHVzdGVyX05hbWVzLGxhYmVsPXJvdW5kKGRpYXNfbGFib3JhZG9zLGRpZ2l0cz0yKSkpICsgCiAgZ2VvbV9jb2woKSArIAogIGdlb21fdGV4dCgpCmBgYAoqKkdyYWZpY2EgZGUgQm94cGxvdCAoQW5hbGlzaXMgZGUgbGFzIGVkYWRlcyBkZSBsb3MgNCBncnVwb3MuKSoqCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmdncGxvdChSSEJBSkFTMywgYWVzKHg9Q2x1c3Rlcl9OYW1lcywgeT1lZGFkLCBmaWxsPUNsdXN0ZXJfTmFtZXMpKSArCiAgZ2VvbV9ib3hwbG90KCkrCiAgZ2d0aXRsZSgiRWRhZCAoRGlzcGVyc2lvbikiKQpgYGAKCgojIyAgPHNwYW4gc3R5bGU9ImNvbG9yOm9yYW5nZSI+ICoqSGFsbGF6Z29zIGlkZW50aWZpY2Fjb3MgSy1NZWFucyoqIAoKRHVyYW50ZSBlc3RhIGFjdGl2aWRhZCByZWFsaXphbW9zIHVuIGFuw6FsaXNpcyBlbiBsYSBiYXNlIGRlIGRhdG9zIGRlIFJlY3Vyc29zIEh1bWFub3MsIGVuZm9jYWRvcyBlbiBsYXMgdmFyaWFibGVzIGRlIEVkYWQsIFNhbGFyaW8geSBEw61hcyBUcmFiYWphZG9zLCBwb3IgbG8gcXVlIHNlIGRlY2lkacOzIGRlZmluaXIgdmFyaW9zIHBhc29zIGEgc2VndWlyIHBhcmEgbGxlZ2FyIGFsIG9iamV0aXZvIGRlc2VhZG8gcXVlIGVyYSBmaW5hbG1lbnRlIGxsZWdhciBhIGxhIGNvbnN0cnVjY2nDs24gZGUgbG9zIGNsdXN0ZXJzLiAgCgpUb21hbmRvIGVuIGN1ZW50YSBsb3MgaGFsbGF6Z29zIGRlIGxhIGVkYWQgeSBlbCBzYWxhcmlvIGRpYXJpbywgc2UgbGxlZ28gYSBsYSBjb25jbHVzacOzbiBkZSBsbyBzaWd1aWVudGU6ICAgCgoKMS4gSGF5IG3DoXMgYmFqYXMgZGUgYWR1bHRvcyBjb24gZWwgcmFuZ28gZGUgZWRhZGVzIGRlIDQxIGEgNjEsIGVsIGN1w6FsIHNlIGlkZW50aWZpY28gY29tbyBqdWJpbGFjacOzbi4gICAKCjIuIExvcyBhZHVsdG9zIGRlIDMzLTQwIGHDsW9zIGdhbmFuIG3DoXMgY29uIHVuIHN1ZWxkbyBkaWFyaW8gZGUgMTg2LjE2IGVuIHByb21lZGlvLiAgCgoKRGUgaWd1YWwgbWFuZXJhIHBvZGVtb3Mgb2JzZXJ2YXIgY3VhdHJvIENsdXN0ZXJzIHF1ZSB0b21hbiBlbiBjdWVudGEgbGEgZWRhZCB5IGxvcyBkw61hcyBsYWJvcmFkb3M6ICAKCjEuIEVsIENsdXN0ZXIgUm9qbyAiQWR1bHRvIiBlcyB1biBncnVwbyBlbiBlbCBjdWFsIHNlIG9ic2VydmEgcXVlIHNvbiBsYXMgcGVyc29uYXMgZGUgZWRhZCBhbHRhIHkgY29uIHVuYSBjYXJhY3RlcsOtc3RpY2EgZW4gY29tw7puIHF1ZSBlcyBxdWUgZHVyYW4gcG9jbyB0aWVtcG8gbGFib3JhbmRvIGVuIGxhIGVtcHJlc2EuICAKMi4gRWwgQ2x1c3RlciBBenVsICJNYXlvciIgZXMgZWwgQ2x1c3RlciBxdWUgbcOhcyBzZSBhcGFydGEgZGUgbG9zIGRlbcOhcyBDbHVzdGVycyBkZWJpZG8gYSBxdWUgc29uIHBlcnNvbmFzIGNvbiBtYXlvciByYW5nbyBkZSBlZGFkIHkgbGEgbWF5b3IgcGFydGUgZGUgbG9zIGVtcGxlYWRvcyBjdWVudGFuIGNvbiBlc3RhIGVkYWQuICAKMy4gRWwgQ2x1c3RlciBNb3JhZG8gIkp1dmVuaWwiIGRvbmRlIHNlIGVuY3VlbnRyYW4gbGFzIHBlcnNvbmFzIGNvbiB1biByYW5nbyBkZSBlZGFkIGRlIGVudHJlIDMwIHkgMzYgYcOxb3MsIGhhYmllbmRvIG3DoXMgcGVyc29uYXMgZW4gZWwgcmFuZ28gZGUgbG9zIDMwIGEgMzIgYcOxb3MsICAKNC4gRWwgQ2x1c3RlciBWZXJkZSAiUHJpbmNpcGlhbnRlIiBlcyBlbCBncnVwbyBkZSBwZXJzb25hcyBtw6FzIGrDs3ZlbmVzIGVuIGxhIGVtcHJlc2EsIGNvbiB1biByYW5nbyBkZSBlbnRyZSAyMCB5IDMwIGHDsW9zLiAgCgoKRWwgZ3J1cG8gcXVlIGN1ZW50YSBjb24gbcOhcyBkw61hcyBsYWJvcmFkb3MgZXMgZWwgZGUgZWRhZCBtw6F4aW1hLCBzaWVuZG8gbG9zIGFkdWx0b3MsIGRlIGlndWFsIG1hbmVyYSBlc3RvcyBjdWVudGFuIGNvbiB1biBzYWxhcmlvIG1heW9yLiAgClBvciDDumx0aW1vIHBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGVuIGxvcyBncsOhZmljb3MgcXVlIHNlIGFuYWxpemFuIGNvbiBlc3RhcyB2YXJpYWJsZXMgdGVuZW1vcyBsb3Mgc2lndWllbnRlcyBwdW50b3MgYSBjb25zaWRlcmFjacOzbjogIAotIEVkYWQgTcOheGltYSAgIAotIETDrWFzIExhYm9yYWRvcyBNw6F4aW1vcyAgIAotIFJlY3VlbnRvIGRlIGxvcyBncnVwb3MgcXVlIHByZXNlbnRhbiBtYXlvciBhY3RpdmlkYWQgZW4gbGEgZW1wcmVzYS4gICAKLSBMYSBkaXNwZXJzacOzbiBkZSBlZGFkIHF1ZSBleGlzdGUgZW50cmUgY2FkYSB1bm8gZGUgbG9zIGdydXBvcy4KCgoKIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpvcmFuZ2UiPiAqU2VjY2lvbiA0KgoKKipBIHBhcnRpciBkZWwgYW7DoWxpc2lzIGRlIGxhcyBiYXNlcyBkZSBkYXRvcyBkZSBsYXMgZGlmZXJlbnRlcyDDoXJlYXMgZGUgbGEgZW1wcmVzYSBGT1JNLCBpZGVudGlmaWNhciB5IGRlc2NyaWJpciBsb3MgcHJpbmNpcGFsZXMgNi04IGhhbGxhemdvcyoqCihtZWFuaW5nZnVsIGluc2lnaHRzKS4KQSB0cmF2w6lzIGRlIGxvcyBkaWZlcmVudGVzIGFuw6FsaXNpcyByZWFsaXphZG9zIGVuIGxhcyBkaWZlcmVudGVzIGJhc2VzIGRlIGRhdG9zIHNlIHB1ZGllcm9uIG9idGVuZXIgaGFsbGF6Z29zIGltcG9ydGFudGVzIGVudHJlIGVsbG9zLCBhbGd1bm9zIGltcG9ydGFudGVzIGEgZGVzdGFjYXIgc29uOgpBbmFsaXphbmRvIGxhIGJhc2UgZGUgZGF0b3MgZGUgUkggc2UgcHVkbyBvYnNlcnZhciBxdWUgaGF5IHVuYSBhbHRhIHJvdGFjacOzbiBkZSBwZXJzb25hbC4gRXN0byBlcyBpbXBvcnRhbnRlIG1lbmNpb25hciB5YSBxdWUgcHVlZGUgYWZlY3RhciBhIGxhIHByb2R1Y3RpdmlkYWQgZGUgbGEgZW1wcmVzYSwgZXMgcG9yIGVzbyBxdWUgc2UgZGViZSB2ZXIgY29uIG3DoXMgZGV0YWxsZSBlc3RhIG9ic2VydmFjacOzbiB5IGFuYWxpemFyIGxhIHJhw616IGRlIGxvIHF1ZSBlc3TDoSBjYXVzYW5kbyBsYSByb3RhY2nDs24uCkVuIGxhIGJhc2UgZGUgZGF0b3MgZGUgZGVsaXZlcnkgcGxhbiBzZSBwdWRvIG9idGVuZXIgY3XDoWwgZnVlIGVsIGNsaWVudGUgY29uIG1heW9yIGltcG9ydGFuY2lhIHF1ZSBlbiBlc3RlIGNhc28gZnVlIOKAnEhlbGxh4oCdIHlhIHF1ZSBjdWVudGEgY29uIGVsIG1heW9yIG7Dum1lcm8gZGUgdW5pZGFkZXMgeSBvdXRsaWVycyBwb3IgZW5jaW1hIGRlIGxhIG1lZGlhLgpFbiBjdWFudG8gYSBsYSBiYXNlIGRlIGRlbGl2ZXJ5IHBlcmZvcm1hbmNlLCBzZSBwdWRpZXJvbiBvYnRlbmVyIGNpZXJ0b3MgaGFsbGF6Z29zIGRlIGdyYW4gaW50ZXLDqXMuIFBvciBlamVtcGxvLCBNYWhsZSBlcyBlbCBjbGllbnRlIGNvbiBtYXlvcmVzIHJldHJhc29zIGVuIGN1YW50byBhIGxvcyB0aWVtcG9zIGRlIGVudHJlZ2EuIApQcmludGVsIGVzIGVsIGNsaWVudGUgY29uIGVsIGN1YWwgc2llbXByZSBzZSBtYW50aWVuZW4gZGVudHJvIGRlIGxvcyB0aWVtcG9zIGRlc2VhYmxlcywgcXVlIGVuIGVzdGUgY2FzbyBzZXLDrWEsIGRlYmFqbyBkZSBsb3MgMzAgbWludXRvcy4KRW4gbGEgYmFzZSBkZSBwcm9kdWNjacOzbiBzZSBpZGVudGlmaWPDsyBxdWUgZWwgY2xpZW50ZSDigJxZYW5mZW5n4oCdIGVzIGFsIGN1YWwgc2UgbGUgZGVkaWNhIG1lbm9zIHRpZW1wbyBlbiBjYWxpZGFkLCBsbyBjdWFsIHBvZHLDrWEgc2VyIHVuIHJpZXNnbyBwYXJhIEZvcm0geWEgcXVlIGRhIGVzcGFjaW8gYSB1biBtYXJnZW4gbcOhcyBlbGV2YWRvIGRlIGVycm9yLgpTZSBpZGVudGlmaWPDsyBxdWUgaGF5IHVuYSBhbHRhIGNhbnRpZGFkIGRlIGRlc3BlcmRpY2lvIHF1ZSBwb2Ryw61hIHNlciB1dGlsaXphZGEgcGFyYSB1bmEgbnVldmEgZnVlbnRlIGRlIGluZ3Jlc28uIEVzdGUgaW5zaWdodCBwdWVkZSBzZXIgdHJhbnNmb3JtYWRvIGVuIHVuYSBlc3RyYXRlZ2lhIHlhIHF1ZSB1bm8gZGUgbG9zIHByaW5jaXBhbGVzIG9iamV0aXZvcyBlcyBkYXJsZSB1biBudWV2byB1c28gYSBsYSBtZXJtYS4gCgoqKkEgcGFydGlyIGRlbCBhbsOhbGlzaXMgZGUgbGFzIGJhc2VzIGRlIGRhdG9zIGRlIGxhcyBkaWZlcmVudGVzIMOhcmVhcyBkZSBsYWVtcHJlc2EgRk9STSwgZGVzY3JpYmlyIDMgc3VnZXJlbmNpYXMgcXVlIGxlIHBlcm1pdGFuIGFsIHNvY2lvIGZvcm1hZG9yKioKbWVqb3JhciBzdSBwcm9jZXNvIGRlIGNhcHR1cmEsIG9yZ2FuaXphY2nDs24sIHkgYW5hbMOtdGljYSBkZSBkYXRvcy4KQ29udGFyIGNvbiBiYXNlcyBkZSBkYXRvcyBtw6FzIG9yZ2FuaXphZGFzIHkgY29uIGZvcm1hdG8uIEVzdG8gcGFyYSBmYWNpbGl0YXIgZWwgYW7DoWxpc2lzIGRlIGxvcyBkYXRvcyB5IHBvZGVyIG9idGVuZXIgbXVjaG9zIG3DoXMgaW5zaWdodHMgZGUgbG9zIHF1ZSBzZSBwb2Ryw61hbiBvYnRlbmVyIGNvbiBzdXMgYmFzZXMgYWN0dWFsZXMgeSBkZSBtYW5lcmEgbcOhcyByw6FwaWRhLgoKUG9uZXIgYXRlbmNpb24gYSBsYSBwYXJ0ZSBkZSBSZWN1cnNvcyBIdW1hbm9zIHkgbGEgYWx0YSByb3RhY2lvbiBkZSBlbXBsZWFkb3MgeSB0YW1iaWVuIHF1ZSBsYSBtYXlvcmlhIHNvbiBlbXBsZWFkb3Mgam92ZW5lcy4gSW52ZXN0aWdhciBzaSBlc3RvcyBkb3MgZmFjdG9yZXMgc2UgcmVsYWNpb25hbiB5IGVtcGxlYXIgYWNjaW9uZXMgZGUgcmV0ZW5jaW9uIGRlIGNhcGl0YWwgaHVtYW5vLgoKQWJyaXIgdW4gZGVwYXJ0YW1lbnRvIGRlIGJ1c2luZXNzIGFuYWx5dGljcyBlIGludGVsbGlnZW5jZSB5IHRlbmVyIGEgdW5hIHBlcnNvbmEgcXVlIHNlIGRlZGlxdWUgYSByZWFsaXphciBwcm9ub3N0aWNvcyB5IHByZWRpY2Npb25lcyBxdWUgcHVlZGVuIGF5dWRhciBhIGRldGVybWluYXIgY29tcG9ydGFtaWVudG9zIGEgZnV0dXJvLiBFc3RvIHB1ZWRlIHNlciBkZSBncmFuIHV0aWxpZGFkIHBhcmEgRm9ybSBwYXJhIGF5dWRhciBhIGlkZW50aWZpY2FyIGFyZWFzIGRlIG1lam9yYSB5IG9wb3J0dW5pZGFkZXMgZGUgY3JlY2ltaWVudG8geSBhaG9ycm8uIEFzaSBtaXNtbyBwdWVkZSBheXVkYXIgYSBwcmV2ZW5pciBlcnJvcmVzIGEgZnV0dXJvLgoKKipEZXNjcmliaXIgY29uIHR1cyBwcm9waWFzIHBhbGFicmFzIGxvcyB0w6lybWlub3MgQnVzaW5lc3MgQW5hbHl0aWNzIGFuZCBCdXNpbmVzcyBJbnRlbGxpZ2VuY2UuIEFzw60gdGFtYmnDqW4sIGlkZW50aWZpY2FyIHkgZGVzY3JpYmlyIDMgcHJpbmNpcGFsZXMgZGlmZXJlbmNpYXMgZW50cmUgQnVzaW5lc3MgQW5hbHl0aWNzIHkgQnVzaW5lc3MgSW50ZWxsaWdlbmNlLioqCkFtYmFzIGhlcnJhbWllbnRhcyBzb24gdXRpbGl6YWRhcyBwYXJhIGVsIHByb2Nlc2FtaWVudG8gZGUgZGF0b3MgeSBwYXJhIHBvZGVyIGxsZXZhciBhIGNhYm8gYW7DoWxpc2lzIGVzdGFkw61zdGljb3MsIHNpbiBlbWJhcmdvIGV4aXN0ZSB1bmEgZGlmZXJlbmNpYSBlbnRyZSBsb3MgZG9zIGNvbmNlcHRvcyBhdW5xdWUgcHVlZGFuIHNvbmFyIHNpbWlsYXJlcy4KQnVzaW5lc3MgYW5hbHl0aWNzIGhhY2UgcmVmZXJlbmNpYSBhIGxhcyBoZXJyYW1pZW50YXMgcXVlIHNlIHV0aWxpemFuIGFsIG1vbWVudG8gZGUgcmVhbGl6YXIgY2llcnRhcyBhY3RpdmlkYWRlcyBjb21vIGVsIGFuw6FsaXNpcyBwcmVkaWN0aXZvLCBmYWNpbGl0YW5kbyByZWFsaXphciBwcmVkaWNjaW9uZXMgdXRpbGl6YW5kbyBjb21vIGVzdHJ1Y3R1cmEgcHJpbmNpcGFsIGxvcyBkYXRvcyBhbmFsaXphZG9zLiBBeXVkYSBhIGxhIHRvbWEgZGUgZGVjaXNpb25lcyBkZW50cm8gZGUgdW5hIG9yZ2FuaXphY2nDs24uIApCdXNpbmVzcyBJbnRlbGxpZ2VuY2UsIHNlIGFwbGljYSBhbCBhbsOhbGlzaXMgZGUgZGF0b3MgeSBuZWdvY2lvcyBsbyBjdWFsIGZhY2lsaXRhIGxhIHRvbWEgZGUgZGVjaXNpb25lcyBkZW50cm8gZGUgdW5hIGVtcHJlc2EuIEdyYWNpYXMgYSBCdXNpbmVzcyBJbnRlbGxpZ2VuY2Ugc2UgcHVlZGVuIGNyZWFyIG9iamV0aXZvcyBvcmllbnRhZG9zIGEgbGFzIG5lY2VzaWRhZGVzIHByaW1vcmRpYWxlcyBkZSBsYSBlbXByZXNhLCBzaWVuZG8gbXVjaG8gbcOhcyBwcmVjaXNhcyB5IGJhc2FkYXMgZW4gZGF0b3MgY29uY3JldG9zIHkgbm8gZW4gc3Vwb3NpY2lvbmVzLgoKMyBEaWZlcmVuY2lhczoKTGEgZGlmZXJlbmNpYSAgcHJpbmNpcGFsIGVudHJlIGVzdGFzIGRvcyBoZXJyYW1pZW50YXMgc2UgYmFzYSBlbiBlbCBlbmZvcXVlIHF1ZSB0aWVuZSAgY2FkYSB1bmEuIEJ1c2luZXNzIEFuYWx5dGljcyBlcyBtYXMgYW7DoWxpc2lzIGVzdGFkw61zdGljbywgbW9kZWxvcyBwcmVkaWN0aXZvcyB5IHRlbmRlbmNpYXMgcGFyYSBwb2RlciBkZXNhcnJvbGxhciBwcm9uw7NzdGljb3MgZGUgY29tcG9ydGFtaWVudG9zIGEgZnV0dXJvLgoKQnVzaW5lc3MgSW50ZWxsaWdlbmNlIHNlIGVuY2FyZ2EgbcOhcyBkZSBhbmFsaXphciBsYSBpbmZvcm1hY2nDs24geSBhIHBhcnRpciBkZSBlbGxhIHBvZGVyIHRvbWFyIGRlY2lzaW9uZXMuIAoKQnVzaW5lc3MgQW5hbHl0aWNzIHNlIGVuY2FyZ2EgZGUgcmVzb2x2ZXIgcHJvYmxlbWFzIGRlbnRybyBkZSB1bmEgIG9yZ2FuaXphY2nDs24gYW50ZXMgZGUgcXVlIGVzdG9zIG9jdXJyYW4sIHByZXZpbmllbmRvIHDDqXJkaWRhcy4gCgoqKkRlc2NyaWJpciBjb24gdHVzIHByb3BpYXMgcGFsYWJyYXMgZWwgY29uY2VwdG8gZGUgSW5kaWNhZG9yIENsYXZlIGRlIFJlbmRpbWllbnRvIC8gS2V5IFBlcmZvcm1hbmNlIEluZGljYXRvcnMqKgpMb3MgS3BpcyBzb24gaW5kaWNhZG9yZXMgZGVudHJvIGRlIHVuYSBlbXByZXNhIHF1ZSBmYWNpbGl0YW4gbWVkaXIgZWwgZGVzZW1wZcOxbyBkZSBsb3MgY29sYWJvcmFkb3JlcyB5IGRlIGxhIG9yZ2FuaXphY2nDs24uIEluZGljYSBlbCBuaXZlbCBkZSByZW5kaW1pZW50byBxdWUgc2UgZXN0w6Egb2J0ZW5pZW5kbyB5IGF5dWRhICBhIGlkZW50aWZpY2FyIGVuIHF1w6kgw6FyZWFzIHNlIGRlYmUgcmVmb3J6YXIgZWwgZW5mb3F1ZS4KCioqQSBwYXJ0aXIgZGVsIGFuw6FsaXNpcyBkZSBsYXMgYmFzZXMgZGUgZGF0b3MgZGUgbGFzIGRpZmVyZW50ZXMgw6FyZWFzIGRlIGxhIGVtcHJlc2EgRk9STSwgcHJvcG9uZXIgeSBkZXNjcmliaXIgMyBwb3NpYmxlcyBLUElzIHF1ZSBwZXJtaXRhbiBldmFsdWFyIGVsIGRlc2VtcGXDsW8gZGUgYWxndW5hcyBkZSBzdXMgw6FyZWFzKioKdGFzYSBkZSBwZWRpZG9zIGVudHJlZ2Fkb3MgYSB0aWVtcG8oMzAgbWluKTogbWVkaXIgcXVlIHRvZG9zIGxvcyBwZWRpZG9zIHNlYW4gZW50cmVnYWRvcyBkZW50cm8gZGVsIHRpZW1wbyBlc3RhYmxlY2lkbyBlcyBkZWNpciAzMCBtaW5udXRvcyB5IHByZXN0YXIgYXRlbmNpb24gYSBsb3MgcXVlIGVzdGFuIGNhdXNhbmRvIHJldHJhc29zIGUgaW52ZXN0aWdhciBsYSBjYXVzYSBkZSBlbGxvcy4gRXN0byBhdW1lbnRhcmlhIGxhIGNhbnRpZGFkIGRlIGVudHJlZ2FzIHBvciBkaWEgbG8gY3VhbCBnZW5lcmFyaWEgbWF5b3IgcmVudGFiaWxpZGFkLgp0YXNhIGRlIHJvdGFjacOzbiBkZSBlbXBsZWFkb3M6IG1lZGlyIGxhIHRhc2EgZGUgcm90YWNpb24gZGUgZW1wZWxhZG9zIHkgYW5hbGl6YXIgZGUgcXVlIG1hbmVyYSBzZSBwdWVkZSBjcmVhciBtYXlvciByZXRlbmNpb24uIEltcGFydGlyIGNhcGFjaXRhY2lvbmVzCnRhc2EgZGUgZGVzcGVyZGljaW86IE1lZGlyIGxhIGNhbnRpZGFkIGRlIGRlc3BlcmRpY2lvIGdlbmVyYWRhLCBkZSBlc3RhIG1hbmVyYSBjb24gbG9zIGRhdG9zIHByZWNpc29zLCBwb2RlciBidXNjYXIgYWx0ZXJuYXRpdmFzIGRlIHF1ZSBzZSBwdWVkZSBoYWNlciBjb24gbGEgbWF0ZXJpYSBzb2JyYW50ZS4KCgoKCkJpYmxpb2dyYWZpYToKRXNjb2JhciwgSi4gKDIwMjEsIE9jdG9iZXIgMjYpLiBCdXNpbmVzcyBBbmFseXRpY3MgdnMgQnVzaW5lc3MgSW50ZWxsaWdlbmNlIMK/Y3XDoWwgZXMgbGEgZGlmZXJlbmNpYT8gRWdhZGUudGVjLm14OyBFR0FERSBJbnNpZ2h0cy4gaHR0cHM6Ly9ibG9nLmVnYWRlLnRlYy5teC9idXNpbmVzcy1hbmFseXRpY3MtdnMtYnVzaW5lc3MtaW50ZWxsaWdlbmNlLWRpZmVyZW5jaWFzCgpHcnVwbyBCaXQuICgyMDIyKS4gwr9DdcOhbCBlcyBsYSBkaWZlcmVuY2lhIGVudHJlIEJ1c2luZXNzIEludGVsbGlnZW5jZSB5IEJ1c2luZXNzIEFuYWx5dGljcz8gR3J1cG9iaXQubmV0LiBodHRwczovL2J1c2luZXNzLWludGVsbGlnZW5jZS5ncnVwb2JpdC5uZXQvYmxvZy9jdWFsLWVzLWxhLWRpZmVyZW5jaWEtZW50cmUtYnVzaW5lc3MtaW50ZWxsaWdlbmNlLXktYnVzaW5lc3MtYW5hbHl0aWNzCgoKCgoKCgoKCgoKCgo=