load_packages <- function(pkg_list) {
  for (pkg in pkg_list) {
    if (!require(pkg, character.only = TRUE)) {
      install.packages(pkg, dependencies = TRUE)
      library(pkg, character.only = TRUE)
    }
  }
}

packages <- c("tidyverse", "readxl", "pander", "forecast")
load_packages(packages)

knitr::opts_chunk$set(echo = TRUE,      
                      warning = FALSE,   
                      message = FALSE,  
                      results = TRUE,
                      comment = NA,
                      fig.align = "center"
                      )   
url <- "https://raw.githubusercontent.com/ncbrechbill/STA321/refs/heads/main/STA321/uspollution.csv"
pollutionus <- read.csv(url)

1 Introduction

The prevalence of air pollution and greenhouse gasses are commonly discussed in conversations about climate change. The several kinds of greenhouse gasses have been increasing and decreasing ever since the industrial revolution. This case study analyzes the family of Nitrogen Oxides (NOx’s). Nitrogen Oxides are released by vehicle emissions, power generation, and other combustion. These pollutants are responsible for a decrease in general air quality.

The 1990 Clean Air Act greatly reduced the emissions of several pollutants including Nitrogen Oxides. This greatly empowered the Environmental Protection Agency (EPA) to undertake several initiatives to reduce pollutant emissions.

1.1 Data Set

Historical Emmissions of pollutants was sourced from Kaggle.com (https://www.kaggle.com/datasets/snehasubramanian/world-pollution-1750-2019?resource=download). The data ranges back to 1750 until 2019 for countries across the world. For this study we focus on the United State’s emissions. The data set records several pollutants, but for this study we will currently observe only Nitrogen Oxide.

The collected information was:

  • Year

  • Nitrogen.Oxide

  • Sulphur.Dioxide

  • Carbon.Monoxide

  • Organic.Carbon

  • NMVOCs

  • Black.Carbon

  • Ammonia

  • Total: Sum of all emissions content.

1.2 Exploratory Data Analysis

With a glance, we can observe the impact of the 1970 Clean Air Act Amendment. When observing data before and after this point, we can see a profound change in direction.

pollution <- read_excel("~/WCU/Schoolwork/STA321/Time Series/country wise 1750 - 2019.xlsx")
pollutionus150 <- pollution %>%
  filter(Country == "United States") %>%
  slice_tail(n = 150) %>%
  select(-Country) %>%
  mutate(total = `Nitrogen Oxide` + `Sulphur Dioxide` + `Carbon Monoxide` + `Organic Carbon` + NMVOCs + `Black Carbon` + `Ammonia`)

nox150 <- ts(pollutionus150[,3],
          frequency = 1,
          start = 1870,
          end = 2019)
plot(nox150,
     xlab = "Year",
     ylab = "NOx Content",
     main = "Nox Content by Year")
abline(v = 1970, col = "darkred", lwd=2, lty=2)

Before 1970 (indicated by the red dashed line), NOx content was increasing steadily. The trend changes direction after the passing of the Clean Air Act, supporting evidence for it’s value and environmental impact.

For analysis moving forward, we will look at data from 1970 onward. This will give us a sufficient number of observations to work with and captures the more relevant negative trend. Values before 1970 are not relevant to forecasting because they capture a trend that is no longer relevant under the Clean Air Act.

2 Time Series Analysis

2.1 Recorded Data and Extracted Trend

The collected NOx data from 1970-2019 are presented in the plot below. The trend in extracted with a moving average and displayed without imputation (the trend does not continue past the threshold).

nox <- ts(pollutionus[,3],
          frequency = 1,
          start = 1970,
          end = 2019)
trend.nox <- ma(nox, order =10, centre = TRUE)
par(mar=c(2,2,2,2))
plot(nox, xlab="", ylab="", col="darkred", lwd =2)
title(main = "Extracted Trend from Nitrogen Oxide Content")
lines(trend.nox, lwd =2, col = "blue")
legend("topright", c("Original Series", "Trend Curve (Moving Average)"), lwd=rep(2,2),
       col=c("darkred", "blue"), bty="n")

2.2 Basic Forecasting Methods

We can use four basic forecasting methods to predict future NOx emissions.

  • Mean: The mean of all recorded values is forecasted.

  • Naive: The last recorded value is forecasted.

  • Seasonal Naive: The last recorded seasonal fluctuation is forecasted.

  • Random Walk with Drift: A line is created connecting the first and last observations. The forecasted predictions are an extension of this line.

Each method’s predicted values are displayed in the table and the plot below.

pred.mv = meanf(nox, h=15)$mean
pred.naive = naive(nox, h=15)$mean
pred.snaive = snaive(nox, h=15)$mean
pred.rwf = rwf(nox, h=15, drift=TRUE)$mean

pred.table = cbind(pred.mv = pred.mv,
                   pred.naive = pred.naive,
                   pred.snaive = pred.snaive,
                   pred.rwf = pred.rwf)
pander(pred.table, caption = "Farecasting Table")
Farecasting Table
  pred.mv pred.naive pred.snaive pred.rwf
2020 16728787 1921172 1921172 1375955
2021 16728787 1921172 1921172 830738
2022 16728787 1921172 1921172 285521
2023 16728787 1921172 1921172 -259696
2024 16728787 1921172 1921172 -804913
2025 16728787 1921172 1921172 -1350130
2026 16728787 1921172 1921172 -1895347
2027 16728787 1921172 1921172 -2440564
2028 16728787 1921172 1921172 -2985781
2029 16728787 1921172 1921172 -3530998
2030 16728787 1921172 1921172 -4076215
2031 16728787 1921172 1921172 -4621432
2032 16728787 1921172 1921172 -5166649
2033 16728787 1921172 1921172 -5711866
2034 16728787 1921172 1921172 -6257083
# Create a time index for forecasts
time_forecast <- time(nox)[length(nox)] + seq(1, length(pred.mv)) / frequency(nox)

# Plot original series
plot(nox, xlab = "Time", ylab = "NOx Content", col = "black", lwd = 2,
     main = "NOx Content with Forecasts",
     xlim = c(min(time(nox)), max(time_forecast)),
     ylim = c(0, max(nox)))


# Add forecasts
lines(time_forecast, pred.mv, col = "red", lwd = 2, lty = 2)
lines(time_forecast, pred.naive, col = "blue", lwd = 2, lty = 3)
lines(time_forecast, pred.snaive, col = "green", lwd = 2, lty = 4)
lines(time_forecast, pred.rwf, col = "purple", lwd = 2, lty = 5)

# Add legend
legend("topright",
       legend = c("Original", "Mean Forecast", "Naive", "Seasonal Naive", "Random Walk w/ Drift"),
       col = c("black", "red", "blue", "green", "purple"),
       lty = c(1, 2, 3, 4, 5), lwd = 2, bty = "n")

2.3 Discussion

These forecast methods are simple, and as such may miss some of the nuance of the true trend. For example, the Random Walk with Drift predicts a negative value by 2023. Additionally, the three other methods predict a constant emission every year (although we understand that the error variation increases with each year.) While these forecasts are either impossible or highly unlikely to become true, they are a useful starting point in understanding the trend of the data. For example, we can see that there is no seasonality in this data, which was expected with the recordings being annual.

We can conclude that the Clean Air Act of 1970 had a profound impact on the emissions the United States produces. There is an undeniable negative trend on the Nitrogen Oxide content.

LS0tDQp0aXRsZTogIlVTIE5pdHJvdXMgT3hpZGUgQ29udGVudCINCmF1dGhvcjogIk5vYWggQnJlY2hiaWxsIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfd2lkdGg6IDYNCiAgICBmaWdfaGVpZ2h0OiA2DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQplZGl0b3Jfb3B0aW9uczogDQogIG1hcmtkb3duOiANCiAgICB3cmFwOiA3Mg0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCi8qIENhc2NhZGluZyBTdHlsZSBTaGVldHMgKENTUykgaXMgYSBzdHlsZXNoZWV0IGxhbmd1YWdlIHVzZWQgdG8gZGVzY3JpYmUgdGhlIHByZXNlbnRhdGlvbiBvZiBhIGRvY3VtZW50IHdyaXR0ZW4gaW4gSFRNTCBvciBYTUwuIGl0IGlzIGEgc2ltcGxlIG1lY2hhbmlzbSBmb3IgYWRkaW5nIHN0eWxlIChlLmcuLCBmb250cywgY29sb3JzLCBzcGFjaW5nKSB0byBXZWIgZG9jdW1lbnRzLiAqLw0KDQpoMS50aXRsZSB7ICAvKiBUaXRsZSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgdGhlIHJlcG9ydCB0aXRsZSAqLw0KICBmb250LXNpemU6IDI0cHg7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGF1dGhvcnMgICovDQogIGZvbnQtc2l6ZTogMjBweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciB0aGUgZGF0ZSAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMSB7IC8qIEhlYWRlciAxIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgbGV2ZWwgMSBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDIgc2VjdGlvbiB0aXRsZSAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgMyBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgNCBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCmBgYA0KDQpgYGB7ciBwYWNrYWdlcywgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmxvYWRfcGFja2FnZXMgPC0gZnVuY3Rpb24ocGtnX2xpc3QpIHsNCiAgZm9yIChwa2cgaW4gcGtnX2xpc3QpIHsNCiAgICBpZiAoIXJlcXVpcmUocGtnLCBjaGFyYWN0ZXIub25seSA9IFRSVUUpKSB7DQogICAgICBpbnN0YWxsLnBhY2thZ2VzKHBrZywgZGVwZW5kZW5jaWVzID0gVFJVRSkNCiAgICAgIGxpYnJhcnkocGtnLCBjaGFyYWN0ZXIub25seSA9IFRSVUUpDQogICAgfQ0KICB9DQp9DQoNCnBhY2thZ2VzIDwtIGMoInRpZHl2ZXJzZSIsICJyZWFkeGwiLCAicGFuZGVyIiwgImZvcmVjYXN0IikNCmxvYWRfcGFja2FnZXMocGFja2FnZXMpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLCAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbiA9ICJjZW50ZXIiDQogICAgICAgICAgICAgICAgICAgICAgKSAgIA0KdXJsIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbmNicmVjaGJpbGwvU1RBMzIxL3JlZnMvaGVhZHMvbWFpbi9TVEEzMjEvdXNwb2xsdXRpb24uY3N2Ig0KcG9sbHV0aW9udXMgPC0gcmVhZC5jc3YodXJsKQ0KYGBgDQoNCiMgSW50cm9kdWN0aW9uDQoNClRoZSBwcmV2YWxlbmNlIG9mIGFpciBwb2xsdXRpb24gYW5kIGdyZWVuaG91c2UgZ2Fzc2VzIGFyZSBjb21tb25seQ0KZGlzY3Vzc2VkIGluIGNvbnZlcnNhdGlvbnMgYWJvdXQgY2xpbWF0ZSBjaGFuZ2UuIFRoZSBzZXZlcmFsIGtpbmRzIG9mDQpncmVlbmhvdXNlIGdhc3NlcyBoYXZlIGJlZW4gaW5jcmVhc2luZyBhbmQgZGVjcmVhc2luZyBldmVyIHNpbmNlIHRoZQ0KaW5kdXN0cmlhbCByZXZvbHV0aW9uLiBUaGlzIGNhc2Ugc3R1ZHkgYW5hbHl6ZXMgdGhlIGZhbWlseSBvZiBOaXRyb2dlbg0KT3hpZGVzIChOT3gncykuIE5pdHJvZ2VuIE94aWRlcyBhcmUgcmVsZWFzZWQgYnkgdmVoaWNsZSBlbWlzc2lvbnMsIHBvd2VyDQpnZW5lcmF0aW9uLCBhbmQgb3RoZXIgY29tYnVzdGlvbi4gVGhlc2UgcG9sbHV0YW50cyBhcmUgcmVzcG9uc2libGUgZm9yIGENCmRlY3JlYXNlIGluIGdlbmVyYWwgYWlyIHF1YWxpdHkuDQoNClRoZSAxOTkwIENsZWFuIEFpciBBY3QgZ3JlYXRseSByZWR1Y2VkIHRoZSBlbWlzc2lvbnMgb2Ygc2V2ZXJhbA0KcG9sbHV0YW50cyBpbmNsdWRpbmcgTml0cm9nZW4gT3hpZGVzLiBUaGlzIGdyZWF0bHkgZW1wb3dlcmVkIHRoZQ0KRW52aXJvbm1lbnRhbCBQcm90ZWN0aW9uIEFnZW5jeSAoRVBBKSB0byB1bmRlcnRha2Ugc2V2ZXJhbCBpbml0aWF0aXZlcw0KdG8gcmVkdWNlIHBvbGx1dGFudCBlbWlzc2lvbnMuDQoNCiMjIERhdGEgU2V0DQoNCkhpc3RvcmljYWwgRW1taXNzaW9ucyBvZiBwb2xsdXRhbnRzIHdhcyBzb3VyY2VkIGZyb20gS2FnZ2xlLmNvbQ0KKDxodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL3NuZWhhc3VicmFtYW5pYW4vd29ybGQtcG9sbHV0aW9uLTE3NTAtMjAxOT9yZXNvdXJjZT1kb3dubG9hZD4pLg0KVGhlIGRhdGEgcmFuZ2VzIGJhY2sgdG8gMTc1MCB1bnRpbCAyMDE5IGZvciBjb3VudHJpZXMgYWNyb3NzIHRoZSB3b3JsZC4NCkZvciB0aGlzIHN0dWR5IHdlIGZvY3VzIG9uIHRoZSBVbml0ZWQgU3RhdGUncyBlbWlzc2lvbnMuIFRoZSBkYXRhIHNldA0KcmVjb3JkcyBzZXZlcmFsIHBvbGx1dGFudHMsIGJ1dCBmb3IgdGhpcyBzdHVkeSB3ZSB3aWxsIGN1cnJlbnRseSBvYnNlcnZlDQpvbmx5IE5pdHJvZ2VuIE94aWRlLg0KDQpUaGUgY29sbGVjdGVkIGluZm9ybWF0aW9uIHdhczoNCg0KLSAgICoqWWVhcioqDQoNCi0gICAqKk5pdHJvZ2VuLk94aWRlKioNCg0KLSAgICoqU3VscGh1ci5EaW94aWRlKioNCg0KLSAgICoqQ2FyYm9uLk1vbm94aWRlKioNCg0KLSAgICoqT3JnYW5pYy5DYXJib24qKg0KDQotICAgKipOTVZPQ3MqKg0KDQotICAgKipCbGFjay5DYXJib24qKg0KDQotICAgKipBbW1vbmlhKioNCg0KLSAgICoqVG90YWw6KiogU3VtIG9mIGFsbCBlbWlzc2lvbnMgY29udGVudC4NCg0KIyMgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNpcw0KDQpXaXRoIGEgZ2xhbmNlLCB3ZSBjYW4gb2JzZXJ2ZSB0aGUgaW1wYWN0IG9mIHRoZSAxOTcwIENsZWFuIEFpciBBY3QNCkFtZW5kbWVudC4gV2hlbiBvYnNlcnZpbmcgZGF0YSBiZWZvcmUgYW5kIGFmdGVyIHRoaXMgcG9pbnQsIHdlIGNhbiBzZWUgYQ0KcHJvZm91bmQgY2hhbmdlIGluIGRpcmVjdGlvbi4NCg0KYGBge3J9DQpwb2xsdXRpb24gPC0gcmVhZF9leGNlbCgifi9XQ1UvU2Nob29sd29yay9TVEEzMjEvVGltZSBTZXJpZXMvY291bnRyeSB3aXNlIDE3NTAgLSAyMDE5Lnhsc3giKQ0KcG9sbHV0aW9udXMxNTAgPC0gcG9sbHV0aW9uICU+JQ0KICBmaWx0ZXIoQ291bnRyeSA9PSAiVW5pdGVkIFN0YXRlcyIpICU+JQ0KICBzbGljZV90YWlsKG4gPSAxNTApICU+JQ0KICBzZWxlY3QoLUNvdW50cnkpICU+JQ0KICBtdXRhdGUodG90YWwgPSBgTml0cm9nZW4gT3hpZGVgICsgYFN1bHBodXIgRGlveGlkZWAgKyBgQ2FyYm9uIE1vbm94aWRlYCArIGBPcmdhbmljIENhcmJvbmAgKyBOTVZPQ3MgKyBgQmxhY2sgQ2FyYm9uYCArIGBBbW1vbmlhYCkNCg0Kbm94MTUwIDwtIHRzKHBvbGx1dGlvbnVzMTUwWywzXSwNCiAgICAgICAgICBmcmVxdWVuY3kgPSAxLA0KICAgICAgICAgIHN0YXJ0ID0gMTg3MCwNCiAgICAgICAgICBlbmQgPSAyMDE5KQ0KcGxvdChub3gxNTAsDQogICAgIHhsYWIgPSAiWWVhciIsDQogICAgIHlsYWIgPSAiTk94IENvbnRlbnQiLA0KICAgICBtYWluID0gIk5veCBDb250ZW50IGJ5IFllYXIiKQ0KYWJsaW5lKHYgPSAxOTcwLCBjb2wgPSAiZGFya3JlZCIsIGx3ZD0yLCBsdHk9MikNCmBgYA0KDQpCZWZvcmUgMTk3MCAoaW5kaWNhdGVkIGJ5IHRoZSByZWQgZGFzaGVkIGxpbmUpLCBOT3ggY29udGVudCB3YXMNCmluY3JlYXNpbmcgc3RlYWRpbHkuIFRoZSB0cmVuZCBjaGFuZ2VzIGRpcmVjdGlvbiBhZnRlciB0aGUgcGFzc2luZyBvZg0KdGhlIENsZWFuIEFpciBBY3QsIHN1cHBvcnRpbmcgZXZpZGVuY2UgZm9yIGl0J3MgdmFsdWUgYW5kIGVudmlyb25tZW50YWwNCmltcGFjdC4NCg0KRm9yIGFuYWx5c2lzIG1vdmluZyBmb3J3YXJkLCB3ZSB3aWxsIGxvb2sgYXQgZGF0YSBmcm9tIDE5NzAgb253YXJkLiBUaGlzDQp3aWxsIGdpdmUgdXMgYSBzdWZmaWNpZW50IG51bWJlciBvZiBvYnNlcnZhdGlvbnMgdG8gd29yayB3aXRoIGFuZA0KY2FwdHVyZXMgdGhlIG1vcmUgcmVsZXZhbnQgbmVnYXRpdmUgdHJlbmQuIFZhbHVlcyBiZWZvcmUgMTk3MCBhcmUgbm90DQpyZWxldmFudCB0byBmb3JlY2FzdGluZyBiZWNhdXNlIHRoZXkgY2FwdHVyZSBhIHRyZW5kIHRoYXQgaXMgbm8gbG9uZ2VyDQpyZWxldmFudCB1bmRlciB0aGUgQ2xlYW4gQWlyIEFjdC4NCg0KIyBUaW1lIFNlcmllcyBBbmFseXNpcw0KDQojIyBSZWNvcmRlZCBEYXRhIGFuZCBFeHRyYWN0ZWQgVHJlbmQNCg0KVGhlIGNvbGxlY3RlZCBOT3ggZGF0YSBmcm9tIDE5NzAtMjAxOSBhcmUgcHJlc2VudGVkIGluIHRoZSBwbG90IGJlbG93Lg0KVGhlIHRyZW5kIGluIGV4dHJhY3RlZCB3aXRoIGEgbW92aW5nIGF2ZXJhZ2UgYW5kIGRpc3BsYXllZCB3aXRob3V0DQppbXB1dGF0aW9uICh0aGUgdHJlbmQgZG9lcyBub3QgY29udGludWUgcGFzdCB0aGUgdGhyZXNob2xkKS4NCg0KYGBge3J9DQpub3ggPC0gdHMocG9sbHV0aW9udXNbLDNdLA0KICAgICAgICAgIGZyZXF1ZW5jeSA9IDEsDQogICAgICAgICAgc3RhcnQgPSAxOTcwLA0KICAgICAgICAgIGVuZCA9IDIwMTkpDQp0cmVuZC5ub3ggPC0gbWEobm94LCBvcmRlciA9MTAsIGNlbnRyZSA9IFRSVUUpDQpwYXIobWFyPWMoMiwyLDIsMikpDQpwbG90KG5veCwgeGxhYj0iIiwgeWxhYj0iIiwgY29sPSJkYXJrcmVkIiwgbHdkID0yKQ0KdGl0bGUobWFpbiA9ICJFeHRyYWN0ZWQgVHJlbmQgZnJvbSBOaXRyb2dlbiBPeGlkZSBDb250ZW50IikNCmxpbmVzKHRyZW5kLm5veCwgbHdkID0yLCBjb2wgPSAiYmx1ZSIpDQpsZWdlbmQoInRvcHJpZ2h0IiwgYygiT3JpZ2luYWwgU2VyaWVzIiwgIlRyZW5kIEN1cnZlIChNb3ZpbmcgQXZlcmFnZSkiKSwgbHdkPXJlcCgyLDIpLA0KICAgICAgIGNvbD1jKCJkYXJrcmVkIiwgImJsdWUiKSwgYnR5PSJuIikNCmBgYA0KDQojIyBCYXNpYyBGb3JlY2FzdGluZyBNZXRob2RzDQoNCldlIGNhbiB1c2UgZm91ciBiYXNpYyBmb3JlY2FzdGluZyBtZXRob2RzIHRvIHByZWRpY3QgZnV0dXJlIE5PeA0KZW1pc3Npb25zLg0KDQotICAgKipNZWFuOioqIFRoZSBtZWFuIG9mIGFsbCByZWNvcmRlZCB2YWx1ZXMgaXMgZm9yZWNhc3RlZC4NCg0KLSAgICoqTmFpdmU6KiogVGhlIGxhc3QgcmVjb3JkZWQgdmFsdWUgaXMgZm9yZWNhc3RlZC4NCg0KLSAgICoqU2Vhc29uYWwgTmFpdmU6KiogVGhlIGxhc3QgcmVjb3JkZWQgc2Vhc29uYWwgZmx1Y3R1YXRpb24gaXMNCiAgICBmb3JlY2FzdGVkLg0KDQotICAgKipSYW5kb20gV2FsayB3aXRoIERyaWZ0OioqIEEgbGluZSBpcyBjcmVhdGVkIGNvbm5lY3RpbmcgdGhlIGZpcnN0DQogICAgYW5kIGxhc3Qgb2JzZXJ2YXRpb25zLiBUaGUgZm9yZWNhc3RlZCBwcmVkaWN0aW9ucyBhcmUgYW4gZXh0ZW5zaW9uDQogICAgb2YgdGhpcyBsaW5lLg0KDQpFYWNoIG1ldGhvZCdzIHByZWRpY3RlZCB2YWx1ZXMgYXJlIGRpc3BsYXllZCBpbiB0aGUgdGFibGUgYW5kIHRoZSBwbG90DQpiZWxvdy4NCg0KYGBge3J9DQpwcmVkLm12ID0gbWVhbmYobm94LCBoPTE1KSRtZWFuDQpwcmVkLm5haXZlID0gbmFpdmUobm94LCBoPTE1KSRtZWFuDQpwcmVkLnNuYWl2ZSA9IHNuYWl2ZShub3gsIGg9MTUpJG1lYW4NCnByZWQucndmID0gcndmKG5veCwgaD0xNSwgZHJpZnQ9VFJVRSkkbWVhbg0KDQpwcmVkLnRhYmxlID0gY2JpbmQocHJlZC5tdiA9IHByZWQubXYsDQogICAgICAgICAgICAgICAgICAgcHJlZC5uYWl2ZSA9IHByZWQubmFpdmUsDQogICAgICAgICAgICAgICAgICAgcHJlZC5zbmFpdmUgPSBwcmVkLnNuYWl2ZSwNCiAgICAgICAgICAgICAgICAgICBwcmVkLnJ3ZiA9IHByZWQucndmKQ0KcGFuZGVyKHByZWQudGFibGUsIGNhcHRpb24gPSAiRmFyZWNhc3RpbmcgVGFibGUiKQ0KDQojIENyZWF0ZSBhIHRpbWUgaW5kZXggZm9yIGZvcmVjYXN0cw0KdGltZV9mb3JlY2FzdCA8LSB0aW1lKG5veClbbGVuZ3RoKG5veCldICsgc2VxKDEsIGxlbmd0aChwcmVkLm12KSkgLyBmcmVxdWVuY3kobm94KQ0KDQojIFBsb3Qgb3JpZ2luYWwgc2VyaWVzDQpwbG90KG5veCwgeGxhYiA9ICJUaW1lIiwgeWxhYiA9ICJOT3ggQ29udGVudCIsIGNvbCA9ICJibGFjayIsIGx3ZCA9IDIsDQogICAgIG1haW4gPSAiTk94IENvbnRlbnQgd2l0aCBGb3JlY2FzdHMiLA0KICAgICB4bGltID0gYyhtaW4odGltZShub3gpKSwgbWF4KHRpbWVfZm9yZWNhc3QpKSwNCiAgICAgeWxpbSA9IGMoMCwgbWF4KG5veCkpKQ0KDQoNCiMgQWRkIGZvcmVjYXN0cw0KbGluZXModGltZV9mb3JlY2FzdCwgcHJlZC5tdiwgY29sID0gInJlZCIsIGx3ZCA9IDIsIGx0eSA9IDIpDQpsaW5lcyh0aW1lX2ZvcmVjYXN0LCBwcmVkLm5haXZlLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIsIGx0eSA9IDMpDQpsaW5lcyh0aW1lX2ZvcmVjYXN0LCBwcmVkLnNuYWl2ZSwgY29sID0gImdyZWVuIiwgbHdkID0gMiwgbHR5ID0gNCkNCmxpbmVzKHRpbWVfZm9yZWNhc3QsIHByZWQucndmLCBjb2wgPSAicHVycGxlIiwgbHdkID0gMiwgbHR5ID0gNSkNCg0KIyBBZGQgbGVnZW5kDQpsZWdlbmQoInRvcHJpZ2h0IiwNCiAgICAgICBsZWdlbmQgPSBjKCJPcmlnaW5hbCIsICJNZWFuIEZvcmVjYXN0IiwgIk5haXZlIiwgIlNlYXNvbmFsIE5haXZlIiwgIlJhbmRvbSBXYWxrIHcvIERyaWZ0IiksDQogICAgICAgY29sID0gYygiYmxhY2siLCAicmVkIiwgImJsdWUiLCAiZ3JlZW4iLCAicHVycGxlIiksDQogICAgICAgbHR5ID0gYygxLCAyLCAzLCA0LCA1KSwgbHdkID0gMiwgYnR5ID0gIm4iKQ0KDQpgYGANCg0KIyMgRGlzY3Vzc2lvbg0KDQpUaGVzZSBmb3JlY2FzdCBtZXRob2RzIGFyZSBzaW1wbGUsIGFuZCBhcyBzdWNoIG1heSBtaXNzIHNvbWUgb2YgdGhlDQpudWFuY2Ugb2YgdGhlIHRydWUgdHJlbmQuIEZvciBleGFtcGxlLCB0aGUgUmFuZG9tIFdhbGsgd2l0aCBEcmlmdA0KcHJlZGljdHMgYSBuZWdhdGl2ZSB2YWx1ZSBieSAyMDIzLiBBZGRpdGlvbmFsbHksIHRoZSB0aHJlZSBvdGhlciBtZXRob2RzDQpwcmVkaWN0IGEgY29uc3RhbnQgZW1pc3Npb24gZXZlcnkgeWVhciAoYWx0aG91Z2ggd2UgdW5kZXJzdGFuZCB0aGF0IHRoZQ0KZXJyb3IgdmFyaWF0aW9uIGluY3JlYXNlcyB3aXRoIGVhY2ggeWVhci4pIFdoaWxlIHRoZXNlIGZvcmVjYXN0cyBhcmUNCmVpdGhlciBpbXBvc3NpYmxlIG9yIGhpZ2hseSB1bmxpa2VseSB0byBiZWNvbWUgdHJ1ZSwgdGhleSBhcmUgYSB1c2VmdWwNCnN0YXJ0aW5nIHBvaW50IGluIHVuZGVyc3RhbmRpbmcgdGhlIHRyZW5kIG9mIHRoZSBkYXRhLiBGb3IgZXhhbXBsZSwgd2UNCmNhbiBzZWUgdGhhdCB0aGVyZSBpcyBubyBzZWFzb25hbGl0eSBpbiB0aGlzIGRhdGEsIHdoaWNoIHdhcyBleHBlY3RlZA0Kd2l0aCB0aGUgcmVjb3JkaW5ncyBiZWluZyBhbm51YWwuDQoNCldlIGNhbiBjb25jbHVkZSB0aGF0IHRoZSBDbGVhbiBBaXIgQWN0IG9mIDE5NzAgaGFkIGEgcHJvZm91bmQgaW1wYWN0IG9uDQp0aGUgZW1pc3Npb25zIHRoZSBVbml0ZWQgU3RhdGVzIHByb2R1Y2VzLiBUaGVyZSBpcyBhbiB1bmRlbmlhYmxlDQpuZWdhdGl2ZSB0cmVuZCBvbiB0aGUgTml0cm9nZW4gT3hpZGUgY29udGVudC4NCg==