AGREGAR IMAGEN

Introducción

…………..

Contexto

El paquete nycflights13 contiene información sore todos los vueles que partieron desde Nueva York(EWR, JFL, LGA) en destinos a los Estados Unidos en 2013. Fueron 336,776 vuelos en total. Para ayudar a comprender las causas de los retrasos, también incluye otros ocnjuntos de datos útiles.

Este paquete incluye las siguientes tablas:

  • flights = todos los vuelos que salieron de NUeva York en el 2013
  • weather = datos metereológicos por hora de cada aeropuerto
  • planes = información de construcción de cada avión
  • airports = nombres y ublicaciones de aeropuertos
  • airlines = relación entre nombres y códigos de las aerolíneas

Fuente: Origen de los datos

Instalar paquetes y llamar librerías

#install.packages("nycflight13")
library(nycflights13)
#install.packages("tidyverse")
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## Warning: package 'ggplot2' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ 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
#install.packages("dplyr")
library(dplyr)
#install.packages("ggplot2")
library(ggplot2)
#install.packages("")
library(broom)
## Warning: package 'broom' was built under R version 4.3.3

Guardar base de datos

flights <- flights
weather <- weather
planes <- planes
airports <- airports
airlines <- airlines

Relación entre las bases de datos

agregar imagen

Data Wrangling

1. Funciones básicas de manejo de datos

Select

La función select sirve para seleccionar columnos de un table (data frame).

df1 <- flights %>% select(carrier, flight) # Selección de columnas específicas
df2 <- flights %>% select(carrier:distance) # Selección de rango de columnas
df3 <- flights %>% select(-carrier, -flight) # Eliminar columnas específicas
df4 <- flights %>% select(-carrier: -flight) # Eliminar rango de columnas
df5 <- flights %>% select(aerolinea = carrier) # Selecciona una columna y le cambia el nombre
df6 <- flights %>% rename(aerolinea = carrier) # Cambia el nombre de una columna

Filter

La función Filter sirve para seleccionar renglones de un tabla(data frame).

df7 <- flights %>% filter(dep_delay >=500) # Extrae renglones que cumplan condición
# Condicionales: Igual ==, Desigual =!=, Mayor que >, Mayor o igual que >=, Menor o igual que <=
# Operadores lógicos: AND &, OR |, NOT !
df8 <- flights %>% filter(dep_delay >=500, dep_delay <=600) # Extrae renglones que cumplan con dos condiciones
df9 <- flights %>% slice(1000: 1099) # Extrae los números de los renglones indicados, sin importar sus valores

Distinct

La función distinct sirve para eliminar renglones duplicados.

df10 <- distinct(flights) # Dejar solo los renglones diferentes, borra todos los repetidos.

Merge

La función merge sirve para juntar bases de datos.

bdgrande <- merge(flights, airlines, by="carrier")
bdgrande2 <- merge(bdgrande,planes, by="tailnum")

Mutate

bdgrande3 <- mutate(bdgrande2, dist_mts = distance*1.609)
#Agrega variables nuevas caluladas a partir de variables existentes en la base de datos.

Ejercicios

  1. Encuentra todos los vuelos que tuvieron un atraso en llegada de 2 horas o más.
ejercicio1 <- bdgrande2 %>% filter(arr_delay>=120)
  1. Encuentra todos los vuelos que llegaron a Houston (IAN O HOU)
ejercicio2 <- bdgrande2 %>% filter(dest== "IAH" | dest == "HOU")
  1. Encuentra todos los vuelos operados por United, American o Delta.
ejercicio3 <- bdgrande2 %>% filter(carrier %in% c("UA", "AA", "DL"))
  1. Encuentra todos los vuelos que despegaron en Julio, Agosto o Septiembre
ejercicio4 <- bdgrande2 %>% filter(month %in% c(7, 8, 9))
ejercicio4a <- bdgrande2 %>% filter(month == 7 | month == 8 | month == 9) 
  1. Encuentra todos los vuelos que arrivaron más de 2 horas tarde, pero no despegaron tarde.
ejercicio5 <- bdgrande2 %>% filter(arr_delay>120 & dep_time == sched_dep_time)
ejercicio5a <- bdgrande2 %>% filter(arr_delay>120 & dep_delay<=0)
  1. Encuentra todos los vuelos que se retrasaron al menos 1 hora, pero que llegaron antes 30 minutos o más.
ejercicio6 <- bdgrande2 %>% filter(dep_delay>=60 & arr_delay<=-30)
  1. Encuentra todos los vuelos que salieron entre la medianoche y las 6 a.m.
ejercicio7 <- bdgrande2 %>% filter(dep_time %in% c("2400", "100", "200", "300", "400", "500", "600"))
ejercicio7a <- bdgrande2 %>% filter(dep_time==2400 | dep_time<=600) 
ejercicio7b <- bdgrande2 %>% filter(hour %in% c("0", "1", "2", "3", "4", "5", "6"))

Arrange

Similar a filter () pero en lugar de seleccionar renglones, los ordena de menor a mayor.

df11 <- arrange(bdgrande2, year.x, month, day)

Para acomodar de mayor a menor.

df12 <- arrange(bdgrande2, year.x, desc(month), day)

Summarize

Colapsa una tabla a un sólo renglón

# Obtén el retraso promedio de salida de despegue de todos los vuelos
summarize(bdgrande2, mean(dep_delay, na.rm=TRUE))
##   mean(dep_delay, na.rm = TRUE)
## 1                      13.17979

Group by

Agrupa tabla basado en algunas columnas.

# Obtener el retraso promedio de despegue por día
por_dia <- group_by(bdgrande2, year.x, month, day)
summarize(por_dia, mean(dep_delay, na.rm=TRUE))
## `summarise()` has grouped output by 'year.x', 'month'. You can override using
## the `.groups` argument.
## # A tibble: 365 × 4
## # Groups:   year.x, month [12]
##    year.x month   day `mean(dep_delay, na.rm = TRUE)`
##     <int> <int> <int>                           <dbl>
##  1   2013     1     1                           10.7 
##  2   2013     1     2                           14.4 
##  3   2013     1     3                           11.1 
##  4   2013     1     4                           10.0 
##  5   2013     1     5                            5.70
##  6   2013     1     6                            7.98
##  7   2013     1     7                            6.49
##  8   2013     1     8                            3.10
##  9   2013     1     9                            3.17
## 10   2013     1    10                            1.89
## # ℹ 355 more rows

Evidencia 1 New York (Hecha en clase)

1. Cargar en memoria la tabla “flights” y mostrar su contenido

# La carga a a memoria se hizo en el paso anterior
flights
## # A tibble: 336,776 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 336,766 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

2. Consulta la estructura de “flights”

str(flights)
## tibble [336,776 × 19] (S3: tbl_df/tbl/data.frame)
##  $ year          : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month         : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day           : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_time      : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
##  $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
##  $ dep_delay     : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_time      : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
##  $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
##  $ arr_delay     : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ carrier       : chr [1:336776] "UA" "UA" "AA" "B6" ...
##  $ flight        : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
##  $ tailnum       : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
##  $ origin        : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
##  $ dest          : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
##  $ air_time      : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ distance      : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ hour          : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
##  $ minute        : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
# int:entero (sin decimales)
# num:numérico (con decimales)
# chr: caractér (letras)
# date: fecha (en R va año-mes-dia)
# POSIXct:formato fecha y hora

3. ¿Cuál es la clase “flights” y qué significa?

class(flights)
## [1] "tbl_df"     "tbl"        "data.frame"
# Las 5 clases de objetos
# 1. numeric: Número real o décimal
# 2. integer: Números enteros
# 3. Complex: Números complejos
# 4. Character: Caractéres 
# 5. Logical: TRUE o FALSE

# Las 4 clases de objetos compuestos son:
# 1. list: lista
# 2. Matrix: Matriz
# 3. Array: colección de objetos
# 4. data.frame: base de datos

4. ¿Cuántas columnas y renglones tiene “flights”?

# Número de columnas
ncol(flights)
## [1] 19
# Numero de renglones
nrow(flights)
## [1] 336776
# Dimensión
dim(flights)
## [1] 336776     19

5. Muestra los primeros 6 renglones de “flights”. Tambien los ultimos 6

head(flights)
## # A tibble: 6 × 19
##    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
## 1  2013     1     1      517            515         2      830            819
## 2  2013     1     1      533            529         4      850            830
## 3  2013     1     1      542            540         2      923            850
## 4  2013     1     1      544            545        -1     1004           1022
## 5  2013     1     1      554            600        -6      812            837
## 6  2013     1     1      554            558        -4      740            728
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
tail(flights)
## # A tibble: 6 × 19
##    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
## 1  2013     9    30       NA           1842        NA       NA           2019
## 2  2013     9    30       NA           1455        NA       NA           1634
## 3  2013     9    30       NA           2200        NA       NA           2312
## 4  2013     9    30       NA           1210        NA       NA           1330
## 5  2013     9    30       NA           1159        NA       NA           1344
## 6  2013     9    30       NA            840        NA       NA           1020
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
# Si quisieramos 7 renglones: head(flights,7)

6. Muestra los estadisticos descriptivos de “flights”

summary(flights)
##       year          month             day           dep_time    sched_dep_time
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1   Min.   : 106  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 907   1st Qu.: 906  
##  Median :2013   Median : 7.000   Median :16.00   Median :1401   Median :1359  
##  Mean   :2013   Mean   : 6.549   Mean   :15.71   Mean   :1349   Mean   :1344  
##  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1744   3rd Qu.:1729  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400   Max.   :2359  
##                                                  NA's   :8255                 
##    dep_delay          arr_time    sched_arr_time   arr_delay       
##  Min.   : -43.00   Min.   :   1   Min.   :   1   Min.   : -86.000  
##  1st Qu.:  -5.00   1st Qu.:1104   1st Qu.:1124   1st Qu.: -17.000  
##  Median :  -2.00   Median :1535   Median :1556   Median :  -5.000  
##  Mean   :  12.64   Mean   :1502   Mean   :1536   Mean   :   6.895  
##  3rd Qu.:  11.00   3rd Qu.:1940   3rd Qu.:1945   3rd Qu.:  14.000  
##  Max.   :1301.00   Max.   :2400   Max.   :2359   Max.   :1272.000  
##  NA's   :8255      NA's   :8713                  NA's   :9430      
##    carrier              flight       tailnum             origin         
##  Length:336776      Min.   :   1   Length:336776      Length:336776     
##  Class :character   1st Qu.: 553   Class :character   Class :character  
##  Mode  :character   Median :1496   Mode  :character   Mode  :character  
##                     Mean   :1972                                        
##                     3rd Qu.:3465                                        
##                     Max.   :8500                                        
##                                                                         
##      dest              air_time        distance         hour      
##  Length:336776      Min.   : 20.0   Min.   :  17   Min.   : 1.00  
##  Class :character   1st Qu.: 82.0   1st Qu.: 502   1st Qu.: 9.00  
##  Mode  :character   Median :129.0   Median : 872   Median :13.00  
##                     Mean   :150.7   Mean   :1040   Mean   :13.18  
##                     3rd Qu.:192.0   3rd Qu.:1389   3rd Qu.:17.00  
##                     Max.   :695.0   Max.   :4983   Max.   :23.00  
##                     NA's   :9430                                  
##      minute        time_hour                     
##  Min.   : 0.00   Min.   :2013-01-01 05:00:00.00  
##  1st Qu.: 8.00   1st Qu.:2013-04-04 13:00:00.00  
##  Median :29.00   Median :2013-07-03 10:00:00.00  
##  Mean   :26.23   Mean   :2013-07-03 05:22:54.64  
##  3rd Qu.:44.00   3rd Qu.:2013-10-01 07:00:00.00  
##  Max.   :59.00   Max.   :2013-12-31 23:00:00.00  
## 

Conclusión

En este trabajo pudimos utlizar las funciones más comunes del análisis exploratorio, el cual es el primer paso para cualquier trabajo de manipulación de datos.

Evidencia 1 Analítica descriptiva

Exploración

flights

# Consulta la estructura de cada data frame
# Para el data frame flights
data(flights) 
str(flights)
## tibble [336,776 × 19] (S3: tbl_df/tbl/data.frame)
##  $ year          : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month         : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day           : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_time      : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
##  $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
##  $ dep_delay     : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_time      : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
##  $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
##  $ arr_delay     : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ carrier       : chr [1:336776] "UA" "UA" "AA" "B6" ...
##  $ flight        : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
##  $ tailnum       : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
##  $ origin        : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
##  $ dest          : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
##  $ air_time      : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ distance      : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ hour          : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
##  $ minute        : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
ncol(flights)
## [1] 19
nrow(flights)
## [1] 336776
dim(flights)
## [1] 336776     19
head(flights)
## # A tibble: 6 × 19
##    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
## 1  2013     1     1      517            515         2      830            819
## 2  2013     1     1      533            529         4      850            830
## 3  2013     1     1      542            540         2      923            850
## 4  2013     1     1      544            545        -1     1004           1022
## 5  2013     1     1      554            600        -6      812            837
## 6  2013     1     1      554            558        -4      740            728
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
tail(flights)
## # A tibble: 6 × 19
##    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
## 1  2013     9    30       NA           1842        NA       NA           2019
## 2  2013     9    30       NA           1455        NA       NA           1634
## 3  2013     9    30       NA           2200        NA       NA           2312
## 4  2013     9    30       NA           1210        NA       NA           1330
## 5  2013     9    30       NA           1159        NA       NA           1344
## 6  2013     9    30       NA            840        NA       NA           1020
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
summary(flights)
##       year          month             day           dep_time    sched_dep_time
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1   Min.   : 106  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 907   1st Qu.: 906  
##  Median :2013   Median : 7.000   Median :16.00   Median :1401   Median :1359  
##  Mean   :2013   Mean   : 6.549   Mean   :15.71   Mean   :1349   Mean   :1344  
##  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1744   3rd Qu.:1729  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400   Max.   :2359  
##                                                  NA's   :8255                 
##    dep_delay          arr_time    sched_arr_time   arr_delay       
##  Min.   : -43.00   Min.   :   1   Min.   :   1   Min.   : -86.000  
##  1st Qu.:  -5.00   1st Qu.:1104   1st Qu.:1124   1st Qu.: -17.000  
##  Median :  -2.00   Median :1535   Median :1556   Median :  -5.000  
##  Mean   :  12.64   Mean   :1502   Mean   :1536   Mean   :   6.895  
##  3rd Qu.:  11.00   3rd Qu.:1940   3rd Qu.:1945   3rd Qu.:  14.000  
##  Max.   :1301.00   Max.   :2400   Max.   :2359   Max.   :1272.000  
##  NA's   :8255      NA's   :8713                  NA's   :9430      
##    carrier              flight       tailnum             origin         
##  Length:336776      Min.   :   1   Length:336776      Length:336776     
##  Class :character   1st Qu.: 553   Class :character   Class :character  
##  Mode  :character   Median :1496   Mode  :character   Mode  :character  
##                     Mean   :1972                                        
##                     3rd Qu.:3465                                        
##                     Max.   :8500                                        
##                                                                         
##      dest              air_time        distance         hour      
##  Length:336776      Min.   : 20.0   Min.   :  17   Min.   : 1.00  
##  Class :character   1st Qu.: 82.0   1st Qu.: 502   1st Qu.: 9.00  
##  Mode  :character   Median :129.0   Median : 872   Median :13.00  
##                     Mean   :150.7   Mean   :1040   Mean   :13.18  
##                     3rd Qu.:192.0   3rd Qu.:1389   3rd Qu.:17.00  
##                     Max.   :695.0   Max.   :4983   Max.   :23.00  
##                     NA's   :9430                                  
##      minute        time_hour                     
##  Min.   : 0.00   Min.   :2013-01-01 05:00:00.00  
##  1st Qu.: 8.00   1st Qu.:2013-04-04 13:00:00.00  
##  Median :29.00   Median :2013-07-03 10:00:00.00  
##  Mean   :26.23   Mean   :2013-07-03 05:22:54.64  
##  3rd Qu.:44.00   3rd Qu.:2013-10-01 07:00:00.00  
##  Max.   :59.00   Max.   :2013-12-31 23:00:00.00  
## 

¿Cuáles son los campos y sus tipos de datos? Los campos del conjunto de datos flights y sus tipos de datos son:

  • year: int (entero) - Año del vuelo.
  • month: int (entero) - Mes del vuelo.
  • day: int (entero) - Día del vuelo.
  • dep_time: int (entero) - Hora de salida real del vuelo.
  • sched_dep_time: int (entero) - Hora de salida programada del vuelo.
  • dep_delay: num (número) - Retraso de salida en minutos.
  • arr_time: int (entero) - Hora de llegada real.
  • sched_arr_time: int (entero) - Hora de llegada programada.
  • arr_delay: num (número) - Retraso de llegada en minutos.
  • carrier: chr (carácter) - Código de la aerolínea.
  • flight: int (entero) - Número del vuelo.
  • tailnum: chr (carácter) - Número de cola del avión.
  • origin: chr (carácter) - Aeropuerto de origen.
  • dest: chr (carácter) - Aeropuerto de destino.
  • air_time: num (número) - Tiempo en el aire en minutos.
  • distance: num (número) - Distancia del vuelo en millas.
  • hour: num (número) - Hora programada de salida (hora).
  • minute: num (número) - Hora programada de salida (minutos).
  • time_hour: POSIXct (dttm) - Fecha y hora del vuelo.

weather

# Para el data frame weather
data(weather) 
str(weather)
## tibble [26,115 × 15] (S3: tbl_df/tbl/data.frame)
##  $ origin    : chr [1:26115] "EWR" "EWR" "EWR" "EWR" ...
##  $ year      : int [1:26115] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month     : int [1:26115] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day       : int [1:26115] 1 1 1 1 1 1 1 1 1 1 ...
##  $ hour      : int [1:26115] 1 2 3 4 5 6 7 8 9 10 ...
##  $ temp      : num [1:26115] 39 39 39 39.9 39 ...
##  $ dewp      : num [1:26115] 26.1 27 28 28 28 ...
##  $ humid     : num [1:26115] 59.4 61.6 64.4 62.2 64.4 ...
##  $ wind_dir  : num [1:26115] 270 250 240 250 260 240 240 250 260 260 ...
##  $ wind_speed: num [1:26115] 10.36 8.06 11.51 12.66 12.66 ...
##  $ wind_gust : num [1:26115] NA NA NA NA NA NA NA NA NA NA ...
##  $ precip    : num [1:26115] 0 0 0 0 0 0 0 0 0 0 ...
##  $ pressure  : num [1:26115] 1012 1012 1012 1012 1012 ...
##  $ visib     : num [1:26115] 10 10 10 10 10 10 10 10 10 10 ...
##  $ time_hour : POSIXct[1:26115], format: "2013-01-01 01:00:00" "2013-01-01 02:00:00" ...
ncol(weather)
## [1] 15
nrow(weather)
## [1] 26115
dim(weather)
## [1] 26115    15
head(weather)
## # A tibble: 6 × 15
##   origin  year month   day  hour  temp  dewp humid wind_dir wind_speed wind_gust
##   <chr>  <int> <int> <int> <int> <dbl> <dbl> <dbl>    <dbl>      <dbl>     <dbl>
## 1 EWR     2013     1     1     1  39.0  26.1  59.4      270      10.4         NA
## 2 EWR     2013     1     1     2  39.0  27.0  61.6      250       8.06        NA
## 3 EWR     2013     1     1     3  39.0  28.0  64.4      240      11.5         NA
## 4 EWR     2013     1     1     4  39.9  28.0  62.2      250      12.7         NA
## 5 EWR     2013     1     1     5  39.0  28.0  64.4      260      12.7         NA
## 6 EWR     2013     1     1     6  37.9  28.0  67.2      240      11.5         NA
## # ℹ 4 more variables: precip <dbl>, pressure <dbl>, visib <dbl>,
## #   time_hour <dttm>
tail(weather)
## # A tibble: 6 × 15
##   origin  year month   day  hour  temp  dewp humid wind_dir wind_speed wind_gust
##   <chr>  <int> <int> <int> <int> <dbl> <dbl> <dbl>    <dbl>      <dbl>     <dbl>
## 1 LGA     2013    12    30    13  37.0  21.9  54.0      340       17.3      20.7
## 2 LGA     2013    12    30    14  36.0  19.9  51.8      340       13.8      21.9
## 3 LGA     2013    12    30    15  34.0  17.1  49.5      330       17.3      21.9
## 4 LGA     2013    12    30    16  32    15.1  49.2      340       15.0      23.0
## 5 LGA     2013    12    30    17  30.9  12.9  46.7      320       17.3      NA  
## 6 LGA     2013    12    30    18  28.9  10.9  46.4      330       18.4      NA  
## # ℹ 4 more variables: precip <dbl>, pressure <dbl>, visib <dbl>,
## #   time_hour <dttm>
summary(weather)
##     origin               year          month             day       
##  Length:26115       Min.   :2013   Min.   : 1.000   Min.   : 1.00  
##  Class :character   1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00  
##  Mode  :character   Median :2013   Median : 7.000   Median :16.00  
##                     Mean   :2013   Mean   : 6.504   Mean   :15.68  
##                     3rd Qu.:2013   3rd Qu.: 9.000   3rd Qu.:23.00  
##                     Max.   :2013   Max.   :12.000   Max.   :31.00  
##                                                                    
##       hour            temp             dewp           humid       
##  Min.   : 0.00   Min.   : 10.94   Min.   :-9.94   Min.   : 12.74  
##  1st Qu.: 6.00   1st Qu.: 39.92   1st Qu.:26.06   1st Qu.: 47.05  
##  Median :11.00   Median : 55.40   Median :42.08   Median : 61.79  
##  Mean   :11.49   Mean   : 55.26   Mean   :41.44   Mean   : 62.53  
##  3rd Qu.:17.00   3rd Qu.: 69.98   3rd Qu.:57.92   3rd Qu.: 78.79  
##  Max.   :23.00   Max.   :100.04   Max.   :78.08   Max.   :100.00  
##                  NA's   :1        NA's   :1       NA's   :1       
##     wind_dir       wind_speed         wind_gust         precip        
##  Min.   :  0.0   Min.   :   0.000   Min.   :16.11   Min.   :0.000000  
##  1st Qu.:120.0   1st Qu.:   6.905   1st Qu.:20.71   1st Qu.:0.000000  
##  Median :220.0   Median :  10.357   Median :24.17   Median :0.000000  
##  Mean   :199.8   Mean   :  10.518   Mean   :25.49   Mean   :0.004469  
##  3rd Qu.:290.0   3rd Qu.:  13.809   3rd Qu.:28.77   3rd Qu.:0.000000  
##  Max.   :360.0   Max.   :1048.361   Max.   :66.75   Max.   :1.210000  
##  NA's   :460     NA's   :4          NA's   :20778                     
##     pressure          visib          time_hour                    
##  Min.   : 983.8   Min.   : 0.000   Min.   :2013-01-01 01:00:00.0  
##  1st Qu.:1012.9   1st Qu.:10.000   1st Qu.:2013-04-01 21:30:00.0  
##  Median :1017.6   Median :10.000   Median :2013-07-01 14:00:00.0  
##  Mean   :1017.9   Mean   : 9.255   Mean   :2013-07-01 18:26:37.7  
##  3rd Qu.:1023.0   3rd Qu.:10.000   3rd Qu.:2013-09-30 13:00:00.0  
##  Max.   :1042.1   Max.   :10.000   Max.   :2013-12-30 18:00:00.0  
##  NA's   :2729

¿Cuáles son los campos y sus tipos de datos? Los campos del conjunto de datos weather y sus tipos de datos son:

  • origin: chr (carácter) - Código del aeropuerto de origen.
  • year: int (entero) - Año de la observación meteorológica.
  • month: int (entero) - Mes de la observación meteorológica.
  • day: int (entero) - Día de la observación meteorológica.
  • hour: int (entero) - Hora de la observación meteorológica.
  • temp: num (número) - Temperatura en grados Fahrenheit.
  • dewp: num (número) - Punto de rocío en grados Fahrenheit.
  • humid: num (número) - Humedad relativa en porcentaje.
  • wind_dir: num (número) - Dirección del viento en grados.
  • wind_speed: num (número) - Velocidad del viento en millas por hora.
  • wind_gust: num (número) - Ráfaga de viento en millas por hora.
  • precip: num (número) - Precipitación en pulgadas.
  • pressure: num (número) - Presión atmosférica en milibares.
  • visib: num (número) - Visibilidad en millas.
  • time_hour: POSIXct (dttm) - Fecha y hora de la observación meteorológica.

planes

# Para el data frame planes
data(planes) 
str(planes)
## tibble [3,322 × 9] (S3: tbl_df/tbl/data.frame)
##  $ tailnum     : chr [1:3322] "N10156" "N102UW" "N103US" "N104UW" ...
##  $ year        : int [1:3322] 2004 1998 1999 1999 2002 1999 1999 1999 1999 1999 ...
##  $ type        : chr [1:3322] "Fixed wing multi engine" "Fixed wing multi engine" "Fixed wing multi engine" "Fixed wing multi engine" ...
##  $ manufacturer: chr [1:3322] "EMBRAER" "AIRBUS INDUSTRIE" "AIRBUS INDUSTRIE" "AIRBUS INDUSTRIE" ...
##  $ model       : chr [1:3322] "EMB-145XR" "A320-214" "A320-214" "A320-214" ...
##  $ engines     : int [1:3322] 2 2 2 2 2 2 2 2 2 2 ...
##  $ seats       : int [1:3322] 55 182 182 182 55 182 182 182 182 182 ...
##  $ speed       : int [1:3322] NA NA NA NA NA NA NA NA NA NA ...
##  $ engine      : chr [1:3322] "Turbo-fan" "Turbo-fan" "Turbo-fan" "Turbo-fan" ...
ncol(planes)
## [1] 9
nrow(planes)
## [1] 3322
dim(planes)
## [1] 3322    9
head(planes)
## # A tibble: 6 × 9
##   tailnum  year type               manufacturer model engines seats speed engine
##   <chr>   <int> <chr>              <chr>        <chr>   <int> <int> <int> <chr> 
## 1 N10156   2004 Fixed wing multi … EMBRAER      EMB-…       2    55    NA Turbo…
## 2 N102UW   1998 Fixed wing multi … AIRBUS INDU… A320…       2   182    NA Turbo…
## 3 N103US   1999 Fixed wing multi … AIRBUS INDU… A320…       2   182    NA Turbo…
## 4 N104UW   1999 Fixed wing multi … AIRBUS INDU… A320…       2   182    NA Turbo…
## 5 N10575   2002 Fixed wing multi … EMBRAER      EMB-…       2    55    NA Turbo…
## 6 N105UW   1999 Fixed wing multi … AIRBUS INDU… A320…       2   182    NA Turbo…
tail(planes)
## # A tibble: 6 × 9
##   tailnum  year type               manufacturer model engines seats speed engine
##   <chr>   <int> <chr>              <chr>        <chr>   <int> <int> <int> <chr> 
## 1 N996DL   1991 Fixed wing multi … MCDONNELL D… MD-88       2   142    NA Turbo…
## 2 N997AT   2002 Fixed wing multi … BOEING       717-…       2   100    NA Turbo…
## 3 N997DL   1992 Fixed wing multi … MCDONNELL D… MD-88       2   142    NA Turbo…
## 4 N998AT   2002 Fixed wing multi … BOEING       717-…       2   100    NA Turbo…
## 5 N998DL   1992 Fixed wing multi … MCDONNELL D… MD-88       2   142    NA Turbo…
## 6 N999DN   1992 Fixed wing multi … MCDONNELL D… MD-88       2   142    NA Turbo…
summary(planes)
##    tailnum               year          type           manufacturer      
##  Length:3322        Min.   :1956   Length:3322        Length:3322       
##  Class :character   1st Qu.:1997   Class :character   Class :character  
##  Mode  :character   Median :2001   Mode  :character   Mode  :character  
##                     Mean   :2000                                        
##                     3rd Qu.:2005                                        
##                     Max.   :2013                                        
##                     NA's   :70                                          
##     model              engines          seats           speed      
##  Length:3322        Min.   :1.000   Min.   :  2.0   Min.   : 90.0  
##  Class :character   1st Qu.:2.000   1st Qu.:140.0   1st Qu.:107.5  
##  Mode  :character   Median :2.000   Median :149.0   Median :162.0  
##                     Mean   :1.995   Mean   :154.3   Mean   :236.8  
##                     3rd Qu.:2.000   3rd Qu.:182.0   3rd Qu.:432.0  
##                     Max.   :4.000   Max.   :450.0   Max.   :432.0  
##                                                     NA's   :3299   
##     engine         
##  Length:3322       
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 

¿Cuáles son los campos y sus tipos de datos? Los campos del conjunto de datos planes y sus tipos de datos son:

  • tailnum: chr (carácter) - Número de cola del avión.
  • year: int (entero) - Año de fabricación del avión.
  • type: chr (carácter) - Tipo de avión, en este caso todos son de ala fija con múltiples motores.
  • manufacturer: chr (carácter) - Fabricante del avión.
  • model: chr (carácter) - Modelo del avión.
  • engines: int (entero) - Número de motores del avión.
  • seats: int (entero) - Número de asientos del avión.
  • speed: int (entero) - Velocidad del avión, aunque la mayoría de los registros parecen no tener esta información (NA).
  • engine: chr (carácter) - Tipo de motor del avión, la mayoría son turbofán.

airports

# Para el data frame airports
data(airports) 
str(airports)
## tibble [1,458 × 8] (S3: tbl_df/tbl/data.frame)
##  $ faa  : chr [1:1458] "04G" "06A" "06C" "06N" ...
##  $ name : chr [1:1458] "Lansdowne Airport" "Moton Field Municipal Airport" "Schaumburg Regional" "Randall Airport" ...
##  $ lat  : num [1:1458] 41.1 32.5 42 41.4 31.1 ...
##  $ lon  : num [1:1458] -80.6 -85.7 -88.1 -74.4 -81.4 ...
##  $ alt  : num [1:1458] 1044 264 801 523 11 ...
##  $ tz   : num [1:1458] -5 -6 -6 -5 -5 -5 -5 -5 -5 -8 ...
##  $ dst  : chr [1:1458] "A" "A" "A" "A" ...
##  $ tzone: chr [1:1458] "America/New_York" "America/Chicago" "America/Chicago" "America/New_York" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   name = col_character(),
##   ..   city = col_character(),
##   ..   country = col_character(),
##   ..   faa = col_character(),
##   ..   icao = col_character(),
##   ..   lat = col_double(),
##   ..   lon = col_double(),
##   ..   alt = col_double(),
##   ..   tz = col_double(),
##   ..   dst = col_character(),
##   ..   tzone = col_character()
##   .. )
ncol(airports)
## [1] 8
nrow(airports)
## [1] 1458
dim(airports)
## [1] 1458    8
head(airports)
## # A tibble: 6 × 8
##   faa   name                             lat   lon   alt    tz dst   tzone      
##   <chr> <chr>                          <dbl> <dbl> <dbl> <dbl> <chr> <chr>      
## 1 04G   Lansdowne Airport               41.1 -80.6  1044    -5 A     America/Ne…
## 2 06A   Moton Field Municipal Airport   32.5 -85.7   264    -6 A     America/Ch…
## 3 06C   Schaumburg Regional             42.0 -88.1   801    -6 A     America/Ch…
## 4 06N   Randall Airport                 41.4 -74.4   523    -5 A     America/Ne…
## 5 09J   Jekyll Island Airport           31.1 -81.4    11    -5 A     America/Ne…
## 6 0A9   Elizabethton Municipal Airport  36.4 -82.2  1593    -5 A     America/Ne…
tail(airports)
## # A tibble: 6 × 8
##   faa   name                        lat    lon   alt    tz dst   tzone          
##   <chr> <chr>                     <dbl>  <dbl> <dbl> <dbl> <chr> <chr>          
## 1 ZTY   Boston Back Bay Station    42.3  -71.1    20    -5 A     America/New_Yo…
## 2 ZUN   Black Rock                 35.1 -109.   6454    -7 A     America/Denver 
## 3 ZVE   New Haven Rail Station     41.3  -72.9     7    -5 A     America/New_Yo…
## 4 ZWI   Wilmington Amtrak Station  39.7  -75.6     0    -5 A     America/New_Yo…
## 5 ZWU   Washington Union Station   38.9  -77.0    76    -5 A     America/New_Yo…
## 6 ZYP   Penn Station               40.8  -74.0    35    -5 A     America/New_Yo…
summary(airports)
##      faa                name                lat             lon         
##  Length:1458        Length:1458        Min.   :19.72   Min.   :-176.65  
##  Class :character   Class :character   1st Qu.:34.26   1st Qu.:-119.19  
##  Mode  :character   Mode  :character   Median :40.09   Median : -94.66  
##                                        Mean   :41.65   Mean   :-103.39  
##                                        3rd Qu.:45.07   3rd Qu.: -82.52  
##                                        Max.   :72.27   Max.   : 174.11  
##       alt                tz              dst               tzone          
##  Min.   : -54.00   Min.   :-10.000   Length:1458        Length:1458       
##  1st Qu.:  70.25   1st Qu.: -8.000   Class :character   Class :character  
##  Median : 473.00   Median : -6.000   Mode  :character   Mode  :character  
##  Mean   :1001.42   Mean   : -6.519                                        
##  3rd Qu.:1062.50   3rd Qu.: -5.000                                        
##  Max.   :9078.00   Max.   :  8.000

¿Cuáles son los campos y sus tipos de datos? Los campos del conjunto de datos airports y sus tipos de datos son:

  • origin: chr (carácter) - Código del aeropuerto.
  • name: chr (carácter) - Nombre del aeropuerto.
  • lat: num (número) - Latitud del aeropuerto.
  • lon: num (número) - Longitud del aeropuerto.
  • alt: num (número) - Altitud del aeropuerto en pies.
  • tz: num (número) - Zona horaria del aeropuerto, basada en el desplazamiento del UTC.
  • dst: chr (carácter) - Indicador de horario de verano (p. ej., “A” para horario de verano, “N” para no observarlo).
  • tzone: chr (carácter) - Zona horaria del aeropuerto en texto, por ejemplo, “America/New_York”.

airlines

# Para el data frame airlines
data(airlines) 
str(airlines)
## tibble [16 × 2] (S3: tbl_df/tbl/data.frame)
##  $ carrier: chr [1:16] "9E" "AA" "AS" "B6" ...
##  $ name   : chr [1:16] "Endeavor Air Inc." "American Airlines Inc." "Alaska Airlines Inc." "JetBlue Airways" ...
ncol(airlines)
## [1] 2
nrow(airlines)
## [1] 16
dim(airlines)
## [1] 16  2
head(airlines)
## # A tibble: 6 × 2
##   carrier name                    
##   <chr>   <chr>                   
## 1 9E      Endeavor Air Inc.       
## 2 AA      American Airlines Inc.  
## 3 AS      Alaska Airlines Inc.    
## 4 B6      JetBlue Airways         
## 5 DL      Delta Air Lines Inc.    
## 6 EV      ExpressJet Airlines Inc.
tail(airlines)
## # A tibble: 6 × 2
##   carrier name                  
##   <chr>   <chr>                 
## 1 OO      SkyWest Airlines Inc. 
## 2 UA      United Air Lines Inc. 
## 3 US      US Airways Inc.       
## 4 VX      Virgin America        
## 5 WN      Southwest Airlines Co.
## 6 YV      Mesa Airlines Inc.
summary(airlines)
##    carrier              name          
##  Length:16          Length:16         
##  Class :character   Class :character  
##  Mode  :character   Mode  :character

¿Cuáles son los campos y sus tipos de datos?

Los campos del conjunto de datos airlines y sus tipos de datos son:

  • carrier: chr (carácter) - Código de dos letras de la aerolínea.
  • name: chr (carácter) - Nombre completo de la aerolínea.

Manipulación de datos

1 Consultar dataframe

#Al consultar l DataFrame nos permite visualizar la base de datos *flights*.
view(flights)

2 Encuentra los datos descriptivos del data frame flights. Identifica la media de las distancias recorridas en millas.

#la media (Mean) de la distancia es de 1040 millas, lo que indica que, en promedio, los vuelos en este conjunto de datos recorren una distancia de 1040 millas.
summary(flights)
##       year          month             day           dep_time    sched_dep_time
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   :   1   Min.   : 106  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 907   1st Qu.: 906  
##  Median :2013   Median : 7.000   Median :16.00   Median :1401   Median :1359  
##  Mean   :2013   Mean   : 6.549   Mean   :15.71   Mean   :1349   Mean   :1344  
##  3rd Qu.:2013   3rd Qu.:10.000   3rd Qu.:23.00   3rd Qu.:1744   3rd Qu.:1729  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :2400   Max.   :2359  
##                                                  NA's   :8255                 
##    dep_delay          arr_time    sched_arr_time   arr_delay       
##  Min.   : -43.00   Min.   :   1   Min.   :   1   Min.   : -86.000  
##  1st Qu.:  -5.00   1st Qu.:1104   1st Qu.:1124   1st Qu.: -17.000  
##  Median :  -2.00   Median :1535   Median :1556   Median :  -5.000  
##  Mean   :  12.64   Mean   :1502   Mean   :1536   Mean   :   6.895  
##  3rd Qu.:  11.00   3rd Qu.:1940   3rd Qu.:1945   3rd Qu.:  14.000  
##  Max.   :1301.00   Max.   :2400   Max.   :2359   Max.   :1272.000  
##  NA's   :8255      NA's   :8713                  NA's   :9430      
##    carrier              flight       tailnum             origin         
##  Length:336776      Min.   :   1   Length:336776      Length:336776     
##  Class :character   1st Qu.: 553   Class :character   Class :character  
##  Mode  :character   Median :1496   Mode  :character   Mode  :character  
##                     Mean   :1972                                        
##                     3rd Qu.:3465                                        
##                     Max.   :8500                                        
##                                                                         
##      dest              air_time        distance         hour      
##  Length:336776      Min.   : 20.0   Min.   :  17   Min.   : 1.00  
##  Class :character   1st Qu.: 82.0   1st Qu.: 502   1st Qu.: 9.00  
##  Mode  :character   Median :129.0   Median : 872   Median :13.00  
##                     Mean   :150.7   Mean   :1040   Mean   :13.18  
##                     3rd Qu.:192.0   3rd Qu.:1389   3rd Qu.:17.00  
##                     Max.   :695.0   Max.   :4983   Max.   :23.00  
##                     NA's   :9430                                  
##      minute        time_hour                     
##  Min.   : 0.00   Min.   :2013-01-01 05:00:00.00  
##  1st Qu.: 8.00   1st Qu.:2013-04-04 13:00:00.00  
##  Median :29.00   Median :2013-07-03 10:00:00.00  
##  Mean   :26.23   Mean   :2013-07-03 05:22:54.64  
##  3rd Qu.:44.00   3rd Qu.:2013-10-01 07:00:00.00  
##  Max.   :59.00   Max.   :2013-12-31 23:00:00.00  
## 

3. Criterios para encontrar aerolíneas

df <- flights %>% 
  select(carrier, distance, origin, dest) %>%
  filter(distance > mean(distance, na.rm= TRUE)) %>% 
  arrange(desc(distance))
# Mostrar el nuevo DataFrame filtrado
print(df)
## # A tibble: 127,665 × 4
##    carrier distance origin dest 
##    <chr>      <dbl> <chr>  <chr>
##  1 HA          4983 JFK    HNL  
##  2 HA          4983 JFK    HNL  
##  3 HA          4983 JFK    HNL  
##  4 HA          4983 JFK    HNL  
##  5 HA          4983 JFK    HNL  
##  6 HA          4983 JFK    HNL  
##  7 HA          4983 JFK    HNL  
##  8 HA          4983 JFK    HNL  
##  9 HA          4983 JFK    HNL  
## 10 HA          4983 JFK    HNL  
## # ℹ 127,655 more rows

4. Suma y Media de las distancias recorridas por carrier

# Encuentra la suma y la media de las distancias recorridas por carrier, elimina los NA’S e interpreta que significa la suma y la media de las distancias recorridas.


dfDR <- df %>% 
  group_by(carrier, origin, dest) %>% 
  summarise(suma_distancia= sum(distance, na.rm= TRUE), 
            media_distancia= mean(distance, na.rm= TRUE)) %>% 
# Ordena en forma descendente por distancia recorrida
    arrange(desc(carrier), desc(suma_distancia))
## `summarise()` has grouped output by 'carrier', 'origin'. You can override using
## the `.groups` argument.
dfDR
## # A tibble: 150 × 5
## # Groups:   carrier, origin [26]
##    carrier origin dest  suma_distancia media_distancia
##    <chr>   <chr>  <chr>          <dbl>           <dbl>
##  1 WN      EWR    HOU          1377136            1411
##  2 WN      LGA    DEN          1158300            1620
##  3 WN      EWR    DEN          1105845            1605
##  4 WN      EWR    PHX           919323            2133
##  5 WN      LGA    HOU           606900            1428
##  6 WN      EWR    AUS           448192            1504
##  7 WN      EWR    MSY           347766            1167
##  8 VX      JFK    LAX          4447575            2475
##  9 VX      JFK    SFO          3656604            2586
## 10 VX      EWR    SFO          2008395            2565
## # ℹ 140 more rows

5.Observa tus resultados de la última tabla y agrega tus interpretaciones.

###6. Identificar aerolíneas líderes en los aeropuertos

#En esta parte se identifica si las aerolíneas líderes son las mismas en los tres aeropuertos cuyo origen es Nueva York ya sea el John F. Kennedy (JFK), el de LaGuardia (LGA) o el de Newark Liberty (EWR). Se genera un dataframe para cada aeropuerto.

df_JFK <- dfDR %>% 
  filter(origin == "JFK") %>% arrange(carrier, desc(suma_distancia))

df_JFK
## # A tibble: 69 × 5
## # Groups:   carrier, origin [8]
##    carrier origin dest  suma_distancia media_distancia
##    <chr>   <chr>  <chr>          <dbl>           <dbl>
##  1 9E      JFK    MSY           515352            1182
##  2 9E      JFK    DFW           507715            1391
##  3 9E      JFK    MCI           307188            1113
##  4 9E      JFK    SAT            84111            1587
##  5 9E      JFK    AUS             3042            1521
##  6 AA      JFK    LAX          7962075            2475
##  7 AA      JFK    SFO          3677292            2586
##  8 AA      JFK    MIA          2418669            1089
##  9 AA      JFK    SJU          1756202            1598
## 10 AA      JFK    LAS          1436472            2248
## # ℹ 59 more rows
df_LGA <- dfDR %>% 
  filter(origin == "LGA") %>% arrange(carrier, desc(suma_distancia))

df_LGA
## # A tibble: 31 × 5
## # Groups:   carrier, origin [9]
##    carrier origin dest  suma_distancia media_distancia
##    <chr>   <chr>  <chr>          <dbl>           <dbl>
##  1 9E      LGA    MCI            94095            1107
##  2 9E      LGA    SRQ            81666            1047
##  3 9E      LGA    RSW            72360            1080
##  4 9E      LGA    DFW            19446            1389
##  5 9E      LGA    MSY             1183            1183
##  6 AA      LGA    DFW          6717204            1389
##  7 AA      LGA    MIA          4323720            1096
##  8 B6      LGA    FLL          2354288            1076
##  9 B6      LGA    RSW           394200            1080
## 10 B6      LGA    SRQ           382155            1047
## # ℹ 21 more rows
df_EWR <- dfDR %>% 
  filter(origin == "EWR") %>% arrange(carrier, desc(suma_distancia))

df_EWR
## # A tibble: 50 × 5
## # Groups:   carrier, origin [9]
##    carrier origin dest  suma_distancia media_distancia
##    <chr>   <chr>  <chr>          <dbl>           <dbl>
##  1 AA      EWR    DFW          2818088            1372
##  2 AA      EWR    MIA          1158780            1085
##  3 AA      EWR    LAX           895710            2454
##  4 AS      EWR    SEA          1715028            2402
##  5 B6      EWR    FLL          1476090            1065
##  6 B6      EWR    SJU           609432            1608
##  7 B6      EWR    RSW           389820            1068
##  8 DL      EWR    SLC           697026            1969
##  9 EV      EWR    MCI          1480752            1092
## 10 EV      EWR    OMA           852768            1134
## # ℹ 40 more rows

7. Conclusión: Evidencia 1

7. Reporte ejecutivo

Evidencia 2 - Analítica descriptiva (Integración de datos a través de modelo entidad-relación) y el compromiso ético y ciudadano

Modelo Entidad-Relación

Se ha solicitado hacer un estudio sobre la situación actual de la aerolínea American Airlines ya que se necesita revisar sus destinos, horarios y aviones con los que cuenta para hacer propuestas de aumento o reducción de vuelos por destino y horarios, así como la cantidad de aviones. ## Consulta y explora el data frame planes y weather para que conozcas su contenido.

view(flights)

Información para cada vuelo/span>

#Se necesita saber de cada vuelo, la aerolínea, el aeropuerto de origen y el aeropuerto destino.Función: select()




#En la consulta anterior se necesita conocer el nombre de la aerolínea.Función: left_join()

Cantidad de vuelos por destino

#Se identifica la cantidad de vuelos por cada destino para identificar cuáles son los destinos más buscados.Función: select() y count()





#Posteriormente Agregar el nombre de la aerolínea al data frame anterior.Función: left_join()

Aerolíneas y Destinos: Mañana, Tarde, Noche y Madrugada

#Se necesita conocer las aerolíneas (clave y nombre) y destinos que vuelan por la Mañana: de 6 a 12, Tarde: de 12 a 19 , Noche: de 19 a 24 y Madrugada de 24 a 6.



#Posteriormente agregar un nuevo campo a la tabla con el nombre de clas_horario y agrega, mañana, tarde, noche y madrugada según sea el caso.Función: select(), left_join(), mutate(),ifelse con in

Cantidad de vuelos por aerolínea y destino que hay por la Mañana, Tarde, Noche y Madrugada

#Se necesita saber la cantidad de vuelos por aerolínea y destino que hay por la Mañana, Tarde, Noche y Madrugada.Función: group_by() y count()

Destinos a los que vuela American Airlines en Madrugada

#se necesita saber a qué destinos vuela la aerolínea American Airlines Inc.-AA  durante la madrugada. Función: select(),filter(),group_by()

¿Qué aviones utiliza la aerolínea AA?, y ¿Cuántos vuelos se han realizado con cada uno? elimina los NA’s

#Se presenta la aerolínea, tipo, motor, número de asientos y la cantidad de vuelos que se han realizado con cada uno de los aviones.Se elimina los NA's  Función: left_join(), select(), filter(), group_by(), count()

Interpretaciones de la evidencia 2

………….

Visualización de Datos

Dentro de las aerolíneas el retraso tanto en la hora de partida como en la hora de llegada a su destino van generando indicadores negativos.

Vuelos con retraso en ida y regreso

#Se solicita analizar para la aerolínea American Airlines si los vuelos que tienen retraso en la partida también tienen retraso en la hora de llegada.Realiza una visualización con una gráfica Scatterplot.

Tendencia de la temperatura

##Visualiza la tendencia de la temperatura durante los primeros 15 días del mes de Enero en los vuelos que parten del aeropuerto “Newark,  EWR”, utilizar una gráfica de línea.

Temperatura más frecuente

#Visualiza la temperatura más frecuente en los primeros 15 días del mes de Enero, utilizar un histrograma

Facets

#Utiliza Facets para observar cómo varía la temperatura en cada mes en él histograma del punto anterior

Vuelos que salieron de Nueva York en el 2013

#Número de vuelos que salieron de Nueva York en 2013 por aerolínea (mostrar solamente las 10 aerolíneas con más vuelos), utilizar gráfica de barras.

Grafica de pie

#Visualiza el punto anterior en una gráfica de pie.

Relación Flights and Airports

#Relaciona el data frame flights con el data frame airports a través del campo destino ¿cómo lograr estas relación?

Data frame

#Crea un nuevo data frame con el punto anterior únicamente con los 5 carriers con más vuelos por destino.

3 visualizaciones

#Realiza una visualización del punto anterior de las siguientes tres formas.

Reporte ejecutivo

#elabora un reporte ejecutivo utilizando los resultados obtenidos.

10. Conclusiónes de la evidencia 2

Compromiso ético y ciudadano

Describe el valor de la integridad.

Reflexión Personal:

¿ cómo puedes actuar con respeto y honestidad en los negocios y en el uso de datos cuando realices análisis de datos y estés en contacto con los datos de una empresa?

Alma: xxx: xxx:

Agrega al menos 3 bibliografías y cítalas en el punto anterior. http://codigoeticaeintegridad.com/

CASO: ¿Por qué se retrasan los vuelos en Nueva York?

Merge

bdgrande <-merge(flights,airlines, by="carrier")
bdgrande2 <-merge(bdgrande,planes, by="tailnum")
bdgrande3 <- left_join(bdgrande2,weather,by=c("origin","time_hour"))

¿Cómo los retrasos varían con el número de asientos?

df1 <- bdgrande2 %>% select(dep_delay, seats)
df2 <- df1 %>% filter(seats >= 2 & seats <= 100)
df3 <- df1 %>% filter(seats >100)
summarize(df2, mean(dep_delay, na.rm=TRUE))
##   mean(dep_delay, na.rm = TRUE)
## 1                      16.90538
summarize(df3, mean(dep_delay, na.rm=TRUE))
##   mean(dep_delay, na.rm = TRUE)
## 1                      11.14191
summary(df1)
##    dep_delay           seats      
##  Min.   : -43.00   Min.   :  2.0  
##  1st Qu.:  -5.00   1st Qu.: 55.0  
##  Median :  -1.00   Median :149.0  
##  Mean   :  13.18   Mean   :136.7  
##  3rd Qu.:  11.00   3rd Qu.:189.0  
##  Max.   :1301.00   Max.   :450.0  
##  NA's   :4199
summary(df2)
##    dep_delay          seats       
##  Min.   :-32.00   Min.   :  2.00  
##  1st Qu.: -6.00   1st Qu.: 20.00  
##  Median : -2.00   Median : 55.00  
##  Mean   : 16.91   Mean   : 53.71  
##  3rd Qu.: 19.00   3rd Qu.: 55.00  
##  Max.   :798.00   Max.   :100.00  
##  NA's   :3237
summary(df3)
##    dep_delay           seats      
##  Min.   : -43.00   Min.   :102.0  
##  1st Qu.:  -4.00   1st Qu.:149.0  
##  Median :  -1.00   Median :179.0  
##  Mean   :  11.14   Mean   :183.4  
##  3rd Qu.:   9.00   3rd Qu.:200.0  
##  Max.   :1301.00   Max.   :450.0  
##  NA's   :962

Relación entre todos los asientos disponibles y los retrasos, sin filtrar por tamaño del avión.

ggplot(df1, aes(x = factor(seats), y = dep_delay)) +
  geom_point(alpha = 0.5, position = position_jitter(width = 0.2)) +  # Añade un poco de 'jitter' para evitar la superposición de puntos  
  labs(title = "Retrasos por Asientos",
       x = "Número de Asientos",
       y = "Retraso (minutos)") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),  # Centrar el título
        axis.title.x = element_text(face = "bold"),  # Negrita para la etiqueta del eje X
        axis.title.y = element_text(face = "bold"),  # Negrita para la etiqueta del eje Y
        axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar etiquetas para mejor
## Warning: Removed 4199 rows containing missing values or values outside the scale range
## (`geom_point()`).

Aviones con 2 a 100 asientos (Pequeños)

ggplot(df2, aes(x = factor(seats), y = dep_delay)) +
  geom_point(alpha = 0.5, position = position_jitter(width = 0.2)) +  # Añade un poco de 'jitter' para evitar la superposición de puntos
  labs(title = "Retrasos por Número de Asientos en  Aviones Pequeños",
       x = "Número de Asientos",
       y = "Retraso al Despegue (minutos)") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),  # Centrar el título
        axis.title.x = element_text(face = "bold"),  # Negrita para la etiqueta del eje X
        axis.title.y = element_text(face = "bold"),  # Negrita para la etiqueta del eje Y
        axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar etiquetas para mejor lectura
## Warning: Removed 3237 rows containing missing values or values outside the scale range
## (`geom_point()`).

Aviones con más de 100 asientos (Grandes)

ggplot(df3, aes(x = factor(seats), y = dep_delay)) +
  geom_point(alpha = 0.5 , position = position_jitter(width = 0.2)) +
  labs(title = "Retrasos por Número de Asientos en Aviones Grandes",
       x = "Número de Asientos",
       y = "Retraso al Despegue (minutos)") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5),  # Centrar el título
        axis.title.x = element_text(face = "bold"),  # Negrita para la etiqueta del eje X
        axis.title.y = element_text(face = "bold"),  # Negrita para la etiqueta del eje Y
        axis.text.x = element_text(angle = 45, hjust = 1))  # Rotar etiquetas para mejor lectura
## Warning: Removed 962 rows containing missing values or values outside the scale range
## (`geom_point()`).

Interpretación:

Influencia de las Condiciones Climáticas en los Retrasos de Vuelos

summary(bdgrande3)
##    tailnum            carrier              year.x        month.x      
##  Length:284170      Length:284170      Min.   :2013   Min.   : 1.000  
##  Class :character   Class :character   1st Qu.:2013   1st Qu.: 4.000  
##  Mode  :character   Mode  :character   Median :2013   Median : 7.000  
##                                        Mean   :2013   Mean   : 6.569  
##                                        3rd Qu.:2013   3rd Qu.:10.000  
##                                        Max.   :2013   Max.   :12.000  
##                                                                       
##      day.x          dep_time    sched_dep_time   dep_delay          arr_time   
##  Min.   : 1.00   Min.   :   1   Min.   : 500   Min.   : -43.00   Min.   :   1  
##  1st Qu.: 8.00   1st Qu.: 905   1st Qu.: 905   1st Qu.:  -5.00   1st Qu.:1059  
##  Median :16.00   Median :1358   Median :1358   Median :  -1.00   Median :1529  
##  Mean   :15.71   Mean   :1350   Mean   :1344   Mean   :  13.18   Mean   :1495  
##  3rd Qu.:23.00   3rd Qu.:1752   3rd Qu.:1730   3rd Qu.:  11.00   3rd Qu.:1942  
##  Max.   :31.00   Max.   :2400   Max.   :2359   Max.   :1301.00   Max.   :2400  
##                  NA's   :4199                  NA's   :4199      NA's   :4551  
##  sched_arr_time   arr_delay           flight        origin         
##  Min.   :   1   Min.   : -86.00   Min.   :   1   Length:284170     
##  1st Qu.:1119   1st Qu.: -17.00   1st Qu.: 511   Class :character  
##  Median :1553   Median :  -5.00   Median :1381   Mode  :character  
##  Mean   :1531   Mean   :   7.05   Mean   :1883                     
##  3rd Qu.:1946   3rd Qu.:  14.00   3rd Qu.:3318                     
##  Max.   :2359   Max.   :1272.00   Max.   :8500                     
##                 NA's   :5153                                       
##      dest              air_time        distance        hour.x     
##  Length:284170      Min.   : 20.0   Min.   :  80   Min.   : 5.00  
##  Class :character   1st Qu.: 83.0   1st Qu.: 529   1st Qu.: 9.00  
##  Mode  :character   Median :131.0   Median : 937   Median :13.00  
##                     Mean   :153.8   Mean   :1069   Mean   :13.18  
##                     3rd Qu.:197.0   3rd Qu.:1416   3rd Qu.:17.00  
##                     Max.   :695.0   Max.   :4983   Max.   :23.00  
##                     NA's   :5153                                  
##      minute        time_hour                          name          
##  Min.   : 0.00   Min.   :2013-01-01 05:00:00.00   Length:284170     
##  1st Qu.: 7.00   1st Qu.:2013-04-05 11:00:00.00   Class :character  
##  Median :29.00   Median :2013-07-04 09:00:00.00   Mode  :character  
##  Mean   :26.07   Mean   :2013-07-03 20:30:56.16                     
##  3rd Qu.:43.00   3rd Qu.:2013-10-01 17:00:00.00                     
##  Max.   :59.00   Max.   :2013-12-31 23:00:00.00                     
##                                                                     
##      year.y         type           manufacturer          model          
##  Min.   :1956   Length:284170      Length:284170      Length:284170     
##  1st Qu.:1999   Class :character   Class :character   Class :character  
##  Median :2002   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :2001                                                           
##  3rd Qu.:2006                                                           
##  Max.   :2013                                                           
##  NA's   :5306                                                           
##     engines          seats           speed           engine         
##  Min.   :1.000   Min.   :  2.0   Min.   : 90.0    Length:284170     
##  1st Qu.:2.000   1st Qu.: 55.0   1st Qu.:105.0    Class :character  
##  Median :2.000   Median :149.0   Median :126.0    Mode  :character  
##  Mean   :1.994   Mean   :136.7   Mean   :150.8                      
##  3rd Qu.:2.000   3rd Qu.:189.0   3rd Qu.:127.0                      
##  Max.   :4.000   Max.   :450.0   Max.   :432.0                      
##                                  NA's   :283207                     
##       year         month.y           day.y           hour.y     
##  Min.   :2013   Min.   : 1.000   Min.   : 1.00   Min.   : 5.00  
##  1st Qu.:2013   1st Qu.: 4.000   1st Qu.: 8.00   1st Qu.: 9.00  
##  Median :2013   Median : 7.000   Median :16.00   Median :13.00  
##  Mean   :2013   Mean   : 6.551   Mean   :15.67   Mean   :13.18  
##  3rd Qu.:2013   3rd Qu.: 9.000   3rd Qu.:23.00   3rd Qu.:17.00  
##  Max.   :2013   Max.   :12.000   Max.   :31.00   Max.   :23.00  
##  NA's   :1340   NA's   :1340     NA's   :1340    NA's   :1340   
##       temp             dewp           humid           wind_dir    
##  Min.   : 10.94   Min.   :-9.94   Min.   : 12.74   Min.   :  0.0  
##  1st Qu.: 42.08   1st Qu.:26.06   1st Qu.: 44.00   1st Qu.:130.0  
##  Median : 57.20   Median :42.98   Median : 57.87   Median :220.0  
##  Mean   : 57.04   Mean   :41.71   Mean   : 59.66   Mean   :201.5  
##  3rd Qu.: 71.96   3rd Qu.:57.92   3rd Qu.: 75.50   3rd Qu.:290.0  
##  Max.   :100.04   Max.   :78.08   Max.   :100.00   Max.   :360.0  
##  NA's   :1356     NA's   :1356    NA's   :1356     NA's   :8481   
##    wind_speed       wind_gust          precip          pressure     
##  Min.   : 0.000   Min.   :16.11    Min.   :0.0000   Min.   : 983.8  
##  1st Qu.: 6.905   1st Qu.:20.71    1st Qu.:0.0000   1st Qu.:1012.8  
##  Median :10.357   Median :24.17    Median :0.0000   Median :1017.6  
##  Mean   :11.019   Mean   :25.14    Mean   :0.0045   Mean   :1017.9  
##  3rd Qu.:13.809   3rd Qu.:27.62    3rd Qu.:0.0000   3rd Qu.:1022.8  
##  Max.   :42.579   Max.   :66.75    Max.   :1.2100   Max.   :1042.1  
##  NA's   :1413     NA's   :216885   NA's   :1340     NA's   :32389   
##      visib       
##  Min.   : 0.000  
##  1st Qu.:10.000  
##  Median :10.000  
##  Mean   : 9.262  
##  3rd Qu.:10.000  
##  Max.   :10.000  
##  NA's   :1340
# Ajustamos el modelo de regresión lineal
modelo <- lm(dep_delay ~ temp + dewp + humid + wind_speed + precip + pressure + visib, data = bdgrande3)

# Obtenemos un resumen del modelo para ver los resultados
summary(modelo)
## 
## Call:
## lm(formula = dep_delay ~ temp + dewp + humid + wind_speed + precip + 
##     pressure + visib, data = bdgrande3)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
##  -68.86  -17.10  -11.37   -0.49 1294.21 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 411.30928   11.87766  34.629  < 2e-16 ***
## temp          0.42279    0.04571   9.250  < 2e-16 ***
## dewp         -0.33839    0.04924  -6.873 6.32e-12 ***
## humid         0.29136    0.02513  11.595  < 2e-16 ***
## wind_speed    0.29202    0.01517  19.248  < 2e-16 ***
## precip       74.63811    6.32365  11.803  < 2e-16 ***
## pressure     -0.41823    0.01118 -37.399  < 2e-16 ***
## visib        -0.42820    0.06695  -6.395 1.60e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 37.49 on 248789 degrees of freedom
##   (35373 observations deleted due to missingness)
## Multiple R-squared:  0.02236,    Adjusted R-squared:  0.02233 
## F-statistic: 812.9 on 7 and 248789 DF,  p-value: < 2.2e-16
# Para una visualización más limpia de los coeficientes, utilizamos broom
coeficientes <- tidy(modelo)

# Mostramos los coeficientes, excluyendo el intercepto si es necesario
coeficientes %>% filter(term != "(Intercept)")
## # A tibble: 7 × 5
##   term       estimate std.error statistic   p.value
##   <chr>         <dbl>     <dbl>     <dbl>     <dbl>
## 1 temp          0.423    0.0457      9.25 2.27e- 20
## 2 dewp         -0.338    0.0492     -6.87 6.32e- 12
## 3 humid         0.291    0.0251     11.6  4.44e- 31
## 4 wind_speed    0.292    0.0152     19.2  1.67e- 82
## 5 precip       74.6      6.32       11.8  3.84e- 32
## 6 pressure     -0.418    0.0112    -37.4  2.86e-305
## 7 visib        -0.428    0.0670     -6.40 1.60e- 10
# Filtrar o excluir el intercepto si no es relevante para la visualización
coeficientes <- coeficientes %>% filter(term != "(Intercept)")

# Crear la gráfica
ggplot(coeficientes, aes(x = term, y = estimate)) +
  geom_col(fill = "steelblue") +
  geom_errorbar(aes(ymin = estimate - std.error, ymax = estimate + std.error), width = 0.2) +
  labs(title = "Impacto de Variables Climáticas en Retrasos de Vuelos",
       x = "Variables Climáticas",
       y = "Coeficiente Estimado") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

La gráfica muestra los coeficientes estimados para cada variable climática a partir de un modelo de regresión lineal, el cual predice el retraso de los vuelos (dep_delay). Los coeficientes indican cómo cambia el retraso esperado de un vuelo (en minutos) con cada unidad de cambio en la variable climática. Los resultados significativos (p-valor < 0.05) son especialmente dignos de mención.

** temp (Temperatura): Tiene un coeficiente positivo pequeño (0.423), lo que sugiere que a medida que la temperatura aumenta, los retrasos en los vuelos tienden a aumentar ligeramente, pero el efecto es relativamente pequeño.

** dewp (Punto de Rocío): Presenta un coeficiente negativo (-0.338), implicando que un aumento en el punto de rocío podría asociarse levemente con una disminución en los retrasos de los vuelos.

** humid (Humedad): Con un coeficiente positivo de 0.291, sugiere que la humedad más alta podría estar ligeramente asociada con mayores retrasos.

** wind_speed (Velocidad del Viento): También tiene un efecto positivo (0.292) en los retrasos de los vuelos, lo que podría indicar que a mayor velocidad del viento, es más probable que los vuelos experimenten retrasos.

** precip (Precipitación): Muestra un gran coeficiente positivo (74.6), sugiriendo que la precipitación es un factor significativo y tiene un fuerte impacto en el aumento de los retrasos de los vuelos.

** pressure (Presión Atmosférica): Tiene un coeficiente negativo significativo (-0.418), lo que indica que un aumento en la presión atmosférica está asociado con una disminución en los retrasos de los vuelos.

** visib (Visibilidad): Con un coeficiente negativo (-0.428), sugiere que la visibilidad reducida está asociada con aumentos en los retrasos de los vuelos.

La precipitación parece tener el impacto más significativo en los retrasos de los vuelos, con un gran coeficiente positivo, lo que sugiere que los días lluviosos o con mal tiempo pueden causar retrasos sustanciales. La presión y la visibilidad también son factores significativos, pero su impacto es inverso, donde la mayor visibilidad y presión atmosférica están relacionadas con menores retrasos.

Retraso por aeropuerto

   # Calculamos el retraso promedio por aeropuerto de origen y el porcentaje de vuelos retrasados
retraso_por_aeropuerto <- bdgrande3 %>%
  group_by(origin) %>%
  summarise(
    retraso_promedio = mean(dep_delay, na.rm = TRUE),  # Calculamos el retraso promedio excluyendo NA
    vuelos = n(),  # Contamos el número total de vuelos para cada aeropuerto
    vuelos_retrasados = sum(dep_delay > 0, na.rm = TRUE),  # Contamos los vuelos retrasados
    porcentaje_retrasados = vuelos_retrasados / vuelos * 100  # Calculamos el porcentaje de vuelos retrasados
  ) %>%
  arrange(desc(retraso_promedio))  # Ordenamos por el retraso promedio descendente

# Mostramos los resultados
print(retraso_por_aeropuerto) 
## # A tibble: 3 × 5
##   origin retraso_promedio vuelos vuelos_retrasados porcentaje_retrasados
##   <chr>             <dbl>  <int>             <int>                 <dbl>
## 1 EWR                15.2 114927             50942                  44.3
## 2 JFK                12.2  94142             36278                  38.5
## 3 LGA                11.3  75101             25576                  34.1
# Crear una gráfica que muestra tanto el retraso promedio como el porcentaje de vuelos retrasados
ggplot(retraso_por_aeropuerto, aes(x = origin)) +
  geom_col(aes(y = retraso_promedio), fill = "steelblue", width = 0.4, position = position_dodge(width = 0.5)) +
  geom_col(aes(y = porcentaje_retrasados), fill = "firebrick", width = 0.4, position = position_dodge(width = 0.5), alpha = 0.5) +
  scale_y_continuous(sec.axis = sec_axis(~., name = "Porcentaje de Vuelos Retrasados")) +
  labs(title = "Retraso Promedio y Porcentaje de Vuelos Retrasados por Aeropuerto de Origen",
       x = "Aeropuerto de Origen",
       y = "Retraso Promedio (minutos)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Mostrar la gráfica
ggsave("retraso_y_porcentaje_por_aeropuerto.png", width = 10, height = 6) # Opcional: Guardar la gráfica
names(bdgrande3)
##  [1] "tailnum"        "carrier"        "year.x"         "month.x"       
##  [5] "day.x"          "dep_time"       "sched_dep_time" "dep_delay"     
##  [9] "arr_time"       "sched_arr_time" "arr_delay"      "flight"        
## [13] "origin"         "dest"           "air_time"       "distance"      
## [17] "hour.x"         "minute"         "time_hour"      "name"          
## [21] "year.y"         "type"           "manufacturer"   "model"         
## [25] "engines"        "seats"          "speed"          "engine"        
## [29] "year"           "month.y"        "day.y"          "hour.y"        
## [33] "temp"           "dewp"           "humid"          "wind_dir"      
## [37] "wind_speed"     "wind_gust"      "precip"         "pressure"      
## [41] "visib"

Retrasos promedio por mes y aeropuerto de origen

# Calculamos el retraso promedio por mes y aeropuerto de origen
retraso_promedio_mes_aeropuerto <- bdgrande3 %>%
  group_by(origin, month.x) %>%
  summarise(retraso_promedio = mean(dep_delay, na.rm = TRUE)) %>%
  arrange(origin, month.x)
## `summarise()` has grouped output by 'origin'. You can override using the
## `.groups` argument.
# Resultado
print(retraso_promedio_mes_aeropuerto)
## # A tibble: 36 × 3
## # Groups:   origin [3]
##    origin month.x retraso_promedio
##    <chr>    <int>            <dbl>
##  1 EWR          1            15.1 
##  2 EWR          2            13.3 
##  3 EWR          3            18.5 
##  4 EWR          4            17.2 
##  5 EWR          5            15.4 
##  6 EWR          6            22.6 
##  7 EWR          7            22.3 
##  8 EWR          8            13.5 
##  9 EWR          9             7.24
## 10 EWR         10             8.74
## # ℹ 26 more rows
# Creamos una gráfica para visualizar los retrasos promedio por mes y aeropuerto de origen
ggplot(retraso_promedio_mes_aeropuerto, aes(x = month.x, y = retraso_promedio, color = origin)) +
  geom_line() +  # Líneas para conectar los puntos de retraso promedio
  geom_point() +  # Puntos para destacar cada valor de retraso promedio
  scale_x_continuous(breaks = 1:12, labels = c("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic")) +
  labs(title = "Retrasos Promedio por Mes y Aeropuerto de Origen",
       x = "Mes",
       y = "Retraso Promedio (minutos)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_color_manual(values = c("steelblue", "firebrick", "forestgreen"))  # Colores personalizados para cada aeropuerto

# Mostrar la gráfica
ggsave("retraso_promedio_mes_aeropuerto.png", width = 10, height = 6) 

Relación entre la antigüedad de un avión y sus retrasos

bdgrande3 <- bdgrande3 %>%
  filter(!is.na(year.y)) %>%
  mutate(age = 2013 - year.y) %>%  # Asumiendo que los datos de vuelo son de 2013
  filter(age >= 0)  # Asegurar que la antigüedad sea lógica
age_delay_summary_bdgrande3 <- bdgrande3 %>%
  group_by(age) %>%
  summarise(
    avg_dep_delay = mean(dep_delay, na.rm = TRUE),
    n = n()
  ) %>%
  filter(n > 100)  # Filtrar grupos con suficientes datos
ggplot(age_delay_summary_bdgrande3, aes(x = age, y = avg_dep_delay)) +
  geom_line(color = "blue", na.rm = TRUE) +
  geom_point(color = "blue", na.rm = TRUE) +  # Añadir puntos para mayor claridad
  labs(title = "Retraso Promedio de Salida por Antigüedad del Avión",
       x = "Antigüedad del Avión (años)",
       y = "Retraso Promedio de Salida (minutos)") +
  theme_minimal()

Promedio de Retraso de Vuelo por Hora del Día

bdgrande3 <- bdgrande3 %>%
  mutate(
    hour_of_day = sched_dep_time %/% 100,  # Extrae la hora del tiempo de salida programado
    dep_delay = ifelse(is.na(dep_delay), 0, dep_delay)  # Trata los NA en dep_delay como 0 para este análisis
  )
retraso_promedio_por_hora <- bdgrande3 %>%
  group_by(hour_of_day) %>%
  summarise(retraso_promedio = mean(dep_delay, na.rm = TRUE)) %>%
  arrange(hour_of_day)
ggplot(retraso_promedio_por_hora, aes(x = hour_of_day, y = retraso_promedio)) +
  geom_line() +  # Línea para conectar los puntos de retraso promedio
  geom_point() +  # Puntos para resaltar cada hora
  labs(title = "Promedio de Retraso de Vuelo por Hora del Día",
       x = "Hora del Día",
       y = "Retraso Promedio (minutos)") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

Conclusión

Bibliografías

LS0tDQp0aXRsZTogIkV2aWRlbmNpYSBGaW5hbCINCmF1dGhvcjogIkFsbWEgU2FudGlhZ28gLSBBMDA4MzY2MzYsIHh4eHggLSBBMCwgeHh4eHh4eHh4IC0gQTAwIg0KZGF0ZTogIjIwMjQtMDMtMDQiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCiAgICB0aGVtZTogY29zbW8NCi0tLQ0KDQpBR1JFR0FSIElNQUdFTg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+SW50cm9kdWNjacOzbjwvc3Bhbj4gDQouLi4uLi4uLi4uLi4uLg0KDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5Db250ZXh0bzwvc3Bhbj4gDQpFbCBwYXF1ZXRlICoqbnljZmxpZ2h0czEzKiogY29udGllbmUgaW5mb3JtYWNpw7NuIHNvcmUgdG9kb3MgbG9zIHZ1ZWxlcyBxdWUgcGFydGllcm9uIGRlc2RlIE51ZXZhIFlvcmsoRVdSLCBKRkwsIExHQSkgZW4gZGVzdGlub3MgYSBsb3MgRXN0YWRvcyBVbmlkb3MgZW4gMjAxMy4gRnVlcm9uIDMzNiw3NzYgdnVlbG9zIGVuIHRvdGFsLiBQYXJhIGF5dWRhciBhIGNvbXByZW5kZXIgbGFzIGNhdXNhcyBkZSBsb3MgcmV0cmFzb3MsIHRhbWJpw6luIGluY2x1eWUgb3Ryb3Mgb2NuanVudG9zIGRlIGRhdG9zIMO6dGlsZXMuICANCg0KRXN0ZSBwYXF1ZXRlIGluY2x1eWUgbGFzIHNpZ3VpZW50ZXMgdGFibGFzOg0KDQorIGZsaWdodHMgPSB0b2RvcyBsb3MgdnVlbG9zIHF1ZSBzYWxpZXJvbiBkZSBOVWV2YSBZb3JrIGVuIGVsIDIwMTMgIA0KKyB3ZWF0aGVyID0gZGF0b3MgbWV0ZXJlb2zDs2dpY29zIHBvciBob3JhIGRlIGNhZGEgYWVyb3B1ZXJ0byAgDQorIHBsYW5lcyA9IGluZm9ybWFjacOzbiBkZSBjb25zdHJ1Y2Npw7NuIGRlIGNhZGEgYXZpw7NuICANCisgYWlycG9ydHMgPSBub21icmVzIHkgdWJsaWNhY2lvbmVzIGRlIGFlcm9wdWVydG9zICANCisgYWlybGluZXMgPSByZWxhY2nDs24gZW50cmUgbm9tYnJlcyB5IGPDs2RpZ29zIGRlIGxhcyBhZXJvbMOtbmVhcyAgDQoNCkZ1ZW50ZToNCltPcmlnZW4gZGUgbG9zIGRhdG9zXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvbnljZmxpZ2h0czEzL255Y2ZsaWdodHMxMy5wZGYpDQoNCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkluc3RhbGFyIHBhcXVldGVzIHkgbGxhbWFyIGxpYnJlcsOtYXM8L3NwYW4+DQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJueWNmbGlnaHQxMyIpDQpsaWJyYXJ5KG55Y2ZsaWdodHMxMykNCiNpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQojaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQ0KbGlicmFyeShkcGx5cikNCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCmxpYnJhcnkoZ2dwbG90MikNCiNpbnN0YWxsLnBhY2thZ2VzKCIiKQ0KbGlicmFyeShicm9vbSkNCg0KYGBgDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij5HdWFyZGFyIGJhc2UgZGUgZGF0b3M8L3NwYW4+IA0KYGBge3J9DQpmbGlnaHRzIDwtIGZsaWdodHMNCndlYXRoZXIgPC0gd2VhdGhlcg0KcGxhbmVzIDwtIHBsYW5lcw0KYWlycG9ydHMgPC0gYWlycG9ydHMNCmFpcmxpbmVzIDwtIGFpcmxpbmVzDQpgYGANCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPlJlbGFjacOzbiBlbnRyZSBsYXMgYmFzZXMgZGUgZGF0b3M8L3NwYW4+IA0KYWdyZWdhciBpbWFnZW4NCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPkRhdGEgV3JhbmdsaW5nPC9zcGFuPiANCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmx1ZTsiPjEuIEZ1bmNpb25lcyBiw6FzaWNhcyBkZSBtYW5lam8gZGUgZGF0b3M8L3NwYW4+IA0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5TZWxlY3Q8L3NwYW4+IA0KTGEgZnVuY2nDs24gKnNlbGVjdCogc2lydmUgcGFyYSBzZWxlY2Npb25hciBjb2x1bW5vcyBkZSB1biB0YWJsZSAoKmRhdGEgZnJhbWUqKS4NCmBgYHtyfQ0KZGYxIDwtIGZsaWdodHMgJT4lIHNlbGVjdChjYXJyaWVyLCBmbGlnaHQpICMgU2VsZWNjacOzbiBkZSBjb2x1bW5hcyBlc3BlY8OtZmljYXMNCmRmMiA8LSBmbGlnaHRzICU+JSBzZWxlY3QoY2FycmllcjpkaXN0YW5jZSkgIyBTZWxlY2Npw7NuIGRlIHJhbmdvIGRlIGNvbHVtbmFzDQpkZjMgPC0gZmxpZ2h0cyAlPiUgc2VsZWN0KC1jYXJyaWVyLCAtZmxpZ2h0KSAjIEVsaW1pbmFyIGNvbHVtbmFzIGVzcGVjw61maWNhcw0KZGY0IDwtIGZsaWdodHMgJT4lIHNlbGVjdCgtY2FycmllcjogLWZsaWdodCkgIyBFbGltaW5hciByYW5nbyBkZSBjb2x1bW5hcw0KZGY1IDwtIGZsaWdodHMgJT4lIHNlbGVjdChhZXJvbGluZWEgPSBjYXJyaWVyKSAjIFNlbGVjY2lvbmEgdW5hIGNvbHVtbmEgeSBsZSBjYW1iaWEgZWwgbm9tYnJlDQpkZjYgPC0gZmxpZ2h0cyAlPiUgcmVuYW1lKGFlcm9saW5lYSA9IGNhcnJpZXIpICMgQ2FtYmlhIGVsIG5vbWJyZSBkZSB1bmEgY29sdW1uYQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+RmlsdGVyPC9zcGFuPiANCkxhIGZ1bmNpw7NuICpGaWx0ZXIqIHNpcnZlIHBhcmEgc2VsZWNjaW9uYXIgcmVuZ2xvbmVzIGRlIHVuIHRhYmxhKCpkYXRhIGZyYW1lKikuDQpgYGB7cn0NCmRmNyA8LSBmbGlnaHRzICU+JSBmaWx0ZXIoZGVwX2RlbGF5ID49NTAwKSAjIEV4dHJhZSByZW5nbG9uZXMgcXVlIGN1bXBsYW4gY29uZGljacOzbg0KIyBDb25kaWNpb25hbGVzOiBJZ3VhbCA9PSwgRGVzaWd1YWwgPSE9LCBNYXlvciBxdWUgPiwgTWF5b3IgbyBpZ3VhbCBxdWUgPj0sIE1lbm9yIG8gaWd1YWwgcXVlIDw9DQojIE9wZXJhZG9yZXMgbMOzZ2ljb3M6IEFORCAmLCBPUiB8LCBOT1QgIQ0KZGY4IDwtIGZsaWdodHMgJT4lIGZpbHRlcihkZXBfZGVsYXkgPj01MDAsIGRlcF9kZWxheSA8PTYwMCkgIyBFeHRyYWUgcmVuZ2xvbmVzIHF1ZSBjdW1wbGFuIGNvbiBkb3MgY29uZGljaW9uZXMNCmRmOSA8LSBmbGlnaHRzICU+JSBzbGljZSgxMDAwOiAxMDk5KSAjIEV4dHJhZSBsb3MgbsO6bWVyb3MgZGUgbG9zIHJlbmdsb25lcyBpbmRpY2Fkb3MsIHNpbiBpbXBvcnRhciBzdXMgdmFsb3Jlcw0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+RGlzdGluY3Q8L3NwYW4+IA0KTGEgZnVuY2nDs24gKmRpc3RpbmN0KiBzaXJ2ZSBwYXJhIGVsaW1pbmFyIHJlbmdsb25lcyBkdXBsaWNhZG9zLg0KYGBge3J9DQpkZjEwIDwtIGRpc3RpbmN0KGZsaWdodHMpICMgRGVqYXIgc29sbyBsb3MgcmVuZ2xvbmVzIGRpZmVyZW50ZXMsIGJvcnJhIHRvZG9zIGxvcyByZXBldGlkb3MuDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5NZXJnZTwvc3Bhbj4gDQpMYSBmdW5jacOzbiAqbWVyZ2UqIHNpcnZlIHBhcmEganVudGFyIGJhc2VzIGRlIGRhdG9zLg0KYGBge3J9DQpiZGdyYW5kZSA8LSBtZXJnZShmbGlnaHRzLCBhaXJsaW5lcywgYnk9ImNhcnJpZXIiKQ0KYmRncmFuZGUyIDwtIG1lcmdlKGJkZ3JhbmRlLHBsYW5lcywgYnk9InRhaWxudW0iKQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+TXV0YXRlPC9zcGFuPiANCmBgYHtyfQ0KYmRncmFuZGUzIDwtIG11dGF0ZShiZGdyYW5kZTIsIGRpc3RfbXRzID0gZGlzdGFuY2UqMS42MDkpDQojQWdyZWdhIHZhcmlhYmxlcyBudWV2YXMgY2FsdWxhZGFzIGEgcGFydGlyIGRlIHZhcmlhYmxlcyBleGlzdGVudGVzIGVuIGxhIGJhc2UgZGUgZGF0b3MuDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5FamVyY2ljaW9zPC9zcGFuPiANCjEuIEVuY3VlbnRyYSB0b2RvcyBsb3MgdnVlbG9zIHF1ZSB0dXZpZXJvbiB1biBhdHJhc28gZW4gbGxlZ2FkYSBkZSAyIGhvcmFzIG8gbcOhcy4NCmBgYHtyfQ0KZWplcmNpY2lvMSA8LSBiZGdyYW5kZTIgJT4lIGZpbHRlcihhcnJfZGVsYXk+PTEyMCkNCmBgYA0KDQoyLiBFbmN1ZW50cmEgdG9kb3MgbG9zIHZ1ZWxvcyBxdWUgbGxlZ2Fyb24gYSBIb3VzdG9uIChJQU4gTyBIT1UpDQpgYGB7cn0NCmVqZXJjaWNpbzIgPC0gYmRncmFuZGUyICU+JSBmaWx0ZXIoZGVzdD09ICJJQUgiIHwgZGVzdCA9PSAiSE9VIikNCmBgYA0KDQozLiBFbmN1ZW50cmEgdG9kb3MgbG9zIHZ1ZWxvcyBvcGVyYWRvcyBwb3IgVW5pdGVkLCBBbWVyaWNhbiBvIERlbHRhLg0KYGBge3J9DQplamVyY2ljaW8zIDwtIGJkZ3JhbmRlMiAlPiUgZmlsdGVyKGNhcnJpZXIgJWluJSBjKCJVQSIsICJBQSIsICJETCIpKQ0KYGBgDQoNCjQuIEVuY3VlbnRyYSB0b2RvcyBsb3MgdnVlbG9zIHF1ZSBkZXNwZWdhcm9uIGVuIEp1bGlvLCBBZ29zdG8gbyBTZXB0aWVtYnJlDQpgYGB7cn0NCmVqZXJjaWNpbzQgPC0gYmRncmFuZGUyICU+JSBmaWx0ZXIobW9udGggJWluJSBjKDcsIDgsIDkpKQ0KZWplcmNpY2lvNGEgPC0gYmRncmFuZGUyICU+JSBmaWx0ZXIobW9udGggPT0gNyB8IG1vbnRoID09IDggfCBtb250aCA9PSA5KSANCmBgYA0KDQo1LiBFbmN1ZW50cmEgdG9kb3MgbG9zIHZ1ZWxvcyBxdWUgYXJyaXZhcm9uIG3DoXMgZGUgMiBob3JhcyB0YXJkZSwgcGVybyBubyBkZXNwZWdhcm9uIHRhcmRlLg0KYGBge3J9DQplamVyY2ljaW81IDwtIGJkZ3JhbmRlMiAlPiUgZmlsdGVyKGFycl9kZWxheT4xMjAgJiBkZXBfdGltZSA9PSBzY2hlZF9kZXBfdGltZSkNCmVqZXJjaWNpbzVhIDwtIGJkZ3JhbmRlMiAlPiUgZmlsdGVyKGFycl9kZWxheT4xMjAgJiBkZXBfZGVsYXk8PTApDQpgYGANCg0KNi4gRW5jdWVudHJhIHRvZG9zIGxvcyB2dWVsb3MgcXVlIHNlIHJldHJhc2Fyb24gYWwgbWVub3MgMSBob3JhLCBwZXJvIHF1ZSBsbGVnYXJvbiBhbnRlcyAzMCBtaW51dG9zIG8gbcOhcy4NCmBgYHtyfQ0KZWplcmNpY2lvNiA8LSBiZGdyYW5kZTIgJT4lIGZpbHRlcihkZXBfZGVsYXk+PTYwICYgYXJyX2RlbGF5PD0tMzApDQpgYGANCg0KNy4gRW5jdWVudHJhIHRvZG9zIGxvcyB2dWVsb3MgcXVlIHNhbGllcm9uIGVudHJlIGxhIG1lZGlhbm9jaGUgeSBsYXMgNiBhLm0uDQpgYGB7cn0NCmVqZXJjaWNpbzcgPC0gYmRncmFuZGUyICU+JSBmaWx0ZXIoZGVwX3RpbWUgJWluJSBjKCIyNDAwIiwgIjEwMCIsICIyMDAiLCAiMzAwIiwgIjQwMCIsICI1MDAiLCAiNjAwIikpDQplamVyY2ljaW83YSA8LSBiZGdyYW5kZTIgJT4lIGZpbHRlcihkZXBfdGltZT09MjQwMCB8IGRlcF90aW1lPD02MDApIA0KZWplcmNpY2lvN2IgPC0gYmRncmFuZGUyICU+JSBmaWx0ZXIoaG91ciAlaW4lIGMoIjAiLCAiMSIsICIyIiwgIjMiLCAiNCIsICI1IiwgIjYiKSkNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPkFycmFuZ2U8L3NwYW4+IA0KU2ltaWxhciBhIGZpbHRlciAoKSBwZXJvIGVuIGx1Z2FyIGRlIHNlbGVjY2lvbmFyIHJlbmdsb25lcywgbG9zIG9yZGVuYSBkZSBtZW5vciBhIG1heW9yLg0KYGBge3J9DQpkZjExIDwtIGFycmFuZ2UoYmRncmFuZGUyLCB5ZWFyLngsIG1vbnRoLCBkYXkpDQpgYGANCg0KUGFyYSBhY29tb2RhciBkZSBtYXlvciBhIG1lbm9yLg0KYGBge3J9DQpkZjEyIDwtIGFycmFuZ2UoYmRncmFuZGUyLCB5ZWFyLngsIGRlc2MobW9udGgpLCBkYXkpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5TdW1tYXJpemU8L3NwYW4+IA0KQ29sYXBzYSB1bmEgdGFibGEgYSB1biBzw7NsbyByZW5nbMOzbg0KYGBge3J9DQojIE9idMOpbiBlbCByZXRyYXNvIHByb21lZGlvIGRlIHNhbGlkYSBkZSBkZXNwZWd1ZSBkZSB0b2RvcyBsb3MgdnVlbG9zDQpzdW1tYXJpemUoYmRncmFuZGUyLCBtZWFuKGRlcF9kZWxheSwgbmEucm09VFJVRSkpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5Hcm91cCBieTwvc3Bhbj4gDQpBZ3J1cGEgdGFibGEgYmFzYWRvIGVuIGFsZ3VuYXMgY29sdW1uYXMuDQpgYGB7cn0NCiMgT2J0ZW5lciBlbCByZXRyYXNvIHByb21lZGlvIGRlIGRlc3BlZ3VlIHBvciBkw61hDQpwb3JfZGlhIDwtIGdyb3VwX2J5KGJkZ3JhbmRlMiwgeWVhci54LCBtb250aCwgZGF5KQ0Kc3VtbWFyaXplKHBvcl9kaWEsIG1lYW4oZGVwX2RlbGF5LCBuYS5ybT1UUlVFKSkNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyI+RXZpZGVuY2lhIDEgTmV3IFlvcmsgKEhlY2hhIGVuIGNsYXNlKTwvc3Bhbj4NCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+MS4gQ2FyZ2FyIGVuIG1lbW9yaWEgbGEgdGFibGEgImZsaWdodHMiIHkgbW9zdHJhciBzdSBjb250ZW5pZG88L3NwYW4+DQpgYGB7cn0NCiMgTGEgY2FyZ2EgYSBhIG1lbW9yaWEgc2UgaGl6byBlbiBlbCBwYXNvIGFudGVyaW9yDQpmbGlnaHRzDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij4yLiBDb25zdWx0YSBsYSBlc3RydWN0dXJhIGRlICJmbGlnaHRzIiA8L3NwYW4+DQpgYGB7cn0NCnN0cihmbGlnaHRzKQ0KIyBpbnQ6ZW50ZXJvIChzaW4gZGVjaW1hbGVzKQ0KIyBudW06bnVtw6lyaWNvIChjb24gZGVjaW1hbGVzKQ0KIyBjaHI6IGNhcmFjdMOpciAobGV0cmFzKQ0KIyBkYXRlOiBmZWNoYSAoZW4gUiB2YSBhw7FvLW1lcy1kaWEpDQojIFBPU0lYY3Q6Zm9ybWF0byBmZWNoYSB5IGhvcmENCg0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+My4gwr9DdcOhbCBlcyBsYSBjbGFzZSAiZmxpZ2h0cyIgeSBxdcOpIHNpZ25pZmljYT88L3NwYW4+DQpgYGB7cn0NCmNsYXNzKGZsaWdodHMpDQoNCiMgTGFzIDUgY2xhc2VzIGRlIG9iamV0b3MNCiMgMS4gbnVtZXJpYzogTsO6bWVybyByZWFsIG8gZMOpY2ltYWwNCiMgMi4gaW50ZWdlcjogTsO6bWVyb3MgZW50ZXJvcw0KIyAzLiBDb21wbGV4OiBOw7ptZXJvcyBjb21wbGVqb3MNCiMgNC4gQ2hhcmFjdGVyOiBDYXJhY3TDqXJlcyANCiMgNS4gTG9naWNhbDogVFJVRSBvIEZBTFNFDQoNCiMgTGFzIDQgY2xhc2VzIGRlIG9iamV0b3MgY29tcHVlc3RvcyBzb246DQojIDEuIGxpc3Q6IGxpc3RhDQojIDIuIE1hdHJpeDogTWF0cml6DQojIDMuIEFycmF5OiBjb2xlY2Npw7NuIGRlIG9iamV0b3MNCiMgNC4gZGF0YS5mcmFtZTogYmFzZSBkZSBkYXRvcw0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+NC4gwr9DdcOhbnRhcyBjb2x1bW5hcyB5IHJlbmdsb25lcyB0aWVuZSAiZmxpZ2h0cyI/PC9zcGFuPg0KYGBge3J9DQojIE7Dum1lcm8gZGUgY29sdW1uYXMNCm5jb2woZmxpZ2h0cykNCiMgTnVtZXJvIGRlIHJlbmdsb25lcw0KbnJvdyhmbGlnaHRzKQ0KIyBEaW1lbnNpw7NuDQpkaW0oZmxpZ2h0cykNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPjUuIE11ZXN0cmEgbG9zIHByaW1lcm9zIDYgcmVuZ2xvbmVzIGRlICJmbGlnaHRzIi4gVGFtYmllbiBsb3MgdWx0aW1vcyA2IDwvc3Bhbj4NCmBgYHtyfQ0KaGVhZChmbGlnaHRzKQ0KdGFpbChmbGlnaHRzKQ0KIyBTaSBxdWlzaWVyYW1vcyA3IHJlbmdsb25lczogaGVhZChmbGlnaHRzLDcpDQoNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPjYuIE11ZXN0cmEgbG9zIGVzdGFkaXN0aWNvcyBkZXNjcmlwdGl2b3MgZGUgImZsaWdodHMiPC9zcGFuPg0KYGBge3J9DQpzdW1tYXJ5KGZsaWdodHMpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5Db25jbHVzacOzbjwvc3Bhbj4NCkVuIGVzdGUgdHJhYmFqbyBwdWRpbW9zIHV0bGl6YXIgbGFzIGZ1bmNpb25lcyBtw6FzIGNvbXVuZXMgZGVsIGFuw6FsaXNpcyBleHBsb3JhdG9yaW8sIGVsIGN1YWwgZXMgZWwgcHJpbWVyIHBhc28gcGFyYSBjdWFscXVpZXIgdHJhYmFqbyBkZSBtYW5pcHVsYWNpw7NuIGRlIGRhdG9zLg0KDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOnJlZDsiPkV2aWRlbmNpYSAxIEFuYWzDrXRpY2EgZGVzY3JpcHRpdmE8L3NwYW4+IA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsdWU7Ij5FeHBsb3JhY2nDs248L3NwYW4+IA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+ZmxpZ2h0czwvc3Bhbj4gDQoNCmBgYHtyfQ0KIyBDb25zdWx0YSBsYSBlc3RydWN0dXJhIGRlIGNhZGEgZGF0YSBmcmFtZQ0KIyBQYXJhIGVsIGRhdGEgZnJhbWUgZmxpZ2h0cw0KZGF0YShmbGlnaHRzKSANCnN0cihmbGlnaHRzKQ0KbmNvbChmbGlnaHRzKQ0KbnJvdyhmbGlnaHRzKQ0KZGltKGZsaWdodHMpDQpoZWFkKGZsaWdodHMpDQp0YWlsKGZsaWdodHMpDQpzdW1tYXJ5KGZsaWdodHMpDQpgYGANCg0Kwr9DdcOhbGVzIHNvbiBsb3MgY2FtcG9zIHkgc3VzIHRpcG9zIGRlIGRhdG9zPyANCkxvcyBjYW1wb3MgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGZsaWdodHMgeSBzdXMgdGlwb3MgZGUgZGF0b3Mgc29uOg0KDQorIHllYXI6IGludCAoZW50ZXJvKSAtIEHDsW8gZGVsIHZ1ZWxvLg0KKyBtb250aDogaW50IChlbnRlcm8pIC0gTWVzIGRlbCB2dWVsby4NCisgZGF5OiBpbnQgKGVudGVybykgLSBEw61hIGRlbCB2dWVsby4NCisgZGVwX3RpbWU6IGludCAoZW50ZXJvKSAtIEhvcmEgZGUgc2FsaWRhIHJlYWwgZGVsIHZ1ZWxvLg0KKyBzY2hlZF9kZXBfdGltZTogaW50IChlbnRlcm8pIC0gSG9yYSBkZSBzYWxpZGEgcHJvZ3JhbWFkYSBkZWwgdnVlbG8uDQorIGRlcF9kZWxheTogbnVtIChuw7ptZXJvKSAtIFJldHJhc28gZGUgc2FsaWRhIGVuIG1pbnV0b3MuDQorIGFycl90aW1lOiBpbnQgKGVudGVybykgLSBIb3JhIGRlIGxsZWdhZGEgcmVhbC4NCisgc2NoZWRfYXJyX3RpbWU6IGludCAoZW50ZXJvKSAtIEhvcmEgZGUgbGxlZ2FkYSBwcm9ncmFtYWRhLg0KKyBhcnJfZGVsYXk6IG51bSAobsO6bWVybykgLSBSZXRyYXNvIGRlIGxsZWdhZGEgZW4gbWludXRvcy4NCisgY2FycmllcjogY2hyIChjYXLDoWN0ZXIpIC0gQ8OzZGlnbyBkZSBsYSBhZXJvbMOtbmVhLg0KKyBmbGlnaHQ6IGludCAoZW50ZXJvKSAtIE7Dum1lcm8gZGVsIHZ1ZWxvLg0KKyB0YWlsbnVtOiBjaHIgKGNhcsOhY3RlcikgLSBOw7ptZXJvIGRlIGNvbGEgZGVsIGF2acOzbi4NCisgb3JpZ2luOiBjaHIgKGNhcsOhY3RlcikgLSBBZXJvcHVlcnRvIGRlIG9yaWdlbi4NCisgZGVzdDogY2hyIChjYXLDoWN0ZXIpIC0gQWVyb3B1ZXJ0byBkZSBkZXN0aW5vLg0KKyBhaXJfdGltZTogbnVtIChuw7ptZXJvKSAtIFRpZW1wbyBlbiBlbCBhaXJlIGVuIG1pbnV0b3MuDQorIGRpc3RhbmNlOiBudW0gKG7Dum1lcm8pIC0gRGlzdGFuY2lhIGRlbCB2dWVsbyBlbiBtaWxsYXMuDQorIGhvdXI6IG51bSAobsO6bWVybykgLSBIb3JhIHByb2dyYW1hZGEgZGUgc2FsaWRhIChob3JhKS4NCisgbWludXRlOiBudW0gKG7Dum1lcm8pIC0gSG9yYSBwcm9ncmFtYWRhIGRlIHNhbGlkYSAobWludXRvcykuDQorIHRpbWVfaG91cjogUE9TSVhjdCAoZHR0bSkgLSBGZWNoYSB5IGhvcmEgZGVsIHZ1ZWxvLg0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPndlYXRoZXI8L3NwYW4+IA0KYGBge3J9DQojIFBhcmEgZWwgZGF0YSBmcmFtZSB3ZWF0aGVyDQpkYXRhKHdlYXRoZXIpIA0Kc3RyKHdlYXRoZXIpDQpuY29sKHdlYXRoZXIpDQpucm93KHdlYXRoZXIpDQpkaW0od2VhdGhlcikNCmhlYWQod2VhdGhlcikNCnRhaWwod2VhdGhlcikNCnN1bW1hcnkod2VhdGhlcikNCmBgYA0KDQrCv0N1w6FsZXMgc29uIGxvcyBjYW1wb3MgeSBzdXMgdGlwb3MgZGUgZGF0b3M/IA0KTG9zIGNhbXBvcyBkZWwgY29uanVudG8gZGUgZGF0b3Mgd2VhdGhlciB5IHN1cyB0aXBvcyBkZSBkYXRvcyBzb246DQoNCisgb3JpZ2luOiBjaHIgKGNhcsOhY3RlcikgLSBDw7NkaWdvIGRlbCBhZXJvcHVlcnRvIGRlIG9yaWdlbi4NCisgeWVhcjogaW50IChlbnRlcm8pIC0gQcOxbyBkZSBsYSBvYnNlcnZhY2nDs24gbWV0ZW9yb2zDs2dpY2EuDQorIG1vbnRoOiBpbnQgKGVudGVybykgLSBNZXMgZGUgbGEgb2JzZXJ2YWNpw7NuIG1ldGVvcm9sw7NnaWNhLg0KKyBkYXk6IGludCAoZW50ZXJvKSAtIETDrWEgZGUgbGEgb2JzZXJ2YWNpw7NuIG1ldGVvcm9sw7NnaWNhLg0KKyBob3VyOiBpbnQgKGVudGVybykgLSBIb3JhIGRlIGxhIG9ic2VydmFjacOzbiBtZXRlb3JvbMOzZ2ljYS4NCisgdGVtcDogbnVtIChuw7ptZXJvKSAtIFRlbXBlcmF0dXJhIGVuIGdyYWRvcyBGYWhyZW5oZWl0Lg0KKyBkZXdwOiBudW0gKG7Dum1lcm8pIC0gUHVudG8gZGUgcm9jw61vIGVuIGdyYWRvcyBGYWhyZW5oZWl0Lg0KKyBodW1pZDogbnVtIChuw7ptZXJvKSAtIEh1bWVkYWQgcmVsYXRpdmEgZW4gcG9yY2VudGFqZS4NCisgd2luZF9kaXI6IG51bSAobsO6bWVybykgLSBEaXJlY2Npw7NuIGRlbCB2aWVudG8gZW4gZ3JhZG9zLg0KKyB3aW5kX3NwZWVkOiBudW0gKG7Dum1lcm8pIC0gVmVsb2NpZGFkIGRlbCB2aWVudG8gZW4gbWlsbGFzIHBvciBob3JhLg0KKyB3aW5kX2d1c3Q6IG51bSAobsO6bWVybykgLSBSw6FmYWdhIGRlIHZpZW50byBlbiBtaWxsYXMgcG9yIGhvcmEuDQorIHByZWNpcDogbnVtIChuw7ptZXJvKSAtIFByZWNpcGl0YWNpw7NuIGVuIHB1bGdhZGFzLg0KKyBwcmVzc3VyZTogbnVtIChuw7ptZXJvKSAtIFByZXNpw7NuIGF0bW9zZsOpcmljYSBlbiBtaWxpYmFyZXMuDQorIHZpc2liOiBudW0gKG7Dum1lcm8pIC0gVmlzaWJpbGlkYWQgZW4gbWlsbGFzLg0KKyB0aW1lX2hvdXI6IFBPU0lYY3QgKGR0dG0pIC0gRmVjaGEgeSBob3JhIGRlIGxhIG9ic2VydmFjacOzbiBtZXRlb3JvbMOzZ2ljYS4NCg0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPnBsYW5lczwvc3Bhbj4gDQpgYGB7cn0NCiMgUGFyYSBlbCBkYXRhIGZyYW1lIHBsYW5lcw0KZGF0YShwbGFuZXMpIA0Kc3RyKHBsYW5lcykNCm5jb2wocGxhbmVzKQ0KbnJvdyhwbGFuZXMpDQpkaW0ocGxhbmVzKQ0KaGVhZChwbGFuZXMpDQp0YWlsKHBsYW5lcykNCnN1bW1hcnkocGxhbmVzKQ0KYGBgDQoNCsK/Q3XDoWxlcyBzb24gbG9zIGNhbXBvcyB5IHN1cyB0aXBvcyBkZSBkYXRvcz8gDQpMb3MgY2FtcG9zIGRlbCBjb25qdW50byBkZSBkYXRvcyBwbGFuZXMgeSBzdXMgdGlwb3MgZGUgZGF0b3Mgc29uOg0KDQorIHRhaWxudW06IGNociAoY2Fyw6FjdGVyKSAtIE7Dum1lcm8gZGUgY29sYSBkZWwgYXZpw7NuLg0KKyB5ZWFyOiBpbnQgKGVudGVybykgLSBBw7FvIGRlIGZhYnJpY2FjacOzbiBkZWwgYXZpw7NuLg0KKyB0eXBlOiBjaHIgKGNhcsOhY3RlcikgLSBUaXBvIGRlIGF2acOzbiwgZW4gZXN0ZSBjYXNvIHRvZG9zIHNvbiBkZSBhbGEgZmlqYSBjb24gbcO6bHRpcGxlcyBtb3RvcmVzLg0KKyBtYW51ZmFjdHVyZXI6IGNociAoY2Fyw6FjdGVyKSAtIEZhYnJpY2FudGUgZGVsIGF2acOzbi4NCisgbW9kZWw6IGNociAoY2Fyw6FjdGVyKSAtIE1vZGVsbyBkZWwgYXZpw7NuLg0KKyBlbmdpbmVzOiBpbnQgKGVudGVybykgLSBOw7ptZXJvIGRlIG1vdG9yZXMgZGVsIGF2acOzbi4NCisgc2VhdHM6IGludCAoZW50ZXJvKSAtIE7Dum1lcm8gZGUgYXNpZW50b3MgZGVsIGF2acOzbi4NCisgc3BlZWQ6IGludCAoZW50ZXJvKSAtIFZlbG9jaWRhZCBkZWwgYXZpw7NuLCBhdW5xdWUgbGEgbWF5b3LDrWEgZGUgbG9zIHJlZ2lzdHJvcyBwYXJlY2VuIG5vIHRlbmVyIGVzdGEgaW5mb3JtYWNpw7NuIChOQSkuDQorIGVuZ2luZTogY2hyIChjYXLDoWN0ZXIpIC0gVGlwbyBkZSBtb3RvciBkZWwgYXZpw7NuLCBsYSBtYXlvcsOtYSBzb24gdHVyYm9mw6FuLg0KDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+YWlycG9ydHM8L3NwYW4+IA0KYGBge3J9DQojIFBhcmEgZWwgZGF0YSBmcmFtZSBhaXJwb3J0cw0KZGF0YShhaXJwb3J0cykgDQpzdHIoYWlycG9ydHMpDQpuY29sKGFpcnBvcnRzKQ0KbnJvdyhhaXJwb3J0cykNCmRpbShhaXJwb3J0cykNCmhlYWQoYWlycG9ydHMpDQp0YWlsKGFpcnBvcnRzKQ0Kc3VtbWFyeShhaXJwb3J0cykNCmBgYA0KDQrCv0N1w6FsZXMgc29uIGxvcyBjYW1wb3MgeSBzdXMgdGlwb3MgZGUgZGF0b3M/IA0KTG9zIGNhbXBvcyBkZWwgY29uanVudG8gZGUgZGF0b3MgYWlycG9ydHMgeSBzdXMgdGlwb3MgZGUgZGF0b3Mgc29uOg0KDQorIG9yaWdpbjogY2hyIChjYXLDoWN0ZXIpIC0gQ8OzZGlnbyBkZWwgYWVyb3B1ZXJ0by4NCisgbmFtZTogY2hyIChjYXLDoWN0ZXIpIC0gTm9tYnJlIGRlbCBhZXJvcHVlcnRvLg0KKyBsYXQ6IG51bSAobsO6bWVybykgLSBMYXRpdHVkIGRlbCBhZXJvcHVlcnRvLg0KKyBsb246IG51bSAobsO6bWVybykgLSBMb25naXR1ZCBkZWwgYWVyb3B1ZXJ0by4NCisgYWx0OiBudW0gKG7Dum1lcm8pIC0gQWx0aXR1ZCBkZWwgYWVyb3B1ZXJ0byBlbiBwaWVzLg0KKyB0ejogbnVtIChuw7ptZXJvKSAtIFpvbmEgaG9yYXJpYSBkZWwgYWVyb3B1ZXJ0bywgYmFzYWRhIGVuIGVsIGRlc3BsYXphbWllbnRvIGRlbCBVVEMuDQorIGRzdDogY2hyIChjYXLDoWN0ZXIpIC0gSW5kaWNhZG9yIGRlIGhvcmFyaW8gZGUgdmVyYW5vIChwLiBlai4sICJBIiBwYXJhIGhvcmFyaW8gZGUgdmVyYW5vLCAiTiIgcGFyYSBubyBvYnNlcnZhcmxvKS4NCisgdHpvbmU6IGNociAoY2Fyw6FjdGVyKSAtIFpvbmEgaG9yYXJpYSBkZWwgYWVyb3B1ZXJ0byBlbiB0ZXh0bywgcG9yIGVqZW1wbG8sICJBbWVyaWNhL05ld19Zb3JrIi4NCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5haXJsaW5lczwvc3Bhbj4gDQpgYGB7cn0NCiMgUGFyYSBlbCBkYXRhIGZyYW1lIGFpcmxpbmVzDQpkYXRhKGFpcmxpbmVzKSANCnN0cihhaXJsaW5lcykNCm5jb2woYWlybGluZXMpDQpucm93KGFpcmxpbmVzKQ0KZGltKGFpcmxpbmVzKQ0KaGVhZChhaXJsaW5lcykNCnRhaWwoYWlybGluZXMpDQpzdW1tYXJ5KGFpcmxpbmVzKQ0KYGBgDQoNCsK/Q3XDoWxlcyBzb24gbG9zIGNhbXBvcyB5IHN1cyB0aXBvcyBkZSBkYXRvcz8gDQoNCkxvcyBjYW1wb3MgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGFpcmxpbmVzIHkgc3VzIHRpcG9zIGRlIGRhdG9zIHNvbjoNCg0KKyBjYXJyaWVyOiBjaHIgKGNhcsOhY3RlcikgLSBDw7NkaWdvIGRlIGRvcyBsZXRyYXMgZGUgbGEgYWVyb2zDrW5lYS4NCisgbmFtZTogY2hyIChjYXLDoWN0ZXIpIC0gTm9tYnJlIGNvbXBsZXRvIGRlIGxhIGFlcm9sw61uZWEuDQoNCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibHVlOyI+TWFuaXB1bGFjacOzbiBkZSBkYXRvczwvc3Bhbj4gDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+MSBDb25zdWx0YXIgZGF0YWZyYW1lPC9zcGFuPg0KDQpgYGB7cn0NCiNBbCBjb25zdWx0YXIgbCBEYXRhRnJhbWUgbm9zIHBlcm1pdGUgdmlzdWFsaXphciBsYSBiYXNlIGRlIGRhdG9zICpmbGlnaHRzKi4NCnZpZXcoZmxpZ2h0cykNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPjIgRW5jdWVudHJhIGxvcyBkYXRvcyBkZXNjcmlwdGl2b3MgZGVsIGRhdGEgZnJhbWUgZmxpZ2h0cy4gSWRlbnRpZmljYSBsYSBtZWRpYSBkZSBsYXMgZGlzdGFuY2lhcyByZWNvcnJpZGFzIGVuIG1pbGxhcy48L3NwYW4+DQpgYGB7cn0NCiNsYSBtZWRpYSAoTWVhbikgZGUgbGEgZGlzdGFuY2lhIGVzIGRlIDEwNDAgbWlsbGFzLCBsbyBxdWUgaW5kaWNhIHF1ZSwgZW4gcHJvbWVkaW8sIGxvcyB2dWVsb3MgZW4gZXN0ZSBjb25qdW50byBkZSBkYXRvcyByZWNvcnJlbiB1bmEgZGlzdGFuY2lhIGRlIDEwNDAgbWlsbGFzLg0Kc3VtbWFyeShmbGlnaHRzKQ0KDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij4zLiBDcml0ZXJpb3MgcGFyYSBlbmNvbnRyYXIgYWVyb2zDrW5lYXM8L3NwYW4+IA0KDQpgYGB7cn0NCmRmIDwtIGZsaWdodHMgJT4lIA0KICBzZWxlY3QoY2FycmllciwgZGlzdGFuY2UsIG9yaWdpbiwgZGVzdCkgJT4lDQogIGZpbHRlcihkaXN0YW5jZSA+IG1lYW4oZGlzdGFuY2UsIG5hLnJtPSBUUlVFKSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoZGlzdGFuY2UpKQ0KIyBNb3N0cmFyIGVsIG51ZXZvIERhdGFGcmFtZSBmaWx0cmFkbw0KcHJpbnQoZGYpDQpgYGANCg0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPjQuIFN1bWEgeSBNZWRpYSBkZSBsYXMgZGlzdGFuY2lhcyByZWNvcnJpZGFzIHBvciBjYXJyaWVyPC9zcGFuPiANCmBgYHtyfQ0KIyBFbmN1ZW50cmEgbGEgc3VtYSB5IGxhIG1lZGlhIGRlIGxhcyBkaXN0YW5jaWFzIHJlY29ycmlkYXMgcG9yIGNhcnJpZXIsIGVsaW1pbmEgbG9zIE5B4oCZUyBlIGludGVycHJldGEgcXVlIHNpZ25pZmljYSBsYSBzdW1hIHkgbGEgbWVkaWEgZGUgbGFzIGRpc3RhbmNpYXMgcmVjb3JyaWRhcy4NCg0KDQpkZkRSIDwtIGRmICU+JSANCiAgZ3JvdXBfYnkoY2Fycmllciwgb3JpZ2luLCBkZXN0KSAlPiUgDQogIHN1bW1hcmlzZShzdW1hX2Rpc3RhbmNpYT0gc3VtKGRpc3RhbmNlLCBuYS5ybT0gVFJVRSksIA0KICAgICAgICAgICAgbWVkaWFfZGlzdGFuY2lhPSBtZWFuKGRpc3RhbmNlLCBuYS5ybT0gVFJVRSkpICU+JSANCiMgT3JkZW5hIGVuIGZvcm1hIGRlc2NlbmRlbnRlIHBvciBkaXN0YW5jaWEgcmVjb3JyaWRhDQogICAgYXJyYW5nZShkZXNjKGNhcnJpZXIpLCBkZXNjKHN1bWFfZGlzdGFuY2lhKSkNCmRmRFINCg0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+NS5PYnNlcnZhIHR1cyByZXN1bHRhZG9zIGRlIGxhIMO6bHRpbWEgdGFibGEgeSBhZ3JlZ2EgdHVzIGludGVycHJldGFjaW9uZXMuPC9zcGFuPg0KDQoNCiMjIzxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij42LiBJZGVudGlmaWNhciBhZXJvbMOtbmVhcyBsw61kZXJlcyBlbiBsb3MgYWVyb3B1ZXJ0b3M8L3NwYW4+DQpgYGB7cn0NCiNFbiBlc3RhIHBhcnRlIHNlIGlkZW50aWZpY2Egc2kgbGFzIGFlcm9sw61uZWFzIGzDrWRlcmVzIHNvbiBsYXMgbWlzbWFzIGVuIGxvcyB0cmVzIGFlcm9wdWVydG9zIGN1eW8gb3JpZ2VuIGVzIE51ZXZhIFlvcmsgeWEgc2VhIGVsIEpvaG4gRi4gS2VubmVkeSAoSkZLKSwgZWwgZGUgTGFHdWFyZGlhIChMR0EpIG8gZWwgZGUgTmV3YXJrIExpYmVydHkgKEVXUikuIFNlIGdlbmVyYSB1biBkYXRhZnJhbWUgcGFyYSBjYWRhIGFlcm9wdWVydG8uDQoNCmRmX0pGSyA8LSBkZkRSICU+JSANCiAgZmlsdGVyKG9yaWdpbiA9PSAiSkZLIikgJT4lIGFycmFuZ2UoY2FycmllciwgZGVzYyhzdW1hX2Rpc3RhbmNpYSkpDQoNCmRmX0pGSw0KDQpkZl9MR0EgPC0gZGZEUiAlPiUgDQogIGZpbHRlcihvcmlnaW4gPT0gIkxHQSIpICU+JSBhcnJhbmdlKGNhcnJpZXIsIGRlc2Moc3VtYV9kaXN0YW5jaWEpKQ0KDQpkZl9MR0ENCg0KZGZfRVdSIDwtIGRmRFIgJT4lIA0KICBmaWx0ZXIob3JpZ2luID09ICJFV1IiKSAlPiUgYXJyYW5nZShjYXJyaWVyLCBkZXNjKHN1bWFfZGlzdGFuY2lhKSkNCg0KZGZfRVdSDQoNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPjcuIENvbmNsdXNpw7NuOiBFdmlkZW5jaWEgMTwvc3Bhbj4NCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij43LiBSZXBvcnRlIGVqZWN1dGl2bzwvc3Bhbj4NCg0KDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij4gRXZpZGVuY2lhIDIgLSBBbmFsw610aWNhIGRlc2NyaXB0aXZhIChJbnRlZ3JhY2nDs24gZGUgZGF0b3MgYSB0cmF2w6lzIGRlIG1vZGVsbyBlbnRpZGFkLXJlbGFjacOzbikgIHkgZWwgY29tcHJvbWlzbyDDqXRpY28geSBjaXVkYWRhbm88L3NwYW4+DQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmx1ZTsiPk1vZGVsbyBFbnRpZGFkLVJlbGFjacOzbjwvc3Bhbj4NCg0KU2UgaGEgc29saWNpdGFkbyBoYWNlciB1biBlc3R1ZGlvIHNvYnJlIGxhIHNpdHVhY2nDs24gYWN0dWFsIGRlIGxhIGFlcm9sw61uZWEgQW1lcmljYW4gQWlybGluZXMgeWEgcXVlIHNlIG5lY2VzaXRhIHJldmlzYXIgc3VzIGRlc3Rpbm9zLCBob3JhcmlvcyB5IGF2aW9uZXMgY29uIGxvcyBxdWUgY3VlbnRhIHBhcmEgaGFjZXIgcHJvcHVlc3RhcyBkZSBhdW1lbnRvIG8gcmVkdWNjacOzbiBkZSB2dWVsb3MgcG9yIGRlc3Rpbm8geSBob3JhcmlvcywgYXPDrSBjb21vIGxhIGNhbnRpZGFkIGRlIGF2aW9uZXMuDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+Q29uc3VsdGEgeSBleHBsb3JhIGVsIGRhdGEgZnJhbWUgcGxhbmVzIHkgd2VhdGhlciBwYXJhIHF1ZSBjb25vemNhcyBzdSBjb250ZW5pZG8uPC9zcGFuPg0KDQpgYGB7cn0NCnZpZXcoZmxpZ2h0cykNCmBgYA0KDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5JbmZvcm1hY2nDs24gcGFyYSBjYWRhIHZ1ZWxvL3NwYW4+DQoNCmBgYHtyfQ0KI1NlIG5lY2VzaXRhIHNhYmVyIGRlIGNhZGEgdnVlbG8sIGxhIGFlcm9sw61uZWEsIGVsIGFlcm9wdWVydG8gZGUgb3JpZ2VuIHkgZWwgYWVyb3B1ZXJ0byBkZXN0aW5vLkZ1bmNpw7NuOiBzZWxlY3QoKQ0KDQoNCg0KDQojRW4gbGEgY29uc3VsdGEgYW50ZXJpb3Igc2UgbmVjZXNpdGEgY29ub2NlciBlbCBub21icmUgZGUgbGEgYWVyb2zDrW5lYS5GdW5jacOzbjogbGVmdF9qb2luKCkNCg0KDQpgYGANCg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+Q2FudGlkYWQgZGUgdnVlbG9zIHBvciBkZXN0aW5vPC9zcGFuPg0KYGBge3J9IA0KI1NlIGlkZW50aWZpY2EgbGEgY2FudGlkYWQgZGUgdnVlbG9zIHBvciBjYWRhIGRlc3Rpbm8gcGFyYSBpZGVudGlmaWNhciBjdcOhbGVzIHNvbiBsb3MgZGVzdGlub3MgbcOhcyBidXNjYWRvcy5GdW5jacOzbjogc2VsZWN0KCkgeSBjb3VudCgpDQoNCg0KDQoNCg0KI1Bvc3Rlcmlvcm1lbnRlIEFncmVnYXIgZWwgbm9tYnJlIGRlIGxhIGFlcm9sw61uZWEgYWwgZGF0YSBmcmFtZSBhbnRlcmlvci5GdW5jacOzbjogbGVmdF9qb2luKCkNCg0KDQpgYGANCg0KDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5BZXJvbMOtbmVhcyB5IERlc3Rpbm9zOiBNYcOxYW5hLCBUYXJkZSwgTm9jaGUgeSBNYWRydWdhZGE8L3NwYW4+DQpgYGB7cn0NCiNTZSBuZWNlc2l0YSBjb25vY2VyIGxhcyBhZXJvbMOtbmVhcyAoY2xhdmUgeSBub21icmUpIHkgZGVzdGlub3MgcXVlIHZ1ZWxhbiBwb3IgbGEgTWHDsWFuYTogZGUgNiBhIDEyLCBUYXJkZTogZGUgMTIgYSAxOSAsIE5vY2hlOiBkZSAxOSBhIDI0IHkgTWFkcnVnYWRhIGRlIDI0IGEgNi4NCg0KDQoNCiNQb3N0ZXJpb3JtZW50ZSBhZ3JlZ2FyIHVuIG51ZXZvIGNhbXBvIGEgbGEgdGFibGEgY29uIGVsIG5vbWJyZSBkZSBjbGFzX2hvcmFyaW8geSBhZ3JlZ2EsIG1hw7FhbmEsIHRhcmRlLCBub2NoZSB5IG1hZHJ1Z2FkYSBzZWfDum4gc2VhIGVsIGNhc28uRnVuY2nDs246IHNlbGVjdCgpLCBsZWZ0X2pvaW4oKSwgbXV0YXRlKCksaWZlbHNlIGNvbiBpbg0KDQoNCmBgYA0KDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij4gQ2FudGlkYWQgZGUgdnVlbG9zIHBvciBhZXJvbMOtbmVhIHkgZGVzdGlubyBxdWUgaGF5IHBvciBsYSBNYcOxYW5hLCBUYXJkZSwgTm9jaGUgeSBNYWRydWdhZGE8L3NwYW4+DQpgYGB7cn0NCiNTZSBuZWNlc2l0YSBzYWJlciBsYSBjYW50aWRhZCBkZSB2dWVsb3MgcG9yIGFlcm9sw61uZWEgeSBkZXN0aW5vIHF1ZSBoYXkgcG9yIGxhIE1hw7FhbmEsIFRhcmRlLCBOb2NoZSB5IE1hZHJ1Z2FkYS5GdW5jacOzbjogZ3JvdXBfYnkoKSB5IGNvdW50KCkNCmBgYA0KDQoNCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPiBEZXN0aW5vcyBhIGxvcyBxdWUgdnVlbGEgQW1lcmljYW4gQWlybGluZXMgZW4gTWFkcnVnYWRhPC9zcGFuPg0KYGBge3J9DQojc2UgbmVjZXNpdGEgc2FiZXIgYSBxdcOpIGRlc3Rpbm9zIHZ1ZWxhIGxhIGFlcm9sw61uZWEgQW1lcmljYW4gQWlybGluZXMgSW5jLi1BQSAgZHVyYW50ZSBsYSBtYWRydWdhZGEuIEZ1bmNpw7NuOiBzZWxlY3QoKSxmaWx0ZXIoKSxncm91cF9ieSgpDQoNCg0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPiDCv1F1w6kgYXZpb25lcyB1dGlsaXphIGxhIGFlcm9sw61uZWEgQUE/LCB5IMK/Q3XDoW50b3MgdnVlbG9zIHNlIGhhbiByZWFsaXphZG8gY29uIGNhZGEgdW5vPyBlbGltaW5hIGxvcyBOQSdzPC9zcGFuPg0KDQpgYGB7cn0NCiNTZSBwcmVzZW50YSBsYSBhZXJvbMOtbmVhLCB0aXBvLCBtb3RvciwgbsO6bWVybyBkZSBhc2llbnRvcyB5IGxhIGNhbnRpZGFkIGRlIHZ1ZWxvcyBxdWUgc2UgaGFuIHJlYWxpemFkbyBjb24gY2FkYSB1bm8gZGUgbG9zIGF2aW9uZXMuU2UgZWxpbWluYSBsb3MgTkEncyAgRnVuY2nDs246IGxlZnRfam9pbigpLCBzZWxlY3QoKSwgZmlsdGVyKCksIGdyb3VwX2J5KCksIGNvdW50KCkNCg0KDQpgYGANCg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+IEludGVycHJldGFjaW9uZXMgZGUgbGEgZXZpZGVuY2lhIDI8L3NwYW4+DQouLi4uLi4uLi4uLi4uDQoNCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibHVlOyI+IFZpc3VhbGl6YWNpw7NuIGRlIERhdG9zPC9zcGFuPg0KRGVudHJvIGRlIGxhcyBhZXJvbMOtbmVhcyBlbCByZXRyYXNvIHRhbnRvIGVuIGxhIGhvcmEgZGUgcGFydGlkYSBjb21vIGVuIGxhIGhvcmEgZGUgbGxlZ2FkYSBhIHN1IGRlc3Rpbm8gdmFuIGdlbmVyYW5kbyBpbmRpY2Fkb3JlcyBuZWdhdGl2b3MuIA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+VnVlbG9zIGNvbiByZXRyYXNvIGVuIGlkYSB5IHJlZ3Jlc288L3NwYW4+DQoNCmBgYHtyfQ0KI1NlIHNvbGljaXRhIGFuYWxpemFyIHBhcmEgbGEgYWVyb2zDrW5lYSBBbWVyaWNhbiBBaXJsaW5lcyBzaSBsb3MgdnVlbG9zIHF1ZSB0aWVuZW4gcmV0cmFzbyBlbiBsYSBwYXJ0aWRhIHRhbWJpw6luIHRpZW5lbiByZXRyYXNvIGVuIGxhIGhvcmEgZGUgbGxlZ2FkYS5SZWFsaXphIHVuYSB2aXN1YWxpemFjacOzbiBjb24gdW5hIGdyw6FmaWNhIFNjYXR0ZXJwbG90Lg0KDQoNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPlRlbmRlbmNpYSBkZSBsYSB0ZW1wZXJhdHVyYTwvc3Bhbj4NCg0KYGBge3J9DQojI1Zpc3VhbGl6YSBsYSB0ZW5kZW5jaWEgZGUgbGEgdGVtcGVyYXR1cmEgZHVyYW50ZSBsb3MgcHJpbWVyb3MgMTUgZMOtYXMgZGVsIG1lcyBkZSBFbmVybyBlbiBsb3MgdnVlbG9zIHF1ZSBwYXJ0ZW4gZGVsIGFlcm9wdWVydG8g4oCcTmV3YXJrLCAgRVdS4oCdLCB1dGlsaXphciB1bmEgZ3LDoWZpY2EgZGUgbMOtbmVhLg0KDQoNCg0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+VGVtcGVyYXR1cmEgbcOhcyBmcmVjdWVudGU8L3NwYW4+DQpgYGB7cn0NCiNWaXN1YWxpemEgbGEgdGVtcGVyYXR1cmEgbcOhcyBmcmVjdWVudGUgZW4gbG9zIHByaW1lcm9zIDE1IGTDrWFzIGRlbCBtZXMgZGUgRW5lcm8sIHV0aWxpemFyIHVuIGhpc3Ryb2dyYW1hDQoNCmBgYA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+RmFjZXRzPC9zcGFuPg0KYGBge3J9DQojVXRpbGl6YSBGYWNldHMgcGFyYSBvYnNlcnZhciBjw7NtbyB2YXLDrWEgbGEgdGVtcGVyYXR1cmEgZW4gY2FkYSBtZXMgZW4gw6lsIGhpc3RvZ3JhbWEgZGVsIHB1bnRvIGFudGVyaW9yDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5WdWVsb3MgcXVlIHNhbGllcm9uIGRlIE51ZXZhIFlvcmsgZW4gZWwgMjAxMzwvc3Bhbj4NCmBgYHtyfQ0KI07Dum1lcm8gZGUgdnVlbG9zIHF1ZSBzYWxpZXJvbiBkZSBOdWV2YSBZb3JrIGVuIDIwMTMgcG9yIGFlcm9sw61uZWEgKG1vc3RyYXIgc29sYW1lbnRlIGxhcyAxMCBhZXJvbMOtbmVhcyBjb24gbcOhcyB2dWVsb3MpLCB1dGlsaXphciBncsOhZmljYSBkZSBiYXJyYXMuDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5HcmFmaWNhIGRlIHBpZTwvc3Bhbj4NCmBgYHtyfQ0KI1Zpc3VhbGl6YSBlbCBwdW50byBhbnRlcmlvciBlbiB1bmEgZ3LDoWZpY2EgZGUgcGllLg0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+UmVsYWNpw7NuIEZsaWdodHMgYW5kIEFpcnBvcnRzPC9zcGFuPg0KYGBge3J9DQojUmVsYWNpb25hIGVsIGRhdGEgZnJhbWUgZmxpZ2h0cyBjb24gZWwgZGF0YSBmcmFtZSBhaXJwb3J0cyBhIHRyYXbDqXMgZGVsIGNhbXBvIGRlc3Rpbm8gwr9jw7NtbyBsb2dyYXIgZXN0YXMgcmVsYWNpw7NuPw0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+RGF0YSBmcmFtZTwvc3Bhbj4NCmBgYHtyfQ0KI0NyZWEgdW4gbnVldm8gZGF0YSBmcmFtZSBjb24gZWwgcHVudG8gYW50ZXJpb3Igw7puaWNhbWVudGUgY29uIGxvcyA1IGNhcnJpZXJzIGNvbiBtw6FzIHZ1ZWxvcyBwb3IgZGVzdGluby4NCg0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+MyB2aXN1YWxpemFjaW9uZXM8L3NwYW4+DQpgYGB7cn0NCiNSZWFsaXphIHVuYSB2aXN1YWxpemFjacOzbiBkZWwgcHVudG8gYW50ZXJpb3IgZGUgbGFzIHNpZ3VpZW50ZXMgdHJlcyBmb3JtYXMuDQoNCg0KYGBgDQoNCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYmxhY2s7Ij5SZXBvcnRlIGVqZWN1dGl2bzwvc3Bhbj4NCmBgYHtyfQ0KI2VsYWJvcmEgdW4gcmVwb3J0ZSBlamVjdXRpdm8gdXRpbGl6YW5kbyBsb3MgcmVzdWx0YWRvcyBvYnRlbmlkb3MuDQoNCg0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPjEwLiBDb25jbHVzacOzbmVzIGRlIGxhIGV2aWRlbmNpYSAyPC9zcGFuPg0KDQoNCg0KDQoNCg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+Q29tcHJvbWlzbyDDqXRpY28geSBjaXVkYWRhbm88L3NwYW4+IA0KRGVzY3JpYmUgZWwgdmFsb3IgZGUgbGEgaW50ZWdyaWRhZC4NCg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+UmVmbGV4acOzbiBQZXJzb25hbDoNCg0KIMK/IGPDs21vIHB1ZWRlcyBhY3R1YXIgY29uIHJlc3BldG8geSBob25lc3RpZGFkIGVuIGxvcyBuZWdvY2lvcyB5IGVuIGVsIHVzbyBkZSBkYXRvcyBjdWFuZG8gcmVhbGljZXMgYW7DoWxpc2lzIGRlIGRhdG9zIHkgZXN0w6lzIGVuIGNvbnRhY3RvIGNvbiBsb3MgZGF0b3MgZGUgdW5hIGVtcHJlc2E/DQoNCkFsbWE6DQp4eHg6DQp4eHg6DQoNCkFncmVnYSBhbCBtZW5vcyAzIGJpYmxpb2dyYWbDrWFzIHkgY8OtdGFsYXMgZW4gZWwgcHVudG8gYW50ZXJpb3IuDQpodHRwOi8vY29kaWdvZXRpY2FlaW50ZWdyaWRhZC5jb20vDQoNCg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjogcmVkOyIgPkNBU086IMK/UG9yIHF1w6kgc2UgcmV0cmFzYW4gbG9zIHZ1ZWxvcyBlbiBOdWV2YSBZb3JrPzwvc3Bhbj48L3NwYW4+DQoNCiMjIyBbTWVyZ2Vde3N0eWxlPSJibGFjazogYmx1ZTsifQ0KDQpgYGB7cn0NCmJkZ3JhbmRlIDwtbWVyZ2UoZmxpZ2h0cyxhaXJsaW5lcywgYnk9ImNhcnJpZXIiKQ0KYmRncmFuZGUyIDwtbWVyZ2UoYmRncmFuZGUscGxhbmVzLCBieT0idGFpbG51bSIpDQpiZGdyYW5kZTMgPC0gbGVmdF9qb2luKGJkZ3JhbmRlMix3ZWF0aGVyLGJ5PWMoIm9yaWdpbiIsInRpbWVfaG91ciIpKQ0KYGBgDQoNCiMjIyBbwr9Dw7NtbyBsb3MgcmV0cmFzb3MgdmFyw61hbiBjb24gZWwgbsO6bWVybyBkZSBhc2llbnRvcz9de3N0eWxlPSJjb2xvcjogYmxhY2s7In0NCg0KYGBge3J9DQpkZjEgPC0gYmRncmFuZGUyICU+JSBzZWxlY3QoZGVwX2RlbGF5LCBzZWF0cykNCmRmMiA8LSBkZjEgJT4lIGZpbHRlcihzZWF0cyA+PSAyICYgc2VhdHMgPD0gMTAwKQ0KZGYzIDwtIGRmMSAlPiUgZmlsdGVyKHNlYXRzID4xMDApDQpzdW1tYXJpemUoZGYyLCBtZWFuKGRlcF9kZWxheSwgbmEucm09VFJVRSkpDQpzdW1tYXJpemUoZGYzLCBtZWFuKGRlcF9kZWxheSwgbmEucm09VFJVRSkpDQpzdW1tYXJ5KGRmMSkNCnN1bW1hcnkoZGYyKQ0Kc3VtbWFyeShkZjMpDQpgYGANCg0KIyMjIFtSZWxhY2nDs24gZW50cmUgdG9kb3MgbG9zIGFzaWVudG9zIGRpc3BvbmlibGVzIHkgbG9zIHJldHJhc29zLCBzaW4gZmlsdHJhciBwb3IgdGFtYcOxbyBkZWwgYXZpw7NuLl17c3R5bGU9ImNvbG9yOiBibGFjazsifQ0KDQpgYGB7cn0NCmdncGxvdChkZjEsIGFlcyh4ID0gZmFjdG9yKHNlYXRzKSwgeSA9IGRlcF9kZWxheSkpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjIpKSArICAjIEHDsWFkZSB1biBwb2NvIGRlICdqaXR0ZXInIHBhcmEgZXZpdGFyIGxhIHN1cGVycG9zaWNpw7NuIGRlIHB1bnRvcyAgDQogIGxhYnModGl0bGUgPSAiUmV0cmFzb3MgcG9yIEFzaWVudG9zIiwNCiAgICAgICB4ID0gIk7Dum1lcm8gZGUgQXNpZW50b3MiLA0KICAgICAgIHkgPSAiUmV0cmFzbyAobWludXRvcykiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLCAgIyBDZW50cmFyIGVsIHTDrXR1bG8NCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLCAgIyBOZWdyaXRhIHBhcmEgbGEgZXRpcXVldGEgZGVsIGVqZSBYDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwgICMgTmVncml0YSBwYXJhIGxhIGV0aXF1ZXRhIGRlbCBlamUgWQ0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSAgIyBSb3RhciBldGlxdWV0YXMgcGFyYSBtZWpvcg0KYGBgDQoNCiMjIyBbQXZpb25lcyBjb24gMiBhIDEwMCBhc2llbnRvcyAoUGVxdWXDsW9zKV17c3R5bGU9ImNvbG9yOiBibGFjazsifQ0KDQpgYGB7cn0NCmdncGxvdChkZjIsIGFlcyh4ID0gZmFjdG9yKHNlYXRzKSwgeSA9IGRlcF9kZWxheSkpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjIpKSArICAjIEHDsWFkZSB1biBwb2NvIGRlICdqaXR0ZXInIHBhcmEgZXZpdGFyIGxhIHN1cGVycG9zaWNpw7NuIGRlIHB1bnRvcw0KICBsYWJzKHRpdGxlID0gIlJldHJhc29zIHBvciBOw7ptZXJvIGRlIEFzaWVudG9zIGVuICBBdmlvbmVzIFBlcXVlw7FvcyIsDQogICAgICAgeCA9ICJOw7ptZXJvIGRlIEFzaWVudG9zIiwNCiAgICAgICB5ID0gIlJldHJhc28gYWwgRGVzcGVndWUgKG1pbnV0b3MpIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgICMgQ2VudHJhciBlbCB0w610dWxvDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwgICMgTmVncml0YSBwYXJhIGxhIGV0aXF1ZXRhIGRlbCBlamUgWA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksICAjIE5lZ3JpdGEgcGFyYSBsYSBldGlxdWV0YSBkZWwgZWplIFkNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgICMgUm90YXIgZXRpcXVldGFzIHBhcmEgbWVqb3IgbGVjdHVyYQ0KYGBgDQoNCiMjIyBbQXZpb25lcyBjb24gbcOhcyBkZSAxMDAgYXNpZW50b3MgKEdyYW5kZXMpXXtzdHlsZT0iY29sb3I6IGJsYWNrOyJ9DQoNCmBgYHtyfQ0KZ2dwbG90KGRmMywgYWVzKHggPSBmYWN0b3Ioc2VhdHMpLCB5ID0gZGVwX2RlbGF5KSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC41ICwgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjIpKSArDQogIGxhYnModGl0bGUgPSAiUmV0cmFzb3MgcG9yIE7Dum1lcm8gZGUgQXNpZW50b3MgZW4gQXZpb25lcyBHcmFuZGVzIiwNCiAgICAgICB4ID0gIk7Dum1lcm8gZGUgQXNpZW50b3MiLA0KICAgICAgIHkgPSAiUmV0cmFzbyBhbCBEZXNwZWd1ZSAobWludXRvcykiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLCAgIyBDZW50cmFyIGVsIHTDrXR1bG8NCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLCAgIyBOZWdyaXRhIHBhcmEgbGEgZXRpcXVldGEgZGVsIGVqZSBYDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwgICMgTmVncml0YSBwYXJhIGxhIGV0aXF1ZXRhIGRlbCBlamUgWQ0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSAgIyBSb3RhciBldGlxdWV0YXMgcGFyYSBtZWpvciBsZWN0dXJhDQpgYGANCkludGVycHJldGFjacOzbjoNCg0KDQojIyMgWyBJbmZsdWVuY2lhIGRlIGxhcyBDb25kaWNpb25lcyBDbGltw6F0aWNhcyBlbiBsb3MgUmV0cmFzb3MgZGUgVnVlbG9zXXtzdHlsZT0iY29sb3I6IGJsYWNrOyJ9DQoNCmBgYHtyfQ0Kc3VtbWFyeShiZGdyYW5kZTMpDQoNCmBgYA0KDQpgYGB7cn0NCiMgQWp1c3RhbW9zIGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbA0KbW9kZWxvIDwtIGxtKGRlcF9kZWxheSB+IHRlbXAgKyBkZXdwICsgaHVtaWQgKyB3aW5kX3NwZWVkICsgcHJlY2lwICsgcHJlc3N1cmUgKyB2aXNpYiwgZGF0YSA9IGJkZ3JhbmRlMykNCg0KIyBPYnRlbmVtb3MgdW4gcmVzdW1lbiBkZWwgbW9kZWxvIHBhcmEgdmVyIGxvcyByZXN1bHRhZG9zDQpzdW1tYXJ5KG1vZGVsbykNCg0KIyBQYXJhIHVuYSB2aXN1YWxpemFjacOzbiBtw6FzIGxpbXBpYSBkZSBsb3MgY29lZmljaWVudGVzLCB1dGlsaXphbW9zIGJyb29tDQpjb2VmaWNpZW50ZXMgPC0gdGlkeShtb2RlbG8pDQoNCiMgTW9zdHJhbW9zIGxvcyBjb2VmaWNpZW50ZXMsIGV4Y2x1eWVuZG8gZWwgaW50ZXJjZXB0byBzaSBlcyBuZWNlc2FyaW8NCmNvZWZpY2llbnRlcyAlPiUgZmlsdGVyKHRlcm0gIT0gIihJbnRlcmNlcHQpIikNCg0KYGBgDQoNCmBgYHtyfQ0KIyBGaWx0cmFyIG8gZXhjbHVpciBlbCBpbnRlcmNlcHRvIHNpIG5vIGVzIHJlbGV2YW50ZSBwYXJhIGxhIHZpc3VhbGl6YWNpw7NuDQpjb2VmaWNpZW50ZXMgPC0gY29lZmljaWVudGVzICU+JSBmaWx0ZXIodGVybSAhPSAiKEludGVyY2VwdCkiKQ0KDQojIENyZWFyIGxhIGdyw6FmaWNhDQpnZ3Bsb3QoY29lZmljaWVudGVzLCBhZXMoeCA9IHRlcm0sIHkgPSBlc3RpbWF0ZSkpICsNCiAgZ2VvbV9jb2woZmlsbCA9ICJzdGVlbGJsdWUiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBlc3RpbWF0ZSAtIHN0ZC5lcnJvciwgeW1heCA9IGVzdGltYXRlICsgc3RkLmVycm9yKSwgd2lkdGggPSAwLjIpICsNCiAgbGFicyh0aXRsZSA9ICJJbXBhY3RvIGRlIFZhcmlhYmxlcyBDbGltw6F0aWNhcyBlbiBSZXRyYXNvcyBkZSBWdWVsb3MiLA0KICAgICAgIHggPSAiVmFyaWFibGVzIENsaW3DoXRpY2FzIiwNCiAgICAgICB5ID0gIkNvZWZpY2llbnRlIEVzdGltYWRvIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KYGBgDQoNCkxhIGdyw6FmaWNhIG11ZXN0cmEgbG9zIGNvZWZpY2llbnRlcyBlc3RpbWFkb3MgcGFyYSBjYWRhIHZhcmlhYmxlIGNsaW3DoXRpY2EgYSBwYXJ0aXIgZGUgdW4gbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsLCBlbCBjdWFsIHByZWRpY2UgZWwgcmV0cmFzbyBkZSBsb3MgdnVlbG9zIChkZXBfZGVsYXkpLiBMb3MgY29lZmljaWVudGVzIGluZGljYW4gY8OzbW8gY2FtYmlhIGVsIHJldHJhc28gZXNwZXJhZG8gZGUgdW4gdnVlbG8gKGVuIG1pbnV0b3MpIGNvbiBjYWRhIHVuaWRhZCBkZSBjYW1iaW8gZW4gbGEgdmFyaWFibGUgY2xpbcOhdGljYS4gTG9zIHJlc3VsdGFkb3Mgc2lnbmlmaWNhdGl2b3MgKHAtdmFsb3IgPCAwLjA1KSBzb24gZXNwZWNpYWxtZW50ZSBkaWdub3MgZGUgbWVuY2nDs24uDQoNCiAgICoqIHRlbXAgKFRlbXBlcmF0dXJhKTogVGllbmUgdW4gY29lZmljaWVudGUgcG9zaXRpdm8gcGVxdWXDsW8gKDAuNDIzKSwgbG8gcXVlIHN1Z2llcmUgcXVlIGEgbWVkaWRhIHF1ZSBsYSB0ZW1wZXJhdHVyYSBhdW1lbnRhLCBsb3MgcmV0cmFzb3MgZW4gbG9zIHZ1ZWxvcyB0aWVuZGVuIGEgYXVtZW50YXIgbGlnZXJhbWVudGUsIHBlcm8gZWwgZWZlY3RvIGVzIHJlbGF0aXZhbWVudGUgcGVxdWXDsW8uDQoNCiAgKiogZGV3cCAoUHVudG8gZGUgUm9jw61vKTogUHJlc2VudGEgdW4gY29lZmljaWVudGUgbmVnYXRpdm8gKC0wLjMzOCksIGltcGxpY2FuZG8gcXVlIHVuIGF1bWVudG8gZW4gZWwgcHVudG8gZGUgcm9jw61vIHBvZHLDrWEgYXNvY2lhcnNlIGxldmVtZW50ZSBjb24gdW5hIGRpc21pbnVjacOzbiBlbiBsb3MgcmV0cmFzb3MgZGUgbG9zIHZ1ZWxvcy4NCg0KICAgKiogaHVtaWQgKEh1bWVkYWQpOiBDb24gdW4gY29lZmljaWVudGUgcG9zaXRpdm8gZGUgMC4yOTEsIHN1Z2llcmUgcXVlIGxhIGh1bWVkYWQgbcOhcyBhbHRhIHBvZHLDrWEgZXN0YXIgbGlnZXJhbWVudGUgYXNvY2lhZGEgY29uIG1heW9yZXMgcmV0cmFzb3MuDQoNCiAgICoqIHdpbmRfc3BlZWQgKFZlbG9jaWRhZCBkZWwgVmllbnRvKTogVGFtYmnDqW4gdGllbmUgdW4gZWZlY3RvIHBvc2l0aXZvICgwLjI5MikgZW4gbG9zIHJldHJhc29zIGRlIGxvcyB2dWVsb3MsIGxvIHF1ZSBwb2Ryw61hIGluZGljYXIgcXVlIGEgbWF5b3IgdmVsb2NpZGFkIGRlbCB2aWVudG8sIGVzIG3DoXMgcHJvYmFibGUgcXVlIGxvcyB2dWVsb3MgZXhwZXJpbWVudGVuIHJldHJhc29zLg0KDQogICoqIHByZWNpcCAoUHJlY2lwaXRhY2nDs24pOiBNdWVzdHJhIHVuIGdyYW4gY29lZmljaWVudGUgcG9zaXRpdm8gKDc0LjYpLCBzdWdpcmllbmRvIHF1ZSBsYSBwcmVjaXBpdGFjacOzbiBlcyB1biBmYWN0b3Igc2lnbmlmaWNhdGl2byB5IHRpZW5lIHVuIGZ1ZXJ0ZSBpbXBhY3RvIGVuIGVsIGF1bWVudG8gZGUgbG9zIHJldHJhc29zIGRlIGxvcyB2dWVsb3MuDQoNCiAgKiogcHJlc3N1cmUgKFByZXNpw7NuIEF0bW9zZsOpcmljYSk6IFRpZW5lIHVuIGNvZWZpY2llbnRlIG5lZ2F0aXZvIHNpZ25pZmljYXRpdm8gKC0wLjQxOCksIGxvIHF1ZSBpbmRpY2EgcXVlIHVuIGF1bWVudG8gZW4gbGEgcHJlc2nDs24gYXRtb3Nmw6lyaWNhIGVzdMOhIGFzb2NpYWRvIGNvbiB1bmEgZGlzbWludWNpw7NuIGVuIGxvcyByZXRyYXNvcyBkZSBsb3MgdnVlbG9zLg0KDQogICoqIHZpc2liIChWaXNpYmlsaWRhZCk6IENvbiB1biBjb2VmaWNpZW50ZSBuZWdhdGl2byAoLTAuNDI4KSwgc3VnaWVyZSBxdWUgbGEgdmlzaWJpbGlkYWQgcmVkdWNpZGEgZXN0w6EgYXNvY2lhZGEgY29uIGF1bWVudG9zIGVuIGxvcyByZXRyYXNvcyBkZSBsb3MgdnVlbG9zLg0KDQpMYSBwcmVjaXBpdGFjacOzbiBwYXJlY2UgdGVuZXIgZWwgaW1wYWN0byBtw6FzIHNpZ25pZmljYXRpdm8gZW4gbG9zIHJldHJhc29zIGRlIGxvcyB2dWVsb3MsIGNvbiB1biBncmFuIGNvZWZpY2llbnRlIHBvc2l0aXZvLCBsbyBxdWUgc3VnaWVyZSBxdWUgbG9zIGTDrWFzIGxsdXZpb3NvcyBvIGNvbiBtYWwgdGllbXBvIHB1ZWRlbiBjYXVzYXIgcmV0cmFzb3Mgc3VzdGFuY2lhbGVzLiBMYSBwcmVzacOzbiB5IGxhIHZpc2liaWxpZGFkIHRhbWJpw6luIHNvbiBmYWN0b3JlcyBzaWduaWZpY2F0aXZvcywgcGVybyBzdSBpbXBhY3RvIGVzIGludmVyc28sIGRvbmRlIGxhIG1heW9yIHZpc2liaWxpZGFkIHkgcHJlc2nDs24gYXRtb3Nmw6lyaWNhIGVzdMOhbiByZWxhY2lvbmFkYXMgY29uIG1lbm9yZXMgcmV0cmFzb3MuDQoNCiMjIyBbIFJldHJhc28gcG9yIGFlcm9wdWVydG9de3N0eWxlPSJjb2xvcjogYmxhY2s7In0NCg0KYGBge3J9DQoNCiAgICMgQ2FsY3VsYW1vcyBlbCByZXRyYXNvIHByb21lZGlvIHBvciBhZXJvcHVlcnRvIGRlIG9yaWdlbiB5IGVsIHBvcmNlbnRhamUgZGUgdnVlbG9zIHJldHJhc2Fkb3MNCnJldHJhc29fcG9yX2Flcm9wdWVydG8gPC0gYmRncmFuZGUzICU+JQ0KICBncm91cF9ieShvcmlnaW4pICU+JQ0KICBzdW1tYXJpc2UoDQogICAgcmV0cmFzb19wcm9tZWRpbyA9IG1lYW4oZGVwX2RlbGF5LCBuYS5ybSA9IFRSVUUpLCAgIyBDYWxjdWxhbW9zIGVsIHJldHJhc28gcHJvbWVkaW8gZXhjbHV5ZW5kbyBOQQ0KICAgIHZ1ZWxvcyA9IG4oKSwgICMgQ29udGFtb3MgZWwgbsO6bWVybyB0b3RhbCBkZSB2dWVsb3MgcGFyYSBjYWRhIGFlcm9wdWVydG8NCiAgICB2dWVsb3NfcmV0cmFzYWRvcyA9IHN1bShkZXBfZGVsYXkgPiAwLCBuYS5ybSA9IFRSVUUpLCAgIyBDb250YW1vcyBsb3MgdnVlbG9zIHJldHJhc2Fkb3MNCiAgICBwb3JjZW50YWplX3JldHJhc2Fkb3MgPSB2dWVsb3NfcmV0cmFzYWRvcyAvIHZ1ZWxvcyAqIDEwMCAgIyBDYWxjdWxhbW9zIGVsIHBvcmNlbnRhamUgZGUgdnVlbG9zIHJldHJhc2Fkb3MNCiAgKSAlPiUNCiAgYXJyYW5nZShkZXNjKHJldHJhc29fcHJvbWVkaW8pKSAgIyBPcmRlbmFtb3MgcG9yIGVsIHJldHJhc28gcHJvbWVkaW8gZGVzY2VuZGVudGUNCg0KIyBNb3N0cmFtb3MgbG9zIHJlc3VsdGFkb3MNCnByaW50KHJldHJhc29fcG9yX2Flcm9wdWVydG8pIA0KYGBgDQoNCmBgYHtyfQ0KIyBDcmVhciB1bmEgZ3LDoWZpY2EgcXVlIG11ZXN0cmEgdGFudG8gZWwgcmV0cmFzbyBwcm9tZWRpbyBjb21vIGVsIHBvcmNlbnRhamUgZGUgdnVlbG9zIHJldHJhc2Fkb3MNCmdncGxvdChyZXRyYXNvX3Bvcl9hZXJvcHVlcnRvLCBhZXMoeCA9IG9yaWdpbikpICsNCiAgZ2VvbV9jb2woYWVzKHkgPSByZXRyYXNvX3Byb21lZGlvKSwgZmlsbCA9ICJzdGVlbGJsdWUiLCB3aWR0aCA9IDAuNCwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsNCiAgZ2VvbV9jb2woYWVzKHkgPSBwb3JjZW50YWplX3JldHJhc2Fkb3MpLCBmaWxsID0gImZpcmVicmljayIsIHdpZHRoID0gMC40LCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSwgYWxwaGEgPSAwLjUpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofi4sIG5hbWUgPSAiUG9yY2VudGFqZSBkZSBWdWVsb3MgUmV0cmFzYWRvcyIpKSArDQogIGxhYnModGl0bGUgPSAiUmV0cmFzbyBQcm9tZWRpbyB5IFBvcmNlbnRhamUgZGUgVnVlbG9zIFJldHJhc2Fkb3MgcG9yIEFlcm9wdWVydG8gZGUgT3JpZ2VuIiwNCiAgICAgICB4ID0gIkFlcm9wdWVydG8gZGUgT3JpZ2VuIiwNCiAgICAgICB5ID0gIlJldHJhc28gUHJvbWVkaW8gKG1pbnV0b3MpIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQ0KDQojIE1vc3RyYXIgbGEgZ3LDoWZpY2ENCmdnc2F2ZSgicmV0cmFzb195X3BvcmNlbnRhamVfcG9yX2Flcm9wdWVydG8ucG5nIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNikgIyBPcGNpb25hbDogR3VhcmRhciBsYSBncsOhZmljYQ0KYGBgDQoNCmBgYHtyfQ0KbmFtZXMoYmRncmFuZGUzKQ0KYGBgDQoNCiMjIyBbIFJldHJhc29zIHByb21lZGlvIHBvciBtZXMgeSBhZXJvcHVlcnRvIGRlIG9yaWdlbl17c3R5bGU9ImNvbG9yOiBibGFjazsifQ0KDQoNCmBgYHtyfQ0KIyBDYWxjdWxhbW9zIGVsIHJldHJhc28gcHJvbWVkaW8gcG9yIG1lcyB5IGFlcm9wdWVydG8gZGUgb3JpZ2VuDQpyZXRyYXNvX3Byb21lZGlvX21lc19hZXJvcHVlcnRvIDwtIGJkZ3JhbmRlMyAlPiUNCiAgZ3JvdXBfYnkob3JpZ2luLCBtb250aC54KSAlPiUNCiAgc3VtbWFyaXNlKHJldHJhc29fcHJvbWVkaW8gPSBtZWFuKGRlcF9kZWxheSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFycmFuZ2Uob3JpZ2luLCBtb250aC54KQ0KDQojIFJlc3VsdGFkbw0KcHJpbnQocmV0cmFzb19wcm9tZWRpb19tZXNfYWVyb3B1ZXJ0bykNCmBgYA0KDQpgYGB7cn0NCiMgQ3JlYW1vcyB1bmEgZ3LDoWZpY2EgcGFyYSB2aXN1YWxpemFyIGxvcyByZXRyYXNvcyBwcm9tZWRpbyBwb3IgbWVzIHkgYWVyb3B1ZXJ0byBkZSBvcmlnZW4NCmdncGxvdChyZXRyYXNvX3Byb21lZGlvX21lc19hZXJvcHVlcnRvLCBhZXMoeCA9IG1vbnRoLngsIHkgPSByZXRyYXNvX3Byb21lZGlvLCBjb2xvciA9IG9yaWdpbikpICsNCiAgZ2VvbV9saW5lKCkgKyAgIyBMw61uZWFzIHBhcmEgY29uZWN0YXIgbG9zIHB1bnRvcyBkZSByZXRyYXNvIHByb21lZGlvDQogIGdlb21fcG9pbnQoKSArICAjIFB1bnRvcyBwYXJhIGRlc3RhY2FyIGNhZGEgdmFsb3IgZGUgcmV0cmFzbyBwcm9tZWRpbw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMToxMiwgbGFiZWxzID0gYygiRW5lIiwgIkZlYiIsICJNYXIiLCAiQWJyIiwgIk1heSIsICJKdW4iLCAiSnVsIiwgIkFnbyIsICJTZXAiLCAiT2N0IiwgIk5vdiIsICJEaWMiKSkgKw0KICBsYWJzKHRpdGxlID0gIlJldHJhc29zIFByb21lZGlvIHBvciBNZXMgeSBBZXJvcHVlcnRvIGRlIE9yaWdlbiIsDQogICAgICAgeCA9ICJNZXMiLA0KICAgICAgIHkgPSAiUmV0cmFzbyBQcm9tZWRpbyAobWludXRvcykiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInN0ZWVsYmx1ZSIsICJmaXJlYnJpY2siLCAiZm9yZXN0Z3JlZW4iKSkgICMgQ29sb3JlcyBwZXJzb25hbGl6YWRvcyBwYXJhIGNhZGEgYWVyb3B1ZXJ0bw0KDQojIE1vc3RyYXIgbGEgZ3LDoWZpY2ENCmdnc2F2ZSgicmV0cmFzb19wcm9tZWRpb19tZXNfYWVyb3B1ZXJ0by5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KSANCmBgYA0KDQoNCiMjIyBbUmVsYWNpw7NuIGVudHJlIGxhIGFudGlnw7xlZGFkIGRlIHVuIGF2acOzbiB5IHN1cyByZXRyYXNvc117c3R5bGU9ImNvbG9yOiBibGFjazsifQ0KYGBge3J9DQpiZGdyYW5kZTMgPC0gYmRncmFuZGUzICU+JQ0KICBmaWx0ZXIoIWlzLm5hKHllYXIueSkpICU+JQ0KICBtdXRhdGUoYWdlID0gMjAxMyAtIHllYXIueSkgJT4lICAjIEFzdW1pZW5kbyBxdWUgbG9zIGRhdG9zIGRlIHZ1ZWxvIHNvbiBkZSAyMDEzDQogIGZpbHRlcihhZ2UgPj0gMCkgICMgQXNlZ3VyYXIgcXVlIGxhIGFudGlnw7xlZGFkIHNlYSBsw7NnaWNhDQpgYGANCg0KYGBge3J9DQphZ2VfZGVsYXlfc3VtbWFyeV9iZGdyYW5kZTMgPC0gYmRncmFuZGUzICU+JQ0KICBncm91cF9ieShhZ2UpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgYXZnX2RlcF9kZWxheSA9IG1lYW4oZGVwX2RlbGF5LCBuYS5ybSA9IFRSVUUpLA0KICAgIG4gPSBuKCkNCiAgKSAlPiUNCiAgZmlsdGVyKG4gPiAxMDApICAjIEZpbHRyYXIgZ3J1cG9zIGNvbiBzdWZpY2llbnRlcyBkYXRvcw0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGFnZV9kZWxheV9zdW1tYXJ5X2JkZ3JhbmRlMywgYWVzKHggPSBhZ2UsIHkgPSBhdmdfZGVwX2RlbGF5KSkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAiYmx1ZSIsIG5hLnJtID0gVFJVRSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiLCBuYS5ybSA9IFRSVUUpICsgICMgQcOxYWRpciBwdW50b3MgcGFyYSBtYXlvciBjbGFyaWRhZA0KICBsYWJzKHRpdGxlID0gIlJldHJhc28gUHJvbWVkaW8gZGUgU2FsaWRhIHBvciBBbnRpZ8O8ZWRhZCBkZWwgQXZpw7NuIiwNCiAgICAgICB4ID0gIkFudGlnw7xlZGFkIGRlbCBBdmnDs24gKGHDsW9zKSIsDQogICAgICAgeSA9ICJSZXRyYXNvIFByb21lZGlvIGRlIFNhbGlkYSAobWludXRvcykiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KIyMjIFtQcm9tZWRpbyBkZSBSZXRyYXNvIGRlIFZ1ZWxvIHBvciBIb3JhIGRlbCBEw61hXXtzdHlsZT0iY29sb3I6IGJsYWNrOyJ9DQoNCmBgYHtyfQ0KYmRncmFuZGUzIDwtIGJkZ3JhbmRlMyAlPiUNCiAgbXV0YXRlKA0KICAgIGhvdXJfb2ZfZGF5ID0gc2NoZWRfZGVwX3RpbWUgJS8lIDEwMCwgICMgRXh0cmFlIGxhIGhvcmEgZGVsIHRpZW1wbyBkZSBzYWxpZGEgcHJvZ3JhbWFkbw0KICAgIGRlcF9kZWxheSA9IGlmZWxzZShpcy5uYShkZXBfZGVsYXkpLCAwLCBkZXBfZGVsYXkpICAjIFRyYXRhIGxvcyBOQSBlbiBkZXBfZGVsYXkgY29tbyAwIHBhcmEgZXN0ZSBhbsOhbGlzaXMNCiAgKQ0KYGBgDQoNCmBgYHtyfQ0KcmV0cmFzb19wcm9tZWRpb19wb3JfaG9yYSA8LSBiZGdyYW5kZTMgJT4lDQogIGdyb3VwX2J5KGhvdXJfb2ZfZGF5KSAlPiUNCiAgc3VtbWFyaXNlKHJldHJhc29fcHJvbWVkaW8gPSBtZWFuKGRlcF9kZWxheSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGFycmFuZ2UoaG91cl9vZl9kYXkpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QocmV0cmFzb19wcm9tZWRpb19wb3JfaG9yYSwgYWVzKHggPSBob3VyX29mX2RheSwgeSA9IHJldHJhc29fcHJvbWVkaW8pKSArDQogIGdlb21fbGluZSgpICsgICMgTMOtbmVhIHBhcmEgY29uZWN0YXIgbG9zIHB1bnRvcyBkZSByZXRyYXNvIHByb21lZGlvDQogIGdlb21fcG9pbnQoKSArICAjIFB1bnRvcyBwYXJhIHJlc2FsdGFyIGNhZGEgaG9yYQ0KICBsYWJzKHRpdGxlID0gIlByb21lZGlvIGRlIFJldHJhc28gZGUgVnVlbG8gcG9yIEhvcmEgZGVsIETDrWEiLA0KICAgICAgIHggPSAiSG9yYSBkZWwgRMOtYSIsDQogICAgICAgeSA9ICJSZXRyYXNvIFByb21lZGlvIChtaW51dG9zKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpDQpgYGANCg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6IGJsYWNrOyI+Q29uY2x1c2nDs24gPC9zcGFuPiANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBibGFjazsiPkJpYmxpb2dyYWbDrWFzPC9zcGFuPiANCg0KDQo=