Introducción
Se busca a través de este EDA responder algunas preguntas que
consideramos importantes y relevantes para FORM. Y así tener información
útil para tomar decisiones estratégicas en la administración y operación
de la empresa.
Las preguntas se mostraran a continuación.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.2 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(stringr)
library(readr)
library(dplyr)
library(tidyr)
library(grid)
library(psych)
##
## Attaching package: 'psych'
##
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
library(gplots)
##
## Attaching package: 'gplots'
##
## The following object is masked from 'package:stats':
##
## lowess
Pregunta 1
¿Que estado civil estan lo que se dan de baja?
Abrir base de datos
# file.choose()
BDD_FORM_BAJAS_2023 <- read_csv("/Users/davidcavazos/Desktop/BDD_FORM_BAJAS_2023.csv")
## Rows: 279 Columns: 28
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (24): Apellidos, Nombre, Fecha de Nacimiento, Género, RFC, Fecha de Alta...
## dbl (4): No., SD, CP, Número de Télefono
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Seleccionar las variables de Motivo de baja y Estado Civil en un
nuevo data frame.
mbaja <- select(BDD_FORM_BAJAS_2023,`Motivo de Baja`,`Estado Civil`) %>% na.omit(mbaja)
Agrupar la categoría con diferentes nombres cambiando a el mismo
nombre
mbaja$"Motivo de Baja"[mbaja$"Motivo de Baja" == "Inducida."] <- "Inducida"
mbaja$"Motivo de Baja"[mbaja$"Motivo de Baja" == "Inducida (Faltas)"] <- "Inducida por faltas"
mbaja$"Motivo de Baja"[mbaja$"Motivo de Baja" == "Inducida (Faltas no dio los tiempos)"] <- "Inducida"
Calcular los porcentajes por categoría y estado civil
porcentajes <- mbaja %>%
group_by(`Estado Civil`, `Motivo de Baja`) %>%
summarise(Frecuencia = n()) %>%
group_by(`Estado Civil`) %>%
mutate(Pct = scales::percent(Frecuencia / sum(Frecuencia)))
## `summarise()` has grouped output by 'Estado Civil'. You can override using the
## `.groups` argument.
Gráfica de barras
apliadas
plot <- ggplot(porcentajes, aes(x = `Estado Civil`, y = Frecuencia, fill = `Motivo de Baja`)) +
geom_bar(stat = "identity") +
theme_minimal() +
theme(
panel.grid.major = element_line(color = "grey", linewidth = 0.4, linetype = "dotted"), # Líneas verticales
panel.grid.minor = element_line(color = "grey", linewidth = 0.4, linetype = "dotted") # Líneas horizontales
)+
ggtitle("Relación entre Motivo de Baja y Estado Civil")
Agregar etiquetas de porcentaje
plot + geom_text(aes(label = Pct), position = position_stack(vjust = 0.5),size=2)

Interpretación 1
Por lo que podemos ver en la gráfica, la gran mayoría de las bajas en
todas las categorías son por separación voluntaria y realmente no se
logra ver una correlación entre el estado civil de la persona y el
motivo de baja, lo que podría indicar una alta rotación de empleados en
los trabajos de maquila en general o podría ser un indicador de que hay
varias áreas de oportunidad en cuestión de amenidades, salarios, bonos,
oportunidades de crecimiento en la empresa, traslado o prestaciones que
la empresa ofrece además de las básicas dictadas por la ley.
Pregunta 2
¿Cual es la relacion entre la edad y las bajas?
Carga de datos
#file.choose()
bajas<-read_csv("/Users/davidcavazos/Desktop/form_bajas_22.csv")
## Rows: 238 Columns: 25
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (23): APELLIDOS, NOMBRE, FECHA DE NACIMIENTO, GENERO, RFC, FECHA DE ALTA...
## dbl (2): DIAS LABORADOS, SALARIO DIARIO IMSS
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#view(bajas)
Modificación de base de datos
#Estoy creando un data frame nuevo con las columnas necesarias para hacer la gráfica
bajas1 <- select(bajas,"NOMBRE","APELLIDOS","FECHA DE NACIMIENTO","DIAS LABORADOS","SALARIO DIARIO IMSS") %>% na.omit(bajas1)
#view(bajas1)
Estadísiticos
Descriptivos
Dias Laborados
summary(bajas1$`DIAS LABORADOS`)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.00 8.75 19.00 80.00 49.25 1966.00
Salario
summary(bajas1$`SALARIO DIARIO IMSS`)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 144.4 180.7 180.7 177.7 180.7 500.0
Edad de colaboradores
#Aquí reviso que formato tienen las columnas
str(bajas1)
## tibble [212 × 5] (S3: tbl_df/tbl/data.frame)
## $ NOMBRE : chr [1:212] "MARIA FERNANDA" "EMANUEL" "TRINIDAD" "WILMAR" ...
## $ APELLIDOS : chr [1:212] "JIMENEZ ALANIS" "JAUREGUI SANCHEZ" "GARCIA CAZARES" "LOPEZ ROMERO" ...
## $ FECHA DE NACIMIENTO: chr [1:212] "7/10/1998" "10/3/1998" "5/25/1997" "9/4/2001" ...
## $ DIAS LABORADOS : num [1:212] 423 35 102 63 34 23 30 6 0 141 ...
## $ SALARIO DIARIO IMSS: num [1:212] 177 181 181 177 181 ...
## - attr(*, "na.action")= 'omit' Named int [1:26] 8 27 28 58 67 110 135 136 137 141 ...
## ..- attr(*, "names")= chr [1:26] "8" "27" "28" "58" ...
#Aquí estoy haciendo una extracción del año de nacimiento excluyendo los días y meses.
#Decidí hacer esto porque hay filas en las que está escrito M/D/A y otras D/M/A
bajas1$ANIO<-str_sub(bajas1$`FECHA DE NACIMIENTO`,-4,-1)
#Convirtiendo la columna de "ANIO" en integer
bajas1$ANIO <- as.integer(bajas1$ANIO)
str(bajas1)
## tibble [212 × 6] (S3: tbl_df/tbl/data.frame)
## $ NOMBRE : chr [1:212] "MARIA FERNANDA" "EMANUEL" "TRINIDAD" "WILMAR" ...
## $ APELLIDOS : chr [1:212] "JIMENEZ ALANIS" "JAUREGUI SANCHEZ" "GARCIA CAZARES" "LOPEZ ROMERO" ...
## $ FECHA DE NACIMIENTO: chr [1:212] "7/10/1998" "10/3/1998" "5/25/1997" "9/4/2001" ...
## $ DIAS LABORADOS : num [1:212] 423 35 102 63 34 23 30 6 0 141 ...
## $ SALARIO DIARIO IMSS: num [1:212] 177 181 181 177 181 ...
## $ ANIO : int [1:212] 1998 1998 1997 2001 2002 2000 2000 1999 2002 1994 ...
## - attr(*, "na.action")= 'omit' Named int [1:26] 8 27 28 58 67 110 135 136 137 141 ...
## ..- attr(*, "names")= chr [1:26] "8" "27" "28" "58" ...
#Aquí creó una nueva columna llamada "EDAD" restando el año actual con el de "ANIO
bajas1$EDAD <- 2023-bajas1$ANIO
#Había un error en el cual existían tres filas que tenían edad de 1 por lo cual le pedí que solo mostrara los que son mayor a 18.
bajas1 <- bajas1[bajas1$EDAD >18,]
Histograma de
frecuencias
hist(bajas1$EDAD,col = blues9,xlab = "Edad",ylab ="Frecuencia" ,main = "Bajas por Edad")

Interpretación
2
Nos damos cuenta de que la rotación de personal se ve más alta en los
colaboradores más jóvenes. Esto es información útil ya que nos permite
tomar decisiones adecuadas para mejorar la satisfacción laboral en
específico para estos rangos de edades. Con esta gráfica podemos entrar
más a detalle en el área de oportunidad y así entender las razones de la
alta rotación. Nos damos cuenta de que se tiene que hacer un esfuerzo
por mejorar la relación con las nuevas generaciones o contratar a
personas mayores.
Pregunta 3
¿A que edad ingresan a trabajar nuevos empleados a FORM y que
genero son?
Carga de datos
rh <- read.csv("/Users/davidcavazos/Desktop/form_rh_datos.csv")
#View(rh)
edad <- select(rh,"FECHA.DE.ALTA", "FECHA.DE.NACIMIENTO")
#str(rh)
Modificacion de Datos
rh$año_alta <- str_sub(rh$FECHA.DE.ALTA, -4, -1)
rh$año_nac <- str_sub(rh$FECHA.DE.NACIMIENTO, -4, -1)
rh$año_alta <- as.integer(rh$año_alta)
rh$año_nac <- as.integer(rh$año_nac)
rh <- rh[rh$año_alta > 2013,]
rh <- rh[-30,]
Calcular la edad de ingreso y Medidas de Dispersion
rh$edad_ingreso <- rh$año_alta - rh$año_nac
rh <- rh[rh$edad_ingreso > 18,]
edad_de_ingreso_max <- max(rh$edad_ingreso)
print(edad_de_ingreso_max)
## [1] 60
edad_de_ingreso_min <- min(rh$edad_ingreso)
print(edad_de_ingreso_min)
## [1] 19
edad_de_ingreso_mean <- mean(rh$edad_ingreso)
print(edad_de_ingreso_mean)
## [1] 34.92308
Histograma de
Edad
hist(rh$edad_ingreso,col = "#009E73" ,xlab = "Edad",main = "Alta por Edad")

Histograma
Genero
ggplot(rh, aes(edad_ingreso, fill = GENERO)) +
geom_histogram(bins=10) +
labs(y="")

Interpretacion
3
Podemos analizar en las graficas que la edad mas comun para ingresar
a trabajar a FORM es entre los 25 - 30 lo que nos puede ayudar a crear
campañas de reclutamiento enfocadas en el mercado de edad al que los
empleados de FORM estan enfocados, FORM cuenta con un gran rango de
edades comenzando desde los 19 y llegando hasta los 60. Este ultimo
siendo el grupo mas pequeño dentro de la empresa mientras que los
jovenes de 18 - 20 tienden a ser un porcentaje mas alto de hombres. Nos
damos cuenta con la grafica que FORM le abre las puertas a muchas
personas y ofrece oportunidades de trabajo para nuevas generaciones y
personas con experiencia
Tabla de
frecuencia/contingencia
Importar datasets
bajas = read.csv("/Users/davidcavazos/Desktop/form_bajas_22.csv")
dfbajas = bajas
#View(bajas)
empleados = read.csv("/Users/davidcavazos/Desktop/form_rh_datos.csv")
empleadosdf = empleados
#View(empleados)
LIMPIEZA BASE DE DATOS
bajas$ESTADO.CIVIL = gsub("MATRIOMONIO", "MATRIMONIO", bajas$ESTADO.CIVIL)
MOTIVO DE BAJA
motivo_bajas = ggplot(bajas, aes(x = MOTIVO.DE.BAJA)) +
geom_bar() +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
estado_civil = ggplot(bajas, aes(x = ESTADO.CIVIL)) +
geom_bar()
FRECUENCIA DE DÍAS LABORADOS
hist(bajas$DIAS.LABORADOS,col = blues9,xlab = "DIAS LABORADOS",ylab ="Frecuencia" ,main = "Días Laborados")

SEPARACION DE FECHAS - BAJAS
df_rotacion = bajas %>% select(GENERO, FECHA.DE.ALTA,BAJA, MOTIVO.DE.BAJA, DIAS.LABORADOS, PUESTO)
df_rotacion = df_rotacion %>% separate(BAJA, into = c("MONTH_BAJA", "DAY_BAJA", "YEAR_BAJA"), sep = "/")
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 15 rows [27, 28, 58, 135,
## 137, 141, 151, 178, 179, 198, 203, 205, 207, 212, 238].
SEPARACION DE FECHAS - ALTAS
df_rotacion = df_rotacion %>% separate(FECHA.DE.ALTA, into = c("MONTH_ALTA", "DAY_ALTA", "YEAR_ALTA"), sep = "/")
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 1 rows [238].
HISTOGRAMAS MESES EN LOS QUE DAN BAJAS
df_rotacion$MONTH_BAJA = as.numeric(df_rotacion$MONTH_BAJA)
hist(df_rotacion$MONTH_BAJA,col = blues9,xlab = "MONTH_BAJA",ylab ="Frecuencia" ,main = "Bajas por Mes")

ASIGNACIÓN DE MESES
df_months <- df_rotacion %>%
mutate(NAME_MONTH = case_when(
MONTH_BAJA == 1 ~ "Enero",
MONTH_BAJA == 2 ~ "Febrero",
MONTH_BAJA == 3 ~ "Marzo",
MONTH_BAJA == 4 ~ "Abril",
MONTH_BAJA == 5 ~ "Mayo",
MONTH_BAJA == 6 ~ "Junio",
MONTH_BAJA == 7 ~ "Julio",
MONTH_BAJA == 8 ~ "Agosto",
MONTH_BAJA == 9 ~ "Septiembre",
MONTH_BAJA == 10 ~ "Octubre",
MONTH_BAJA == 11 ~ "Noviembre",
MONTH_BAJA == 12 ~ "Diciembre"
)) %>%
filter(NAME_MONTH %in% c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")) %>%
select(GENERO, MONTH_BAJA, DAY_ALTA, YEAR_ALTA, MOTIVO.DE.BAJA, NAME_MONTH, PUESTO)
#View(df_months)
GRAFICO DE BARRAS
barplot_subcategory = ggplot(df_months, aes(NAME_MONTH))+geom_bar(aes(), width = 0.5)
barplot_subcategory

TABLA DE FRECUENCIAS
month_frecuencias = table(df_months$NAME_MONTH)
meses_cronologicos <- c("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre")
Datos adicionales
requeridos
Para llevar a cabo un análisis más completo y una comprensión más
profunda del clima organizacional en Form, resulta fundamental la
implementación de encuestas cualitativas. Estas encuestas abordarán
aspectos clave, tales como la satisfacción con las instalaciones
laborales, las condiciones de trabajo, los horarios, el transporte al
lugar de trabajo, la remuneración, la dinámica de liderazgo en Form, la
comodidad en el entorno de trabajo y su posible correlación con las
tasas de rotación, tanto voluntaria como involuntaria, y otras
relaciones y respuestas relevantes que podrían identificarse.
LS0tCnRpdGxlOiAiRW50cmVnYWJsZSAyIgphdXRob3I6ICJSb2dlaXJvLERhdmlkLFJvZ2VsaW8sTWFyaWFuYSxMeW5ldHRlIgpkYXRlOiAiMjAyMy0wOS0wNSIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQogICAgY29kZV9kb3dubG9hZDogVFJVRQogICAgdGhlbWU6ICJ1bml0ZWQiCi0tLQoKIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gSW50cm9kdWNjacOzbgoKU2UgYnVzY2EgYSB0cmF2w6lzIGRlIGVzdGUgRURBIHJlc3BvbmRlciBhbGd1bmFzIHByZWd1bnRhcyBxdWUgY29uc2lkZXJhbW9zIGltcG9ydGFudGVzIHkgcmVsZXZhbnRlcyBwYXJhIEZPUk0uIFkgYXPDrSB0ZW5lciBpbmZvcm1hY2nDs24gw7p0aWwgcGFyYSB0b21hciBkZWNpc2lvbmVzIGVzdHJhdMOpZ2ljYXMgZW4gbGEgYWRtaW5pc3RyYWNpw7NuIHkgb3BlcmFjacOzbiBkZSBsYSBlbXByZXNhLgoKTGFzIHByZWd1bnRhcyBzZSBtb3N0cmFyYW4gYSBjb250aW51YWNpw7NuLgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShyZWFkcikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShncmlkKQpsaWJyYXJ5KHBzeWNoKQpsaWJyYXJ5KGdwbG90cykKYGBgCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKlByZWd1bnRhIDEqKiAKCioqwr9RdWUgZXN0YWRvIGNpdmlsIGVzdGFuIGxvIHF1ZSBzZSBkYW4gZGUgYmFqYT8qKgoKIyMjIEFicmlyIGJhc2UgZGUgZGF0b3MKCmBgYHtyfQojIGZpbGUuY2hvb3NlKCkKQkREX0ZPUk1fQkFKQVNfMjAyMyA8LSByZWFkX2NzdigiL1VzZXJzL2RhdmlkY2F2YXpvcy9EZXNrdG9wL0JERF9GT1JNX0JBSkFTXzIwMjMuY3N2IikKYGBgCgojIyMgU2VsZWNjaW9uYXIgbGFzIHZhcmlhYmxlcyBkZSBNb3Rpdm8gZGUgYmFqYSB5IEVzdGFkbyBDaXZpbCBlbiB1biBudWV2byBkYXRhIGZyYW1lLgoKYGBge3J9Cm1iYWphIDwtIHNlbGVjdChCRERfRk9STV9CQUpBU18yMDIzLGBNb3Rpdm8gZGUgQmFqYWAsYEVzdGFkbyBDaXZpbGApICU+JSBuYS5vbWl0KG1iYWphKQpgYGAKCiMjIyBBZ3J1cGFyIGxhIGNhdGVnb3LDrWEgY29uIGRpZmVyZW50ZXMgbm9tYnJlcyBjYW1iaWFuZG8gYSBlbCBtaXNtbyBub21icmUKYGBge3J9CgptYmFqYSQiTW90aXZvIGRlIEJhamEiW21iYWphJCJNb3Rpdm8gZGUgQmFqYSIgPT0gIkluZHVjaWRhLiJdIDwtICJJbmR1Y2lkYSIKCm1iYWphJCJNb3Rpdm8gZGUgQmFqYSJbbWJhamEkIk1vdGl2byBkZSBCYWphIiA9PSAiSW5kdWNpZGEgKEZhbHRhcykiXSA8LSAiSW5kdWNpZGEgcG9yIGZhbHRhcyIKCm1iYWphJCJNb3Rpdm8gZGUgQmFqYSJbbWJhamEkIk1vdGl2byBkZSBCYWphIiA9PSAiSW5kdWNpZGEgKEZhbHRhcyBubyBkaW8gbG9zIHRpZW1wb3MpIl0gPC0gIkluZHVjaWRhIgpgYGAKCiMjIyBDYWxjdWxhciBsb3MgcG9yY2VudGFqZXMgcG9yIGNhdGVnb3LDrWEgeSBlc3RhZG8gY2l2aWwKYGBge3J9CnBvcmNlbnRhamVzIDwtIG1iYWphICU+JQogIGdyb3VwX2J5KGBFc3RhZG8gQ2l2aWxgLCBgTW90aXZvIGRlIEJhamFgKSAlPiUKICBzdW1tYXJpc2UoRnJlY3VlbmNpYSA9IG4oKSkgJT4lCiAgZ3JvdXBfYnkoYEVzdGFkbyBDaXZpbGApICU+JQogIG11dGF0ZShQY3QgPSBzY2FsZXM6OnBlcmNlbnQoRnJlY3VlbmNpYSAvIHN1bShGcmVjdWVuY2lhKSkpCmBgYAoKIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKipHcsOhZmljYSBkZSBiYXJyYXMgYXBsaWFkYXMqKgpgYGB7cn0KcGxvdCA8LSBnZ3Bsb3QocG9yY2VudGFqZXMsIGFlcyh4ID0gYEVzdGFkbyBDaXZpbGAsIHkgPSBGcmVjdWVuY2lhLCBmaWxsID0gYE1vdGl2byBkZSBCYWphYCkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoCiAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyZXkiLCBsaW5ld2lkdGggPSAwLjQsIGxpbmV0eXBlID0gImRvdHRlZCIpLCAgIyBMw61uZWFzIHZlcnRpY2FsZXMKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JleSIsIGxpbmV3aWR0aCA9IDAuNCwgbGluZXR5cGUgPSAiZG90dGVkIikgICMgTMOtbmVhcyBob3Jpem9udGFsZXMKICApKwogIGdndGl0bGUoIlJlbGFjacOzbiBlbnRyZSBNb3Rpdm8gZGUgQmFqYSB5IEVzdGFkbyBDaXZpbCIpCgpgYGAKCiMjIyBBZ3JlZ2FyIGV0aXF1ZXRhcyBkZSBwb3JjZW50YWplCmBgYHtyfQpwbG90ICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFBjdCksIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLHNpemU9MikKYGBgCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiBJbnRlcnByZXRhY2nDs24gMSAKClBvciBsbyBxdWUgcG9kZW1vcyB2ZXIgZW4gbGEgZ3LDoWZpY2EsIGxhIGdyYW4gbWF5b3LDrWEgZGUgbGFzIGJhamFzIGVuIHRvZGFzIGxhcyBjYXRlZ29yw61hcyBzb24gcG9yIHNlcGFyYWNpw7NuIHZvbHVudGFyaWEgeSByZWFsbWVudGUgbm8gc2UgbG9ncmEgdmVyIHVuYSBjb3JyZWxhY2nDs24gZW50cmUgZWwgZXN0YWRvIGNpdmlsIGRlIGxhIHBlcnNvbmEgeSBlbCBtb3Rpdm8gZGUgYmFqYSwgbG8gcXVlIHBvZHLDrWEgaW5kaWNhciB1bmEgYWx0YSByb3RhY2nDs24gZGUgZW1wbGVhZG9zIGVuIGxvcyB0cmFiYWpvcyBkZSBtYXF1aWxhIGVuIGdlbmVyYWwgbyBwb2Ryw61hIHNlciB1biBpbmRpY2Fkb3IgZGUgcXVlIGhheSB2YXJpYXMgw6FyZWFzIGRlIG9wb3J0dW5pZGFkIGVuIGN1ZXN0acOzbiBkZSBhbWVuaWRhZGVzLCBzYWxhcmlvcywgYm9ub3MsIG9wb3J0dW5pZGFkZXMgZGUgY3JlY2ltaWVudG8gZW4gbGEgZW1wcmVzYSwgdHJhc2xhZG8gbyBwcmVzdGFjaW9uZXMgcXVlIGxhIGVtcHJlc2Egb2ZyZWNlIGFkZW3DoXMgZGUgbGFzIGLDoXNpY2FzIGRpY3RhZGFzIHBvciBsYSBsZXkuCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKlByZWd1bnRhIDIqKgoKKirCv0N1YWwgZXMgbGEgcmVsYWNpb24gZW50cmUgbGEgZWRhZCB5IGxhcyBiYWphcz8qKgoKIyMjIENhcmdhIGRlIGRhdG9zCgpgYGB7cn0KI2ZpbGUuY2hvb3NlKCkKYmFqYXM8LXJlYWRfY3N2KCIvVXNlcnMvZGF2aWRjYXZhem9zL0Rlc2t0b3AvZm9ybV9iYWphc18yMi5jc3YiKQojdmlldyhiYWphcykKYGBgCgoKIyMjICoqTW9kaWZpY2FjacOzbiBkZSBiYXNlIGRlIGRhdG9zKioKCmBgYHtyfQoKI0VzdG95IGNyZWFuZG8gdW4gZGF0YSBmcmFtZSBudWV2byBjb24gbGFzIGNvbHVtbmFzIG5lY2VzYXJpYXMgcGFyYSBoYWNlciBsYSBncsOhZmljYQoKYmFqYXMxIDwtIHNlbGVjdChiYWphcywiTk9NQlJFIiwiQVBFTExJRE9TIiwiRkVDSEEgREUgTkFDSU1JRU5UTyIsIkRJQVMgTEFCT1JBRE9TIiwiU0FMQVJJTyBESUFSSU8gSU1TUyIpICU+JSBuYS5vbWl0KGJhamFzMSkKI3ZpZXcoYmFqYXMxKQpgYGAKCiMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqRXN0YWTDrXNpdGljb3MgRGVzY3JpcHRpdm9zKioKCiMjIyBEaWFzIExhYm9yYWRvcwpgYGB7cn0Kc3VtbWFyeShiYWphczEkYERJQVMgTEFCT1JBRE9TYCkKYGBgCiMjIyBTYWxhcmlvCmBgYHtyfQpzdW1tYXJ5KGJhamFzMSRgU0FMQVJJTyBESUFSSU8gSU1TU2ApCmBgYAoKIyMjIEVkYWQgZGUgY29sYWJvcmFkb3JlcwoKYGBge3J9CgojQXF1w60gcmV2aXNvIHF1ZSBmb3JtYXRvIHRpZW5lbiBsYXMgY29sdW1uYXMgCgpzdHIoYmFqYXMxKQpgYGAKYGBge3J9CgojQXF1w60gZXN0b3kgaGFjaWVuZG8gdW5hIGV4dHJhY2Npw7NuIGRlbCBhw7FvIGRlIG5hY2ltaWVudG8gZXhjbHV5ZW5kbyBsb3MgZMOtYXMgeSBtZXNlcy4gCgojRGVjaWTDrSBoYWNlciBlc3RvIHBvcnF1ZSBoYXkgZmlsYXMgZW4gbGFzIHF1ZSBlc3TDoSBlc2NyaXRvIE0vRC9BIHkgb3RyYXMgRC9NL0EKCgpiYWphczEkQU5JTzwtc3RyX3N1YihiYWphczEkYEZFQ0hBIERFIE5BQ0lNSUVOVE9gLC00LC0xKQoKI0NvbnZpcnRpZW5kbyBsYSBjb2x1bW5hIGRlICJBTklPIiBlbiBpbnRlZ2VyCgpiYWphczEkQU5JTyA8LSBhcy5pbnRlZ2VyKGJhamFzMSRBTklPKQoKc3RyKGJhamFzMSkKYGBgCmBgYHtyfQoKCiNBcXXDrSBjcmXDsyB1bmEgbnVldmEgY29sdW1uYSBsbGFtYWRhICJFREFEIiByZXN0YW5kbyBlbCBhw7FvIGFjdHVhbCBjb24gZWwgZGUgIkFOSU8KCmJhamFzMSRFREFEIDwtIDIwMjMtYmFqYXMxJEFOSU8KCiNIYWLDrWEgdW4gZXJyb3IgZW4gZWwgY3VhbCBleGlzdMOtYW4gdHJlcyBmaWxhcyBxdWUgdGVuw61hbiBlZGFkIGRlIDEgcG9yIGxvIGN1YWwgbGUgcGVkw60gcXVlIHNvbG8gbW9zdHJhcmEgbG9zIHF1ZSBzb24gbWF5b3IgYSAxOC4KCmJhamFzMSA8LSBiYWphczFbYmFqYXMxJEVEQUQgPjE4LF0KYGBgCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkhpc3RvZ3JhbWEgZGUgZnJlY3VlbmNpYXMqKgoKYGBge3J9Cmhpc3QoYmFqYXMxJEVEQUQsY29sID0gYmx1ZXM5LHhsYWIgPSAiRWRhZCIseWxhYiA9IkZyZWN1ZW5jaWEiICxtYWluID0gIkJhamFzIHBvciBFZGFkIikKYGBgCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkludGVycHJldGFjacOzbiAyKioKCk5vcyBkYW1vcyBjdWVudGEgZGUgcXVlIGxhIHJvdGFjacOzbiBkZSBwZXJzb25hbCBzZSB2ZSBtw6FzIGFsdGEgZW4gbG9zIGNvbGFib3JhZG9yZXMgbcOhcyBqw7N2ZW5lcy4gRXN0byBlcyBpbmZvcm1hY2nDs24gw7p0aWwgeWEgcXVlIG5vcyBwZXJtaXRlIHRvbWFyIGRlY2lzaW9uZXMgYWRlY3VhZGFzIHBhcmEgbWVqb3JhciBsYSBzYXRpc2ZhY2Npw7NuIGxhYm9yYWwgZW4gZXNwZWPDrWZpY28gcGFyYSBlc3RvcyByYW5nb3MgZGUgZWRhZGVzLiBDb24gZXN0YSBncsOhZmljYSBwb2RlbW9zIGVudHJhciBtw6FzIGEgZGV0YWxsZSBlbiBlbCDDoXJlYSBkZSBvcG9ydHVuaWRhZCB5IGFzw60gZW50ZW5kZXIgbGFzIHJhem9uZXMgZGUgbGEgYWx0YSByb3RhY2nDs24uIE5vcyBkYW1vcyBjdWVudGEgZGUgcXVlIHNlIHRpZW5lIHF1ZSBoYWNlciB1biBlc2Z1ZXJ6byBwb3IgbWVqb3JhciBsYSByZWxhY2nDs24gY29uIGxhcyBudWV2YXMgZ2VuZXJhY2lvbmVzIG8gY29udHJhdGFyIGEgcGVyc29uYXMgbWF5b3Jlcy4gCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKlByZWd1bnRhIDMqKgoKKirCv0EgcXVlIGVkYWQgaW5ncmVzYW4gYSB0cmFiYWphciBudWV2b3MgZW1wbGVhZG9zIGEgRk9STSB5IHF1ZSBnZW5lcm8gc29uPyoqCgojIyMgQ2FyZ2EgZGUgZGF0b3MKYGBge3J9CgpyaCA8LSByZWFkLmNzdigiL1VzZXJzL2RhdmlkY2F2YXpvcy9EZXNrdG9wL2Zvcm1fcmhfZGF0b3MuY3N2IikKCiNWaWV3KHJoKQoKZWRhZCA8LSBzZWxlY3QocmgsIkZFQ0hBLkRFLkFMVEEiLCAiRkVDSEEuREUuTkFDSU1JRU5UTyIpIAoKI3N0cihyaCkKYGBgCgojIyMgTW9kaWZpY2FjaW9uIGRlIERhdG9zCgpgYGB7cn0KcmgkYcOxb19hbHRhIDwtIHN0cl9zdWIocmgkRkVDSEEuREUuQUxUQSwgLTQsIC0xKSAKcmgkYcOxb19uYWMgPC0gc3RyX3N1YihyaCRGRUNIQS5ERS5OQUNJTUlFTlRPLCAtNCwgLTEpCnJoJGHDsW9fYWx0YSA8LSBhcy5pbnRlZ2VyKHJoJGHDsW9fYWx0YSkKcmgkYcOxb19uYWMgPC0gYXMuaW50ZWdlcihyaCRhw7FvX25hYykKCnJoIDwtIHJoW3JoJGHDsW9fYWx0YSA+IDIwMTMsXQpyaCA8LSByaFstMzAsXQoKYGBgCgojIyMgQ2FsY3VsYXIgbGEgZWRhZCBkZSBpbmdyZXNvIHkgTWVkaWRhcyBkZSBEaXNwZXJzaW9uCgpgYGB7cn0KcmgkZWRhZF9pbmdyZXNvIDwtIHJoJGHDsW9fYWx0YSAtIHJoJGHDsW9fbmFjCnJoIDwtIHJoW3JoJGVkYWRfaW5ncmVzbyA+IDE4LF0KCmVkYWRfZGVfaW5ncmVzb19tYXggPC0gbWF4KHJoJGVkYWRfaW5ncmVzbykKcHJpbnQoZWRhZF9kZV9pbmdyZXNvX21heCkKCmVkYWRfZGVfaW5ncmVzb19taW4gPC0gbWluKHJoJGVkYWRfaW5ncmVzbykKcHJpbnQoZWRhZF9kZV9pbmdyZXNvX21pbikKCmVkYWRfZGVfaW5ncmVzb19tZWFuIDwtIG1lYW4ocmgkZWRhZF9pbmdyZXNvKQpwcmludChlZGFkX2RlX2luZ3Jlc29fbWVhbikKCmBgYAoKIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKipIaXN0b2dyYW1hIGRlIEVkYWQqKgpgYGB7cn0KaGlzdChyaCRlZGFkX2luZ3Jlc28sY29sID0gIiMwMDlFNzMiICx4bGFiID0gIkVkYWQiLG1haW4gPSAiQWx0YSBwb3IgRWRhZCIpCmBgYAoKIyMgPHNwYW4gc3R5bGUgPSJjb2xvcjpkYXJrb3JhbmdlIj4gKipIaXN0b2dyYW1hIEdlbmVybyoqCmBgYHtyfQpnZ3Bsb3QocmgsIGFlcyhlZGFkX2luZ3Jlc28sIGZpbGwgPSBHRU5FUk8pKSArIAogIGdlb21faGlzdG9ncmFtKGJpbnM9MTApICsgCiAgbGFicyh5PSIiKSAKYGBgCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkludGVycHJldGFjaW9uIDMqKgoKUG9kZW1vcyBhbmFsaXphciBlbiBsYXMgZ3JhZmljYXMgcXVlIGxhIGVkYWQgbWFzIGNvbXVuIHBhcmEgaW5ncmVzYXIgYSB0cmFiYWphciBhIEZPUk0gZXMgZW50cmUgbG9zIDI1IC0gMzAgbG8gcXVlIG5vcyBwdWVkZSBheXVkYXIgYSBjcmVhciBjYW1wYcOxYXMgZGUgcmVjbHV0YW1pZW50byBlbmZvY2FkYXMgZW4gZWwgbWVyY2FkbyBkZSBlZGFkIGFsIHF1ZSBsb3MgZW1wbGVhZG9zIGRlIEZPUk0gZXN0YW4gZW5mb2NhZG9zLCBGT1JNIGN1ZW50YSBjb24gdW4gZ3JhbiByYW5nbyBkZSBlZGFkZXMgY29tZW56YW5kbyBkZXNkZSBsb3MgMTkgeSBsbGVnYW5kbyBoYXN0YSBsb3MgNjAuIEVzdGUgdWx0aW1vIHNpZW5kbyBlbCBncnVwbyBtYXMgcGVxdWXDsW8gZGVudHJvIGRlIGxhIGVtcHJlc2EgbWllbnRyYXMgcXVlIGxvcyBqb3ZlbmVzIGRlIDE4IC0gMjAgdGllbmRlbiBhIHNlciB1biBwb3JjZW50YWplIG1hcyBhbHRvIGRlIGhvbWJyZXMuIE5vcyBkYW1vcyBjdWVudGEgY29uIGxhIGdyYWZpY2EgcXVlIEZPUk0gbGUgYWJyZSBsYXMgcHVlcnRhcyBhIG11Y2hhcyBwZXJzb25hcyB5IG9mcmVjZSBvcG9ydHVuaWRhZGVzIGRlIHRyYWJham8gcGFyYSBudWV2YXMgZ2VuZXJhY2lvbmVzIHkgcGVyc29uYXMgY29uIGV4cGVyaWVuY2lhICAKCiMjIDxzcGFuIHN0eWxlID0iY29sb3I6ZGFya29yYW5nZSI+ICoqVGFibGEgZGUgZnJlY3VlbmNpYS9jb250aW5nZW5jaWEqKgoKIyMjIEltcG9ydGFyIGRhdGFzZXRzCmBgYHtyfQpiYWphcyA9IHJlYWQuY3N2KCIvVXNlcnMvZGF2aWRjYXZhem9zL0Rlc2t0b3AvZm9ybV9iYWphc18yMi5jc3YiKQpkZmJhamFzID0gYmFqYXMgCiNWaWV3KGJhamFzKQplbXBsZWFkb3MgPSByZWFkLmNzdigiL1VzZXJzL2RhdmlkY2F2YXpvcy9EZXNrdG9wL2Zvcm1fcmhfZGF0b3MuY3N2IikKZW1wbGVhZG9zZGYgPSBlbXBsZWFkb3MKI1ZpZXcoZW1wbGVhZG9zKQpgYGAKCiMjIyBMSU1QSUVaQSBCQVNFIERFIERBVE9TCmBgYHtyfQpiYWphcyRFU1RBRE8uQ0lWSUwgPSBnc3ViKCJNQVRSSU9NT05JTyIsICJNQVRSSU1PTklPIiwgYmFqYXMkRVNUQURPLkNJVklMKQpgYGAKCiMjIyBNT1RJVk8gREUgQkFKQQpgYGB7cn0KbW90aXZvX2JhamFzID0gZ2dwbG90KGJhamFzLCBhZXMoeCA9IE1PVElWTy5ERS5CQUpBKSkgKwogIGdlb21fYmFyKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpCmVzdGFkb19jaXZpbCA9IGdncGxvdChiYWphcywgYWVzKHggPSBFU1RBRE8uQ0lWSUwpKSArCiAgZ2VvbV9iYXIoKSAKYGBgCgojIyMgRlJFQ1VFTkNJQSBERSBEw41BUyBMQUJPUkFET1MKYGBge3J9Cmhpc3QoYmFqYXMkRElBUy5MQUJPUkFET1MsY29sID0gYmx1ZXM5LHhsYWIgPSAiRElBUyBMQUJPUkFET1MiLHlsYWIgPSJGcmVjdWVuY2lhIiAsbWFpbiA9ICJEw61hcyBMYWJvcmFkb3MiKQpgYGAKCiMjIyBTRVBBUkFDSU9OIERFIEZFQ0hBUyAtIEJBSkFTCmBgYHtyfQpkZl9yb3RhY2lvbiA9IGJhamFzICU+JSBzZWxlY3QoR0VORVJPLCBGRUNIQS5ERS5BTFRBLEJBSkEsIE1PVElWTy5ERS5CQUpBLCBESUFTLkxBQk9SQURPUywgUFVFU1RPKQpkZl9yb3RhY2lvbiA9IGRmX3JvdGFjaW9uICU+JSBzZXBhcmF0ZShCQUpBLCBpbnRvID0gYygiTU9OVEhfQkFKQSIsICJEQVlfQkFKQSIsICJZRUFSX0JBSkEiKSwgc2VwID0gIi8iKQpgYGAKCiMjIyBTRVBBUkFDSU9OIERFIEZFQ0hBUyAtIEFMVEFTCmBgYHtyfQpkZl9yb3RhY2lvbiA9IGRmX3JvdGFjaW9uICU+JSBzZXBhcmF0ZShGRUNIQS5ERS5BTFRBLCBpbnRvID0gYygiTU9OVEhfQUxUQSIsICJEQVlfQUxUQSIsICJZRUFSX0FMVEEiKSwgc2VwID0gIi8iKQpgYGAKCiMjIyBISVNUT0dSQU1BUyBNRVNFUyBFTiBMT1MgUVVFIERBTiBCQUpBUwpgYGB7cn0KZGZfcm90YWNpb24kTU9OVEhfQkFKQSA9IGFzLm51bWVyaWMoZGZfcm90YWNpb24kTU9OVEhfQkFKQSkKaGlzdChkZl9yb3RhY2lvbiRNT05USF9CQUpBLGNvbCA9IGJsdWVzOSx4bGFiID0gIk1PTlRIX0JBSkEiLHlsYWIgPSJGcmVjdWVuY2lhIiAsbWFpbiA9ICJCYWphcyBwb3IgTWVzIikKYGBgCgojIyMgQVNJR05BQ0nDk04gREUgTUVTRVMKYGBge3J9CmRmX21vbnRocyA8LSBkZl9yb3RhY2lvbiAlPiUKICBtdXRhdGUoTkFNRV9NT05USCA9IGNhc2Vfd2hlbigKICAgIE1PTlRIX0JBSkEgPT0gMSB+ICJFbmVybyIsCiAgICBNT05USF9CQUpBID09IDIgfiAiRmVicmVybyIsCiAgICBNT05USF9CQUpBID09IDMgfiAiTWFyem8iLAogICAgTU9OVEhfQkFKQSA9PSA0IH4gIkFicmlsIiwKICAgIE1PTlRIX0JBSkEgPT0gNSB+ICJNYXlvIiwKICAgIE1PTlRIX0JBSkEgPT0gNiB+ICJKdW5pbyIsCiAgICBNT05USF9CQUpBID09IDcgfiAiSnVsaW8iLAogICAgTU9OVEhfQkFKQSA9PSA4IH4gIkFnb3N0byIsCiAgICBNT05USF9CQUpBID09IDkgfiAiU2VwdGllbWJyZSIsCiAgICBNT05USF9CQUpBID09IDEwIH4gIk9jdHVicmUiLAogICAgTU9OVEhfQkFKQSA9PSAxMSB+ICJOb3ZpZW1icmUiLAogICAgTU9OVEhfQkFKQSA9PSAxMiB+ICJEaWNpZW1icmUiCiAgKSkgJT4lCiAgZmlsdGVyKE5BTUVfTU9OVEggJWluJSBjKCJFbmVybyIsICJGZWJyZXJvIiwgIk1hcnpvIiwgIkFicmlsIiwgIk1heW8iLCAiSnVuaW8iLCAiSnVsaW8iLCAiQWdvc3RvIiwgIlNlcHRpZW1icmUiLCAiT2N0dWJyZSIsICJOb3ZpZW1icmUiLCAiRGljaWVtYnJlIikpICU+JQogIHNlbGVjdChHRU5FUk8sIE1PTlRIX0JBSkEsIERBWV9BTFRBLCBZRUFSX0FMVEEsIE1PVElWTy5ERS5CQUpBLCBOQU1FX01PTlRILCBQVUVTVE8pCiNWaWV3KGRmX21vbnRocykKYGBgCgojIyMgR1JBRklDTyBERSBCQVJSQVMgCmBgYHtyfQpiYXJwbG90X3N1YmNhdGVnb3J5ID0gZ2dwbG90KGRmX21vbnRocywgYWVzKE5BTUVfTU9OVEgpKStnZW9tX2JhcihhZXMoKSwgd2lkdGggPSAwLjUpCmJhcnBsb3Rfc3ViY2F0ZWdvcnkKYGBgCgojIyMgVEFCTEEgREUgRlJFQ1VFTkNJQVMKYGBge3J9Cm1vbnRoX2ZyZWN1ZW5jaWFzID0gdGFibGUoZGZfbW9udGhzJE5BTUVfTU9OVEgpCm1lc2VzX2Nyb25vbG9naWNvcyA8LSBjKCJFbmVybyIsICJGZWJyZXJvIiwgIk1hcnpvIiwgIkFicmlsIiwgIk1heW8iLCAiSnVuaW8iLCAiSnVsaW8iLCAiQWdvc3RvIiwgIlNlcHRpZW1icmUiLCAiT2N0dWJyZSIsICJOb3ZpZW1icmUiLCAiRGljaWVtYnJlIikKYGBgCgojIyA8c3BhbiBzdHlsZSA9ImNvbG9yOmRhcmtvcmFuZ2UiPiAqKkRhdG9zIGFkaWNpb25hbGVzIHJlcXVlcmlkb3MqKgoKUGFyYSBsbGV2YXIgYSBjYWJvIHVuIGFuw6FsaXNpcyBtw6FzIGNvbXBsZXRvIHkgdW5hIGNvbXByZW5zacOzbiBtw6FzIHByb2Z1bmRhIGRlbCBjbGltYSBvcmdhbml6YWNpb25hbCBlbiBGb3JtLCByZXN1bHRhIGZ1bmRhbWVudGFsIGxhIGltcGxlbWVudGFjacOzbiBkZSBlbmN1ZXN0YXMgY3VhbGl0YXRpdmFzLiBFc3RhcyBlbmN1ZXN0YXMgYWJvcmRhcsOhbiBhc3BlY3RvcyBjbGF2ZSwgdGFsZXMgY29tbyBsYSBzYXRpc2ZhY2Npw7NuIGNvbiBsYXMgaW5zdGFsYWNpb25lcyBsYWJvcmFsZXMsIGxhcyBjb25kaWNpb25lcyBkZSB0cmFiYWpvLCBsb3MgaG9yYXJpb3MsIGVsIHRyYW5zcG9ydGUgYWwgbHVnYXIgZGUgdHJhYmFqbywgbGEgcmVtdW5lcmFjacOzbiwgbGEgZGluw6FtaWNhIGRlIGxpZGVyYXpnbyBlbiBGb3JtLCBsYSBjb21vZGlkYWQgZW4gZWwgZW50b3JubyBkZSB0cmFiYWpvIHkgc3UgcG9zaWJsZSBjb3JyZWxhY2nDs24gY29uIGxhcyB0YXNhcyBkZSByb3RhY2nDs24sIHRhbnRvIHZvbHVudGFyaWEgY29tbyBpbnZvbHVudGFyaWEsIHkgb3RyYXMgcmVsYWNpb25lcyB5IHJlc3B1ZXN0YXMgcmVsZXZhbnRlcyBxdWUgcG9kcsOtYW4gaWRlbnRpZmljYXJzZS4KCg==