The R Notebook published at RPubs website

The R Notebook requires below packages to be installed.

install.packages('ggplot2')
install.packages('plotly')
install.packages('dplyr')
install.packages("magrittr")
devtools::install_github('hadley/ggplot2')

Objective:

This notebook focuses on transponder flight data analysis of Santa Monica VOR(SMOVOR) which locates on the southwest edge of Santa Monica Airport (SMO).

Dataset Scope:

The scope of the analysis is to see if there are any quantifiable differences between before/after Columbus day (Monday, October 12th, 2015) - an oft cited milestone for recent changes in noise.

Two dates are selected in this analysis for comparisons: March 14, 2015 and December 12, 2015.

Data Wrangling:

1. There are total four data files in this analysis.

  1. day1_night: 00:00AM ~ 06:30AM on March 14, 2015
  2. day1_day: 06:30AM on March 14, 2015 ~ 00:00AM on March 15, 2015
  3. day2_night: 00:00AM ~ 06:30AM on December 12, 2015
  4. day2_day: 06:30AM on December 12, 2015 ~ 00:00AM on December 13, 2015

2. Data cleaning process:

  1. Load the data
  2. Select the data columns we want
  3. Transform date and time values to timestamp
  4. Remove unuse data of columns by null
  5. Set up the name to columns
  6. Get valid altitude (alt), and latitude (lat)
  7. Strip white spaces from flight name and fill in empty flight name by unique flight name associated using the flight code
  8. Remove private plan from dataset by flight code = a60, d60, c60, c50, d20 with null flight name.
  9. Remove duplicate row data.
  10. Get the first data for same position (alt, lon, lat), timestamp, and flight
  11. Add track variable on same flight on same date if the flight stay more than 1 hour, remove less than 6 records
  12. Re-order column names
  13. keep only altitude between 3000 and 11000 feet
  14. Filter flights that get within 2Km from SMOVOR
  15. Remove any row with NA
  16. Filter correct time period and save to csv format for each data file.

3. Final dataset:

df1_day <- read.csv("RTL150314_day.csv")
str(df1_day)
'data.frame':   1984 obs. of  9 variables:
 $ timestamp: Factor w/ 1977 levels "2015-03-14 07:32:53",..: 453 452 451 450 449 448 447 446 445 444 ...
 $ flight   : Factor w/ 41 levels "3527","464","AAL1150",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ code     : Factor w/ 40 levels "71BE09","71BF00",..: 36 36 36 36 36 36 36 36 36 36 ...
 $ track    : int  0 0 0 0 0 0 0 0 0 0 ...
 $ id       : Factor w/ 41 levels "71BE09KAL2130",..: 36 36 36 36 36 36 36 36 36 36 ...
 $ lon      : num  -118 -118 -118 -118 -118 ...
 $ lat      : num  34 34 34 34 34 ...
 $ alt      : int  3625 4500 5475 5475 5600 5625 5775 6000 6000 6150 ...
 $ dist     : num  13100 13100 12795 11792 11792 ...
df1_day$dt <- as.POSIXct(df1_day$timestamp, tz="America/Los_Angeles")
df1_night <- read.csv("RTL150314_night.csv")
str(df1_night)
'data.frame':   85 obs. of  9 variables:
 $ timestamp: Factor w/ 85 levels "2015-03-14 01:44:12",..: 85 84 83 82 81 80 79 78 77 76 ...
 $ flight   : Factor w/ 2 levels "FDX1508","TWY878": 1 1 1 1 1 1 1 1 1 1 ...
 $ code     : Factor w/ 2 levels "A76535","AC145B": 1 1 1 1 1 1 1 1 1 1 ...
 $ track    : int  0 0 0 0 0 0 0 0 0 0 ...
 $ id       : Factor w/ 2 levels "A76535FDX15080",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ lon      : num  -118 -118 -118 -118 -118 ...
 $ lat      : num  34 34 34 34 34 ...
 $ alt      : int  7075 7400 7425 7850 7825 8000 8025 8100 8225 8300 ...
 $ dist     : num  1298 1298 1298 1298 9646 ...
df1_night$dt <- as.POSIXct(df1_night$timestamp, tz="America/Los_Angeles")
df2_day <- read.csv("RTL151212_day.csv")
str(df2_day)
'data.frame':   24054 obs. of  9 variables:
 $ timestamp: Factor w/ 20371 levels "2015-12-12 06:31:03",..: 6444 6443 6442 6441 6440 6439 6438 6437 6436 6435 ...
 $ flight   : Factor w/ 131 levels "AAL1143","AAL155",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ code     : Factor w/ 123 levels "3A2DD5","3C6517",..: 106 106 106 106 106 106 106 106 106 106 ...
 $ track    : int  0 0 0 0 0 0 0 0 0 0 ...
 $ id       : Factor w/ 131 levels "3A2DD5THT70",..: 113 113 113 113 113 113 113 113 113 113 ...
 $ lon      : num  -118 -118 -118 -118 -118 ...
 $ lat      : num  34 34 34 34 34 ...
 $ alt      : int  4225 4875 5350 5500 5550 5625 6050 6075 6225 6300 ...
 $ dist     : num  8048 8048 7691 7164 7164 ...
df2_day$dt <- as.POSIXct(df2_day$timestamp, tz="America/Los_Angeles")
df2_night <- read.csv("RTL151212_night.csv")
str(df2_night)
'data.frame':   4998 obs. of  9 variables:
 $ timestamp: Factor w/ 4248 levels "2015-12-12 01:14:40",..: 1878 1877 1875 1873 1871 1868 1864 1857 1854 1852 ...
 $ flight   : Factor w/ 24 levels "1735","AAL14",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ code     : Factor w/ 24 levels "424970","78023E",..: 16 16 16 16 16 16 16 16 16 16 ...
 $ track    : int  0 0 0 0 0 0 0 0 0 0 ...
 $ id       : Factor w/ 24 levels "424970ABW5970",..: 16 16 16 16 16 16 16 16 16 16 ...
 $ lon      : num  -118 -118 -118 -118 -118 ...
 $ lat      : num  34 34 34 34 34 ...
 $ alt      : int  4675 5050 5150 5175 5275 5375 5475 5650 6000 6000 ...
 $ dist     : num  7690 7690 7425 7086 6431 ...
df2_night$dt <- as.POSIXct(df2_night$timestamp, tz="America/Los_Angeles")

Comparisons:

2. Differences in pathes (latitude, longitude and altitude) over time

library('ggmap')
library('ggplot2')
library('plotly')
SMO <- data.frame(label = "SMO", lon=-118.456667, lat=34.010167)
smo <- c(SMO$lon, SMO$lat)
title <- "00:00AM ~ 06:30AM on March, 14, 2015"
map.google <- get_map(location = smo, zoom = 10)
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=10&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false
p <- ggmap(map.google) +
  geom_point(data = SMO, aes(x=lon, y=lat), color="red", size=5, alpha=.5) +
  geom_path(data = df1_night, aes(x=lon, y=lat, color=alt), alpha=.5) +
  scale_colour_gradient(limits=c(3000, 11000), low="orange", high="blue" ) +
  ggtitle(paste(title))
p

Figure 2-1. Flight pathes in the nighttime on Mar. 14, 2015

library('ggmap')
library('ggplot2')
library('plotly')
SMO <- data.frame(label = "SMO", lon=-118.456667, lat=34.010167)
smo <- c(SMO$lon, SMO$lat)
title <- "06:30AM on Mar. 14, 2015 ~ 00:00AM on Mar. 15, 2015"
map.google <- get_map(location = smo, zoom = 10)
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=10&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false
p <- ggmap(map.google) +
  geom_point(data = SMO, aes(x=lon, y=lat), color="red", size=5, alpha=.5) +
  geom_path(data = df1_day, aes(x=lon, y=lat, color=alt), alpha=.5) +
  scale_colour_gradient(limits=c(3000, 11000), low="red", high="green" ) +
  ggtitle(paste(title))
p

Figure 2-2. Flight pathes in the daytime on Mar. 14, 2015

library('ggmap')
library('ggplot2')
library('plotly')
SMO <- data.frame(label = "SMO", lon=-118.456667, lat=34.010167)
smo <- c(SMO$lon, SMO$lat)
title <- "00:00AM ~ 06:30AM on Dec. 12, 2015"
map.google <- get_map(location = smo, zoom = 10)
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=10&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false
p <- ggmap(map.google) +
  geom_point(data = SMO, aes(x=lon, y=lat), color="red", size=5, alpha=.5) +
  geom_path(data = df2_night, aes(x=lon, y=lat, color=alt), alpha=.5) +
  scale_colour_gradient(limits=c(3000, 11000), low="orange", high="blue" ) +
  ggtitle(paste(title))
p

Figure 2-3. Flight pathes in the nighttime on Dec. 12, 2015

library('ggmap')
library('ggplot2')
library('plotly')
SMO <- data.frame(label = "SMO", lon=-118.456667, lat=34.010167)
smo <- c(SMO$lon, SMO$lat)
title <- "06:30AM on Dec. 12, 2015 ~ 00:00AM on Dec. 13, 2015"
map.google <- get_map(location = smo, zoom = 10)
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=34.010167,-118.456667&zoom=10&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false
p <- ggmap(map.google) +
  geom_point(data = SMO, aes(x=lon, y=lat), color="red", size=5, alpha=.5) +
  geom_path(data = df2_day, aes(x=lon, y=lat, color=alt), alpha=.5) +
  scale_colour_gradient(limits=c(3000, 11000), low="red", high="green" ) +
  ggtitle(paste(title))
p

Figure 2-4. Flight pathes in the daytime on Dec. 12, 2015

3. Differences in descent rate (altitude vs time)

library('ggmap')
library('ggplot2')
library('plotly')
title <- "00:00AM ~ 06:30AM on March, 14, 2015"
p <- ggplot(df1_night, aes(x = dt, y = alt, colour = factor(substring(flight,1,3)))) +
  geom_point(alpha = 1/3, aes(text = paste("Airline:", flight, "<br>CODE:", code))) +
  labs(x="Date Time", y="Altitude - Miles", colour = "Airlines" ) +
  ggtitle(paste(title)) 
Ignoring unknown aesthetics: text
ggplotly()

Figure 3-1. Descent rate in nighttime on Mar. 14, 2015

library('ggmap')
library('ggplot2')
library('plotly')
title <- "06:30AM on Mar. 14, 2015 ~ 00:00AM on Mar. 15, 2015"
p <- ggplot(df1_day, aes(x = dt, y = alt,  colour = factor(substring(flight,1,3)))) +
  geom_point(alpha = 1/3) +
  labs(x="Date Time", y="Altitude - Miles", colour = "Airlines" ) +
  ggtitle(paste(title)) 
ggplotly()

Figure 3-2. Descent rate in daytime on Mar. 14, 2015

library('ggmap')
library('ggplot2')
library('plotly')
title <- "00:00AM ~ 06:30AM on March, 14, 2015"
p <- ggplot(df2_night, aes(x = dt, y = alt, colour = factor(substring(flight,1,3)))) +
  geom_point(alpha = 1/3) +
  labs(x="Date Time", y="Altitude - Miles", colour = "Airlines" ) +
  ggtitle(paste(title)) 
ggplotly()

Figure 3-3. Descent rate in nighttime on Dec. 12, 2015

library('ggmap')
library('ggplot2')
library('plotly')
title <- "06:30AM on Mar. 14, 2015 ~ 00:00AM on Mar. 15, 2015"
p <- ggplot(df2_day, aes(x = dt, y = alt, color = factor(substring(flight,1,3)))) +
  geom_point(alpha = 1/3) +
  labs(x="Date Time", y="Altitude - Miles", colour = "Airlines" ) +
  ggtitle(paste(title)) 
ggplotly()

Figure 3-4. Descent rate in daytime on Dec. 12, 2015

Conclusion:

The flight patterns significantly changed between Mar. 14, 2015 and Dec. 12, 2015. The total numbers of flights, airlines companies, density of pathes are all increased around SMOVOR according to above figures. Total flights increase from 42 to 152 which is 362% growth rate compare with these two dates.

Reference & Tools:

  1. Data Source: Airplane transponder data provided in INF554 class at University of Southern California.
  2. Data Wrangling: Source code provided by instructor, Dr. Luciano Nocera, in INF554 class at University of Southern California.
  3. Tools: R Core Team (2017). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. URL https://www.R-project.org/.
LS0tDQp0aXRsZTogIlRyYW5zcG9uZGVyIGZsaWdodCBkYXRhc2V0IGFuYWx5c2lzIG9mIFNhbnRhIE1vbmljYSBWT1IiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdA0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NClRoZSBSIE5vdGVib29rIHB1Ymxpc2hlZCBhdCBbUlB1YnMgd2Vic2l0ZV0oaHR0cDovL3JwdWJzLmNvbS9DaGVuZy1MaW5fTGkvMzA5NTUyKQ0KDQpUaGUgUiBOb3RlYm9vayByZXF1aXJlcyBiZWxvdyBwYWNrYWdlcyB0byBiZSBpbnN0YWxsZWQuDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmluc3RhbGwucGFja2FnZXMoJ2dncGxvdDInKQ0KaW5zdGFsbC5wYWNrYWdlcygncGxvdGx5JykNCmluc3RhbGwucGFja2FnZXMoJ2RwbHlyJykNCmluc3RhbGwucGFja2FnZXMoIm1hZ3JpdHRyIikNCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1YignaGFkbGV5L2dncGxvdDInKQ0KYGBgDQojIyBPYmplY3RpdmU6IA0KIyMjIyBUaGlzIG5vdGVib29rIGZvY3VzZXMgb24gdHJhbnNwb25kZXIgZmxpZ2h0IGRhdGEgYW5hbHlzaXMgb2YgU2FudGEgTW9uaWNhIFZPUihTTU9WT1IpIHdoaWNoIGxvY2F0ZXMgb24gdGhlIHNvdXRod2VzdCBlZGdlIG9mIFNhbnRhIE1vbmljYSBBaXJwb3J0IChTTU8pLg0KDQojIyBEYXRhc2V0IFNjb3BlOiANCiAgVGhlIHNjb3BlIG9mIHRoZSBhbmFseXNpcyBpcyB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBxdWFudGlmaWFibGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBiZWZvcmUvYWZ0ZXIgQ29sdW1idXMgZGF5IChNb25kYXksIE9jdG9iZXIgMTJ0aCwgMjAxNSkgLSBhbiBvZnQgY2l0ZWQgbWlsZXN0b25lIGZvciByZWNlbnQgY2hhbmdlcyBpbiBub2lzZS4NCg0KICBUd28gZGF0ZXMgYXJlIHNlbGVjdGVkIGluIHRoaXMgYW5hbHlzaXMgZm9yIGNvbXBhcmlzb25zOiBNYXJjaCAxNCwgMjAxNSBhbmQgRGVjZW1iZXIgMTIsIDIwMTUuDQoNCiMjIERhdGEgV3JhbmdsaW5nOg0KIyMjMS4gVGhlcmUgYXJlIHRvdGFsIGZvdXIgZGF0YSBmaWxlcyBpbiB0aGlzIGFuYWx5c2lzLiANCg0KICBhLiBkYXkxX25pZ2h0OiAwMDowMEFNIH4gMDY6MzBBTSBvbiBNYXJjaCAxNCwgMjAxNQ0KICBiLiBkYXkxX2RheTogMDY6MzBBTSBvbiBNYXJjaCAxNCwgMjAxNSB+IDAwOjAwQU0gb24gTWFyY2ggMTUsIDIwMTUNCiAgYy4gZGF5Ml9uaWdodDogMDA6MDBBTSB+IDA2OjMwQU0gb24gRGVjZW1iZXIgMTIsIDIwMTUNCiAgZC4gZGF5Ml9kYXk6IDA2OjMwQU0gb24gRGVjZW1iZXIgMTIsIDIwMTUgfiAwMDowMEFNIG9uIERlY2VtYmVyIDEzLCAyMDE1DQoNCiMjIzIuIERhdGEgY2xlYW5pbmcgcHJvY2VzczoNCg0KICBhLiBMb2FkIHRoZSBkYXRhDQogIGIuIFNlbGVjdCB0aGUgZGF0YSBjb2x1bW5zIHdlIHdhbnQNCiAgYy4gVHJhbnNmb3JtIGRhdGUgYW5kIHRpbWUgdmFsdWVzIHRvIHRpbWVzdGFtcA0KICBkLiBSZW1vdmUgdW51c2UgZGF0YSBvZiBjb2x1bW5zIGJ5IG51bGwNCiAgZS4gU2V0IHVwIHRoZSBuYW1lIHRvIGNvbHVtbnMNCiAgZi4gR2V0IHZhbGlkIGFsdGl0dWRlIChhbHQpLCBhbmQgbGF0aXR1ZGUgKGxhdCkNCiAgZy4gU3RyaXAgd2hpdGUgc3BhY2VzIGZyb20gZmxpZ2h0IG5hbWUgYW5kIGZpbGwgaW4gZW1wdHkgZmxpZ2h0IG5hbWUgYnkgdW5pcXVlIGZsaWdodCBuYW1lIGFzc29jaWF0ZWQgdXNpbmcgdGhlIGZsaWdodCBjb2RlDQogIGguIFJlbW92ZSBwcml2YXRlIHBsYW4gZnJvbSBkYXRhc2V0IGJ5IGZsaWdodCBjb2RlID0gYTYwLCBkNjAsIGM2MCwgYzUwLCBkMjAgd2l0aCBudWxsIGZsaWdodCBuYW1lLg0KICBpLiBSZW1vdmUgZHVwbGljYXRlIHJvdyBkYXRhLg0KICBqLiBHZXQgdGhlIGZpcnN0IGRhdGEgZm9yIHNhbWUgcG9zaXRpb24gKGFsdCwgbG9uLCBsYXQpLCB0aW1lc3RhbXAsIGFuZCBmbGlnaHQNCiAgay4gQWRkIHRyYWNrIHZhcmlhYmxlIG9uIHNhbWUgZmxpZ2h0IG9uIHNhbWUgZGF0ZSBpZiB0aGUgZmxpZ2h0IHN0YXkgbW9yZSB0aGFuIDEgaG91ciwgcmVtb3ZlIGxlc3MgdGhhbiA2IHJlY29yZHMNCiAgbC4gUmUtb3JkZXIgY29sdW1uIG5hbWVzDQogIG0uIGtlZXAgb25seSBhbHRpdHVkZSBiZXR3ZWVuIDMwMDAgYW5kIDExMDAwIGZlZXQNCiAgbi4gRmlsdGVyIGZsaWdodHMgdGhhdCBnZXQgd2l0aGluIDJLbSBmcm9tIFNNT1ZPUg0KICBvLiBSZW1vdmUgYW55IHJvdyB3aXRoIE5BDQogIHAuIEZpbHRlciBjb3JyZWN0IHRpbWUgcGVyaW9kIGFuZCBzYXZlIHRvIGNzdiBmb3JtYXQgZm9yIGVhY2ggZGF0YSBmaWxlLg0KDQojIyMzLiBGaW5hbCBkYXRhc2V0Og0KYGBge3J9DQpkZjFfZGF5IDwtIHJlYWQuY3N2KCJSVEwxNTAzMTRfZGF5LmNzdiIpDQpzdHIoZGYxX2RheSkNCmRmMV9kYXkkZHQgPC0gYXMuUE9TSVhjdChkZjFfZGF5JHRpbWVzdGFtcCwgdHo9IkFtZXJpY2EvTG9zX0FuZ2VsZXMiKQ0KDQpkZjFfbmlnaHQgPC0gcmVhZC5jc3YoIlJUTDE1MDMxNF9uaWdodC5jc3YiKQ0Kc3RyKGRmMV9uaWdodCkNCmRmMV9uaWdodCRkdCA8LSBhcy5QT1NJWGN0KGRmMV9uaWdodCR0aW1lc3RhbXAsIHR6PSJBbWVyaWNhL0xvc19BbmdlbGVzIikNCg0KZGYyX2RheSA8LSByZWFkLmNzdigiUlRMMTUxMjEyX2RheS5jc3YiKQ0Kc3RyKGRmMl9kYXkpDQpkZjJfZGF5JGR0IDwtIGFzLlBPU0lYY3QoZGYyX2RheSR0aW1lc3RhbXAsIHR6PSJBbWVyaWNhL0xvc19BbmdlbGVzIikNCg0KZGYyX25pZ2h0IDwtIHJlYWQuY3N2KCJSVEwxNTEyMTJfbmlnaHQuY3N2IikNCnN0cihkZjJfbmlnaHQpDQpkZjJfbmlnaHQkZHQgPC0gYXMuUE9TSVhjdChkZjJfbmlnaHQkdGltZXN0YW1wLCB0ej0iQW1lcmljYS9Mb3NfQW5nZWxlcyIpDQpgYGANCg0KDQojIyBDb21wYXJpc29uczoNCiMjIzEuIE92ZXJhbGwgdHJlbmRzDQoNCkNvbXBhcmUgdGhlIG51bWJlciBvZiBmbGlnaHRzIGNvZGVzIGluIHRoZSBkYXkgYW5kIG5pZ2h0IHBlcmlvZHMgYmV0d2VlbiB0d28gZGF5cy4NCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkobWFncml0dHIpDQpsaWJyYXJ5KCdnZ21hcCcpDQpsaWJyYXJ5KCdwbG90bHknKQ0KIyBDb3VudCB0aGUgZmxpZ2h0IG51bWJlcnMgZm9yIGVhY2ggb2YgdGltZSBwZXJpb2QNCmRmMV9kYXlfZmxpZ2h0cyA8LSBkZjFfZGF5ICU+JSBzZWxlY3QoY29kZSx0cmFjaykgJT4lIGRpc3RpbmN0KGNvZGUsIHRyYWNrKQ0KZGYxX2RheV9mbGlnaHRzWywiRGF0ZSJdIDwtIGMoIjIwMTUtMDMtMTQiKSAjIGxhYmVsIHRoZSAgZGF0ZQ0KZGYxX2RheV9mbGlnaHRzWywiQ2xhc3MiXSA8LSBjKCJEYXkiKSAjIENsYXNzZnkgdGhlIGRheSBvciBuaWdodCBwZXJpb2QNCg0KZGYxX25pZ2h0X2ZsaWdodHMgPC0gZGYxX25pZ2h0ICU+JSBzZWxlY3QoY29kZSx0cmFjaykgJT4lIGRpc3RpbmN0KGNvZGUsIHRyYWNrKQ0KZGYxX25pZ2h0X2ZsaWdodHNbLCJEYXRlIl0gPC0gYygiMjAxNS0wMy0xNCIpDQpkZjFfbmlnaHRfZmxpZ2h0c1ssIkNsYXNzIl0gPC0gYygiTmlnaHQiKQ0KDQpkZjJfZGF5X2ZsaWdodHMgPC0gZGYyX2RheSAgJT4lIHNlbGVjdChjb2RlLHRyYWNrKSAlPiUgZGlzdGluY3QoY29kZSwgdHJhY2spDQpkZjJfZGF5X2ZsaWdodHNbLCJEYXRlIl0gPC0gYygiMjAxNS0xMi0xMiIpDQpkZjJfZGF5X2ZsaWdodHNbLCJDbGFzcyJdIDwtIGMoIkRheSIpDQoNCmRmMl9uaWdodF9mbGlnaHRzIDwtIGRmMl9uaWdodCAlPiUgc2VsZWN0KGNvZGUsdHJhY2spICU+JSBkaXN0aW5jdChjb2RlLCB0cmFjaykNCmRmMl9uaWdodF9mbGlnaHRzWywiRGF0ZSJdIDwtIGMoIjIwMTUtMTItMTIiKQ0KZGYyX25pZ2h0X2ZsaWdodHNbLCJDbGFzcyJdIDwtIGMoIk5pZ2h0IikNCg0KIyBDaGVjayBjbGFzcyB0eXBlIGZvciBlYWNoIGNvbHVtbg0KI3NhcHBseShkZjFfZGF5X2ZsaWdodHMsIGNsYXNzKQ0KI3NhcHBseShkZjFfbmlnaHRfZmxpZ2h0cywgY2xhc3MpDQojc2FwcGx5KGRmMl9kYXlfZmxpZ2h0cywgY2xhc3MpDQojc2FwcGx5KGRmMl9uaWdodF9mbGlnaHRzLCBjbGFzcykNCg0KI1R1cm4gZmFjdG9yIGludG8gY2hhcmFjdGVyDQpkZjFfZGF5X2ZsaWdodHMkY29kZSA8LSBsYXBwbHkoZGYxX2RheV9mbGlnaHRzJGNvZGUsIGFzLmNoYXJhY3RlcikNCmRmMV9uaWdodF9mbGlnaHRzJGNvZGUgPC0gbGFwcGx5KGRmMV9uaWdodF9mbGlnaHRzJGNvZGUsIGFzLmNoYXJhY3RlcikNCmRmMl9kYXlfZmxpZ2h0cyRjb2RlIDwtIGxhcHBseShkZjJfZGF5X2ZsaWdodHMkY29kZSwgYXMuY2hhcmFjdGVyKQ0KZGYyX25pZ2h0X2ZsaWdodHMkY29kZSA8LSBsYXBwbHkoZGYyX25pZ2h0X2ZsaWdodHMkY29kZSwgYXMuY2hhcmFjdGVyKQ0KDQojIEJpbmQgdGhlIDQgdGltZSBwZXJpb2RzIGludG8gc2luZ2xlIGRhdGEgZnJhbWUuDQpkZl9hbGwgPC0gYmluZF9yb3dzKGRmMV9kYXlfZmxpZ2h0cywgZGYxX25pZ2h0X2ZsaWdodHMsIGRmMl9kYXlfZmxpZ2h0cywgZGYyX25pZ2h0X2ZsaWdodHMpIA0KDQp0aXRsZSA8LSAiVG90YWwgZmxpZ2h0cyB0cmVuZCINCg0KIyBQbG90IHRoZSBkaWFncmFtDQpwIDwtIGdncGxvdChkZl9hbGwsIGFlcyh4PURhdGUsIGZpbGwgPSBDbGFzcykgKSArIGdlb21fYmFyKCkgKyANCiAgZ2VvbV90ZXh0KHN0YXQ9ImNvdW50IiwgYWVzKGxhYmVsPS4uY291bnQuLiksIHBvc2l0aW9uID0gInN0YWNrIikgKw0KICBnZ3RpdGxlKHBhc3RlKHRpdGxlKSkNCmdncGxvdGx5KCkNCmBgYA0KRmlndXJlMS4gVGhlIGNvbXBhcmlzb24gb2YgdG90YWwgZmxpZ2h0IGNvdW50cyBiZXR3ZWVuIDE0IE1hcmNoLCAyMDE1IGFuZCAxMiBEZWMuLCAyMDE1LiANCg0KVGhlIHRvdGFsIGZsaWdodHMgc2lnbmlmaWNhbnRseSBpbmNyZWFzZWQgZHVyaW5nIHRoZSBwZXJpb2QgYXQgdGhlIHJlZ2lvbiBvZiBTTU9WT1IuIFRoZSB0b3RhbCBkYXkgdGltZSBmbGlnaHRzIGFyZSA0MCBpbiBNYXJjaCwgMjAxNSBhbmQgaW5jcmVhc2UgdG8gMTI4IGluIERlY2VtYmVyLCAyMDE1LiAgVGhlIHRvdGFsIG5pZ2h0IHRpbWUgZmxpZ2h0cyBhcmUgMiBpbiBNYXJjaCwgMjAxNSBhbmQgaW5jcmVhc2UgdG8gMjQgaW4gRGVjZW1iZXIsIDIwMTUuIFRvdGFsIGZsaWdodHMgaW5jcmVhc2UgZnJvbSA0MiB0byAxNTIgZHVyaW5nIHRoZSBwZXJpb2QuDQoNCg0KDQojIyMyLiBEaWZmZXJlbmNlcyBpbiBwYXRoZXMgKGxhdGl0dWRlLCBsb25naXR1ZGUgYW5kIGFsdGl0dWRlKSBvdmVyIHRpbWUNCmBgYHtyfQ0KbGlicmFyeSgnZ2dtYXAnKQ0KbGlicmFyeSgnZ2dwbG90MicpDQpsaWJyYXJ5KCdwbG90bHknKQ0KDQpTTU8gPC0gZGF0YS5mcmFtZShsYWJlbCA9ICJTTU8iLCBsb249LTExOC40NTY2NjcsIGxhdD0zNC4wMTAxNjcpDQpzbW8gPC0gYyhTTU8kbG9uLCBTTU8kbGF0KQ0KdGl0bGUgPC0gIjAwOjAwQU0gfiAwNjozMEFNIG9uIE1hcmNoLCAxNCwgMjAxNSINCg0KbWFwLmdvb2dsZSA8LSBnZXRfbWFwKGxvY2F0aW9uID0gc21vLCB6b29tID0gMTApDQpwIDwtIGdnbWFwKG1hcC5nb29nbGUpICsNCiAgZ2VvbV9wb2ludChkYXRhID0gU01PLCBhZXMoeD1sb24sIHk9bGF0KSwgY29sb3I9InJlZCIsIHNpemU9NSwgYWxwaGE9LjUpICsNCiAgZ2VvbV9wYXRoKGRhdGEgPSBkZjFfbmlnaHQsIGFlcyh4PWxvbiwgeT1sYXQsIGNvbG9yPWFsdCksIGFscGhhPS41KSArDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChsaW1pdHM9YygzMDAwLCAxMTAwMCksIGxvdz0ib3JhbmdlIiwgaGlnaD0iYmx1ZSIgKSArDQogIGdndGl0bGUocGFzdGUodGl0bGUpKQ0KcA0KYGBgDQpGaWd1cmUgMi0xLiBGbGlnaHQgcGF0aGVzIGluIHRoZSBuaWdodHRpbWUgb24gTWFyLiAxNCwgMjAxNQ0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KCdnZ21hcCcpDQpsaWJyYXJ5KCdnZ3Bsb3QyJykNCmxpYnJhcnkoJ3Bsb3RseScpDQoNClNNTyA8LSBkYXRhLmZyYW1lKGxhYmVsID0gIlNNTyIsIGxvbj0tMTE4LjQ1NjY2NywgbGF0PTM0LjAxMDE2NykNCnNtbyA8LSBjKFNNTyRsb24sIFNNTyRsYXQpDQp0aXRsZSA8LSAiMDY6MzBBTSBvbiBNYXIuIDE0LCAyMDE1IH4gMDA6MDBBTSBvbiBNYXIuIDE1LCAyMDE1Ig0KDQptYXAuZ29vZ2xlIDwtIGdldF9tYXAobG9jYXRpb24gPSBzbW8sIHpvb20gPSAxMCkNCnAgPC0gZ2dtYXAobWFwLmdvb2dsZSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBTTU8sIGFlcyh4PWxvbiwgeT1sYXQpLCBjb2xvcj0icmVkIiwgc2l6ZT01LCBhbHBoYT0uNSkgKw0KICBnZW9tX3BhdGgoZGF0YSA9IGRmMV9kYXksIGFlcyh4PWxvbiwgeT1sYXQsIGNvbG9yPWFsdCksIGFscGhhPS41KSArDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChsaW1pdHM9YygzMDAwLCAxMTAwMCksIGxvdz0icmVkIiwgaGlnaD0iZ3JlZW4iICkgKw0KICBnZ3RpdGxlKHBhc3RlKHRpdGxlKSkNCnANCmBgYA0KRmlndXJlIDItMi4gRmxpZ2h0IHBhdGhlcyBpbiB0aGUgZGF5dGltZSBvbiBNYXIuIDE0LCAyMDE1DQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkoJ2dnbWFwJykNCmxpYnJhcnkoJ2dncGxvdDInKQ0KbGlicmFyeSgncGxvdGx5JykNCg0KU01PIDwtIGRhdGEuZnJhbWUobGFiZWwgPSAiU01PIiwgbG9uPS0xMTguNDU2NjY3LCBsYXQ9MzQuMDEwMTY3KQ0Kc21vIDwtIGMoU01PJGxvbiwgU01PJGxhdCkNCnRpdGxlIDwtICIwMDowMEFNIH4gMDY6MzBBTSBvbiBEZWMuIDEyLCAyMDE1Ig0KDQptYXAuZ29vZ2xlIDwtIGdldF9tYXAobG9jYXRpb24gPSBzbW8sIHpvb20gPSAxMCkNCnAgPC0gZ2dtYXAobWFwLmdvb2dsZSkgKw0KICBnZW9tX3BvaW50KGRhdGEgPSBTTU8sIGFlcyh4PWxvbiwgeT1sYXQpLCBjb2xvcj0icmVkIiwgc2l6ZT01LCBhbHBoYT0uNSkgKw0KICBnZW9tX3BhdGgoZGF0YSA9IGRmMl9uaWdodCwgYWVzKHg9bG9uLCB5PWxhdCwgY29sb3I9YWx0KSwgYWxwaGE9LjUpICsNCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50KGxpbWl0cz1jKDMwMDAsIDExMDAwKSwgbG93PSJvcmFuZ2UiLCBoaWdoPSJibHVlIiApICsNCiAgZ2d0aXRsZShwYXN0ZSh0aXRsZSkpDQpwDQpgYGANCkZpZ3VyZSAyLTMuIEZsaWdodCBwYXRoZXMgaW4gdGhlIG5pZ2h0dGltZSBvbiBEZWMuIDEyLCAyMDE1DQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkoJ2dnbWFwJykNCmxpYnJhcnkoJ2dncGxvdDInKQ0KbGlicmFyeSgncGxvdGx5JykNCg0KU01PIDwtIGRhdGEuZnJhbWUobGFiZWwgPSAiU01PIiwgbG9uPS0xMTguNDU2NjY3LCBsYXQ9MzQuMDEwMTY3KQ0Kc21vIDwtIGMoU01PJGxvbiwgU01PJGxhdCkNCnRpdGxlIDwtICIwNjozMEFNIG9uIERlYy4gMTIsIDIwMTUgfiAwMDowMEFNIG9uIERlYy4gMTMsIDIwMTUiDQoNCm1hcC5nb29nbGUgPC0gZ2V0X21hcChsb2NhdGlvbiA9IHNtbywgem9vbSA9IDEwKQ0KcCA8LSBnZ21hcChtYXAuZ29vZ2xlKSArDQogIGdlb21fcG9pbnQoZGF0YSA9IFNNTywgYWVzKHg9bG9uLCB5PWxhdCksIGNvbG9yPSJyZWQiLCBzaXplPTUsIGFscGhhPS41KSArDQogIGdlb21fcGF0aChkYXRhID0gZGYyX2RheSwgYWVzKHg9bG9uLCB5PWxhdCwgY29sb3I9YWx0KSwgYWxwaGE9LjUpICsNCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50KGxpbWl0cz1jKDMwMDAsIDExMDAwKSwgbG93PSJyZWQiLCBoaWdoPSJncmVlbiIgKSArDQogIGdndGl0bGUocGFzdGUodGl0bGUpKQ0KcA0KYGBgDQpGaWd1cmUgMi00LiBGbGlnaHQgcGF0aGVzIGluIHRoZSBkYXl0aW1lIG9uIERlYy4gMTIsIDIwMTUNCg0KDQoNCiMjIzMuIERpZmZlcmVuY2VzIGluIGRlc2NlbnQgcmF0ZSAoYWx0aXR1ZGUgdnMgdGltZSkNCmBgYHtyfQ0KbGlicmFyeSgnZ2dtYXAnKQ0KbGlicmFyeSgnZ2dwbG90MicpDQpsaWJyYXJ5KCdwbG90bHknKQ0KdGl0bGUgPC0gIjAwOjAwQU0gfiAwNjozMEFNIG9uIE1hcmNoLCAxNCwgMjAxNSINCg0KcCA8LSBnZ3Bsb3QoZGYxX25pZ2h0LCBhZXMoeCA9IGR0LCB5ID0gYWx0LCBjb2xvdXIgPSBmYWN0b3Ioc3Vic3RyaW5nKGZsaWdodCwxLDMpKSkpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDEvMywgYWVzKHRleHQgPSBwYXN0ZSgiQWlybGluZToiLCBmbGlnaHQsICI8YnI+Q09ERToiLCBjb2RlKSkpICsNCiAgbGFicyh4PSJEYXRlIFRpbWUiLCB5PSJBbHRpdHVkZSAtIE1pbGVzIiwgY29sb3VyID0gIkFpcmxpbmVzIiApICsNCiAgZ2d0aXRsZShwYXN0ZSh0aXRsZSkpIA0KZ2dwbG90bHkoKQ0KYGBgDQpGaWd1cmUgMy0xLiBEZXNjZW50IHJhdGUgaW4gbmlnaHR0aW1lIG9uIE1hci4gMTQsIDIwMTUNCg0KDQoNCmBgYHtyfQ0KbGlicmFyeSgnZ2dtYXAnKQ0KbGlicmFyeSgnZ2dwbG90MicpDQpsaWJyYXJ5KCdwbG90bHknKQ0KdGl0bGUgPC0gIjA2OjMwQU0gb24gTWFyLiAxNCwgMjAxNSB+IDAwOjAwQU0gb24gTWFyLiAxNSwgMjAxNSINCg0KcCA8LSBnZ3Bsb3QoZGYxX2RheSwgYWVzKHggPSBkdCwgeSA9IGFsdCwgIGNvbG91ciA9IGZhY3RvcihzdWJzdHJpbmcoZmxpZ2h0LDEsMykpKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMS8zKSArDQogIGxhYnMoeD0iRGF0ZSBUaW1lIiwgeT0iQWx0aXR1ZGUgLSBNaWxlcyIsIGNvbG91ciA9ICJBaXJsaW5lcyIgKSArDQogIGdndGl0bGUocGFzdGUodGl0bGUpKSANCmdncGxvdGx5KCkNCmBgYA0KRmlndXJlIDMtMi4gRGVzY2VudCByYXRlIGluIGRheXRpbWUgb24gTWFyLiAxNCwgMjAxNQ0KDQoNCg0KYGBge3J9DQpsaWJyYXJ5KCdnZ21hcCcpDQpsaWJyYXJ5KCdnZ3Bsb3QyJykNCmxpYnJhcnkoJ3Bsb3RseScpDQp0aXRsZSA8LSAiMDA6MDBBTSB+IDA2OjMwQU0gb24gTWFyY2gsIDE0LCAyMDE1Ig0KDQpwIDwtIGdncGxvdChkZjJfbmlnaHQsIGFlcyh4ID0gZHQsIHkgPSBhbHQsIGNvbG91ciA9IGZhY3RvcihzdWJzdHJpbmcoZmxpZ2h0LDEsMykpKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMS8zKSArDQogIGxhYnMoeD0iRGF0ZSBUaW1lIiwgeT0iQWx0aXR1ZGUgLSBNaWxlcyIsIGNvbG91ciA9ICJBaXJsaW5lcyIgKSArDQogIGdndGl0bGUocGFzdGUodGl0bGUpKSANCmdncGxvdGx5KCkNCmBgYA0KRmlndXJlIDMtMy4gRGVzY2VudCByYXRlIGluIG5pZ2h0dGltZSBvbiBEZWMuIDEyLCAyMDE1DQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkoJ2dnbWFwJykNCmxpYnJhcnkoJ2dncGxvdDInKQ0KbGlicmFyeSgncGxvdGx5JykNCnRpdGxlIDwtICIwNjozMEFNIG9uIE1hci4gMTQsIDIwMTUgfiAwMDowMEFNIG9uIE1hci4gMTUsIDIwMTUiDQoNCnAgPC0gZ2dwbG90KGRmMl9kYXksIGFlcyh4ID0gZHQsIHkgPSBhbHQsIGNvbG9yID0gZmFjdG9yKHN1YnN0cmluZyhmbGlnaHQsMSwzKSkpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAxLzMpICsNCiAgbGFicyh4PSJEYXRlIFRpbWUiLCB5PSJBbHRpdHVkZSAtIE1pbGVzIiwgY29sb3VyID0gIkFpcmxpbmVzIiApICsNCiAgZ2d0aXRsZShwYXN0ZSh0aXRsZSkpIA0KZ2dwbG90bHkoKQ0KYGBgDQpGaWd1cmUgMy00LiBEZXNjZW50IHJhdGUgaW4gZGF5dGltZSBvbiBEZWMuIDEyLCAyMDE1DQoNCg0KDQojIyBDb25jbHVzaW9uOg0KVGhlIGZsaWdodCBwYXR0ZXJucyBzaWduaWZpY2FudGx5IGNoYW5nZWQgYmV0d2VlbiBNYXIuIDE0LCAyMDE1IGFuZCBEZWMuIDEyLCAyMDE1LiBUaGUgdG90YWwgbnVtYmVycyBvZiBmbGlnaHRzLCBhaXJsaW5lcyBjb21wYW5pZXMsIGRlbnNpdHkgb2YgcGF0aGVzIGFyZSBhbGwgaW5jcmVhc2VkIGFyb3VuZCBTTU9WT1IgYWNjb3JkaW5nIHRvIGFib3ZlIGZpZ3VyZXMuIFRvdGFsIGZsaWdodHMgaW5jcmVhc2UgZnJvbSA0MiB0byAxNTIgd2hpY2ggaXMgMzYyJSBncm93dGggcmF0ZSBjb21wYXJlIHdpdGggdGhlc2UgdHdvIGRhdGVzLg0KDQoNCiMjIFJlZmVyZW5jZSAmIFRvb2xzOg0KICAxLiBEYXRhIFNvdXJjZTogQWlycGxhbmUgdHJhbnNwb25kZXIgZGF0YSBwcm92aWRlZCBpbiBJTkY1NTQgY2xhc3MgYXQgVW5pdmVyc2l0eSBvZiBTb3V0aGVybiBDYWxpZm9ybmlhLg0KICAyLiBEYXRhIFdyYW5nbGluZzogU291cmNlIGNvZGUgcHJvdmlkZWQgYnkgaW5zdHJ1Y3RvciwgRHIuIEx1Y2lhbm8gTm9jZXJhLCBpbiBJTkY1NTQgY2xhc3MgYXQgVW5pdmVyc2l0eSBvZiBTb3V0aGVybiBDYWxpZm9ybmlhLiANCiAgMy4gVG9vbHM6IFIgQ29yZSBUZWFtICgyMDE3KS4gUjogQSBsYW5ndWFnZSBhbmQgZW52aXJvbm1lbnQgZm9yIHN0YXRpc3RpY2FsIGNvbXB1dGluZy4gUiBGb3VuZGF0aW9uIGZvciBTdGF0aXN0aWNhbCBDb21wdXRpbmcsIFZpZW5uYSwgQXVzdHJpYS4gVVJMIGh0dHBzOi8vd3d3LlItcHJvamVjdC5vcmcvLg0K