• Librairies
  • Load data
  • Data Transformation
    • Clean the data frame
    • Tidying the data frame
  • Data Analysis
    • Airlines performance
    • Plotting the airlines performance
    • Airlines on time comparison per city
    • Note on airlines on-time performance per city
    • Overall on-time performance for both airlines
    • Note on overall on-time performance per carrier
    • A note on discrepancy
  • Take Away
    • Graphs and insights
    • Conclusion

Librairies

library(tidyverse)
## -- Attaching packages -------------------------------------------------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.2     v purrr   0.3.4
## v tibble  3.0.3     v dplyr   1.0.2
## v tidyr   1.1.2     v stringr 1.4.0
## v readr   1.3.1     v forcats 0.5.0
## -- Conflicts ----------------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(kableExtra)
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows

Load data

airlines <- read.csv("https://raw.githubusercontent.com/jnataky/DATA-607/master/A5_Data_transformation/airlines_dest.csv")

Data Transformation

Clean the data frame

# Get rid of the empty row & reset the index

airlines <- na.omit(airlines)
row.names(airlines) <- NULL
# Replace rows 2 and 4 by airlines names

airlines[2, "X"] <- "ALASKA"
airlines[4, "X"] <- "AM WEST"
# Rename the columns names

airlines <- airlines %>%
  rename(carrier = X, status = X.1, los_angeles = Los.Angeles, phoenix = Phoenix, san_diego = San.Diego,
         san_francisco = San.Francisco, seattle = Seattle)

Tidying the data frame

# create new variable for destination and number of flights 

airlines <- airlines %>%
  gather("dest", "n_flights", 3:7)
# Wider the data frame by adding variables "on time" and "delayed"

airlines <- airlines %>%
  pivot_wider(names_from = "status", values_from = "n_flights")
# Table for tidy data


airlines %>%
  kbl(caption = "Airlines info", align = 'c') %>%
  kable_material(c("striped", "hover")) %>%
  row_spec(0, color = "indigo")
Airlines info
carrier dest on time delayed
ALASKA los_angeles 497 62
AM WEST los_angeles 694 117
ALASKA phoenix 221 12
AM WEST phoenix 4840 415
ALASKA san_diego 212 20
AM WEST san_diego 383 65
ALASKA san_francisco 503 102
AM WEST san_francisco 320 129
ALASKA seattle 1841 305
AM WEST seattle 201 61

Data Analysis

Airlines performance

# Create news variables

n_total <- airlines$delayed + airlines$`on time`
ontime_percent <- round((airlines$`on time` / n_total), 3)
delayed_percent <- round((airlines$delayed / n_total), 3)

airlines_df <- airlines %>%
  mutate(n_total, ontime_percent, delayed_percent)


airlines_df %>%
  kbl(caption = "Airlines more info", align = 'c') %>%
  kable_material(c("striped", "hover")) %>%
  row_spec(0, color = "indigo")
Airlines more info
carrier dest on time delayed n_total ontime_percent delayed_percent
ALASKA los_angeles 497 62 559 0.889 0.111
AM WEST los_angeles 694 117 811 0.856 0.144
ALASKA phoenix 221 12 233 0.948 0.052
AM WEST phoenix 4840 415 5255 0.921 0.079
ALASKA san_diego 212 20 232 0.914 0.086
AM WEST san_diego 383 65 448 0.855 0.145
ALASKA san_francisco 503 102 605 0.831 0.169
AM WEST san_francisco 320 129 449 0.713 0.287
ALASKA seattle 1841 305 2146 0.858 0.142
AM WEST seattle 201 61 262 0.767 0.233

Plotting the airlines performance

Airlines on time comparison per city

on_time1 <- airlines_df%>%
  group_by(dest, carrier) %>%
  summarise(ontime_percent)
## `summarise()` regrouping output by 'dest' (override with `.groups` argument)
on_time1 %>%
  kbl(caption = "On time performance per city", align = 'c') %>%
  kable_material(c("striped", "hover")) %>%
  row_spec(0, color = "indigo")
On time performance per city
dest carrier ontime_percent
los_angeles ALASKA 0.889
los_angeles AM WEST 0.856
phoenix ALASKA 0.948
phoenix AM WEST 0.921
san_diego ALASKA 0.914
san_diego AM WEST 0.855
san_francisco ALASKA 0.831
san_francisco AM WEST 0.713
seattle ALASKA 0.858
seattle AM WEST 0.767
# Plotting on time performance

ggplot(data = on_time1, aes(x = dest, y = ontime_percent, fill = carrier)) +
  geom_bar(stat = "identity", position = "dodge") +
  xlab("City") + ylab("On time % ") + ggtitle("Carriers on time performance per city")

Note on airlines on-time performance per city

Alaska performs better than AM West in every single of the five cities.

Overall on-time performance for both airlines

on_time2 <- airlines_df%>%
  group_by(carrier) %>%
  summarise(ontime_wg_mean = mean(ontime_percent))
## `summarise()` ungrouping output (override with `.groups` argument)
on_time2 %>%
  kbl(caption = "Overall on-time performance", align = 'c') %>%
  kable_material(c("striped", "hover")) %>%
  row_spec(0, color = "indigo")
Overall on-time performance
carrier ontime_wg_mean
ALASKA 0.8880
AM WEST 0.8224
on_time2 <- airlines_df%>%
  group_by(carrier) %>%
  summarise(ontime_wg_mean = sum(`on time`) / sum(`on time`, delayed))
## `summarise()` ungrouping output (override with `.groups` argument)
on_time2 %>%
  kbl(caption = "Overall on-time performance", align = 'c') %>%
  kable_material(c("striped", "hover")) %>%
  row_spec(0, color = "indigo")
Overall on-time performance
carrier ontime_wg_mean
ALASKA 0.8672848
AM WEST 0.8910727
# Plotting overall on-time performance

ggplot(data = on_time2, aes(x = carrier, y = ontime_wg_mean)) +
  geom_bar(stat = "identity", width = 0.5, fill = "#b629a0") +
  xlab("Carrier") + ylab("On-time mean % ") + ggtitle("Overall on-time performance per carrier")

Note on overall on-time performance per carrier

Overall AM West has more on-time flights than Alaska Air.

A note on discrepancy

When it comes to on-time performance per city for both airlines, Alaska Airlines performs better but it is worse in overall on-time performance. In per city performance, AM West doesn’t perform better than Alaska might be due to the number of flights its operates.

Take Away

The analyze has shown some discrepancy when comparing the performance between per city and overall performance.

Before digging into the conclusion, let have a look on delays and analyze the overall number of flights per city, and see how it goes!

Graphs and insights

on_time3 <- airlines_df%>%
  group_by(dest, carrier) %>%
  summarise(ontime_percent)
## `summarise()` regrouping output by 'dest' (override with `.groups` argument)
# Plotting on time performance

ggplot(data = on_time3, aes(x = dest, y = delayed_percent, fill = carrier)) +
  geom_bar(stat = "identity", position = "dodge") +
  xlab("City") + ylab("Delayed  % ") + ggtitle("Carriers delay per city")

on_time4 <- airlines_df%>%
  group_by(dest, carrier) %>%
  summarise(n_total)
## `summarise()` regrouping output by 'dest' (override with `.groups` argument)
# Plotting on time performance

ggplot(data = on_time4, aes(x = dest, y = n_total, fill = carrier)) +
  geom_bar(stat = "identity", position = "dodge") +
  xlab("City") + ylab("Number of flights ") + ggtitle("Number of flights per city")

Conclusion

Here’s: Looking at the graphs above, we can see that Alaska operates more flights in Seattle and San Francisco. In San Francisco, there is not much of difference in number of flights. This explain why Alaska Airlines beat AM West in per city performance. In the city where AM West operates more flights, it has significantly more flights than Alaska, this could explain why there are more delays. But taking into consideration the number of flights AM West operates in these 5 cities, I will recommend AM West to review its reservation system. With that, it will perform way better than Alaska. In the other hand, Alaska Airlines needs to review the internal problem that causes flights to delay.

LS0tDQp0aXRsZTogIkRBVEEgNjA3IEFTU0lHTk1FTlQgNSINCmF1dGhvcjogIkplcmVkIEF0YWt5Ig0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiANCiAgb3BlbmludHJvOjpsYWJfcmVwb3J0OiBkZWZhdWx0DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIyBMaWJyYWlyaWVzDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpgYGANCg0KIyMgTG9hZCBkYXRhDQoNCg0KYGBge3J9DQoNCmFpcmxpbmVzIDwtIHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vam5hdGFreS9EQVRBLTYwNy9tYXN0ZXIvQTVfRGF0YV90cmFuc2Zvcm1hdGlvbi9haXJsaW5lc19kZXN0LmNzdiIpDQpgYGANCg0KDQojIyBEYXRhIFRyYW5zZm9ybWF0aW9uDQoNCiMjIyBDbGVhbiB0aGUgZGF0YSBmcmFtZQ0KDQoNCmBgYHtyfQ0KDQojIEdldCByaWQgb2YgdGhlIGVtcHR5IHJvdyAmIHJlc2V0IHRoZSBpbmRleA0KDQphaXJsaW5lcyA8LSBuYS5vbWl0KGFpcmxpbmVzKQ0Kcm93Lm5hbWVzKGFpcmxpbmVzKSA8LSBOVUxMDQpgYGANCg0KYGBge3J9DQojIFJlcGxhY2Ugcm93cyAyIGFuZCA0IGJ5IGFpcmxpbmVzIG5hbWVzDQoNCmFpcmxpbmVzWzIsICJYIl0gPC0gIkFMQVNLQSINCmFpcmxpbmVzWzQsICJYIl0gPC0gIkFNIFdFU1QiDQpgYGANCg0KYGBge3J9DQojIFJlbmFtZSB0aGUgY29sdW1ucyBuYW1lcw0KDQphaXJsaW5lcyA8LSBhaXJsaW5lcyAlPiUNCiAgcmVuYW1lKGNhcnJpZXIgPSBYLCBzdGF0dXMgPSBYLjEsIGxvc19hbmdlbGVzID0gTG9zLkFuZ2VsZXMsIHBob2VuaXggPSBQaG9lbml4LCBzYW5fZGllZ28gPSBTYW4uRGllZ28sDQogICAgICAgICBzYW5fZnJhbmNpc2NvID0gU2FuLkZyYW5jaXNjbywgc2VhdHRsZSA9IFNlYXR0bGUpDQoNCmBgYA0KDQoNCiMjIyBUaWR5aW5nIHRoZSBkYXRhIGZyYW1lDQoNCg0KYGBge3J9DQoNCiMgY3JlYXRlIG5ldyB2YXJpYWJsZSBmb3IgZGVzdGluYXRpb24gYW5kIG51bWJlciBvZiBmbGlnaHRzIA0KDQphaXJsaW5lcyA8LSBhaXJsaW5lcyAlPiUNCiAgZ2F0aGVyKCJkZXN0IiwgIm5fZmxpZ2h0cyIsIDM6NykNCg0KDQpgYGANCg0KYGBge3J9DQoNCiMgV2lkZXIgdGhlIGRhdGEgZnJhbWUgYnkgYWRkaW5nIHZhcmlhYmxlcyAib24gdGltZSIgYW5kICJkZWxheWVkIg0KDQphaXJsaW5lcyA8LSBhaXJsaW5lcyAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9ICJzdGF0dXMiLCB2YWx1ZXNfZnJvbSA9ICJuX2ZsaWdodHMiKQ0KDQpgYGANCg0KYGBge3J9DQoNCiMgVGFibGUgZm9yIHRpZHkgZGF0YQ0KDQoNCmFpcmxpbmVzICU+JQ0KICBrYmwoY2FwdGlvbiA9ICJBaXJsaW5lcyBpbmZvIiwgYWxpZ24gPSAnYycpICU+JQ0KICBrYWJsZV9tYXRlcmlhbChjKCJzdHJpcGVkIiwgImhvdmVyIikpICU+JQ0KICByb3dfc3BlYygwLCBjb2xvciA9ICJpbmRpZ28iKQ0KYGBgDQoNCiMjIERhdGEgQW5hbHlzaXMNCg0KIyMjIEFpcmxpbmVzIHBlcmZvcm1hbmNlDQpgYGB7cn0NCg0KIyBDcmVhdGUgbmV3cyB2YXJpYWJsZXMNCg0Kbl90b3RhbCA8LSBhaXJsaW5lcyRkZWxheWVkICsgYWlybGluZXMkYG9uIHRpbWVgDQpvbnRpbWVfcGVyY2VudCA8LSByb3VuZCgoYWlybGluZXMkYG9uIHRpbWVgIC8gbl90b3RhbCksIDMpDQpkZWxheWVkX3BlcmNlbnQgPC0gcm91bmQoKGFpcmxpbmVzJGRlbGF5ZWQgLyBuX3RvdGFsKSwgMykNCg0KYWlybGluZXNfZGYgPC0gYWlybGluZXMgJT4lDQogIG11dGF0ZShuX3RvdGFsLCBvbnRpbWVfcGVyY2VudCwgZGVsYXllZF9wZXJjZW50KQ0KDQoNCmFpcmxpbmVzX2RmICU+JQ0KICBrYmwoY2FwdGlvbiA9ICJBaXJsaW5lcyBtb3JlIGluZm8iLCBhbGlnbiA9ICdjJykgJT4lDQogIGthYmxlX21hdGVyaWFsKGMoInN0cmlwZWQiLCAiaG92ZXIiKSkgJT4lDQogIHJvd19zcGVjKDAsIGNvbG9yID0gImluZGlnbyIpDQpgYGANCg0KDQojIyMgUGxvdHRpbmcgdGhlIGFpcmxpbmVzIHBlcmZvcm1hbmNlDQoNCiMjIyBBaXJsaW5lcyBvbiB0aW1lIGNvbXBhcmlzb24gcGVyIGNpdHkNCg0KYGBge3J9DQoNCm9uX3RpbWUxIDwtIGFpcmxpbmVzX2RmJT4lDQogIGdyb3VwX2J5KGRlc3QsIGNhcnJpZXIpICU+JQ0KICBzdW1tYXJpc2Uob250aW1lX3BlcmNlbnQpDQoNCm9uX3RpbWUxICU+JQ0KICBrYmwoY2FwdGlvbiA9ICJPbiB0aW1lIHBlcmZvcm1hbmNlIHBlciBjaXR5IiwgYWxpZ24gPSAnYycpICU+JQ0KICBrYWJsZV9tYXRlcmlhbChjKCJzdHJpcGVkIiwgImhvdmVyIikpICU+JQ0KICByb3dfc3BlYygwLCBjb2xvciA9ICJpbmRpZ28iKQ0KDQoNCmBgYA0KDQpgYGB7cn0NCiMgUGxvdHRpbmcgb24gdGltZSBwZXJmb3JtYW5jZQ0KDQpnZ3Bsb3QoZGF0YSA9IG9uX3RpbWUxLCBhZXMoeCA9IGRlc3QsIHkgPSBvbnRpbWVfcGVyY2VudCwgZmlsbCA9IGNhcnJpZXIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgeGxhYigiQ2l0eSIpICsgeWxhYigiT24gdGltZSAlICIpICsgZ2d0aXRsZSgiQ2FycmllcnMgb24gdGltZSBwZXJmb3JtYW5jZSBwZXIgY2l0eSIpDQoNCg0KYGBgDQoNCiMjIyBOb3RlIG9uIGFpcmxpbmVzIG9uLXRpbWUgcGVyZm9ybWFuY2UgcGVyIGNpdHkNCg0KQWxhc2thIHBlcmZvcm1zIGJldHRlciB0aGFuIEFNIFdlc3QgaW4gZXZlcnkgc2luZ2xlIG9mIHRoZSBmaXZlIGNpdGllcy4NCg0KDQojIyMgT3ZlcmFsbCBvbi10aW1lIHBlcmZvcm1hbmNlIGZvciBib3RoIGFpcmxpbmVzDQoNCg0KYGBge3J9DQoNCm9uX3RpbWUyIDwtIGFpcmxpbmVzX2RmJT4lDQogIGdyb3VwX2J5KGNhcnJpZXIpICU+JQ0KICBzdW1tYXJpc2Uob250aW1lX3dnX21lYW4gPSBtZWFuKG9udGltZV9wZXJjZW50KSkNCg0Kb25fdGltZTIgJT4lDQogIGtibChjYXB0aW9uID0gIk92ZXJhbGwgb24tdGltZSBwZXJmb3JtYW5jZSIsIGFsaWduID0gJ2MnKSAlPiUNCiAga2FibGVfbWF0ZXJpYWwoYygic3RyaXBlZCIsICJob3ZlciIpKSAlPiUNCiAgcm93X3NwZWMoMCwgY29sb3IgPSAiaW5kaWdvIikNCg0KDQpgYGANCg0KDQoNCmBgYHtyfQ0KDQpvbl90aW1lMiA8LSBhaXJsaW5lc19kZiU+JQ0KICBncm91cF9ieShjYXJyaWVyKSAlPiUNCiAgc3VtbWFyaXNlKG9udGltZV93Z19tZWFuID0gc3VtKGBvbiB0aW1lYCkgLyBzdW0oYG9uIHRpbWVgLCBkZWxheWVkKSkNCg0Kb25fdGltZTIgJT4lDQogIGtibChjYXB0aW9uID0gIk92ZXJhbGwgb24tdGltZSBwZXJmb3JtYW5jZSIsIGFsaWduID0gJ2MnKSAlPiUNCiAga2FibGVfbWF0ZXJpYWwoYygic3RyaXBlZCIsICJob3ZlciIpKSAlPiUNCiAgcm93X3NwZWMoMCwgY29sb3IgPSAiaW5kaWdvIikNCg0KDQpgYGANCg0KDQoNCmBgYHtyfQ0KIyBQbG90dGluZyBvdmVyYWxsIG9uLXRpbWUgcGVyZm9ybWFuY2UNCg0KZ2dwbG90KGRhdGEgPSBvbl90aW1lMiwgYWVzKHggPSBjYXJyaWVyLCB5ID0gb250aW1lX3dnX21lYW4pKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuNSwgZmlsbCA9ICIjYjYyOWEwIikgKw0KICB4bGFiKCJDYXJyaWVyIikgKyB5bGFiKCJPbi10aW1lIG1lYW4gJSAiKSArIGdndGl0bGUoIk92ZXJhbGwgb24tdGltZSBwZXJmb3JtYW5jZSBwZXIgY2FycmllciIpDQpgYGANCg0KDQojIyMgTm90ZSBvbiBvdmVyYWxsIG9uLXRpbWUgcGVyZm9ybWFuY2UgcGVyIGNhcnJpZXINCg0KT3ZlcmFsbCBBTSBXZXN0IGhhcyBtb3JlIG9uLXRpbWUgZmxpZ2h0cyB0aGFuIEFsYXNrYSBBaXIuDQoNCg0KIyMjIEEgbm90ZSBvbiBkaXNjcmVwYW5jeQ0KDQoNCjxzdHlsZT4NCmRpdi5hcXVhbWFyaW5lIHsgYmFja2dyb3VuZC1jb2xvcjojN2ZmZmQ0OyBib3JkZXItcmFkaXVzOiAxMHB4OyBwYWRkaW5nOiA1cHg7fQ0KPC9zdHlsZT4NCjxkaXYgY2xhc3MgPSAiYXF1YW1hcmluZSI+DQoNCldoZW4gaXQgY29tZXMgdG8gb24tdGltZSBwZXJmb3JtYW5jZSBwZXIgY2l0eSBmb3IgYm90aCBhaXJsaW5lcywNCkFsYXNrYSBBaXJsaW5lcyBwZXJmb3JtcyBiZXR0ZXIgYnV0IGl0IGlzIHdvcnNlIGluIG92ZXJhbGwgb24tdGltZSBwZXJmb3JtYW5jZS4NCkluIHBlciBjaXR5IHBlcmZvcm1hbmNlLCBBTSBXZXN0IGRvZXNuJ3QgcGVyZm9ybSBiZXR0ZXIgdGhhbiBBbGFza2EgbWlnaHQgYmUNCmR1ZSB0byB0aGUgbnVtYmVyIG9mIGZsaWdodHMgaXRzIG9wZXJhdGVzLg0KDQoNCg0KPC9kaXY+IFxoZmlsbFxicmVhaw0KDQoNCiMjIFRha2UgQXdheQ0KDQo8c3R5bGU+DQpkaXYuYXF1YW1hcmluZSB7IGJhY2tncm91bmQtY29sb3I6IzdmZmZkNDsgYm9yZGVyLXJhZGl1czogMTBweDsgcGFkZGluZzogNXB4O30NCjwvc3R5bGU+DQo8ZGl2IGNsYXNzID0gImFxdWFtYXJpbmUiPg0KDQpUaGUgYW5hbHl6ZSBoYXMgc2hvd24gc29tZSBkaXNjcmVwYW5jeSB3aGVuIGNvbXBhcmluZyB0aGUgcGVyZm9ybWFuY2UgYmV0d2Vlbg0KcGVyIGNpdHkgYW5kIG92ZXJhbGwgcGVyZm9ybWFuY2UuDQoNCkJlZm9yZSBkaWdnaW5nIGludG8gdGhlIGNvbmNsdXNpb24sIGxldCBoYXZlIGEgbG9vayBvbiBkZWxheXMgDQphbmQgYW5hbHl6ZSB0aGUgb3ZlcmFsbCBudW1iZXIgb2YgZmxpZ2h0cyBwZXIgY2l0eSwgYW5kIHNlZSBob3cgaXQgZ29lcyENCg0KDQoNCjwvZGl2PiBcaGZpbGxcYnJlYWsNCg0KDQoNCg0KIyMjIEdyYXBocyBhbmQgaW5zaWdodHMNCg0KDQpgYGB7cn0NCg0Kb25fdGltZTMgPC0gYWlybGluZXNfZGYlPiUNCiAgZ3JvdXBfYnkoZGVzdCwgY2FycmllcikgJT4lDQogIHN1bW1hcmlzZShvbnRpbWVfcGVyY2VudCkNCg0KIyBQbG90dGluZyBvbiB0aW1lIHBlcmZvcm1hbmNlDQoNCmdncGxvdChkYXRhID0gb25fdGltZTMsIGFlcyh4ID0gZGVzdCwgeSA9IGRlbGF5ZWRfcGVyY2VudCwgZmlsbCA9IGNhcnJpZXIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgeGxhYigiQ2l0eSIpICsgeWxhYigiRGVsYXllZCAgJSAiKSArIGdndGl0bGUoIkNhcnJpZXJzIGRlbGF5IHBlciBjaXR5IikNCg0KDQpgYGANCg0KDQpgYGB7cn0NCg0Kb25fdGltZTQgPC0gYWlybGluZXNfZGYlPiUNCiAgZ3JvdXBfYnkoZGVzdCwgY2FycmllcikgJT4lDQogIHN1bW1hcmlzZShuX3RvdGFsKQ0KDQojIFBsb3R0aW5nIG9uIHRpbWUgcGVyZm9ybWFuY2UNCg0KZ2dwbG90KGRhdGEgPSBvbl90aW1lNCwgYWVzKHggPSBkZXN0LCB5ID0gbl90b3RhbCwgZmlsbCA9IGNhcnJpZXIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsNCiAgeGxhYigiQ2l0eSIpICsgeWxhYigiTnVtYmVyIG9mIGZsaWdodHMgIikgKyBnZ3RpdGxlKCJOdW1iZXIgb2YgZmxpZ2h0cyBwZXIgY2l0eSIpDQoNCg0KYGBgDQoNCiMjIyBDb25jbHVzaW9uDQoNCg0KPHN0eWxlPg0KZGl2LmFxdWFtYXJpbmUgeyBiYWNrZ3JvdW5kLWNvbG9yOiM3ZmZmZDQ7IGJvcmRlci1yYWRpdXM6IDEwcHg7IHBhZGRpbmc6IDVweDt9DQo8L3N0eWxlPg0KPGRpdiBjbGFzcyA9ICJhcXVhbWFyaW5lIj4NCg0KDQpIZXJlJ3M6IExvb2tpbmcgYXQgdGhlIGdyYXBocyBhYm92ZSwgd2UgY2FuIHNlZSB0aGF0IEFsYXNrYSBvcGVyYXRlcyBtb3JlIGZsaWdodHMgaW4gU2VhdHRsZSBhbmQgU2FuIEZyYW5jaXNjby4NCkluIFNhbiBGcmFuY2lzY28sIHRoZXJlIGlzIG5vdCBtdWNoIG9mIGRpZmZlcmVuY2UgaW4gbnVtYmVyIG9mIGZsaWdodHMuIFRoaXMgZXhwbGFpbiB3aHkgQWxhc2thIEFpcmxpbmVzIGJlYXQgQU0gV2VzdCANCmluIHBlciBjaXR5IHBlcmZvcm1hbmNlLiBJbiB0aGUgY2l0eSB3aGVyZSBBTSBXZXN0IG9wZXJhdGVzIG1vcmUgZmxpZ2h0cywgaXQgaGFzIHNpZ25pZmljYW50bHkgbW9yZSBmbGlnaHRzIHRoYW4gQWxhc2thLA0KdGhpcyBjb3VsZCBleHBsYWluIHdoeSB0aGVyZSBhcmUgbW9yZSBkZWxheXMuIEJ1dCB0YWtpbmcgaW50byBjb25zaWRlcmF0aW9uIHRoZSBudW1iZXIgb2YgZmxpZ2h0cyBBTSBXZXN0IG9wZXJhdGVzIGluIHRoZXNlIDUgY2l0aWVzLCBJIHdpbGwgcmVjb21tZW5kIEFNIFdlc3QgdG8gcmV2aWV3IGl0cyByZXNlcnZhdGlvbiBzeXN0ZW0uIFdpdGggdGhhdCwgaXQgd2lsbCBwZXJmb3JtIHdheSBiZXR0ZXIgdGhhbiBBbGFza2EuDQpJbiB0aGUgb3RoZXIgaGFuZCwgQWxhc2thIEFpcmxpbmVzIG5lZWRzIHRvIHJldmlldyB0aGUgaW50ZXJuYWwgcHJvYmxlbSB0aGF0IGNhdXNlcyBmbGlnaHRzIHRvIGRlbGF5Lg0KDQoNCg0KDQo8L2Rpdj4gXGhmaWxsXGJyZWFrDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K