# Contexto

El paquete nycflights13 contine información sobre todos los vuelos que partieron desde Nueva York (EWR, JFK Y LGA) a destinos en los Estados Unidos en 2013. Fueron 336776 vuelos en total. Para ayudar a comprender las causas de los retrasos, también incluye otros conjuntos de datos útiles.

Este paquete incluye las siguientes tablas:

flights = todos los vuelos que salieron de Nueva York en 2013 weather = datos meteorológicos por hora de cada aeropuerto planes = información de construcción de cada avión airports = nombres y ubicaciones de aeropuertos airlines = relación entre nombres y códigos de las aerolínea

Situación problema

Te acabas de incorporar a una empresa consultora en Inteligencia de Negocios, actualmente están brindando servicios de análisis para la industria de la aviación y les interesa tener a la aerolínea American Airlines como cliente ya que es una de las aerolíneas líderes en los aeropuertos de Nueva York, motivo por el cuál te han contratado.

Instalar paquetes y llamar librerías

# install.packages("nycflights13")
library(nycflights13)
# install.packages("tidyverse")
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.3     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Guardar bases de datos

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

Relación entre las bases de datos

# 1. Data Frames e Identificación de tipo de datos

## Datos de Weather
weather
## # A tibble: 26,115 × 15
##    origin  year month   day  hour  temp  dewp humid wind_dir wind_speed
##    <chr>  <int> <int> <int> <int> <dbl> <dbl> <dbl>    <dbl>      <dbl>
##  1 EWR     2013     1     1     1  39.0  26.1  59.4      270      10.4 
##  2 EWR     2013     1     1     2  39.0  27.0  61.6      250       8.06
##  3 EWR     2013     1     1     3  39.0  28.0  64.4      240      11.5 
##  4 EWR     2013     1     1     4  39.9  28.0  62.2      250      12.7 
##  5 EWR     2013     1     1     5  39.0  28.0  64.4      260      12.7 
##  6 EWR     2013     1     1     6  37.9  28.0  67.2      240      11.5 
##  7 EWR     2013     1     1     7  39.0  28.0  64.4      240      15.0 
##  8 EWR     2013     1     1     8  39.9  28.0  62.2      250      10.4 
##  9 EWR     2013     1     1     9  39.9  28.0  62.2      260      15.0 
## 10 EWR     2013     1     1    10  41    28.0  59.6      260      13.8 
## # ℹ 26,105 more rows
## # ℹ 5 more variables: wind_gust <dbl>, precip <dbl>, pressure <dbl>,
## #   visib <dbl>, time_hour <dttm>
## Datos de Planes
planes
## # A tibble: 3,322 × 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…
##  7 N107US   1999 Fixed wing multi… AIRBUS INDU… A320…       2   182    NA Turbo…
##  8 N108UW   1999 Fixed wing multi… AIRBUS INDU… A320…       2   182    NA Turbo…
##  9 N109UW   1999 Fixed wing multi… AIRBUS INDU… A320…       2   182    NA Turbo…
## 10 N110UW   1999 Fixed wing multi… AIRBUS INDU… A320…       2   182    NA Turbo…
## # ℹ 3,312 more rows
## Datos de Airports
airports
## # A tibble: 1,458 × 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/…
##  2 06A   Moton Field Municipal Airport   32.5  -85.7   264    -6 A     America/…
##  3 06C   Schaumburg Regional             42.0  -88.1   801    -6 A     America/…
##  4 06N   Randall Airport                 41.4  -74.4   523    -5 A     America/…
##  5 09J   Jekyll Island Airport           31.1  -81.4    11    -5 A     America/…
##  6 0A9   Elizabethton Municipal Airport  36.4  -82.2  1593    -5 A     America/…
##  7 0G6   Williams County Airport         41.5  -84.5   730    -5 A     America/…
##  8 0G7   Finger Lakes Regional Airport   42.9  -76.8   492    -5 A     America/…
##  9 0P2   Shoestring Aviation Airfield    39.8  -76.6  1000    -5 U     America/…
## 10 0S9   Jefferson County Intl           48.1 -123.    108    -8 A     America/…
## # ℹ 1,448 more rows
## Datos de airlines
airlines
## # A tibble: 16 × 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.   
##  7 F9      Frontier Airlines Inc.     
##  8 FL      AirTran Airways Corporation
##  9 HA      Hawaiian Airlines Inc.     
## 10 MQ      Envoy Air                  
## 11 OO      SkyWest Airlines Inc.      
## 12 UA      United Air Lines Inc.      
## 13 US      US Airways Inc.            
## 14 VX      Virgin America             
## 15 WN      Southwest Airlines Co.     
## 16 YV      Mesa Airlines Inc.

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

## La carga 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>

3. 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 (no tiene decimales). Se utiliza para almacenar valores numéricos sin decimales, como la cantidad de pasajeros o el número de vuelos.
# dbl: Se usa para almacenar números con decimales, como distancias o precios.
# num: numérico (tiene decimales) peso
# chr: caracter (letras). Se usa para almacenar texto, como nombres o palabras.  
# Date: fecha (en R va año-mes-día)
# POSIXct: formato fecha y hora. Es un tipo de dato que representa una fecha y hora específica. Se utiliza para almacenar información temporal, como la fecha de un vuelo o la hora de salida.

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

class(flights)
## [1] "tbl_df"     "tbl"        "data.frame"
class
## function (x)  .Primitive("class")
# Las 5 clases de objetos son:
# 1. numeric: número real o decimales
# 2. integer: números enteros
# 3. complex: números complejos
# 4. character: caracteres, letras o palabras
# 5. logical: TRUE o FALSE

# Las 4 clases de objetos compuestos son: 

# 1. list: lista
# 2. matrix: matriz (es todo lo mismo)
# 3. array: colección de objetos
# 4. data.frame: base de datos (es mezclado)

5. ¿Cuántas columnas y renglones tiene “flights” ¿ Cuál es su dimensión?

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

6. Muestra los primeros 6 renglones de “flights”, también los últimos 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. Muestra los estadísticos 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  
## 

7.1. Distancia media recorrida en millas

summary(flights$distance)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##      17     502     872    1040    1389    4983

Podemos observar que la distancia media en millas es de 1040.

7.2. Aerolíneas con millas recorridas superiores a la media, ordenadas en forma descendente.

media_distancia <- mean(flights$distance, na.rm = TRUE)
aerolineas_top <- flights %>%
  filter(distance > media_distancia) %>%
  select(carrier, distance, origin, dest) %>%
  arrange(desc(distance))
print(aerolineas_top)
## # 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

7.3. Encuentra la suma y la media de las distancias recorridas por carrier

distancia_aerolinea <- flights %>%
  filter(!is.na(distance)) %>%
  group_by(carrier) %>%
  summarise(
    suma_distancia = sum(distance),
    media_distancia = mean(distance, na.rm = TRUE)
  ) %>%
  arrange(desc(suma_distancia))
print(distancia_aerolinea)
## # A tibble: 16 × 3
##    carrier suma_distancia media_distancia
##    <chr>            <dbl>           <dbl>
##  1 UA            89705524           1529.
##  2 DL            59507317           1237.
##  3 B6            58384137           1069.
##  4 AA            43864584           1340.
##  5 EV            30498951            563.
##  6 MQ            15033955            570.
##  7 VX            12902327           2499.
##  8 WN            12229203            996.
##  9 US            11365778            553.
## 10 9E             9788152            530.
## 11 FL             2167344            665.
## 12 AS             1715028           2402 
## 13 HA             1704186           4983 
## 14 F9             1109700           1620 
## 15 YV              225395            375.
## 16 OO               16026            501.

8. Identifica si las aerolíneas líderes son las mismas en los tres aeropuertos

# Función para crear un data frame para un aeropuerto
aeropuerto_df <- function(aeropuerto) {
  flights %>%
    filter(origin == aeropuerto) %>%
    filter(!is.na(distance)) %>%
    group_by(carrier) %>%
    summarise(
      suma_distancia = sum(distance),
      media_distancia = mean(distance, na.rm = TRUE)
    ) %>%
    arrange(desc(suma_distancia))
}

# Data frames para cada aeropuerto
jfk_df <- aeropuerto_df("JFK")
lga_df <- aeropuerto_df("LGA")
ewr_df <- aeropuerto_df("EWR")

# Mostrar los data frames
print(jfk_df)
## # A tibble: 10 × 3
##    carrier suma_distancia media_distancia
##    <chr>            <dbl>           <dbl>
##  1 B6            46858933           1114.
##  2 DL            34970353           1689.
##  3 AA            22891534           1661.
##  4 UA            11496375           2536.
##  5 VX             8972450           2495.
##  6 9E             7426450            507.
##  7 US             3376685           1127.
##  8 MQ             2887772            401.
##  9 HA             1704186           4983 
## 10 EV              322193            229.
print(lga_df)
## # A tibble: 13 × 3
##    carrier suma_distancia media_distancia
##    <chr>            <dbl>           <dbl>
##  1 DL            20861920            904.
##  2 AA            16100472           1041.
##  3 MQ            10509739            621.
##  4 UA             9258277           1151.
##  5 B6             6181593           1030.
##  6 WN             5517587            906.
##  7 EV             4316573            489.
##  8 US             3779472            288.
##  9 FL             2167344            665.
## 10 9E             1580071            622.
## 11 F9             1109700           1620 
## 12 YV              225395            375.
## 13 OO               11018            424.
print(ewr_df)
## # A tibble: 12 × 3
##    carrier suma_distancia media_distancia
##    <chr>            <dbl>           <dbl>
##  1 UA            68950872           1496.
##  2 EV            25860185            589.
##  3 WN             6711616           1085.
##  4 B6             5343611            815.
##  5 AA             4872578           1397.
##  6 US             4209621            956.
##  7 VX             3929877           2510.
##  8 DL             3675044            846.
##  9 AS             1715028           2402 
## 10 MQ             1636444            719 
## 11 9E              781631            616.
## 12 OO                5008            835.

Interpretación

American Airlines tiene una alta suma de distancia recorrida, lo que indica que es una aerolínea con una amplia red de rutas y un gran volumen de pasajeros. La media de la distancia recorrida por AA es superior a la media de otras aerolíneas, lo que indica que sus vuelos son generalmente más largos. Estos datos podrían ser relevantes para los inversores que buscan una aerolínea con una fuerte presencia en el mercado y un historial de rentabilidad.

Conclusión

En este trabajo pudimos utilizar las funciones más comunes del análisis explotarotio, el cual es el primer paso para cualquier trabajo de manipulación de datos, hicimos uso de distintas herramientas para analizar medias, distancias mayores y menores y así finalmente analizar los beneficios de tener a American Airlines como nuevo cliente, descubriendo su gran potencial en múltiples aeropuertos como aerolinea líder.

LS0tCnRpdGxlOiAiRXZpZGVuY2lhIDEuIEFuYWzDrXRpY2EgZGVzY3JpcHRpdmEgKEV4dHJhY2Npw7NuIHkgbWFuaXB1bGFjacOzbiBkZSBkYXRvcykiCmF1dGhvcjogIlBhdWxldHRlIE10eiAgIEEwMTc0NzUzNSIKZGF0ZTogIjIwMjQtMDMtMTMiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFIAogICAgdGhlbWU6IGNvc21vIAotLS0KIVtdKC9Vc2Vycy9wYXVsZXR0ZW0uYS4vRGVza3RvcC9NYW5pcHVsYWNpb8yBbiBkZSBkYXRvcyBmZWIvYWVyby5naWYpCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+Q29udGV4dG88L3NwYW4+CgpFbCBwYXF1ZXRlICoqbnljZmxpZ2h0czEzKiogY29udGluZSBpbmZvcm1hY2nDs24gc29icmUgdG9kb3MgbG9zIHZ1ZWxvcyBxdWUgcGFydGllcm9uIGRlc2RlIE51ZXZhIFlvcmsgKEVXUiwgSkZLIFkgTEdBKSBhIGRlc3Rpbm9zIGVuIGxvcyBFc3RhZG9zIFVuaWRvcyBlbiAyMDEzLiBGdWVyb24gMzM2Nzc2IHZ1ZWxvcyBlbiB0b3RhbC4gUGFyYSBheXVkYXIgYSBjb21wcmVuZGVyIGxhcyBjYXVzYXMgZGUgbG9zIHJldHJhc29zLCB0YW1iacOpbiBpbmNsdXllIG90cm9zIGNvbmp1bnRvcyBkZSBkYXRvcyDDunRpbGVzLgoKRXN0ZSBwYXF1ZXRlIGluY2x1eWUgbGFzIHNpZ3VpZW50ZXMgdGFibGFzOgoKZmxpZ2h0cyA9IHRvZG9zIGxvcyB2dWVsb3MgcXVlIHNhbGllcm9uIGRlIE51ZXZhIFlvcmsgZW4gMjAxMwp3ZWF0aGVyID0gZGF0b3MgbWV0ZW9yb2zDs2dpY29zIHBvciBob3JhIGRlIGNhZGEgYWVyb3B1ZXJ0bwpwbGFuZXMgPSBpbmZvcm1hY2nDs24gZGUgY29uc3RydWNjacOzbiBkZSBjYWRhIGF2acOzbgphaXJwb3J0cyA9IG5vbWJyZXMgeSB1YmljYWNpb25lcyBkZSBhZXJvcHVlcnRvcwphaXJsaW5lcyA9IHJlbGFjacOzbiBlbnRyZSBub21icmVzIHkgY8OzZGlnb3MgZGUgbGFzIGFlcm9sw61uZWEKCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+U2l0dWFjacOzbiBwcm9ibGVtYTwvc3Bhbj4KClRlIGFjYWJhcyBkZSBpbmNvcnBvcmFyIGEgdW5hIGVtcHJlc2EgY29uc3VsdG9yYSBlbiBJbnRlbGlnZW5jaWEgZGUgTmVnb2Npb3MsIGFjdHVhbG1lbnRlIGVzdMOhbiBicmluZGFuZG8gc2VydmljaW9zIGRlIGFuw6FsaXNpcyBwYXJhIGxhIGluZHVzdHJpYSBkZSBsYSBhdmlhY2nDs24geSBsZXMgaW50ZXJlc2EgdGVuZXIgYSBsYSBhZXJvbMOtbmVhIEFtZXJpY2FuIEFpcmxpbmVzIGNvbW8gY2xpZW50ZSB5YSBxdWUgZXMgdW5hIGRlIGxhcyBhZXJvbMOtbmVhcyBsw61kZXJlcyBlbiBsb3MgYWVyb3B1ZXJ0b3MgZGUgTnVldmEgWW9yaywgbW90aXZvIHBvciBlbCBjdcOhbCB0ZSBoYW4gY29udHJhdGFkby4gCgojIyMgSW5zdGFsYXIgcGFxdWV0ZXMgeSBsbGFtYXIgbGlicmVyw61hcwoKYGBge3J9CiMgaW5zdGFsbC5wYWNrYWdlcygibnljZmxpZ2h0czEzIikKbGlicmFyeShueWNmbGlnaHRzMTMpCiMgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKbGlicmFyeSh0aWR5dmVyc2UpCmBgYAoKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij5HdWFyZGFyIGJhc2VzIGRlIGRhdG9zIDwvc3Bhbj4KYGBge3J9CmZsaWdodHMgPC0gZmxpZ2h0cwp3ZWF0aGVyIDwtIHdlYXRoZXIKcGxhbmVzIDwtIHBsYW5lcwphaXJwb3J0cyA8LSBhaXJwb3J0cwphaXJsaW5lcyA8LSBhaXJsaW5lcwpgYGAKCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+UmVsYWNpw7NuIGVudHJlIGxhcyBiYXNlcyBkZSBkYXRvcyA8L3NwYW4+CiFbXSgvVXNlcnMvcGF1bGV0dGVtLmEuL0Rlc2t0b3AvTWFuaXB1bGFjaW/MgW4gZGUgZGF0b3MgZmViL3JlbGF0aW9uYWwtbnljZmxpZ2h0cy5wbmcpCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+MS4gRGF0YSBGcmFtZXMgZSBJZGVudGlmaWNhY2nDs24gZGUgdGlwbyBkZSBkYXRvczwvc3Bhbj4KYGBge3J9CiMjIERhdG9zIGRlIFdlYXRoZXIKd2VhdGhlcgojIyBEYXRvcyBkZSBQbGFuZXMKcGxhbmVzCiMjIERhdG9zIGRlIEFpcnBvcnRzCmFpcnBvcnRzCiMjIERhdG9zIGRlIGFpcmxpbmVzCmFpcmxpbmVzCmBgYAojIDxzcGFuIHN0eWxlID0gImNvbG9yOiBncmVlbjsiPjIuIENhcmdhciBlbiBtZW1vcmlhIGxhIHRhYmxhIOKAnGZsaWdodHPigJ0geSBtb3N0cmFyIHN1IGNvbnRlbmlkbzwvc3Bhbj4KYGBge3J9CiMjIExhIGNhcmdhIGEgbWVtb3JpYSBzZSBoaXpvIGVuIGVsIHBhc28gYW50ZXJpb3IKZmxpZ2h0cwpgYGAKCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+My4gQ29uc3VsdGEgbGEgZXN0cnVjdHVyYSBkZSDigJxmbGlnaHRz4oCdPC9zcGFuPgpgYGB7cn0Kc3RyKGZsaWdodHMpCiMgaW50OiBlbnRlcm8gKG5vIHRpZW5lIGRlY2ltYWxlcykuIFNlIHV0aWxpemEgcGFyYSBhbG1hY2VuYXIgdmFsb3JlcyBudW3DqXJpY29zIHNpbiBkZWNpbWFsZXMsIGNvbW8gbGEgY2FudGlkYWQgZGUgcGFzYWplcm9zIG8gZWwgbsO6bWVybyBkZSB2dWVsb3MuCiMgZGJsOiBTZSB1c2EgcGFyYSBhbG1hY2VuYXIgbsO6bWVyb3MgY29uIGRlY2ltYWxlcywgY29tbyBkaXN0YW5jaWFzIG8gcHJlY2lvcy4KIyBudW06IG51bcOpcmljbyAodGllbmUgZGVjaW1hbGVzKSBwZXNvCiMgY2hyOiBjYXJhY3RlciAobGV0cmFzKS4gU2UgdXNhIHBhcmEgYWxtYWNlbmFyIHRleHRvLCBjb21vIG5vbWJyZXMgbyBwYWxhYnJhcy4gIAojIERhdGU6IGZlY2hhIChlbiBSIHZhIGHDsW8tbWVzLWTDrWEpCiMgUE9TSVhjdDogZm9ybWF0byBmZWNoYSB5IGhvcmEuIEVzIHVuIHRpcG8gZGUgZGF0byBxdWUgcmVwcmVzZW50YSB1bmEgZmVjaGEgeSBob3JhIGVzcGVjw61maWNhLiBTZSB1dGlsaXphIHBhcmEgYWxtYWNlbmFyIGluZm9ybWFjacOzbiB0ZW1wb3JhbCwgY29tbyBsYSBmZWNoYSBkZSB1biB2dWVsbyBvIGxhIGhvcmEgZGUgc2FsaWRhLgpgYGAKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij40LiDCv0N1w6FsIGVzIGxhIGNsYXNlIGRlIOKAnGZsaWdodHPigJ0geSBxdcOpIHNpZ25pZmljYT88L3NwYW4+CmBgYHtyfQpjbGFzcyhmbGlnaHRzKQpjbGFzcwoKIyBMYXMgNSBjbGFzZXMgZGUgb2JqZXRvcyBzb246CiMgMS4gbnVtZXJpYzogbsO6bWVybyByZWFsIG8gZGVjaW1hbGVzCiMgMi4gaW50ZWdlcjogbsO6bWVyb3MgZW50ZXJvcwojIDMuIGNvbXBsZXg6IG7Dum1lcm9zIGNvbXBsZWpvcwojIDQuIGNoYXJhY3RlcjogY2FyYWN0ZXJlcywgbGV0cmFzIG8gcGFsYWJyYXMKIyA1LiBsb2dpY2FsOiBUUlVFIG8gRkFMU0UKCiMgTGFzIDQgY2xhc2VzIGRlIG9iamV0b3MgY29tcHVlc3RvcyBzb246IAoKIyAxLiBsaXN0OiBsaXN0YQojIDIuIG1hdHJpeDogbWF0cml6IChlcyB0b2RvIGxvIG1pc21vKQojIDMuIGFycmF5OiBjb2xlY2Npw7NuIGRlIG9iamV0b3MKIyA0LiBkYXRhLmZyYW1lOiBiYXNlIGRlIGRhdG9zIChlcyBtZXpjbGFkbykKYGBgCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+NS4gwr9DdcOhbnRhcyBjb2x1bW5hcyB5IHJlbmdsb25lcyB0aWVuZSDigJxmbGlnaHRz4oCdIMK/IEN1w6FsIGVzIHN1IGRpbWVuc2nDs24/PC9zcGFuPgoKYGBge3J9CiMgTsO6bWVybyBkZSBjb2x1bW5hcwpuY29sKGZsaWdodHMpCiMgTsO6bWVybyBkZSByZW5nbG9uZXMKbnJvdyhmbGlnaHRzKQojIERpbWVuc2nDs24KZGltKGZsaWdodHMpCmBgYAoKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij42LiBNdWVzdHJhIGxvcyBwcmltZXJvcyA2IHJlbmdsb25lcyBkZSDigJxmbGlnaHRz4oCdLCB0YW1iacOpbiBsb3Mgw7psdGltb3MgNi48L3NwYW4+CmBgYHtyfQpoZWFkKGZsaWdodHMpCnRhaWwoZmxpZ2h0cykKIyBTaSBxdWlzaWVyYW1vcyA3IHJlbmdsb25lczogaGVhZChmbGlnaHRzKQpgYGAKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij43LiBNdWVzdHJhIGxvcyBlc3RhZMOtc3RpY29zIGRlc2NyaXB0aXZvcyBkZSDigJxmbGlnaHRz4oCdPC9zcGFuPgpgYGB7cn0Kc3VtbWFyeShmbGlnaHRzKQpgYGAKCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibHVlOyI+Ny4xLiBEaXN0YW5jaWEgbWVkaWEgcmVjb3JyaWRhIGVuIG1pbGxhczwvc3Bhbj4KYGBge3J9CnN1bW1hcnkoZmxpZ2h0cyRkaXN0YW5jZSkKYGBgClBvZGVtb3Mgb2JzZXJ2YXIgcXVlIGxhIGRpc3RhbmNpYSBtZWRpYSBlbiBtaWxsYXMgZXMgZGUgMTA0MC4KCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibHVlOyI+Ny4yLiBBZXJvbMOtbmVhcyBjb24gbWlsbGFzIHJlY29ycmlkYXMgc3VwZXJpb3JlcyBhIGxhIG1lZGlhLCBvcmRlbmFkYXMgZW4gZm9ybWEgZGVzY2VuZGVudGUuPC9zcGFuPgpgYGB7cn0KbWVkaWFfZGlzdGFuY2lhIDwtIG1lYW4oZmxpZ2h0cyRkaXN0YW5jZSwgbmEucm0gPSBUUlVFKQphZXJvbGluZWFzX3RvcCA8LSBmbGlnaHRzICU+JQogIGZpbHRlcihkaXN0YW5jZSA+IG1lZGlhX2Rpc3RhbmNpYSkgJT4lCiAgc2VsZWN0KGNhcnJpZXIsIGRpc3RhbmNlLCBvcmlnaW4sIGRlc3QpICU+JQogIGFycmFuZ2UoZGVzYyhkaXN0YW5jZSkpCnByaW50KGFlcm9saW5lYXNfdG9wKQpgYGAKIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsdWU7Ij43LjMuIEVuY3VlbnRyYSBsYSBzdW1hIHkgbGEgbWVkaWEgZGUgbGFzIGRpc3RhbmNpYXMgcmVjb3JyaWRhcyBwb3IgY2Fycmllcjwvc3Bhbj4KYGBge3J9CmRpc3RhbmNpYV9hZXJvbGluZWEgPC0gZmxpZ2h0cyAlPiUKICBmaWx0ZXIoIWlzLm5hKGRpc3RhbmNlKSkgJT4lCiAgZ3JvdXBfYnkoY2FycmllcikgJT4lCiAgc3VtbWFyaXNlKAogICAgc3VtYV9kaXN0YW5jaWEgPSBzdW0oZGlzdGFuY2UpLAogICAgbWVkaWFfZGlzdGFuY2lhID0gbWVhbihkaXN0YW5jZSwgbmEucm0gPSBUUlVFKQogICkgJT4lCiAgYXJyYW5nZShkZXNjKHN1bWFfZGlzdGFuY2lhKSkKcHJpbnQoZGlzdGFuY2lhX2Flcm9saW5lYSkKYGBgCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+OC4gSWRlbnRpZmljYSBzaSBsYXMgYWVyb2zDrW5lYXMgbMOtZGVyZXMgc29uIGxhcyBtaXNtYXMgZW4gbG9zIHRyZXMgYWVyb3B1ZXJ0b3M8L3NwYW4+CmBgYHtyfQojIEZ1bmNpw7NuIHBhcmEgY3JlYXIgdW4gZGF0YSBmcmFtZSBwYXJhIHVuIGFlcm9wdWVydG8KYWVyb3B1ZXJ0b19kZiA8LSBmdW5jdGlvbihhZXJvcHVlcnRvKSB7CiAgZmxpZ2h0cyAlPiUKICAgIGZpbHRlcihvcmlnaW4gPT0gYWVyb3B1ZXJ0bykgJT4lCiAgICBmaWx0ZXIoIWlzLm5hKGRpc3RhbmNlKSkgJT4lCiAgICBncm91cF9ieShjYXJyaWVyKSAlPiUKICAgIHN1bW1hcmlzZSgKICAgICAgc3VtYV9kaXN0YW5jaWEgPSBzdW0oZGlzdGFuY2UpLAogICAgICBtZWRpYV9kaXN0YW5jaWEgPSBtZWFuKGRpc3RhbmNlLCBuYS5ybSA9IFRSVUUpCiAgICApICU+JQogICAgYXJyYW5nZShkZXNjKHN1bWFfZGlzdGFuY2lhKSkKfQoKIyBEYXRhIGZyYW1lcyBwYXJhIGNhZGEgYWVyb3B1ZXJ0bwpqZmtfZGYgPC0gYWVyb3B1ZXJ0b19kZigiSkZLIikKbGdhX2RmIDwtIGFlcm9wdWVydG9fZGYoIkxHQSIpCmV3cl9kZiA8LSBhZXJvcHVlcnRvX2RmKCJFV1IiKQoKIyBNb3N0cmFyIGxvcyBkYXRhIGZyYW1lcwpwcmludChqZmtfZGYpCnByaW50KGxnYV9kZikKcHJpbnQoZXdyX2RmKQpgYGAKIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcmVkOyI+SW50ZXJwcmV0YWNpw7NuPC9zcGFuPgoKQW1lcmljYW4gQWlybGluZXMgdGllbmUgdW5hIGFsdGEgc3VtYSBkZSBkaXN0YW5jaWEgcmVjb3JyaWRhLCBsbyBxdWUgaW5kaWNhIHF1ZSBlcyB1bmEgYWVyb2zDrW5lYSBjb24gdW5hIGFtcGxpYSByZWQgZGUgcnV0YXMgeSB1biBncmFuIHZvbHVtZW4gZGUgcGFzYWplcm9zLiBMYSBtZWRpYSBkZSBsYSBkaXN0YW5jaWEgcmVjb3JyaWRhIHBvciBBQSBlcyBzdXBlcmlvciBhIGxhIG1lZGlhIGRlIG90cmFzIGFlcm9sw61uZWFzLCBsbyBxdWUgaW5kaWNhIHF1ZSBzdXMgdnVlbG9zIHNvbiBnZW5lcmFsbWVudGUgbcOhcyBsYXJnb3MuIEVzdG9zIGRhdG9zIHBvZHLDrWFuIHNlciByZWxldmFudGVzIHBhcmEgbG9zIGludmVyc29yZXMgcXVlIGJ1c2NhbiB1bmEgYWVyb2zDrW5lYSBjb24gdW5hIGZ1ZXJ0ZSBwcmVzZW5jaWEgZW4gZWwgbWVyY2FkbyB5IHVuIGhpc3RvcmlhbCBkZSByZW50YWJpbGlkYWQuCgojIDxzcGFuIHN0eWxlID0gImNvbG9yOiByZWQ7Ij5Db25jbHVzacOzbjwvc3Bhbj4KCkVuIGVzdGUgdHJhYmFqbyBwdWRpbW9zIHV0aWxpemFyIGxhcyBmdW5jaW9uZXMgbcOhcyBjb211bmVzIGRlbCBhbsOhbGlzaXMgZXhwbG90YXJvdGlvLCBlbCBjdWFsIGVzIGVsIHByaW1lciBwYXNvIHBhcmEgY3VhbHF1aWVyIHRyYWJham8gZGUgbWFuaXB1bGFjacOzbiBkZSBkYXRvcywgaGljaW1vcyB1c28gZGUgZGlzdGludGFzIGhlcnJhbWllbnRhcyBwYXJhIGFuYWxpemFyIG1lZGlhcywgZGlzdGFuY2lhcyBtYXlvcmVzIHkgbWVub3JlcyB5IGFzw60gZmluYWxtZW50ZSBhbmFsaXphciBsb3MgYmVuZWZpY2lvcyBkZSB0ZW5lciBhIEFtZXJpY2FuIEFpcmxpbmVzIGNvbW8gbnVldm8gY2xpZW50ZSwgZGVzY3VicmllbmRvIHN1IGdyYW4gcG90ZW5jaWFsIGVuIG3Dumx0aXBsZXMgYWVyb3B1ZXJ0b3MgY29tbyBhZXJvbGluZWEgbMOtZGVyLgo=