1. Introduction

For this project we have chosen to analyse and forecast on the air quality of the city of Madrid, Spain. In the dataset there are many types of pollutants present in the air but we have chosen to focus on the levels of the ozone gas in the air. High ozone levels can lead to breating difficulty, lung damage and aggravate existing lung diseases. As such we feel this is an important variable to monitor. To determine the severity of the future damage caused by this gas we will be forecasting the levels for the next 10 months.

2. The Data

The dataset used in this forecasting report is ’Air Quality of Madrid (2001 - 2018), it contains several measurements for air pollutants, among them the one variable we are interested in, the ozone level.

Source: https://www.kaggle.com/decide-soluciones/air-quality-madrid

3. Packages

Below are the packages that will be used to conduct this analysis.

library(readr)
library(x12)
library(dynlm)
library(dLagM)
library(forecast)
library(AER)
library(ggplot2)
library(TSA)
library(Hmisc)
library(tseries)
library(dplyr)

4. Preparing the Data

First we need to load up the 18 datasets that will be used. Each dataset corresponds to a year between 2001 and 2018.

year2001 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2001.csv")
year2002 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2002.csv")
year2003 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2003.csv")
year2004 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2004.csv")
year2005 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2005.csv")
year2006 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2006.csv")
year2007 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2007.csv")
year2008 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2008.csv")
year2009 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2009.csv")
year2010 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2010.csv")
year2011 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2011.csv")
year2012 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2012.csv")
year2013 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2013.csv")
year2014 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2014.csv")
year2015 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2015.csv")
year2016 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2016.csv")
year2017 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2017.csv")
year2018 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2018.csv")
stations <- read_csv("air-quality-madrid/stations.csv")

Next we need to modify the format of the date column in order to use them as time series data later.

Then we combine all 18 datasets using the rbind() function to generate the final dataset we will use for our analysis and forecasting. Preview of the final dataset below:

5. Visualisation

In this section we will begin by visualising the daily ozone levels for Madrid in Figure 1 to get a general idea of how the levels vary.

For the sake of predicting the ozone levels 10 months ahead, we will be converting the values to a monthly figure, the mean ozone levels for the month, and visualising again to better suit the goal of this project. Figure 2 provides the monthly ozone levels at 6 month intervals for the years 2001 to 2018.

6. Time Series Analysis

With basic visualisations complete, time series analysis can now be conducted on the final dataset. First, the dataset is converted to a time series and then an initial visualisation (Figure 3) is done to look for any obvious characteristics.

From figure 3 an obvious seasonal trend can be observed based on the behaviour of the points throughout the years. It can also be observed that the months July and August contain the highest ozone levels whereas December has the lowest levels over the time period. No notable intervention points observed. There is a changing variance with the mean, along with a large fluctuation and auto-regressive hehaviour.

6.1 Checking for Stationarity

Using an ADF test we shall determine if the dataset is stationary or not.

As the above result shows, the p value indicates this time series is stationary.

6.2 ACF, PACF & First Decomposition

From figure 3, there is already an observed seasonality for the dataset but just to be sure, an ACF and PACF plot will be made to check (Figure 4 & 5).

From the above figures we can see that there is in fact seasonality within the dataset.

Next we apply the x12 Decomposition to observe the decomposed lines.

There is auto-regressive behaviour which fluctuates around the mean and is present in the figure acroos the entire time series.

From figure 6, the seasonally adjusted keeps along with the trend and orginal trend but with some flucuations, which indicates the seasonality is not completey removed. Therefore, extra differencing is required. Manwhile, it is hard to conclude the exsistence of multi-seasonality beaviour. Furthermore, there is evidence the trend slighlty increases with time. The trend effect will be investigated in the next part.

6.3 Further Decomposition

First an STL decomposition was run on the time series to observe the factors of the time series seperately (Figure 7). Then in Figure 8, the seasonal component is extracted and plotted, showing a much more obvious trend pattern emerging in the time series. Following Figure 8, the trend component is removed as well giving us Figure 9 in which we can see that the fluctuations around the mean are more equal throughout the years and using an ADF test, the time series is concluded to be stationary.

7. Model Fitting

Model fitting will be divided into multiple sections with each section corresponding to specific types of models. Results from the MASE and AIC will be summarised in a table at the bottom in order to determine which model is the most accurate amongst the different types of models.

7.1 Dynamic Linear Models

Model Name AIC MASE
\(model.dynlm1\) 1231.498 0.4039228
\(model.dynlm1.2\) 1263.965 0.4313237
\(model.dynlm1.3\) 1561.645 0.9858214
\(model.dynlm2\) 1255.370 0.4322566
\(model.dynlm4\) 1245.226 0.4173508

From the table and based on the AIC, BIC and MASE results, model.dynlm1 is the best model as it has the lowest AIC, BIC and MASE.

However, from the residuals, there is one significant value in the acf and the tails of the residuals histogram are a bit longer than we would prefer and it shows to be random in the line chart in the residuals check.

7.2 Exponential Smoothing Models

Model Name AIC MASE
\(model.simple\) 2112.865 1.649948
\(model.hw1\) 1778.609 0.687281
\(model.hw2\) 1779.762 0.684349
\(model.hw3\) 1814.686 0.697647
\(model.hw4\) 1829.954 0.707525

From the table above, we can see that the best model is model.hw2 which is the Damped Holt-Winters’ additive method with a MASE value of 0.6843495. Looking at the residuals as well, the histogram appears mostly normal with short tails, there are only 2 significant values in the ACF and the line chart shows equal variances around the mean.

7.3 State-Space Models

Model Name AIC MASE
\(model.ANA\) 1775.858 0.6847280
\(model.AAA\) 1778.488 0.6872814
\(model.AAdA.damped\) 1779.938 0.6843495
\(model.ANN\) 2112.889 1.6495840
\(model.MAM\) 1815.027 0.6918962
\(model.MAM.damped\) 1815.027 0.6918962
\(model.MMM\) 1814.531 0.6919849
\(model.MMdM\) 1814.531 0.6919849
\(model.ZZZ\) 1775.858 0.6847280

From the table above the best model is model.ANA which uses the state space ANA model and has the lowest AIC, BIC and MASE values among the other models. Looking at the residuals, there are 2 significant values in the ACF, the histograms appears mostly normal but with some long tails and the line plot has an almost constant variance around the mean.

8. Model selection for Forecasting

Taking the best models from each modelling category, we will now compare them in the table below.

Model Name AIC MASE
\(model.dynlm1\) 1231.498 0.4039228
\(model.hw2\) 1779.762 0.684349
\(model.ANA\) 1775.858 0.6847280

Finally, from the table above comparing the best models from each category, we have now determined that the best model to use for forecasting is the dynamic linear model, model.dynlm1.

9. Forecasting

Below is the 10 Month ahead forecast of Ozone levels in the City of Madrid using the selected dynamic linear model.

10. Conclusion

To conclude, out of the three modelling techniques applied, our best model resulted from a dynamic linear model with a lag of 1 and the trend and seasonal components added as it resulted in the lowest AIC and MASE values out of all the models.

Based on the forecast above, we are expecting to see an increase in ozone levels for the city of Madrid in the next 10 months, as expected, and residents should take steps to guard themselves against the potential hazards the gas presents and potentially make efforts to enact changes to reduce ozone gas levels for the future.

11. Code

#3
library(readr)
library(x12)
library(dynlm)
library(dLagM)
library(forecast)
library(AER)
library(ggplot2)
library(TSA)
library(Hmisc)
library(tseries)
library(dplyr)

#4
year2001 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2001.csv")
year2002 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2002.csv")
year2003 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2003.csv")
year2004 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2004.csv")
year2005 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2005.csv")
year2006 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2006.csv")
year2007 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2007.csv")
year2008 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2008.csv")
year2009 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2009.csv")
year2010 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2010.csv")
year2011 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2011.csv")
year2012 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2012.csv")
year2013 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2013.csv")
year2014 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2014.csv")
year2015 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2015.csv")
year2016 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2016.csv")
year2017 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2017.csv")
year2018 <- read_csv("air-quality-madrid/csvs_per_year/madrid_2018.csv")
stations <- read_csv("air-quality-madrid/stations.csv")

##Change date format and selecting the O3 variables (pollutants)
##Since the date format is in **factor type**, I change those type into Posixct and selecting only O3 variables.

year2001$date <- as.POSIXct(year2001$date, format = "%Y-%m-%d %H:%M:%S")
year2001$Date <- format(year2001$date, "%Y-%m-%d")
year2001$Time <- format(year2001$date, "%T")
year2001$Date <- as.POSIXct(year2001$Date, format = "%Y-%m-%d")

year2001$day <- format(year2001$date, "%d")
year2001$month <- format(year2001$date, "%m")
year2001$year <- format(year2001$date, "%Y")
year2001$hour <- format(year2001$date, "%H")

m2001 <- year2001 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2002$date <- as.POSIXct(year2002$date, format = "%Y-%m-%d %H:%M:%S")
year2002$Date <- format(year2002$date, "%Y-%m-%d")
year2002$Time <- format(year2002$date, "%T")
year2002$Date <- as.POSIXct(year2002$Date, format = "%Y-%m-%d")

year2002$day <- format(year2002$date, "%d")
year2002$month <- format(year2002$date, "%m")
year2002$year <- format(year2002$date, "%Y")
year2002$hour <- format(year2002$date, "%H")

m2002 <- year2002 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2003$date <- as.POSIXct(year2003$date, format = "%Y-%m-%d %H:%M:%S")
year2003$Date <- format(year2003$date, "%Y-%m-%d")
year2003$Time <- format(year2003$date, "%T")
year2003$Date <- as.POSIXct(year2003$Date, format = "%Y-%m-%d")

year2003$day <- format(year2003$date, "%d")
year2003$month <- format(year2003$date, "%m")
year2003$year <- format(year2003$date, "%Y")
year2003$hour <- format(year2003$date, "%H")

m2003 <- year2003 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2004$date <- as.POSIXct(year2004$date, format = "%Y-%m-%d %H:%M:%S")
year2004$Date <- format(year2004$date, "%Y-%m-%d")
year2004$Time <- format(year2004$date, "%T")
year2004$Date <- as.POSIXct(year2004$Date, format = "%Y-%m-%d")

year2004$day <- format(year2004$date, "%d")
year2004$month <- format(year2004$date, "%m")
year2004$year <- format(year2004$date, "%Y")
year2004$hour <- format(year2004$date, "%H")

m2004 <- year2004 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2005$date <- as.POSIXct(year2005$date, format = "%Y-%m-%d %H:%M:%S")
year2005$Date <- format(year2005$date, "%Y-%m-%d")
year2005$Time <- format(year2005$date, "%T")
year2005$Date <- as.POSIXct(year2005$Date, format = "%Y-%m-%d")

year2005$day <- format(year2005$date, "%d")
year2005$month <- format(year2005$date, "%m")
year2005$year <- format(year2005$date, "%Y")
year2005$hour <- format(year2005$date, "%H")

m2005 <- year2005 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2006$date <- as.POSIXct(year2006$date, format = "%Y-%m-%d %H:%M:%S")
year2006$Date <- format(year2006$date, "%Y-%m-%d")
year2006$Time <- format(year2006$date, "%T")
year2006$Date <- as.POSIXct(year2006$Date, format = "%Y-%m-%d")

year2006$day <- format(year2006$date, "%d")
year2006$month <- format(year2006$date, "%m")
year2006$year <- format(year2006$date, "%Y")
year2006$hour <- format(year2006$date, "%H")

m2006 <- year2006 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2007$date <- as.POSIXct(year2007$date, format = "%Y-%m-%d %H:%M:%S")
year2007$Date <- format(year2007$date, "%Y-%m-%d")
year2007$Time <- format(year2007$date, "%T")
year2007$Date <- as.POSIXct(year2007$Date, format = "%Y-%m-%d")

year2007$day <- format(year2007$date, "%d")
year2007$month <- format(year2007$date, "%m")
year2007$year <- format(year2007$date, "%Y")
year2007$hour <- format(year2007$date, "%H")

m2007 <- year2007 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2008$date <- as.POSIXct(year2008$date, format = "%Y-%m-%d %H:%M:%S")
year2008$Date <- format(year2008$date, "%Y-%m-%d")
year2008$Time <- format(year2008$date, "%T")
year2008$Date <- as.POSIXct(year2008$Date, format = "%Y-%m-%d")

year2008$day <- format(year2008$date, "%d")
year2008$month <- format(year2008$date, "%m")
year2008$year <- format(year2008$date, "%Y")
year2008$hour <- format(year2008$date, "%H")

m2008 <- year2008 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2009$date <- as.POSIXct(year2009$date, format = "%Y-%m-%d %H:%M:%S")
year2009$Date <- format(year2009$date, "%Y-%m-%d")
year2009$Time <- format(year2009$date, "%T")
year2009$Date <- as.POSIXct(year2009$Date, format = "%Y-%m-%d")

year2009$day <- format(year2009$date, "%d")
year2009$month <- format(year2009$date, "%m")
year2009$year <- format(year2009$date, "%Y")
year2009$hour <- format(year2009$date, "%H")

m2009 <- year2009 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2010$date <- as.POSIXct(year2010$date, format = "%Y-%m-%d %H:%M:%S")
year2010$Date <- format(year2010$date, "%Y-%m-%d")
year2010$Time <- format(year2010$date, "%T")
year2010$Date <- as.POSIXct(year2010$Date, format = "%Y-%m-%d")

year2010$day <- format(year2010$date, "%d")
year2010$month <- format(year2010$date, "%m")
year2010$year <- format(year2010$date, "%Y")
year2010$hour <- format(year2010$date, "%H")

m2010 <- year2010 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2011$date <- as.POSIXct(year2011$date, format = "%Y-%m-%d %H:%M:%S")
year2011$Date <- format(year2011$date, "%Y-%m-%d")
year2011$Time <- format(year2011$date, "%T")
year2011$Date <- as.POSIXct(year2011$Date, format = "%Y-%m-%d")

year2011$day <- format(year2011$date, "%d")
year2011$month <- format(year2011$date, "%m")
year2011$year <- format(year2011$date, "%Y")
year2011$hour <- format(year2011$date, "%H")

m2011 <- year2011 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2012$date <- as.POSIXct(year2012$date, format = "%Y-%m-%d %H:%M:%S")
year2012$Date <- format(year2012$date, "%Y-%m-%d")
year2012$Time <- format(year2012$date, "%T")
year2012$Date <- as.POSIXct(year2012$Date, format = "%Y-%m-%d")

year2012$day <- format(year2012$date, "%d")
year2012$month <- format(year2012$date, "%m")
year2012$year <- format(year2012$date, "%Y")
year2012$hour <- format(year2012$date, "%H")

m2012 <- year2012 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2013$date <- as.POSIXct(year2013$date, format = "%Y-%m-%d %H:%M:%S")
year2013$Date <- format(year2013$date, "%Y-%m-%d")
year2013$Time <- format(year2013$date, "%T")
year2013$Date <- as.POSIXct(year2013$Date, format = "%Y-%m-%d")

year2013$day <- format(year2013$date, "%d")
year2013$month <- format(year2013$date, "%m")
year2013$year <- format(year2013$date, "%Y")
year2013$hour <- format(year2013$date, "%H")

m2013 <- year2013 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2014$date <- as.POSIXct(year2014$date, format = "%Y-%m-%d %H:%M:%S")
year2014$Date <- format(year2014$date, "%Y-%m-%d")
year2014$Time <- format(year2014$date, "%T")
year2014$Date <- as.POSIXct(year2014$Date, format = "%Y-%m-%d")

year2014$day <- format(year2014$date, "%d")
year2014$month <- format(year2014$date, "%m")
year2014$year <- format(year2014$date, "%Y")
year2014$hour <- format(year2014$date, "%H")

m2014 <- year2014 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2015$date <- as.POSIXct(year2015$date, format = "%Y-%m-%d %H:%M:%S")
year2015$Date <- format(year2015$date, "%Y-%m-%d")
year2015$Time <- format(year2015$date, "%T")
year2015$Date <- as.POSIXct(year2015$Date, format = "%Y-%m-%d")

year2015$day <- format(year2015$date, "%d")
year2015$month <- format(year2015$date, "%m")
year2015$year <- format(year2015$date, "%Y")
year2015$hour <- format(year2015$date, "%H")

m2015 <- year2015 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2016$date <- as.POSIXct(year2016$date, format = "%Y-%m-%d %H:%M:%S")
year2016$Date <- format(year2016$date, "%Y-%m-%d")
year2016$Time <- format(year2016$date, "%T")
year2016$Date <- as.POSIXct(year2016$Date, format = "%Y-%m-%d")

year2016$day <- format(year2016$date, "%d")
year2016$month <- format(year2016$date, "%m")
year2016$year <- format(year2016$date, "%Y")
year2016$hour <- format(year2016$date, "%H")

m2016 <- year2016 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2017$date <- as.POSIXct(year2017$date, format = "%Y-%m-%d %H:%M:%S")
year2017$Date <- format(year2017$date, "%Y-%m-%d")
year2017$Time <- format(year2017$date, "%T")
year2017$Date <- as.POSIXct(year2017$Date, format = "%Y-%m-%d")

year2017$day <- format(year2017$date, "%d")
year2017$month <- format(year2017$date, "%m")
year2017$year <- format(year2017$date, "%Y")
year2017$hour <- format(year2017$date, "%H")

m2017 <- year2017 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)


year2018$date <- as.POSIXct(year2018$date, format = "%Y-%m-%d %H:%M:%S")
year2018$Date <- format(year2018$date, "%Y-%m-%d")
year2018$Time <- format(year2018$date, "%T")
year2018$Date <- as.POSIXct(year2018$Date, format = "%Y-%m-%d")

year2018$day <- format(year2018$date, "%d")
year2018$month <- format(year2018$date, "%m")
year2018$year <- format(year2018$date, "%Y")
year2018$hour <- format(year2018$date, "%H")

m2018 <- year2018 %>%
  select(date, Date, Time, day, month, year, hour, station, O_3)

madrid <- m2001 %>%
  rbind(m2002) %>%
  rbind(m2003) %>%
  rbind(m2004) %>%
  rbind(m2005) %>%
  rbind(m2006) %>%
  rbind(m2007) %>%
  rbind(m2008) %>%
  rbind(m2009) %>%
  rbind(m2010) %>%
  rbind(m2011) %>%
  rbind(m2012) %>%
  rbind(m2013) %>%
  rbind(m2014) %>%
  rbind(m2015) %>%
  rbind(m2016) %>%
  rbind(m2017) %>%
  rbind(m2018) 

radarstations <- stations %>% select(id, name)
madrid <-  right_join(madrid, radarstations, by = c("station" = "id"))
print(head(madrid))

#5
madrid_mean_daily <- madrid %>% group_by(Date) %>% summarise(O_3_mean = mean(O_3, na.rm = TRUE))
ggplot(madrid_mean_daily, aes(x = as.Date(Date), y = O_3_mean)) + geom_line(color = 'blue') +
  theme_bw() +
  labs(x = 'Year', y = 'Ozone Level (μg/m3)', title='Daily Ozone Levels in Madrid (Figure 1)') +
  theme(axis.text.x=element_text(size=10)) +
  scale_x_date(breaks = seq(as.Date("2001-01-01"), as.Date("2018-07-01"), by="12 months"), date_labels = "%Y")

madrid_mean_monthly <- madrid %>% group_by(year, month) %>% summarise( O_3_mean = mean(O_3, na.rm = TRUE))%>% mutate(time = paste(year, "-", month, "- 01"))

madrid_mean_monthly$time <- as.Date(madrid_mean_monthly$time, format = "%Y - %m - %d")

ggplot(madrid_mean_monthly, aes(x = time, y = O_3_mean)) + geom_line(color = 'blue') + 
  theme_bw() + 
  theme(axis.text.x = element_text(angle = 90)) +
  labs(x = 'Month', y = 'Ozone Level (μg/m3)', title='Monthly Ozone Levels in Madrid (Figure 2)') +
  theme(axis.text.x=element_text(size=10)) +
  scale_x_date(breaks = seq(as.Date("2001-01-01"), as.Date("2018-07-01"), by="6 months"), date_labels = "%b-%y") 

#6
dummy1 <- as.vector(madrid_mean_monthly$O_3_mean)
madrid.ts <- ts(dummy1,start = c(2001,1), end = c(2018,5), frequency = 12)

plot(madrid.ts, ylab="Ozone Level (μg/m3)", main = "Time series plot for O3 (Figure 3)")
points(y=madrid.ts, x=time(madrid.ts), pch = as.vector(season(madrid.ts)))

#6.1
adf.test(madrid.ts)

#6.2
par(mfrow= c(1,2))
acf(madrid.ts, main = "Figure 4")
pacf(madrid.ts, main = "Figure 5")

#6.3
#Using seasonal differencing
fit.madrid <- stl(madrid.ts, t.window=15, s.window="periodic", robust=TRUE)
plot(fit.madrid, main = "Figure 7")
fit.madrid.seasonal = fit.madrid$time.series[,"seasonal"] 

#Extract the seansonal component from the output
madrid.seasonal.adjusted = madrid.ts - fit.madrid.seasonal
plot(madrid.seasonal.adjusted,xlab='Time', ylab ='Ozone Levels (μg/m3)', main = "Seasonal adjusted time series (Figure 8)")
points(y=madrid.seasonal.adjusted,x=time(madrid.seasonal.adjusted), pch=as.vector(season(madrid.seasonal.adjusted)))

#Extract the trend component from the output
fit.madrid.trend = fit.madrid$time.series[,"trend"] 
madrid.seasonal.trend.adjusted = madrid.ts - fit.madrid.seasonal - fit.madrid.trend
plot(madrid.seasonal.trend.adjusted,xlab='Time', ylab ='Ozone Level (μg/m3)', main = "Trend & seasonal adjusted time series (Figure 9)")
points(y=madrid.seasonal.trend.adjusted,x=time(madrid.seasonal.trend.adjusted), pch=as.vector(season(madrid.seasonal.trend.adjusted)))

adf.test(madrid.seasonal.trend.adjusted)

#7.1
#Dynlm Models
Y.t = madrid.ts

model.dynlm1 = dynlm(Y.t ~ L(Y.t , k = 1 ) + trend(Y.t) + season(Y.t))

model.dynlm2 = dynlm(Y.t ~ L(Y.t , k = 2 ) + trend(Y.t) + season(Y.t))

model.dynlm3 = dynlm(Y.t ~ L(Y.t , k = 1 ) + trend(Y.t) + season(Y.t)) #MASE 0.403897   

model.dynlm1.2 = dynlm(Y.t ~ L(Y.t , k = 1 ) + season(Y.t)) 

model.dynlm1.3 = dynlm(Y.t ~ L(Y.t , k = 1 ) + trend(Y.t))

model.dynlm4.1 = dynlm(Y.t ~ L(Y.t , k = 1 ) + L(Y.t , k = 2 )+ season(Y.t))

model.dynlm4.2 = dynlm(Y.t ~ L(Y.t , k = 1 ) + L(Y.t , k = 2 ) + season(Y.t))

#Creating table summary of model results
aic = AIC(model.dynlm1, model.dynlm1.2, model.dynlm1.3,model.dynlm2,model.dynlm3,model.dynlm4.1,model.dynlm4.2)
bic = BIC(model.dynlm1, model.dynlm1.2, model.dynlm1.3,model.dynlm2,model.dynlm3,model.dynlm4.1,model.dynlm4.2)
mase = MASE(lm(model.dynlm1), lm(model.dynlm1.2), lm(model.dynlm1.3),lm(model.dynlm2),lm(model.dynlm3),lm(model.dynlm4.1),lm(model.dynlm4.2))

dynlm_table <- cbind(aic,bic,mase)
dynlm_table
#Best model is model.dynlm1
summary(model.dynlm1)
checkresiduals(model.dynlm1)

#7.2
model.simple <- ses(madrid.ts,h=2*frequency(madrid.ts))#MASE 1.649948

model.hw1 <- hw(madrid.ts,seasonal="additive") #MASE 0.6872814 

model.hw2 <- hw(madrid.ts,seasonal="additive",damped = TRUE) #MASE 0.6843495 

model.hw3 <- hw(madrid.ts,seasonal="multiplicative") #MASE 0.6976475 

model.hw4 <- hw(madrid.ts,seasonal="multiplicative",exponential = TRUE) #MASE 0.7075254 

#Table creation
name_es <- c("model.simple","model.hw1","model.hw2","model.hw3","model.hw4")
mase_es <- c(1.649948,0.687281,0.684349,0.697647,0.707525)

table_es <- as.data.frame(cbind(name_es,mase_es))
table_es
#Best model is model.hw2
summary(model.hw2)
checkresiduals(model.hw2)

#7.3
model.ANA = ets(madrid.ts,model = "ANA") #MASE 0.684728

model.AAA = ets(madrid.ts,model = "AAA")#MASE 0.6872814

model.AAdA.damped = ets(madrid.ts,model = "AAA",damped = TRUE) #MASE 0.6843495

model.ANN = ets(madrid.ts,model = "ANN")#MASE 1.649584 

model.MAM = ets(madrid.ts,model = "MAM")#MASE 0.6918962

model.MAM.damped = ets(madrid.ts,model = "MAM",damped = TRUE) #MASE 0.6918962

model.MMM = ets(madrid.ts,model = "MMM")#MASE 0.6919849

model.MMdM = ets(madrid.ts,model = "MMM",damped = TRUE) #MASE 0.6919849

model.ZZZ = ets(madrid.ts, model="ZZZ")##MASE 0.684728

#Table creation
aic_ss <- AIC(model.ANA, model.AAA, model.AAdA.damped, model.ANN, model.MAM, model.MAM.damped, model.MMM, model.MMdM, model.ZZZ)
bic_ss <- BIC(model.ANA, model.AAA, model.AAdA.damped, model.ANN, model.MAM, model.MAM.damped, model.MMM, model.MMdM, model.ZZZ)
mase_ss <- c(0.684728,0.6872814,0.6843495,1.649584,0.6918962,0.6918962,0.6919849,0.6919849,0.684728)
table_ss <- as.data.frame(cbind(aic_ss,bic_ss,mase_ss))
table_ss
#Best model is model.ANA
summary(model.ANA)
checkresiduals(model.ANA)

#8
#Table creation for final model selection

model_final <- c("model.dynlm1", "model.hw2", "model.ANA")
type_final <- c("Dynamic Linear", "Exponential Smoothing", "State-Space")
aic_final <- c(1231.498, "NA", 1775.858)
bic_final <- c(1281.561, "NA", 1825.993)
mase_final <- c(0.4039228, 0.6843495, 0.6847280)

table_final <- as.data.frame(cbind(model_final,type_final,aic_final,bic_final,mase_final))
table_final

#9
#Dynlm Forecast
q = 10
n = nrow(model.dynlm1$model)

madrid.frc <- array(NA, (n+q))
madrid.frc[1:n] <- Y.t[1:length(Y.t)]

trend <- array(NA,q)
trend.start <- model.dynlm1$model[n, "trend(Y.t)"]
trend <- seq(trend.start, trend.start + q/12, 1/12)

Pi <- array(NA, dim = c(n+q,2))

for (i in 1:q){
  months <- array(0,11)
  months[(i-1)%%12] = 1
  data.new = c(1,madrid.frc[n-1+i],trend[i],months)
  madrid.frc[n+i] = as.vector(model.dynlm1$coefficients) %*% data.new
}

par(mfrow = c(1,1))
plot(Y.t,xlim=c(2001,2020), ylim=c(0,100),ylab='Ozone Level (μg/m3)',xlab='Year',main = "Dynlm Forecast of Ozone Levels in Madrid (Figure 10)")
lines(ts(madrid.frc[(n+1):(n+q)],start=c(2018,6),frequency = 12),col="green")
lines(ts(madrid.frc[(n+1):(n+q)] + 2*sd(madrid.frc[(n+1):(n+q)]), start = c(2018,6), frequency = 12), col = "red")
lines(ts(madrid.frc[(n+1):(n+q)] - 2*sd(madrid.frc[(n+1):(n+q)]), start = c(2018,6), frequency = 12), col = "blue")
legend("topleft", lty=1, pch=1, col=c("black","blue","red","green"), text.width = 4,
       c("Data","5% lower limit","95% upper limit","Mean prediction"))
LS0tDQp0aXRsZTogIkZpbmFsIFByb2plY3QiDQphdXRob3I6ICJTaGlzaGVuIENoZW4gKHMzNDQyMTQwKSwgU2hpcHJlbiBKYXlhZGV2IChzMzc0NDQyMSkiDQpkYXRlOiAiMjAxOS8xMC8xNSINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQojIyAxLiBJbnRyb2R1Y3Rpb24gDQpGb3IgdGhpcyBwcm9qZWN0IHdlIGhhdmUgY2hvc2VuIHRvIGFuYWx5c2UgYW5kIGZvcmVjYXN0IG9uIHRoZSBhaXIgcXVhbGl0eSBvZiB0aGUgY2l0eSBvZiBNYWRyaWQsIFNwYWluLiBJbiB0aGUgZGF0YXNldCB0aGVyZSBhcmUgbWFueSB0eXBlcyBvZiBwb2xsdXRhbnRzIHByZXNlbnQgaW4gdGhlIGFpciBidXQgd2UgaGF2ZSBjaG9zZW4gdG8gZm9jdXMgb24gdGhlIGxldmVscyBvZiB0aGUgb3pvbmUgZ2FzIGluIHRoZSBhaXIuIEhpZ2ggb3pvbmUgbGV2ZWxzIGNhbiBsZWFkIHRvIGJyZWF0aW5nIGRpZmZpY3VsdHksIGx1bmcgZGFtYWdlIGFuZCBhZ2dyYXZhdGUgZXhpc3RpbmcgbHVuZyBkaXNlYXNlcy4gQXMgc3VjaCB3ZSBmZWVsIHRoaXMgaXMgYW4gaW1wb3J0YW50IHZhcmlhYmxlIHRvIG1vbml0b3IuIFRvIGRldGVybWluZSB0aGUgc2V2ZXJpdHkgb2YgdGhlIGZ1dHVyZSBkYW1hZ2UgY2F1c2VkIGJ5IHRoaXMgZ2FzIHdlIHdpbGwgYmUgZm9yZWNhc3RpbmcgdGhlIGxldmVscyBmb3IgdGhlIG5leHQgMTAgbW9udGhzLiAgDQoNCg0KIyMgMi4gVGhlIERhdGEgDQpUaGUgZGF0YXNldCB1c2VkIGluIHRoaXMgZm9yZWNhc3RpbmcgcmVwb3J0IGlzICdBaXIgUXVhbGl0eSBvZiBNYWRyaWQgKDIwMDEgLSAyMDE4KSwgaXQgY29udGFpbnMgc2V2ZXJhbCBtZWFzdXJlbWVudHMgZm9yIGFpciBwb2xsdXRhbnRzLCBhbW9uZyB0aGVtIHRoZSBvbmUgdmFyaWFibGUgd2UgYXJlIGludGVyZXN0ZWQgaW4sIHRoZSBvem9uZSBsZXZlbC4gDQoNClNvdXJjZTogaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kZWNpZGUtc29sdWNpb25lcy9haXItcXVhbGl0eS1tYWRyaWQNCg0KIyMgMy4gUGFja2FnZXMNCkJlbG93IGFyZSB0aGUgcGFja2FnZXMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gY29uZHVjdCB0aGlzIGFuYWx5c2lzLg0KYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoeDEyKQ0KbGlicmFyeShkeW5sbSkNCmxpYnJhcnkoZExhZ00pDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KbGlicmFyeShBRVIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KFRTQSkNCmxpYnJhcnkoSG1pc2MpDQpsaWJyYXJ5KHRzZXJpZXMpDQpsaWJyYXJ5KGRwbHlyKQ0KYGBgDQoNCiMjIDQuIFByZXBhcmluZyB0aGUgRGF0YQ0KRmlyc3Qgd2UgbmVlZCB0byBsb2FkIHVwIHRoZSAxOCBkYXRhc2V0cyB0aGF0IHdpbGwgYmUgdXNlZC4gRWFjaCBkYXRhc2V0IGNvcnJlc3BvbmRzIHRvIGEgeWVhciBiZXR3ZWVuIDIwMDEgYW5kIDIwMTguIA0KYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KeWVhcjIwMDEgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDAxLmNzdiIpDQp5ZWFyMjAwMiA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMDIuY3N2IikNCnllYXIyMDAzIDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAwMy5jc3YiKQ0KeWVhcjIwMDQgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDA0LmNzdiIpDQp5ZWFyMjAwNSA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMDUuY3N2IikNCnllYXIyMDA2IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAwNi5jc3YiKQ0KeWVhcjIwMDcgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDA3LmNzdiIpDQp5ZWFyMjAwOCA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMDguY3N2IikNCnllYXIyMDA5IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAwOS5jc3YiKQ0KeWVhcjIwMTAgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDEwLmNzdiIpDQp5ZWFyMjAxMSA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMTEuY3N2IikNCnllYXIyMDEyIDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAxMi5jc3YiKQ0KeWVhcjIwMTMgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDEzLmNzdiIpDQp5ZWFyMjAxNCA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMTQuY3N2IikNCnllYXIyMDE1IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAxNS5jc3YiKQ0KeWVhcjIwMTYgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDE2LmNzdiIpDQp5ZWFyMjAxNyA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMTcuY3N2IikNCnllYXIyMDE4IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAxOC5jc3YiKQ0Kc3RhdGlvbnMgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9zdGF0aW9ucy5jc3YiKQ0KYGBgDQoNCk5leHQgd2UgbmVlZCB0byBtb2RpZnkgdGhlIGZvcm1hdCBvZiB0aGUgZGF0ZSBjb2x1bW4gaW4gb3JkZXIgdG8gdXNlIHRoZW0gYXMgdGltZSBzZXJpZXMgZGF0YSBsYXRlci4gDQoNCmBgYHtyIGVjaG89RkFMU0V9DQojI0NoYW5nZSBkYXRlIGZvcm1hdCBhbmQgc2VsZWN0aW5nIHRoZSBPMyB2YXJpYWJsZXMgKHBvbGx1dGFudHMpDQojI1NpbmNlIHRoZSBkYXRlIGZvcm1hdCBpcyBpbiAqKmZhY3RvciB0eXBlKiosIEkgY2hhbmdlIHRob3NlIHR5cGUgaW50byBQb3NpeGN0IGFuZCBzZWxlY3Rpbmcgb25seSBPMyB2YXJpYWJsZXMuDQoNCnllYXIyMDAxJGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwMSRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMDEkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMDEkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDAxJFRpbWUgPC0gZm9ybWF0KHllYXIyMDAxJGRhdGUsICIlVCIpDQp5ZWFyMjAwMSREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDEkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMDEkZGF5IDwtIGZvcm1hdCh5ZWFyMjAwMSRkYXRlLCAiJWQiKQ0KeWVhcjIwMDEkbW9udGggPC0gZm9ybWF0KHllYXIyMDAxJGRhdGUsICIlbSIpDQp5ZWFyMjAwMSR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAwMSRkYXRlLCAiJVkiKQ0KeWVhcjIwMDEkaG91ciA8LSBmb3JtYXQoeWVhcjIwMDEkZGF0ZSwgIiVIIikNCg0KbTIwMDEgPC0geWVhcjIwMDEgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMDIkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDAyJGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAwMiREYXRlIDwtIGZvcm1hdCh5ZWFyMjAwMiRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMDIkVGltZSA8LSBmb3JtYXQoeWVhcjIwMDIkZGF0ZSwgIiVUIikNCnllYXIyMDAyJERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwMiREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAwMiRkYXkgPC0gZm9ybWF0KHllYXIyMDAyJGRhdGUsICIlZCIpDQp5ZWFyMjAwMiRtb250aCA8LSBmb3JtYXQoeWVhcjIwMDIkZGF0ZSwgIiVtIikNCnllYXIyMDAyJHllYXIgPC0gZm9ybWF0KHllYXIyMDAyJGRhdGUsICIlWSIpDQp5ZWFyMjAwMiRob3VyIDwtIGZvcm1hdCh5ZWFyMjAwMiRkYXRlLCAiJUgiKQ0KDQptMjAwMiA8LSB5ZWFyMjAwMiAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAwMyRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDMkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDAzJERhdGUgPC0gZm9ybWF0KHllYXIyMDAzJGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAwMyRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAwMyRkYXRlLCAiJVQiKQ0KeWVhcjIwMDMkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDAzJERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDAzJGRheSA8LSBmb3JtYXQoeWVhcjIwMDMkZGF0ZSwgIiVkIikNCnllYXIyMDAzJG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAwMyRkYXRlLCAiJW0iKQ0KeWVhcjIwMDMkeWVhciA8LSBmb3JtYXQoeWVhcjIwMDMkZGF0ZSwgIiVZIikNCnllYXIyMDAzJGhvdXIgPC0gZm9ybWF0KHllYXIyMDAzJGRhdGUsICIlSCIpDQoNCm0yMDAzIDwtIHllYXIyMDAzICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDA0JGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwNCRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMDQkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMDQkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDA0JFRpbWUgPC0gZm9ybWF0KHllYXIyMDA0JGRhdGUsICIlVCIpDQp5ZWFyMjAwNCREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDQkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMDQkZGF5IDwtIGZvcm1hdCh5ZWFyMjAwNCRkYXRlLCAiJWQiKQ0KeWVhcjIwMDQkbW9udGggPC0gZm9ybWF0KHllYXIyMDA0JGRhdGUsICIlbSIpDQp5ZWFyMjAwNCR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAwNCRkYXRlLCAiJVkiKQ0KeWVhcjIwMDQkaG91ciA8LSBmb3JtYXQoeWVhcjIwMDQkZGF0ZSwgIiVIIikNCg0KbTIwMDQgPC0geWVhcjIwMDQgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMDUkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA1JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAwNSREYXRlIDwtIGZvcm1hdCh5ZWFyMjAwNSRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMDUkVGltZSA8LSBmb3JtYXQoeWVhcjIwMDUkZGF0ZSwgIiVUIikNCnllYXIyMDA1JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwNSREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAwNSRkYXkgPC0gZm9ybWF0KHllYXIyMDA1JGRhdGUsICIlZCIpDQp5ZWFyMjAwNSRtb250aCA8LSBmb3JtYXQoeWVhcjIwMDUkZGF0ZSwgIiVtIikNCnllYXIyMDA1JHllYXIgPC0gZm9ybWF0KHllYXIyMDA1JGRhdGUsICIlWSIpDQp5ZWFyMjAwNSRob3VyIDwtIGZvcm1hdCh5ZWFyMjAwNSRkYXRlLCAiJUgiKQ0KDQptMjAwNSA8LSB5ZWFyMjAwNSAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAwNiRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDYkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDA2JERhdGUgPC0gZm9ybWF0KHllYXIyMDA2JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAwNiRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAwNiRkYXRlLCAiJVQiKQ0KeWVhcjIwMDYkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA2JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDA2JGRheSA8LSBmb3JtYXQoeWVhcjIwMDYkZGF0ZSwgIiVkIikNCnllYXIyMDA2JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAwNiRkYXRlLCAiJW0iKQ0KeWVhcjIwMDYkeWVhciA8LSBmb3JtYXQoeWVhcjIwMDYkZGF0ZSwgIiVZIikNCnllYXIyMDA2JGhvdXIgPC0gZm9ybWF0KHllYXIyMDA2JGRhdGUsICIlSCIpDQoNCm0yMDA2IDwtIHllYXIyMDA2ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDA3JGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwNyRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMDckRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMDckZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDA3JFRpbWUgPC0gZm9ybWF0KHllYXIyMDA3JGRhdGUsICIlVCIpDQp5ZWFyMjAwNyREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDckRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMDckZGF5IDwtIGZvcm1hdCh5ZWFyMjAwNyRkYXRlLCAiJWQiKQ0KeWVhcjIwMDckbW9udGggPC0gZm9ybWF0KHllYXIyMDA3JGRhdGUsICIlbSIpDQp5ZWFyMjAwNyR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAwNyRkYXRlLCAiJVkiKQ0KeWVhcjIwMDckaG91ciA8LSBmb3JtYXQoeWVhcjIwMDckZGF0ZSwgIiVIIikNCg0KbTIwMDcgPC0geWVhcjIwMDcgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMDgkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA4JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAwOCREYXRlIDwtIGZvcm1hdCh5ZWFyMjAwOCRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMDgkVGltZSA8LSBmb3JtYXQoeWVhcjIwMDgkZGF0ZSwgIiVUIikNCnllYXIyMDA4JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwOCREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAwOCRkYXkgPC0gZm9ybWF0KHllYXIyMDA4JGRhdGUsICIlZCIpDQp5ZWFyMjAwOCRtb250aCA8LSBmb3JtYXQoeWVhcjIwMDgkZGF0ZSwgIiVtIikNCnllYXIyMDA4JHllYXIgPC0gZm9ybWF0KHllYXIyMDA4JGRhdGUsICIlWSIpDQp5ZWFyMjAwOCRob3VyIDwtIGZvcm1hdCh5ZWFyMjAwOCRkYXRlLCAiJUgiKQ0KDQptMjAwOCA8LSB5ZWFyMjAwOCAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAwOSRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDkkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDA5JERhdGUgPC0gZm9ybWF0KHllYXIyMDA5JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAwOSRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAwOSRkYXRlLCAiJVQiKQ0KeWVhcjIwMDkkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA5JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDA5JGRheSA8LSBmb3JtYXQoeWVhcjIwMDkkZGF0ZSwgIiVkIikNCnllYXIyMDA5JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAwOSRkYXRlLCAiJW0iKQ0KeWVhcjIwMDkkeWVhciA8LSBmb3JtYXQoeWVhcjIwMDkkZGF0ZSwgIiVZIikNCnllYXIyMDA5JGhvdXIgPC0gZm9ybWF0KHllYXIyMDA5JGRhdGUsICIlSCIpDQoNCm0yMDA5IDwtIHllYXIyMDA5ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDEwJGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxMCRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMTAkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMTAkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDEwJFRpbWUgPC0gZm9ybWF0KHllYXIyMDEwJGRhdGUsICIlVCIpDQp5ZWFyMjAxMCREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTAkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMTAkZGF5IDwtIGZvcm1hdCh5ZWFyMjAxMCRkYXRlLCAiJWQiKQ0KeWVhcjIwMTAkbW9udGggPC0gZm9ybWF0KHllYXIyMDEwJGRhdGUsICIlbSIpDQp5ZWFyMjAxMCR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAxMCRkYXRlLCAiJVkiKQ0KeWVhcjIwMTAkaG91ciA8LSBmb3JtYXQoeWVhcjIwMTAkZGF0ZSwgIiVIIikNCg0KbTIwMTAgPC0geWVhcjIwMTAgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMTEkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDExJGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAxMSREYXRlIDwtIGZvcm1hdCh5ZWFyMjAxMSRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMTEkVGltZSA8LSBmb3JtYXQoeWVhcjIwMTEkZGF0ZSwgIiVUIikNCnllYXIyMDExJERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxMSREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAxMSRkYXkgPC0gZm9ybWF0KHllYXIyMDExJGRhdGUsICIlZCIpDQp5ZWFyMjAxMSRtb250aCA8LSBmb3JtYXQoeWVhcjIwMTEkZGF0ZSwgIiVtIikNCnllYXIyMDExJHllYXIgPC0gZm9ybWF0KHllYXIyMDExJGRhdGUsICIlWSIpDQp5ZWFyMjAxMSRob3VyIDwtIGZvcm1hdCh5ZWFyMjAxMSRkYXRlLCAiJUgiKQ0KDQptMjAxMSA8LSB5ZWFyMjAxMSAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAxMiRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTIkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDEyJERhdGUgPC0gZm9ybWF0KHllYXIyMDEyJGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAxMiRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAxMiRkYXRlLCAiJVQiKQ0KeWVhcjIwMTIkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDEyJERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDEyJGRheSA8LSBmb3JtYXQoeWVhcjIwMTIkZGF0ZSwgIiVkIikNCnllYXIyMDEyJG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAxMiRkYXRlLCAiJW0iKQ0KeWVhcjIwMTIkeWVhciA8LSBmb3JtYXQoeWVhcjIwMTIkZGF0ZSwgIiVZIikNCnllYXIyMDEyJGhvdXIgPC0gZm9ybWF0KHllYXIyMDEyJGRhdGUsICIlSCIpDQoNCm0yMDEyIDwtIHllYXIyMDEyICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDEzJGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxMyRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMTMkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMTMkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDEzJFRpbWUgPC0gZm9ybWF0KHllYXIyMDEzJGRhdGUsICIlVCIpDQp5ZWFyMjAxMyREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTMkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMTMkZGF5IDwtIGZvcm1hdCh5ZWFyMjAxMyRkYXRlLCAiJWQiKQ0KeWVhcjIwMTMkbW9udGggPC0gZm9ybWF0KHllYXIyMDEzJGRhdGUsICIlbSIpDQp5ZWFyMjAxMyR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAxMyRkYXRlLCAiJVkiKQ0KeWVhcjIwMTMkaG91ciA8LSBmb3JtYXQoeWVhcjIwMTMkZGF0ZSwgIiVIIikNCg0KbTIwMTMgPC0geWVhcjIwMTMgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMTQkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE0JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAxNCREYXRlIDwtIGZvcm1hdCh5ZWFyMjAxNCRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMTQkVGltZSA8LSBmb3JtYXQoeWVhcjIwMTQkZGF0ZSwgIiVUIikNCnllYXIyMDE0JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxNCREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAxNCRkYXkgPC0gZm9ybWF0KHllYXIyMDE0JGRhdGUsICIlZCIpDQp5ZWFyMjAxNCRtb250aCA8LSBmb3JtYXQoeWVhcjIwMTQkZGF0ZSwgIiVtIikNCnllYXIyMDE0JHllYXIgPC0gZm9ybWF0KHllYXIyMDE0JGRhdGUsICIlWSIpDQp5ZWFyMjAxNCRob3VyIDwtIGZvcm1hdCh5ZWFyMjAxNCRkYXRlLCAiJUgiKQ0KDQptMjAxNCA8LSB5ZWFyMjAxNCAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAxNSRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTUkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDE1JERhdGUgPC0gZm9ybWF0KHllYXIyMDE1JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAxNSRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAxNSRkYXRlLCAiJVQiKQ0KeWVhcjIwMTUkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE1JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDE1JGRheSA8LSBmb3JtYXQoeWVhcjIwMTUkZGF0ZSwgIiVkIikNCnllYXIyMDE1JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAxNSRkYXRlLCAiJW0iKQ0KeWVhcjIwMTUkeWVhciA8LSBmb3JtYXQoeWVhcjIwMTUkZGF0ZSwgIiVZIikNCnllYXIyMDE1JGhvdXIgPC0gZm9ybWF0KHllYXIyMDE1JGRhdGUsICIlSCIpDQoNCm0yMDE1IDwtIHllYXIyMDE1ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDE2JGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxNiRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMTYkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMTYkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDE2JFRpbWUgPC0gZm9ybWF0KHllYXIyMDE2JGRhdGUsICIlVCIpDQp5ZWFyMjAxNiREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTYkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMTYkZGF5IDwtIGZvcm1hdCh5ZWFyMjAxNiRkYXRlLCAiJWQiKQ0KeWVhcjIwMTYkbW9udGggPC0gZm9ybWF0KHllYXIyMDE2JGRhdGUsICIlbSIpDQp5ZWFyMjAxNiR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAxNiRkYXRlLCAiJVkiKQ0KeWVhcjIwMTYkaG91ciA8LSBmb3JtYXQoeWVhcjIwMTYkZGF0ZSwgIiVIIikNCg0KbTIwMTYgPC0geWVhcjIwMTYgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMTckZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE3JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAxNyREYXRlIDwtIGZvcm1hdCh5ZWFyMjAxNyRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMTckVGltZSA8LSBmb3JtYXQoeWVhcjIwMTckZGF0ZSwgIiVUIikNCnllYXIyMDE3JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxNyREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAxNyRkYXkgPC0gZm9ybWF0KHllYXIyMDE3JGRhdGUsICIlZCIpDQp5ZWFyMjAxNyRtb250aCA8LSBmb3JtYXQoeWVhcjIwMTckZGF0ZSwgIiVtIikNCnllYXIyMDE3JHllYXIgPC0gZm9ybWF0KHllYXIyMDE3JGRhdGUsICIlWSIpDQp5ZWFyMjAxNyRob3VyIDwtIGZvcm1hdCh5ZWFyMjAxNyRkYXRlLCAiJUgiKQ0KDQptMjAxNyA8LSB5ZWFyMjAxNyAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAxOCRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTgkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDE4JERhdGUgPC0gZm9ybWF0KHllYXIyMDE4JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAxOCRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAxOCRkYXRlLCAiJVQiKQ0KeWVhcjIwMTgkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE4JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDE4JGRheSA8LSBmb3JtYXQoeWVhcjIwMTgkZGF0ZSwgIiVkIikNCnllYXIyMDE4JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAxOCRkYXRlLCAiJW0iKQ0KeWVhcjIwMTgkeWVhciA8LSBmb3JtYXQoeWVhcjIwMTgkZGF0ZSwgIiVZIikNCnllYXIyMDE4JGhvdXIgPC0gZm9ybWF0KHllYXIyMDE4JGRhdGUsICIlSCIpDQoNCm0yMDE4IDwtIHllYXIyMDE4ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KYGBgDQoNClRoZW4gd2UgY29tYmluZSBhbGwgMTggZGF0YXNldHMgdXNpbmcgdGhlIHJiaW5kKCkgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgdGhlIGZpbmFsIGRhdGFzZXQgd2Ugd2lsbCB1c2UgZm9yIG91ciBhbmFseXNpcyBhbmQgZm9yZWNhc3RpbmcuIFByZXZpZXcgb2YgdGhlIGZpbmFsIGRhdGFzZXQgYmVsb3c6DQpgYGB7ciBlY2hvPUZBTFNFfQ0KbWFkcmlkIDwtIG0yMDAxICU+JQ0KICByYmluZChtMjAwMikgJT4lDQogIHJiaW5kKG0yMDAzKSAlPiUNCiAgcmJpbmQobTIwMDQpICU+JQ0KICByYmluZChtMjAwNSkgJT4lDQogIHJiaW5kKG0yMDA2KSAlPiUNCiAgcmJpbmQobTIwMDcpICU+JQ0KICByYmluZChtMjAwOCkgJT4lDQogIHJiaW5kKG0yMDA5KSAlPiUNCiAgcmJpbmQobTIwMTApICU+JQ0KICByYmluZChtMjAxMSkgJT4lDQogIHJiaW5kKG0yMDEyKSAlPiUNCiAgcmJpbmQobTIwMTMpICU+JQ0KICByYmluZChtMjAxNCkgJT4lDQogIHJiaW5kKG0yMDE1KSAlPiUNCiAgcmJpbmQobTIwMTYpICU+JQ0KICByYmluZChtMjAxNykgJT4lDQogIHJiaW5kKG0yMDE4KSANCg0KcmFkYXJzdGF0aW9ucyA8LSBzdGF0aW9ucyAlPiUgc2VsZWN0KGlkLCBuYW1lKQ0KbWFkcmlkIDwtICByaWdodF9qb2luKG1hZHJpZCwgcmFkYXJzdGF0aW9ucywgYnkgPSBjKCJzdGF0aW9uIiA9ICJpZCIpKQ0KcHJpbnQoaGVhZChtYWRyaWQpKQ0KYGBgDQoNCiMjIDUuIFZpc3VhbGlzYXRpb24NCkluIHRoaXMgc2VjdGlvbiB3ZSB3aWxsIGJlZ2luIGJ5IHZpc3VhbGlzaW5nIHRoZSBkYWlseSBvem9uZSBsZXZlbHMgZm9yIE1hZHJpZCBpbiBGaWd1cmUgMSB0byBnZXQgYSBnZW5lcmFsIGlkZWEgb2YgaG93IHRoZSBsZXZlbHMgdmFyeS4NCmBgYHtyIGVjaG89RkFMU0V9DQptYWRyaWRfbWVhbl9kYWlseSA8LSBtYWRyaWQgJT4lIGdyb3VwX2J5KERhdGUpICU+JSBzdW1tYXJpc2UoT18zX21lYW4gPSBtZWFuKE9fMywgbmEucm0gPSBUUlVFKSkNCmdncGxvdChtYWRyaWRfbWVhbl9kYWlseSwgYWVzKHggPSBhcy5EYXRlKERhdGUpLCB5ID0gT18zX21lYW4pKSArIGdlb21fbGluZShjb2xvciA9ICdibHVlJykgKw0KICB0aGVtZV9idygpICsNCiAgbGFicyh4ID0gJ1llYXInLCB5ID0gJ096b25lIExldmVsICjOvGcvbTMpJywgdGl0bGU9J0RhaWx5IE96b25lIExldmVscyBpbiBNYWRyaWQgKEZpZ3VyZSAxKScpICsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9MTApKSArDQogIHNjYWxlX3hfZGF0ZShicmVha3MgPSBzZXEoYXMuRGF0ZSgiMjAwMS0wMS0wMSIpLCBhcy5EYXRlKCIyMDE4LTA3LTAxIiksIGJ5PSIxMiBtb250aHMiKSwgZGF0ZV9sYWJlbHMgPSAiJVkiKQ0KDQpgYGANCg0KRm9yIHRoZSBzYWtlIG9mIHByZWRpY3RpbmcgdGhlIG96b25lIGxldmVscyAxMCBtb250aHMgYWhlYWQsIHdlIHdpbGwgYmUgY29udmVydGluZyB0aGUgdmFsdWVzIHRvIGEgbW9udGhseSBmaWd1cmUsIHRoZSBtZWFuIG96b25lIGxldmVscyBmb3IgdGhlIG1vbnRoLCBhbmQgdmlzdWFsaXNpbmcgYWdhaW4gdG8gYmV0dGVyIHN1aXQgdGhlIGdvYWwgb2YgdGhpcyBwcm9qZWN0LiBGaWd1cmUgMiBwcm92aWRlcyB0aGUgbW9udGhseSBvem9uZSBsZXZlbHMgYXQgNiBtb250aCBpbnRlcnZhbHMgZm9yIHRoZSB5ZWFycyAyMDAxIHRvIDIwMTguDQoNCmBgYHtyIGVjaG89RkFMU0V9DQptYWRyaWRfbWVhbl9tb250aGx5IDwtIG1hZHJpZCAlPiUgZ3JvdXBfYnkoeWVhciwgbW9udGgpICU+JSBzdW1tYXJpc2UoIE9fM19tZWFuID0gbWVhbihPXzMsIG5hLnJtID0gVFJVRSkpJT4lIG11dGF0ZSh0aW1lID0gcGFzdGUoeWVhciwgIi0iLCBtb250aCwgIi0gMDEiKSkNCg0KbWFkcmlkX21lYW5fbW9udGhseSR0aW1lIDwtIGFzLkRhdGUobWFkcmlkX21lYW5fbW9udGhseSR0aW1lLCBmb3JtYXQgPSAiJVkgLSAlbSAtICVkIikNCg0KZ2dwbG90KG1hZHJpZF9tZWFuX21vbnRobHksIGFlcyh4ID0gdGltZSwgeSA9IE9fM19tZWFuKSkgKyBnZW9tX2xpbmUoY29sb3IgPSAnYmx1ZScpICsgDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh4ID0gJ01vbnRoJywgeSA9ICdPem9uZSBMZXZlbCAozrxnL20zKScsIHRpdGxlPSdNb250aGx5IE96b25lIExldmVscyBpbiBNYWRyaWQgKEZpZ3VyZSAyKScpICsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9MTApKSArDQogIHNjYWxlX3hfZGF0ZShicmVha3MgPSBzZXEoYXMuRGF0ZSgiMjAwMS0wMS0wMSIpLCBhcy5EYXRlKCIyMDE4LTA3LTAxIiksIGJ5PSI2IG1vbnRocyIpLCBkYXRlX2xhYmVscyA9ICIlYi0leSIpIA0KYGBgDQojIyA2LiBUaW1lIFNlcmllcyBBbmFseXNpcw0KV2l0aCBiYXNpYyB2aXN1YWxpc2F0aW9ucyBjb21wbGV0ZSwgdGltZSBzZXJpZXMgYW5hbHlzaXMgY2FuIG5vdyBiZSBjb25kdWN0ZWQgb24gdGhlIGZpbmFsIGRhdGFzZXQuIEZpcnN0LCB0aGUgZGF0YXNldCBpcyBjb252ZXJ0ZWQgdG8gYSB0aW1lIHNlcmllcyBhbmQgdGhlbiBhbiBpbml0aWFsIHZpc3VhbGlzYXRpb24gKEZpZ3VyZSAzKSBpcyBkb25lIHRvIGxvb2sgZm9yIGFueSBvYnZpb3VzIGNoYXJhY3RlcmlzdGljcy4NCmBgYHtyIGVjaG89RkFMU0V9DQpkdW1teTEgPC0gYXMudmVjdG9yKG1hZHJpZF9tZWFuX21vbnRobHkkT18zX21lYW4pDQptYWRyaWQudHMgPC0gdHMoZHVtbXkxLHN0YXJ0ID0gYygyMDAxLDEpLCBlbmQgPSBjKDIwMTgsNSksIGZyZXF1ZW5jeSA9IDEyKQ0KDQpwbG90KG1hZHJpZC50cywgeWxhYj0iT3pvbmUgTGV2ZWwgKM68Zy9tMykiLCBtYWluID0gIlRpbWUgc2VyaWVzIHBsb3QgZm9yIE8zIChGaWd1cmUgMykiKQ0KcG9pbnRzKHk9bWFkcmlkLnRzLCB4PXRpbWUobWFkcmlkLnRzKSwgcGNoID0gYXMudmVjdG9yKHNlYXNvbihtYWRyaWQudHMpKSkNCmBgYA0KRnJvbSBmaWd1cmUgMyBhbiBvYnZpb3VzIHNlYXNvbmFsIHRyZW5kIGNhbiBiZSBvYnNlcnZlZCBiYXNlZCBvbiB0aGUgYmVoYXZpb3VyIG9mIHRoZSBwb2ludHMgdGhyb3VnaG91dCB0aGUgeWVhcnMuIEl0IGNhbiBhbHNvIGJlIG9ic2VydmVkIHRoYXQgdGhlIG1vbnRocyBKdWx5IGFuZCBBdWd1c3QgY29udGFpbiB0aGUgaGlnaGVzdCBvem9uZSBsZXZlbHMgd2hlcmVhcyBEZWNlbWJlciBoYXMgdGhlIGxvd2VzdCBsZXZlbHMgb3ZlciB0aGUgdGltZSBwZXJpb2QuIE5vIG5vdGFibGUgaW50ZXJ2ZW50aW9uIHBvaW50cyBvYnNlcnZlZC4gVGhlcmUgaXMgYSBjaGFuZ2luZyB2YXJpYW5jZSB3aXRoIHRoZSBtZWFuLCBhbG9uZyB3aXRoIGEgbGFyZ2UgZmx1Y3R1YXRpb24gYW5kIGF1dG8tcmVncmVzc2l2ZSBoZWhhdmlvdXIuIA0KDQojIyMgNi4xIENoZWNraW5nIGZvciBTdGF0aW9uYXJpdHkNClVzaW5nIGFuIEFERiB0ZXN0IHdlIHNoYWxsIGRldGVybWluZSBpZiB0aGUgZGF0YXNldCBpcyBzdGF0aW9uYXJ5IG9yIG5vdC4NCmBgYHtyIGVjaG89RkFMU0V9DQphZGYudGVzdChtYWRyaWQudHMpDQpgYGANCkFzIHRoZSBhYm92ZSByZXN1bHQgc2hvd3MsIHRoZSBwIHZhbHVlIGluZGljYXRlcyB0aGlzIHRpbWUgc2VyaWVzIGlzIHN0YXRpb25hcnkuDQoNCiMjIyA2LjIgQUNGLCBQQUNGICYgRmlyc3QgRGVjb21wb3NpdGlvbg0KRnJvbSBmaWd1cmUgMywgdGhlcmUgaXMgYWxyZWFkeSBhbiBvYnNlcnZlZCBzZWFzb25hbGl0eSBmb3IgdGhlIGRhdGFzZXQgYnV0IGp1c3QgdG8gYmUgc3VyZSwgYW4gQUNGIGFuZCBQQUNGIHBsb3Qgd2lsbCBiZSBtYWRlIHRvIGNoZWNrIChGaWd1cmUgNCAmIDUpLg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KcGFyKG1mcm93PSBjKDEsMikpDQphY2YobWFkcmlkLnRzLCBtYWluID0gIkZpZ3VyZSA0IikNCnBhY2YobWFkcmlkLnRzLCBtYWluID0gIkZpZ3VyZSA1IikNCmBgYA0KRnJvbSB0aGUgYWJvdmUgZmlndXJlcyB3ZSBjYW4gc2VlIHRoYXQgdGhlcmUgaXMgaW4gZmFjdCBzZWFzb25hbGl0eSB3aXRoaW4gdGhlIGRhdGFzZXQuDQoNCk5leHQgd2UgYXBwbHkgdGhlIHgxMiBEZWNvbXBvc2l0aW9uIHRvIG9ic2VydmUgdGhlIGRlY29tcG9zZWQgbGluZXMuDQoNCmBgYHtyIGluY2x1ZGU9RkFMU0V9DQpmaXQubWFkcmlkLngxMiA9IHgxMihtYWRyaWQudHMpDQpgYGANCg0KYGBge3IgZWNobz1GQUxTRX0NCnBsb3QoZml0Lm1hZHJpZC54MTIgLCBzYT1UUlVFICwgdHJlbmQ9VFJVRSxtYWluID0gIkRlY29tcG9zZWQoWDEyKSBUaW1lIFNlcmllcyBQbG90IG9mIE96b25lIExldmVscyAoRmlndXJlIDYpIikNCmBgYA0KVGhlcmUgaXMgYXV0by1yZWdyZXNzaXZlIGJlaGF2aW91ciB3aGljaCBmbHVjdHVhdGVzIGFyb3VuZCB0aGUgbWVhbiBhbmQgaXMgcHJlc2VudCBpbiB0aGUgZmlndXJlIGFjcm9vcyB0aGUgZW50aXJlIHRpbWUgc2VyaWVzLiANCg0KRnJvbSBmaWd1cmUgNiwgdGhlIHNlYXNvbmFsbHkgYWRqdXN0ZWQga2VlcHMgYWxvbmcgd2l0aCB0aGUgdHJlbmQgYW5kIG9yZ2luYWwgdHJlbmQgYnV0IHdpdGggc29tZSBmbHVjdWF0aW9ucywgd2hpY2ggaW5kaWNhdGVzIHRoZSBzZWFzb25hbGl0eSBpcyBub3QgY29tcGxldGV5IHJlbW92ZWQuIFRoZXJlZm9yZSwgZXh0cmEgZGlmZmVyZW5jaW5nIGlzIHJlcXVpcmVkLiBNYW53aGlsZSwgaXQgaXMgaGFyZCB0byBjb25jbHVkZSB0aGUgZXhzaXN0ZW5jZSBvZiBtdWx0aS1zZWFzb25hbGl0eSBiZWF2aW91ci4gRnVydGhlcm1vcmUsIHRoZXJlIGlzIGV2aWRlbmNlIHRoZSB0cmVuZCBzbGlnaGx0eSBpbmNyZWFzZXMgd2l0aCB0aW1lLiBUaGUgdHJlbmQgZWZmZWN0IHdpbGwgYmUgaW52ZXN0aWdhdGVkIGluIHRoZSBuZXh0IHBhcnQuDQoNCiMjIyA2LjMgRnVydGhlciBEZWNvbXBvc2l0aW9uDQpGaXJzdCBhbiBTVEwgZGVjb21wb3NpdGlvbiB3YXMgcnVuIG9uIHRoZSB0aW1lIHNlcmllcyB0byBvYnNlcnZlIHRoZSBmYWN0b3JzIG9mIHRoZSB0aW1lIHNlcmllcyBzZXBlcmF0ZWx5IChGaWd1cmUgNykuIFRoZW4gaW4gRmlndXJlIDgsIHRoZSBzZWFzb25hbCBjb21wb25lbnQgaXMgZXh0cmFjdGVkIGFuZCBwbG90dGVkLCBzaG93aW5nIGEgbXVjaCBtb3JlIG9idmlvdXMgdHJlbmQgcGF0dGVybiBlbWVyZ2luZyBpbiB0aGUgdGltZSBzZXJpZXMuIEZvbGxvd2luZyBGaWd1cmUgOCwgdGhlIHRyZW5kIGNvbXBvbmVudCBpcyByZW1vdmVkIGFzIHdlbGwgZ2l2aW5nIHVzIEZpZ3VyZSA5IGluIHdoaWNoIHdlIGNhbiBzZWUgdGhhdCB0aGUgZmx1Y3R1YXRpb25zIGFyb3VuZCB0aGUgbWVhbiBhcmUgbW9yZSBlcXVhbCB0aHJvdWdob3V0IHRoZSB5ZWFycyBhbmQgdXNpbmcgYW4gQURGIHRlc3QsIHRoZSB0aW1lIHNlcmllcyBpcyBjb25jbHVkZWQgdG8gYmUgc3RhdGlvbmFyeS4NCg0KYGBge3IgZWNobz1GQUxTRX0NCiNVc2luZyBzZWFzb25hbCBkaWZmZXJlbmNpbmcNCmZpdC5tYWRyaWQgPC0gc3RsKG1hZHJpZC50cywgdC53aW5kb3c9MTUsIHMud2luZG93PSJwZXJpb2RpYyIsIHJvYnVzdD1UUlVFKQ0KcGxvdChmaXQubWFkcmlkLCBtYWluID0gIkZpZ3VyZSA3IikNCmZpdC5tYWRyaWQuc2Vhc29uYWwgPSBmaXQubWFkcmlkJHRpbWUuc2VyaWVzWywic2Vhc29uYWwiXSANCg0KI0V4dHJhY3QgdGhlIHNlYW5zb25hbCBjb21wb25lbnQgZnJvbSB0aGUgb3V0cHV0DQptYWRyaWQuc2Vhc29uYWwuYWRqdXN0ZWQgPSBtYWRyaWQudHMgLSBmaXQubWFkcmlkLnNlYXNvbmFsDQpwbG90KG1hZHJpZC5zZWFzb25hbC5hZGp1c3RlZCx4bGFiPSdUaW1lJywgeWxhYiA9J096b25lIExldmVscyAozrxnL20zKScsIG1haW4gPSAiU2Vhc29uYWwgYWRqdXN0ZWQgdGltZSBzZXJpZXMgKEZpZ3VyZSA4KSIpDQpwb2ludHMoeT1tYWRyaWQuc2Vhc29uYWwuYWRqdXN0ZWQseD10aW1lKG1hZHJpZC5zZWFzb25hbC5hZGp1c3RlZCksIHBjaD1hcy52ZWN0b3Ioc2Vhc29uKG1hZHJpZC5zZWFzb25hbC5hZGp1c3RlZCkpKQ0KDQojRXh0cmFjdCB0aGUgdHJlbmQgY29tcG9uZW50IGZyb20gdGhlIG91dHB1dA0KZml0Lm1hZHJpZC50cmVuZCA9IGZpdC5tYWRyaWQkdGltZS5zZXJpZXNbLCJ0cmVuZCJdIA0KbWFkcmlkLnNlYXNvbmFsLnRyZW5kLmFkanVzdGVkID0gbWFkcmlkLnRzIC0gZml0Lm1hZHJpZC5zZWFzb25hbCAtIGZpdC5tYWRyaWQudHJlbmQNCnBsb3QobWFkcmlkLnNlYXNvbmFsLnRyZW5kLmFkanVzdGVkLHhsYWI9J1RpbWUnLCB5bGFiID0nT3pvbmUgTGV2ZWwgKM68Zy9tMyknLCBtYWluID0gIlRyZW5kICYgc2Vhc29uYWwgYWRqdXN0ZWQgdGltZSBzZXJpZXMgKEZpZ3VyZSA5KSIpDQpwb2ludHMoeT1tYWRyaWQuc2Vhc29uYWwudHJlbmQuYWRqdXN0ZWQseD10aW1lKG1hZHJpZC5zZWFzb25hbC50cmVuZC5hZGp1c3RlZCksIHBjaD1hcy52ZWN0b3Ioc2Vhc29uKG1hZHJpZC5zZWFzb25hbC50cmVuZC5hZGp1c3RlZCkpKQ0KDQphZGYudGVzdChtYWRyaWQuc2Vhc29uYWwudHJlbmQuYWRqdXN0ZWQpDQpgYGANCg0KIyMgNy4gTW9kZWwgRml0dGluZw0KTW9kZWwgZml0dGluZyB3aWxsIGJlIGRpdmlkZWQgaW50byBtdWx0aXBsZSBzZWN0aW9ucyB3aXRoIGVhY2ggc2VjdGlvbiBjb3JyZXNwb25kaW5nIHRvIHNwZWNpZmljIHR5cGVzIG9mIG1vZGVscy4gUmVzdWx0cyBmcm9tIHRoZSBNQVNFIGFuZCBBSUMgd2lsbCBiZSBzdW1tYXJpc2VkIGluIGEgdGFibGUgYXQgdGhlIGJvdHRvbSBpbiBvcmRlciB0byBkZXRlcm1pbmUgd2hpY2ggbW9kZWwgaXMgdGhlIG1vc3QgYWNjdXJhdGUgYW1vbmdzdCB0aGUgZGlmZmVyZW50IHR5cGVzIG9mIG1vZGVscy4NCg0KIyMjIDcuMSBEeW5hbWljIExpbmVhciBNb2RlbHMNCnwgTW9kZWwgTmFtZSB8IEFJQyB8IE1BU0UgfA0KICB8LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwNCiAgfCAkbW9kZWwuZHlubG0xJCB8IDEyMzEuNDk4IHwgMC40MDM5MjI4IHwNCiAgfCAkbW9kZWwuZHlubG0xLjIkIHwgMTI2My45NjUgfCAwLjQzMTMyMzcgfA0KICB8ICRtb2RlbC5keW5sbTEuMyQgfCAxNTYxLjY0NSB8IDAuOTg1ODIxNCB8DQogIHwgJG1vZGVsLmR5bmxtMiQgfCAxMjU1LjM3MCB8IDAuNDMyMjU2NiB8DQogIHwgJG1vZGVsLmR5bmxtNCQgfCAxMjQ1LjIyNiB8IDAuNDE3MzUwOCB8DQpgYGB7ciBlY2hvPUZBTFNFfQ0KI0R5bmxtIE1vZGVscw0KWS50ID0gbWFkcmlkLnRzDQoNCm1vZGVsLmR5bmxtMSA9IGR5bmxtKFkudCB+IEwoWS50ICwgayA9IDEgKSArIHRyZW5kKFkudCkgKyBzZWFzb24oWS50KSkNCg0KbW9kZWwuZHlubG0yID0gZHlubG0oWS50IH4gTChZLnQgLCBrID0gMiApICsgdHJlbmQoWS50KSArIHNlYXNvbihZLnQpKQ0KDQptb2RlbC5keW5sbTEuMiA9IGR5bmxtKFkudCB+IEwoWS50ICwgayA9IDEgKSArIHNlYXNvbihZLnQpKSANCg0KbW9kZWwuZHlubG0xLjMgPSBkeW5sbShZLnQgfiBMKFkudCAsIGsgPSAxICkgKyB0cmVuZChZLnQpKQ0KDQptb2RlbC5keW5sbTQgPSBkeW5sbShZLnQgfiBMKFkudCAsIGsgPSAxICkgKyBMKFkudCAsIGsgPSAyICkgKyBzZWFzb24oWS50KSkNCg0KI0NyZWF0aW5nIHRhYmxlIHN1bW1hcnkgb2YgbW9kZWwgcmVzdWx0cw0KYWljID0gQUlDKG1vZGVsLmR5bmxtMSwgbW9kZWwuZHlubG0xLjIsIG1vZGVsLmR5bmxtMS4zLG1vZGVsLmR5bmxtMixtb2RlbC5keW5sbTQuMSkNCmJpYyA9IEJJQyhtb2RlbC5keW5sbTEsIG1vZGVsLmR5bmxtMS4yLCBtb2RlbC5keW5sbTEuMyxtb2RlbC5keW5sbTIsbW9kZWwuZHlubG00LjEpDQptYXNlID0gTUFTRShsbShtb2RlbC5keW5sbTEpLCBsbShtb2RlbC5keW5sbTEuMiksIGxtKG1vZGVsLmR5bmxtMS4zKSxsbShtb2RlbC5keW5sbTIpLGxtKG1vZGVsLmR5bmxtNC4xKSkNCg0KI0Jlc3QgbW9kZWwgaXMgbW9kZWwuZHlubG0xDQpzdW1tYXJ5KG1vZGVsLmR5bmxtMSkNCmNoZWNrcmVzaWR1YWxzKG1vZGVsLmR5bmxtMSkNCmBgYA0KRnJvbSB0aGUgdGFibGUgYW5kIGJhc2VkIG9uIHRoZSBBSUMsIEJJQyBhbmQgTUFTRSByZXN1bHRzLCBtb2RlbC5keW5sbTEgaXMgdGhlIGJlc3QgbW9kZWwgYXMgaXQgaGFzIHRoZSBsb3dlc3QgQUlDLCBCSUMgYW5kIE1BU0UuDQoNCkhvd2V2ZXIsIGZyb20gdGhlIHJlc2lkdWFscywgdGhlcmUgaXMgb25lIHNpZ25pZmljYW50IHZhbHVlIGluIHRoZSBhY2YgYW5kIHRoZSB0YWlscyBvZiB0aGUgcmVzaWR1YWxzIGhpc3RvZ3JhbSBhcmUgYSBiaXQgbG9uZ2VyIHRoYW4gd2Ugd291bGQgcHJlZmVyIGFuZCBpdCBzaG93cyB0byBiZSByYW5kb20gaW4gdGhlIGxpbmUgY2hhcnQgaW4gdGhlIHJlc2lkdWFscyBjaGVjay4gDQoNCiMjIyA3LjIgRXhwb25lbnRpYWwgU21vb3RoaW5nIE1vZGVscw0KICB8IE1vZGVsIE5hbWUgfCBBSUMgfCBNQVNFIHwNCiAgfC0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18DQogIHwgJG1vZGVsLnNpbXBsZSQgfCAyMTEyLjg2NSB8IDEuNjQ5OTQ4IHwNCiAgfCAkbW9kZWwuaHcxJCB8IDE3NzguNjA5IHwgMC42ODcyODEgfA0KICB8ICRtb2RlbC5odzIkIHwgMTc3OS43NjIgfCAwLjY4NDM0OSB8DQogIHwgJG1vZGVsLmh3MyR8IDE4MTQuNjg2IHwgMC42OTc2NDcgfA0KICB8ICRtb2RlbC5odzQkIHwgMTgyOS45NTQgfCAwLjcwNzUyNSB8DQpgYGB7ciBlY2hvPUZBTFNFfQ0KbW9kZWwuc2ltcGxlIDwtIHNlcyhtYWRyaWQudHMsaD0yKmZyZXF1ZW5jeShtYWRyaWQudHMpKSNNQVNFIDEuNjQ5OTQ4DQoNCm1vZGVsLmh3MSA8LSBodyhtYWRyaWQudHMsc2Vhc29uYWw9ImFkZGl0aXZlIikgI01BU0UgMC42ODcyODE0IA0KDQptb2RlbC5odzIgPC0gaHcobWFkcmlkLnRzLHNlYXNvbmFsPSJhZGRpdGl2ZSIsZGFtcGVkID0gVFJVRSkgI01BU0UgMC42ODQzNDk1IA0KDQptb2RlbC5odzMgPC0gaHcobWFkcmlkLnRzLHNlYXNvbmFsPSJtdWx0aXBsaWNhdGl2ZSIpICNNQVNFIDAuNjk3NjQ3NSANCg0KbW9kZWwuaHc0IDwtIGh3KG1hZHJpZC50cyxzZWFzb25hbD0ibXVsdGlwbGljYXRpdmUiLGV4cG9uZW50aWFsID0gVFJVRSkgI01BU0UgMC43MDc1MjU0IA0KDQojVGFibGUgY3JlYXRpb24NCm5hbWVfZXMgPC0gYygibW9kZWwuc2ltcGxlIiwibW9kZWwuaHcxIiwibW9kZWwuaHcyIiwibW9kZWwuaHczIiwibW9kZWwuaHc0IikNCm1hc2VfZXMgPC0gYygxLjY0OTk0OCwwLjY4NzI4MSwwLjY4NDM0OSwwLjY5NzY0NywwLjcwNzUyNSkNCg0KI0Jlc3QgbW9kZWwgaXMgbW9kZWwuaHcyDQpzdW1tYXJ5KG1vZGVsLmh3MikNCmNoZWNrcmVzaWR1YWxzKG1vZGVsLmh3MikNCg0KYGBgDQpGcm9tIHRoZSB0YWJsZSBhYm92ZSwgd2UgY2FuIHNlZSB0aGF0IHRoZSBiZXN0IG1vZGVsIGlzIG1vZGVsLmh3MiB3aGljaCBpcyB0aGUgRGFtcGVkIEhvbHQtV2ludGVycycgYWRkaXRpdmUgbWV0aG9kIHdpdGggYSBNQVNFIHZhbHVlIG9mIDAuNjg0MzQ5NS4gTG9va2luZyBhdCB0aGUgcmVzaWR1YWxzIGFzIHdlbGwsIHRoZSBoaXN0b2dyYW0gYXBwZWFycyBtb3N0bHkgbm9ybWFsIHdpdGggc2hvcnQgdGFpbHMsIHRoZXJlIGFyZSBvbmx5IDIgc2lnbmlmaWNhbnQgdmFsdWVzIGluIHRoZSBBQ0YgYW5kIHRoZSBsaW5lIGNoYXJ0IHNob3dzIGVxdWFsIHZhcmlhbmNlcyBhcm91bmQgdGhlIG1lYW4uDQoNCiMjIyA3LjMgU3RhdGUtU3BhY2UgTW9kZWxzDQogIHwgTW9kZWwgTmFtZSB8IEFJQyB8IE1BU0UgfA0KICB8LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwNCiAgfCAkbW9kZWwuQU5BJCB8IDE3NzUuODU4IHwgMC42ODQ3MjgwIHwNCiAgfCAkbW9kZWwuQUFBJCB8IDE3NzguNDg4IHwgMC42ODcyODE0IHwNCiAgfCAkbW9kZWwuQUFkQS5kYW1wZWQkIHwgMTc3OS45MzggfCAwLjY4NDM0OTUgfA0KICB8ICRtb2RlbC5BTk4kIHwgMjExMi44ODkgfCAxLjY0OTU4NDAgfA0KICB8ICRtb2RlbC5NQU0kIHwgMTgxNS4wMjcgfCAwLjY5MTg5NjIgfA0KICB8ICRtb2RlbC5NQU0uZGFtcGVkJCB8IDE4MTUuMDI3IHwgMC42OTE4OTYyIHwNCiAgfCAkbW9kZWwuTU1NJCB8IDE4MTQuNTMxIHwgMC42OTE5ODQ5IHwNCiAgfCAkbW9kZWwuTU1kTSQgfCAxODE0LjUzMSB8IDAuNjkxOTg0OSB8DQogIHwgJG1vZGVsLlpaWiQgfCAxNzc1Ljg1OCB8IDAuNjg0NzI4MCB8DQpgYGB7ciBlY2hvPUZBTFNFfQ0KbW9kZWwuQU5BID0gZXRzKG1hZHJpZC50cyxtb2RlbCA9ICJBTkEiKSAjTUFTRSAwLjY4NDcyOA0KDQptb2RlbC5BQUEgPSBldHMobWFkcmlkLnRzLG1vZGVsID0gIkFBQSIpI01BU0UgMC42ODcyODE0DQoNCm1vZGVsLkFBZEEuZGFtcGVkID0gZXRzKG1hZHJpZC50cyxtb2RlbCA9ICJBQUEiLGRhbXBlZCA9IFRSVUUpICNNQVNFIDAuNjg0MzQ5NQ0KDQptb2RlbC5BTk4gPSBldHMobWFkcmlkLnRzLG1vZGVsID0gIkFOTiIpI01BU0UgMS42NDk1ODQgDQoNCm1vZGVsLk1BTSA9IGV0cyhtYWRyaWQudHMsbW9kZWwgPSAiTUFNIikjTUFTRSAwLjY5MTg5NjINCg0KbW9kZWwuTUFNLmRhbXBlZCA9IGV0cyhtYWRyaWQudHMsbW9kZWwgPSAiTUFNIixkYW1wZWQgPSBUUlVFKSAjTUFTRSAwLjY5MTg5NjINCg0KbW9kZWwuTU1NID0gZXRzKG1hZHJpZC50cyxtb2RlbCA9ICJNTU0iKSNNQVNFIDAuNjkxOTg0OQ0KDQptb2RlbC5NTWRNID0gZXRzKG1hZHJpZC50cyxtb2RlbCA9ICJNTU0iLGRhbXBlZCA9IFRSVUUpICNNQVNFIDAuNjkxOTg0OQ0KDQptb2RlbC5aWlogPSBldHMobWFkcmlkLnRzLCBtb2RlbD0iWlpaIikjI01BU0UgMC42ODQ3MjgNCg0KI1RhYmxlIGNyZWF0aW9uDQphaWNfc3MgPC0gQUlDKG1vZGVsLkFOQSwgbW9kZWwuQUFBLCBtb2RlbC5BQWRBLmRhbXBlZCwgbW9kZWwuQU5OLCBtb2RlbC5NQU0sIG1vZGVsLk1BTS5kYW1wZWQsIG1vZGVsLk1NTSwgbW9kZWwuTU1kTSwgbW9kZWwuWlpaKQ0KYmljX3NzIDwtIEJJQyhtb2RlbC5BTkEsIG1vZGVsLkFBQSwgbW9kZWwuQUFkQS5kYW1wZWQsIG1vZGVsLkFOTiwgbW9kZWwuTUFNLCBtb2RlbC5NQU0uZGFtcGVkLCBtb2RlbC5NTU0sIG1vZGVsLk1NZE0sIG1vZGVsLlpaWikNCm1hc2Vfc3MgPC0gYygwLjY4NDcyOCwwLjY4NzI4MTQsMC42ODQzNDk1LDEuNjQ5NTg0LDAuNjkxODk2MiwwLjY5MTg5NjIsMC42OTE5ODQ5LDAuNjkxOTg0OSwwLjY4NDcyOCkNCg0KI0Jlc3QgbW9kZWwgaXMgbW9kZWwuQU5BDQpzdW1tYXJ5KG1vZGVsLkFOQSkNCmNoZWNrcmVzaWR1YWxzKG1vZGVsLkFOQSkNCg0KYGBgDQpGcm9tIHRoZSB0YWJsZSBhYm92ZSB0aGUgYmVzdCBtb2RlbCBpcyBtb2RlbC5BTkEgd2hpY2ggdXNlcyB0aGUgc3RhdGUgc3BhY2UgQU5BIG1vZGVsIGFuZCBoYXMgdGhlIGxvd2VzdCBBSUMsIEJJQyBhbmQgTUFTRSB2YWx1ZXMgYW1vbmcgdGhlIG90aGVyIG1vZGVscy4gTG9va2luZyBhdCB0aGUgcmVzaWR1YWxzLCB0aGVyZSBhcmUgMiBzaWduaWZpY2FudCB2YWx1ZXMgaW4gdGhlIEFDRiwgdGhlIGhpc3RvZ3JhbXMgYXBwZWFycyBtb3N0bHkgbm9ybWFsIGJ1dCB3aXRoIHNvbWUgbG9uZyB0YWlscyBhbmQgdGhlIGxpbmUgcGxvdCBoYXMgYW4gYWxtb3N0IGNvbnN0YW50IHZhcmlhbmNlIGFyb3VuZCB0aGUgbWVhbi4NCg0KIyMgOC4gTW9kZWwgc2VsZWN0aW9uIGZvciBGb3JlY2FzdGluZw0KVGFraW5nIHRoZSBiZXN0IG1vZGVscyBmcm9tIGVhY2ggbW9kZWxsaW5nIGNhdGVnb3J5LCB3ZSB3aWxsIG5vdyBjb21wYXJlIHRoZW0gaW4gdGhlIHRhYmxlIGJlbG93Lg0KDQogIHwgTW9kZWwgTmFtZSB8IEFJQyB8IE1BU0UgfA0KICB8LS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwNCiAgfCAkbW9kZWwuZHlubG0xJCB8IDEyMzEuNDk4IHwgMC40MDM5MjI4IHwNCiAgfCAkbW9kZWwuaHcyJCB8IDE3NzkuNzYyIHwgMC42ODQzNDkgfA0KICB8ICRtb2RlbC5BTkEkIHwgMTc3NS44NTggfCAwLjY4NDcyODAgfA0KYGBge3IgZWNobz1GQUxTRX0NCiNUYWJsZSBjcmVhdGlvbiBmb3IgZmluYWwgbW9kZWwgc2VsZWN0aW9uDQoNCm1vZGVsX2ZpbmFsIDwtIGMoIm1vZGVsLmR5bmxtMSIsICJtb2RlbC5odzIiLCAibW9kZWwuQU5BIikNCnR5cGVfZmluYWwgPC0gYygiRHluYW1pYyBMaW5lYXIiLCAiRXhwb25lbnRpYWwgU21vb3RoaW5nIiwgIlN0YXRlLVNwYWNlIikNCmFpY19maW5hbCA8LSBjKDEyMzEuNDk4LCAiTkEiLCAxNzc1Ljg1OCkNCmJpY19maW5hbCA8LSBjKDEyODEuNTYxLCAiTkEiLCAxODI1Ljk5MykNCm1hc2VfZmluYWwgPC0gYygwLjQwMzkyMjgsIDAuNjg0MzQ5NSwgMC42ODQ3MjgwKQ0KDQpgYGANCkZpbmFsbHksIGZyb20gdGhlIHRhYmxlIGFib3ZlIGNvbXBhcmluZyB0aGUgYmVzdCBtb2RlbHMgZnJvbSBlYWNoIGNhdGVnb3J5LCB3ZSBoYXZlIG5vdyBkZXRlcm1pbmVkIHRoYXQgdGhlIGJlc3QgbW9kZWwgdG8gdXNlIGZvciBmb3JlY2FzdGluZyBpcyB0aGUgZHluYW1pYyBsaW5lYXIgbW9kZWwsIG1vZGVsLmR5bmxtMS4NCg0KIyMgOS4gRm9yZWNhc3RpbmcNCkJlbG93IGlzIHRoZSAxMCBNb250aCBhaGVhZCBmb3JlY2FzdCBvZiBPem9uZSBsZXZlbHMgaW4gdGhlIENpdHkgb2YgTWFkcmlkIHVzaW5nIHRoZSBzZWxlY3RlZCBkeW5hbWljIGxpbmVhciBtb2RlbC4NCg0KYGBge3IgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNEeW5sbSBGb3JlY2FzdA0KcSA9IDEwDQpuID0gbnJvdyhtb2RlbC5keW5sbTEkbW9kZWwpDQoNCm1hZHJpZC5mcmMgPC0gYXJyYXkoTkEsIChuK3EpKQ0KbWFkcmlkLmZyY1sxOm5dIDwtIFkudFsxOmxlbmd0aChZLnQpXQ0KDQp0cmVuZCA8LSBhcnJheShOQSxxKQ0KdHJlbmQuc3RhcnQgPC0gbW9kZWwuZHlubG0xJG1vZGVsW24sICJ0cmVuZChZLnQpIl0NCnRyZW5kIDwtIHNlcSh0cmVuZC5zdGFydCwgdHJlbmQuc3RhcnQgKyBxLzEyLCAxLzEyKQ0KDQpQaSA8LSBhcnJheShOQSwgZGltID0gYyhuK3EsMikpDQoNCmZvciAoaSBpbiAxOnEpew0KICBtb250aHMgPC0gYXJyYXkoMCwxMSkNCiAgbW9udGhzWyhpLTEpJSUxMl0gPSAxDQogIGRhdGEubmV3ID0gYygxLG1hZHJpZC5mcmNbbi0xK2ldLHRyZW5kW2ldLG1vbnRocykNCiAgbWFkcmlkLmZyY1tuK2ldID0gYXMudmVjdG9yKG1vZGVsLmR5bmxtMSRjb2VmZmljaWVudHMpICUqJSBkYXRhLm5ldw0KfQ0KDQpwYXIobWZyb3cgPSBjKDEsMSkpDQpwbG90KFkudCx4bGltPWMoMjAwMSwyMDIwKSwgeWxpbT1jKDAsMTAwKSx5bGFiPSdPem9uZSBMZXZlbCAozrxnL20zKScseGxhYj0nWWVhcicsbWFpbiA9ICJEeW5sbSBGb3JlY2FzdCBvZiBPem9uZSBMZXZlbHMgaW4gTWFkcmlkIChGaWd1cmUgMTApIikNCmxpbmVzKHRzKG1hZHJpZC5mcmNbKG4rMSk6KG4rcSldLHN0YXJ0PWMoMjAxOCw2KSxmcmVxdWVuY3kgPSAxMiksY29sPSJncmVlbiIpDQpsaW5lcyh0cyhtYWRyaWQuZnJjWyhuKzEpOihuK3EpXSArIDIqc2QobWFkcmlkLmZyY1sobisxKToobitxKV0pLCBzdGFydCA9IGMoMjAxOCw2KSwgZnJlcXVlbmN5ID0gMTIpLCBjb2wgPSAicmVkIikNCmxpbmVzKHRzKG1hZHJpZC5mcmNbKG4rMSk6KG4rcSldIC0gMipzZChtYWRyaWQuZnJjWyhuKzEpOihuK3EpXSksIHN0YXJ0ID0gYygyMDE4LDYpLCBmcmVxdWVuY3kgPSAxMiksIGNvbCA9ICJibHVlIikNCmxlZ2VuZCgidG9wbGVmdCIsIGx0eT0xLCBwY2g9MSwgY29sPWMoImJsYWNrIiwiYmx1ZSIsInJlZCIsImdyZWVuIiksIHRleHQud2lkdGggPSA0LA0KICAgICAgIGMoIkRhdGEiLCI1JSBsb3dlciBsaW1pdCIsIjk1JSB1cHBlciBsaW1pdCIsIk1lYW4gcHJlZGljdGlvbiIpKQ0KDQpgYGANCg0KIyMgMTAuIENvbmNsdXNpb24NClRvIGNvbmNsdWRlLCBvdXQgb2YgdGhlIHRocmVlIG1vZGVsbGluZyB0ZWNobmlxdWVzIGFwcGxpZWQsIG91ciBiZXN0IG1vZGVsIHJlc3VsdGVkIGZyb20gYSBkeW5hbWljIGxpbmVhciBtb2RlbCB3aXRoIGEgbGFnIG9mIDEgYW5kIHRoZSB0cmVuZCBhbmQgc2Vhc29uYWwgY29tcG9uZW50cyBhZGRlZCBhcyBpdCByZXN1bHRlZCBpbiB0aGUgbG93ZXN0IEFJQyBhbmQgTUFTRSB2YWx1ZXMgb3V0IG9mIGFsbCB0aGUgbW9kZWxzLg0KDQpCYXNlZCBvbiB0aGUgZm9yZWNhc3QgYWJvdmUsIHdlIGFyZSBleHBlY3RpbmcgdG8gc2VlIGFuIGluY3JlYXNlIGluIG96b25lIGxldmVscyBmb3IgdGhlIGNpdHkgb2YgTWFkcmlkIGluIHRoZSBuZXh0IDEwIG1vbnRocywgYXMgZXhwZWN0ZWQsIGFuZCByZXNpZGVudHMgc2hvdWxkIHRha2Ugc3RlcHMgdG8gZ3VhcmQgdGhlbXNlbHZlcyBhZ2FpbnN0IHRoZSBwb3RlbnRpYWwgaGF6YXJkcyB0aGUgZ2FzIHByZXNlbnRzIGFuZCBwb3RlbnRpYWxseSBtYWtlIGVmZm9ydHMgdG8gZW5hY3QgY2hhbmdlcyB0byByZWR1Y2Ugb3pvbmUgZ2FzIGxldmVscyBmb3IgdGhlIGZ1dHVyZS4NCg0KIyMgMTEuIENvZGUgDQpgYGB7ciBlY2hvPVRSVUV9DQojMw0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoeDEyKQ0KbGlicmFyeShkeW5sbSkNCmxpYnJhcnkoZExhZ00pDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KbGlicmFyeShBRVIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KFRTQSkNCmxpYnJhcnkoSG1pc2MpDQpsaWJyYXJ5KHRzZXJpZXMpDQpsaWJyYXJ5KGRwbHlyKQ0KDQojNA0KeWVhcjIwMDEgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDAxLmNzdiIpDQp5ZWFyMjAwMiA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMDIuY3N2IikNCnllYXIyMDAzIDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAwMy5jc3YiKQ0KeWVhcjIwMDQgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDA0LmNzdiIpDQp5ZWFyMjAwNSA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMDUuY3N2IikNCnllYXIyMDA2IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAwNi5jc3YiKQ0KeWVhcjIwMDcgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDA3LmNzdiIpDQp5ZWFyMjAwOCA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMDguY3N2IikNCnllYXIyMDA5IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAwOS5jc3YiKQ0KeWVhcjIwMTAgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDEwLmNzdiIpDQp5ZWFyMjAxMSA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMTEuY3N2IikNCnllYXIyMDEyIDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAxMi5jc3YiKQ0KeWVhcjIwMTMgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDEzLmNzdiIpDQp5ZWFyMjAxNCA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMTQuY3N2IikNCnllYXIyMDE1IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAxNS5jc3YiKQ0KeWVhcjIwMTYgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9jc3ZzX3Blcl95ZWFyL21hZHJpZF8yMDE2LmNzdiIpDQp5ZWFyMjAxNyA8LSByZWFkX2NzdigiYWlyLXF1YWxpdHktbWFkcmlkL2NzdnNfcGVyX3llYXIvbWFkcmlkXzIwMTcuY3N2IikNCnllYXIyMDE4IDwtIHJlYWRfY3N2KCJhaXItcXVhbGl0eS1tYWRyaWQvY3N2c19wZXJfeWVhci9tYWRyaWRfMjAxOC5jc3YiKQ0Kc3RhdGlvbnMgPC0gcmVhZF9jc3YoImFpci1xdWFsaXR5LW1hZHJpZC9zdGF0aW9ucy5jc3YiKQ0KDQojI0NoYW5nZSBkYXRlIGZvcm1hdCBhbmQgc2VsZWN0aW5nIHRoZSBPMyB2YXJpYWJsZXMgKHBvbGx1dGFudHMpDQojI1NpbmNlIHRoZSBkYXRlIGZvcm1hdCBpcyBpbiAqKmZhY3RvciB0eXBlKiosIEkgY2hhbmdlIHRob3NlIHR5cGUgaW50byBQb3NpeGN0IGFuZCBzZWxlY3Rpbmcgb25seSBPMyB2YXJpYWJsZXMuDQoNCnllYXIyMDAxJGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwMSRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMDEkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMDEkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDAxJFRpbWUgPC0gZm9ybWF0KHllYXIyMDAxJGRhdGUsICIlVCIpDQp5ZWFyMjAwMSREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDEkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMDEkZGF5IDwtIGZvcm1hdCh5ZWFyMjAwMSRkYXRlLCAiJWQiKQ0KeWVhcjIwMDEkbW9udGggPC0gZm9ybWF0KHllYXIyMDAxJGRhdGUsICIlbSIpDQp5ZWFyMjAwMSR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAwMSRkYXRlLCAiJVkiKQ0KeWVhcjIwMDEkaG91ciA8LSBmb3JtYXQoeWVhcjIwMDEkZGF0ZSwgIiVIIikNCg0KbTIwMDEgPC0geWVhcjIwMDEgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMDIkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDAyJGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAwMiREYXRlIDwtIGZvcm1hdCh5ZWFyMjAwMiRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMDIkVGltZSA8LSBmb3JtYXQoeWVhcjIwMDIkZGF0ZSwgIiVUIikNCnllYXIyMDAyJERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwMiREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAwMiRkYXkgPC0gZm9ybWF0KHllYXIyMDAyJGRhdGUsICIlZCIpDQp5ZWFyMjAwMiRtb250aCA8LSBmb3JtYXQoeWVhcjIwMDIkZGF0ZSwgIiVtIikNCnllYXIyMDAyJHllYXIgPC0gZm9ybWF0KHllYXIyMDAyJGRhdGUsICIlWSIpDQp5ZWFyMjAwMiRob3VyIDwtIGZvcm1hdCh5ZWFyMjAwMiRkYXRlLCAiJUgiKQ0KDQptMjAwMiA8LSB5ZWFyMjAwMiAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAwMyRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDMkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDAzJERhdGUgPC0gZm9ybWF0KHllYXIyMDAzJGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAwMyRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAwMyRkYXRlLCAiJVQiKQ0KeWVhcjIwMDMkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDAzJERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDAzJGRheSA8LSBmb3JtYXQoeWVhcjIwMDMkZGF0ZSwgIiVkIikNCnllYXIyMDAzJG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAwMyRkYXRlLCAiJW0iKQ0KeWVhcjIwMDMkeWVhciA8LSBmb3JtYXQoeWVhcjIwMDMkZGF0ZSwgIiVZIikNCnllYXIyMDAzJGhvdXIgPC0gZm9ybWF0KHllYXIyMDAzJGRhdGUsICIlSCIpDQoNCm0yMDAzIDwtIHllYXIyMDAzICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDA0JGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwNCRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMDQkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMDQkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDA0JFRpbWUgPC0gZm9ybWF0KHllYXIyMDA0JGRhdGUsICIlVCIpDQp5ZWFyMjAwNCREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDQkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMDQkZGF5IDwtIGZvcm1hdCh5ZWFyMjAwNCRkYXRlLCAiJWQiKQ0KeWVhcjIwMDQkbW9udGggPC0gZm9ybWF0KHllYXIyMDA0JGRhdGUsICIlbSIpDQp5ZWFyMjAwNCR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAwNCRkYXRlLCAiJVkiKQ0KeWVhcjIwMDQkaG91ciA8LSBmb3JtYXQoeWVhcjIwMDQkZGF0ZSwgIiVIIikNCg0KbTIwMDQgPC0geWVhcjIwMDQgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMDUkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA1JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAwNSREYXRlIDwtIGZvcm1hdCh5ZWFyMjAwNSRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMDUkVGltZSA8LSBmb3JtYXQoeWVhcjIwMDUkZGF0ZSwgIiVUIikNCnllYXIyMDA1JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwNSREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAwNSRkYXkgPC0gZm9ybWF0KHllYXIyMDA1JGRhdGUsICIlZCIpDQp5ZWFyMjAwNSRtb250aCA8LSBmb3JtYXQoeWVhcjIwMDUkZGF0ZSwgIiVtIikNCnllYXIyMDA1JHllYXIgPC0gZm9ybWF0KHllYXIyMDA1JGRhdGUsICIlWSIpDQp5ZWFyMjAwNSRob3VyIDwtIGZvcm1hdCh5ZWFyMjAwNSRkYXRlLCAiJUgiKQ0KDQptMjAwNSA8LSB5ZWFyMjAwNSAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAwNiRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDYkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDA2JERhdGUgPC0gZm9ybWF0KHllYXIyMDA2JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAwNiRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAwNiRkYXRlLCAiJVQiKQ0KeWVhcjIwMDYkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA2JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDA2JGRheSA8LSBmb3JtYXQoeWVhcjIwMDYkZGF0ZSwgIiVkIikNCnllYXIyMDA2JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAwNiRkYXRlLCAiJW0iKQ0KeWVhcjIwMDYkeWVhciA8LSBmb3JtYXQoeWVhcjIwMDYkZGF0ZSwgIiVZIikNCnllYXIyMDA2JGhvdXIgPC0gZm9ybWF0KHllYXIyMDA2JGRhdGUsICIlSCIpDQoNCm0yMDA2IDwtIHllYXIyMDA2ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDA3JGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwNyRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMDckRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMDckZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDA3JFRpbWUgPC0gZm9ybWF0KHllYXIyMDA3JGRhdGUsICIlVCIpDQp5ZWFyMjAwNyREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDckRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMDckZGF5IDwtIGZvcm1hdCh5ZWFyMjAwNyRkYXRlLCAiJWQiKQ0KeWVhcjIwMDckbW9udGggPC0gZm9ybWF0KHllYXIyMDA3JGRhdGUsICIlbSIpDQp5ZWFyMjAwNyR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAwNyRkYXRlLCAiJVkiKQ0KeWVhcjIwMDckaG91ciA8LSBmb3JtYXQoeWVhcjIwMDckZGF0ZSwgIiVIIikNCg0KbTIwMDcgPC0geWVhcjIwMDcgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMDgkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA4JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAwOCREYXRlIDwtIGZvcm1hdCh5ZWFyMjAwOCRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMDgkVGltZSA8LSBmb3JtYXQoeWVhcjIwMDgkZGF0ZSwgIiVUIikNCnllYXIyMDA4JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAwOCREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAwOCRkYXkgPC0gZm9ybWF0KHllYXIyMDA4JGRhdGUsICIlZCIpDQp5ZWFyMjAwOCRtb250aCA8LSBmb3JtYXQoeWVhcjIwMDgkZGF0ZSwgIiVtIikNCnllYXIyMDA4JHllYXIgPC0gZm9ybWF0KHllYXIyMDA4JGRhdGUsICIlWSIpDQp5ZWFyMjAwOCRob3VyIDwtIGZvcm1hdCh5ZWFyMjAwOCRkYXRlLCAiJUgiKQ0KDQptMjAwOCA8LSB5ZWFyMjAwOCAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAwOSRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMDkkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDA5JERhdGUgPC0gZm9ybWF0KHllYXIyMDA5JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAwOSRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAwOSRkYXRlLCAiJVQiKQ0KeWVhcjIwMDkkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDA5JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDA5JGRheSA8LSBmb3JtYXQoeWVhcjIwMDkkZGF0ZSwgIiVkIikNCnllYXIyMDA5JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAwOSRkYXRlLCAiJW0iKQ0KeWVhcjIwMDkkeWVhciA8LSBmb3JtYXQoeWVhcjIwMDkkZGF0ZSwgIiVZIikNCnllYXIyMDA5JGhvdXIgPC0gZm9ybWF0KHllYXIyMDA5JGRhdGUsICIlSCIpDQoNCm0yMDA5IDwtIHllYXIyMDA5ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDEwJGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxMCRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMTAkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMTAkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDEwJFRpbWUgPC0gZm9ybWF0KHllYXIyMDEwJGRhdGUsICIlVCIpDQp5ZWFyMjAxMCREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTAkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMTAkZGF5IDwtIGZvcm1hdCh5ZWFyMjAxMCRkYXRlLCAiJWQiKQ0KeWVhcjIwMTAkbW9udGggPC0gZm9ybWF0KHllYXIyMDEwJGRhdGUsICIlbSIpDQp5ZWFyMjAxMCR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAxMCRkYXRlLCAiJVkiKQ0KeWVhcjIwMTAkaG91ciA8LSBmb3JtYXQoeWVhcjIwMTAkZGF0ZSwgIiVIIikNCg0KbTIwMTAgPC0geWVhcjIwMTAgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMTEkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDExJGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAxMSREYXRlIDwtIGZvcm1hdCh5ZWFyMjAxMSRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMTEkVGltZSA8LSBmb3JtYXQoeWVhcjIwMTEkZGF0ZSwgIiVUIikNCnllYXIyMDExJERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxMSREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAxMSRkYXkgPC0gZm9ybWF0KHllYXIyMDExJGRhdGUsICIlZCIpDQp5ZWFyMjAxMSRtb250aCA8LSBmb3JtYXQoeWVhcjIwMTEkZGF0ZSwgIiVtIikNCnllYXIyMDExJHllYXIgPC0gZm9ybWF0KHllYXIyMDExJGRhdGUsICIlWSIpDQp5ZWFyMjAxMSRob3VyIDwtIGZvcm1hdCh5ZWFyMjAxMSRkYXRlLCAiJUgiKQ0KDQptMjAxMSA8LSB5ZWFyMjAxMSAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAxMiRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTIkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDEyJERhdGUgPC0gZm9ybWF0KHllYXIyMDEyJGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAxMiRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAxMiRkYXRlLCAiJVQiKQ0KeWVhcjIwMTIkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDEyJERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDEyJGRheSA8LSBmb3JtYXQoeWVhcjIwMTIkZGF0ZSwgIiVkIikNCnllYXIyMDEyJG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAxMiRkYXRlLCAiJW0iKQ0KeWVhcjIwMTIkeWVhciA8LSBmb3JtYXQoeWVhcjIwMTIkZGF0ZSwgIiVZIikNCnllYXIyMDEyJGhvdXIgPC0gZm9ybWF0KHllYXIyMDEyJGRhdGUsICIlSCIpDQoNCm0yMDEyIDwtIHllYXIyMDEyICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDEzJGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxMyRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMTMkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMTMkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDEzJFRpbWUgPC0gZm9ybWF0KHllYXIyMDEzJGRhdGUsICIlVCIpDQp5ZWFyMjAxMyREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTMkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMTMkZGF5IDwtIGZvcm1hdCh5ZWFyMjAxMyRkYXRlLCAiJWQiKQ0KeWVhcjIwMTMkbW9udGggPC0gZm9ybWF0KHllYXIyMDEzJGRhdGUsICIlbSIpDQp5ZWFyMjAxMyR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAxMyRkYXRlLCAiJVkiKQ0KeWVhcjIwMTMkaG91ciA8LSBmb3JtYXQoeWVhcjIwMTMkZGF0ZSwgIiVIIikNCg0KbTIwMTMgPC0geWVhcjIwMTMgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMTQkZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE0JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAxNCREYXRlIDwtIGZvcm1hdCh5ZWFyMjAxNCRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMTQkVGltZSA8LSBmb3JtYXQoeWVhcjIwMTQkZGF0ZSwgIiVUIikNCnllYXIyMDE0JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxNCREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAxNCRkYXkgPC0gZm9ybWF0KHllYXIyMDE0JGRhdGUsICIlZCIpDQp5ZWFyMjAxNCRtb250aCA8LSBmb3JtYXQoeWVhcjIwMTQkZGF0ZSwgIiVtIikNCnllYXIyMDE0JHllYXIgPC0gZm9ybWF0KHllYXIyMDE0JGRhdGUsICIlWSIpDQp5ZWFyMjAxNCRob3VyIDwtIGZvcm1hdCh5ZWFyMjAxNCRkYXRlLCAiJUgiKQ0KDQptMjAxNCA8LSB5ZWFyMjAxNCAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAxNSRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTUkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDE1JERhdGUgPC0gZm9ybWF0KHllYXIyMDE1JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAxNSRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAxNSRkYXRlLCAiJVQiKQ0KeWVhcjIwMTUkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE1JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDE1JGRheSA8LSBmb3JtYXQoeWVhcjIwMTUkZGF0ZSwgIiVkIikNCnllYXIyMDE1JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAxNSRkYXRlLCAiJW0iKQ0KeWVhcjIwMTUkeWVhciA8LSBmb3JtYXQoeWVhcjIwMTUkZGF0ZSwgIiVZIikNCnllYXIyMDE1JGhvdXIgPC0gZm9ybWF0KHllYXIyMDE1JGRhdGUsICIlSCIpDQoNCm0yMDE1IDwtIHllYXIyMDE1ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQoNCnllYXIyMDE2JGRhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxNiRkYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU06JVMiKQ0KeWVhcjIwMTYkRGF0ZSA8LSBmb3JtYXQoeWVhcjIwMTYkZGF0ZSwgIiVZLSVtLSVkIikNCnllYXIyMDE2JFRpbWUgPC0gZm9ybWF0KHllYXIyMDE2JGRhdGUsICIlVCIpDQp5ZWFyMjAxNiREYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTYkRGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkIikNCg0KeWVhcjIwMTYkZGF5IDwtIGZvcm1hdCh5ZWFyMjAxNiRkYXRlLCAiJWQiKQ0KeWVhcjIwMTYkbW9udGggPC0gZm9ybWF0KHllYXIyMDE2JGRhdGUsICIlbSIpDQp5ZWFyMjAxNiR5ZWFyIDwtIGZvcm1hdCh5ZWFyMjAxNiRkYXRlLCAiJVkiKQ0KeWVhcjIwMTYkaG91ciA8LSBmb3JtYXQoeWVhcjIwMTYkZGF0ZSwgIiVIIikNCg0KbTIwMTYgPC0geWVhcjIwMTYgJT4lDQogIHNlbGVjdChkYXRlLCBEYXRlLCBUaW1lLCBkYXksIG1vbnRoLCB5ZWFyLCBob3VyLCBzdGF0aW9uLCBPXzMpDQoNCg0KeWVhcjIwMTckZGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE3JGRhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCAlSDolTTolUyIpDQp5ZWFyMjAxNyREYXRlIDwtIGZvcm1hdCh5ZWFyMjAxNyRkYXRlLCAiJVktJW0tJWQiKQ0KeWVhcjIwMTckVGltZSA8LSBmb3JtYXQoeWVhcjIwMTckZGF0ZSwgIiVUIikNCnllYXIyMDE3JERhdGUgPC0gYXMuUE9TSVhjdCh5ZWFyMjAxNyREYXRlLCBmb3JtYXQgPSAiJVktJW0tJWQiKQ0KDQp5ZWFyMjAxNyRkYXkgPC0gZm9ybWF0KHllYXIyMDE3JGRhdGUsICIlZCIpDQp5ZWFyMjAxNyRtb250aCA8LSBmb3JtYXQoeWVhcjIwMTckZGF0ZSwgIiVtIikNCnllYXIyMDE3JHllYXIgPC0gZm9ybWF0KHllYXIyMDE3JGRhdGUsICIlWSIpDQp5ZWFyMjAxNyRob3VyIDwtIGZvcm1hdCh5ZWFyMjAxNyRkYXRlLCAiJUgiKQ0KDQptMjAxNyA8LSB5ZWFyMjAxNyAlPiUNCiAgc2VsZWN0KGRhdGUsIERhdGUsIFRpbWUsIGRheSwgbW9udGgsIHllYXIsIGhvdXIsIHN0YXRpb24sIE9fMykNCg0KDQp5ZWFyMjAxOCRkYXRlIDwtIGFzLlBPU0lYY3QoeWVhcjIwMTgkZGF0ZSwgZm9ybWF0ID0gIiVZLSVtLSVkICVIOiVNOiVTIikNCnllYXIyMDE4JERhdGUgPC0gZm9ybWF0KHllYXIyMDE4JGRhdGUsICIlWS0lbS0lZCIpDQp5ZWFyMjAxOCRUaW1lIDwtIGZvcm1hdCh5ZWFyMjAxOCRkYXRlLCAiJVQiKQ0KeWVhcjIwMTgkRGF0ZSA8LSBhcy5QT1NJWGN0KHllYXIyMDE4JERhdGUsIGZvcm1hdCA9ICIlWS0lbS0lZCIpDQoNCnllYXIyMDE4JGRheSA8LSBmb3JtYXQoeWVhcjIwMTgkZGF0ZSwgIiVkIikNCnllYXIyMDE4JG1vbnRoIDwtIGZvcm1hdCh5ZWFyMjAxOCRkYXRlLCAiJW0iKQ0KeWVhcjIwMTgkeWVhciA8LSBmb3JtYXQoeWVhcjIwMTgkZGF0ZSwgIiVZIikNCnllYXIyMDE4JGhvdXIgPC0gZm9ybWF0KHllYXIyMDE4JGRhdGUsICIlSCIpDQoNCm0yMDE4IDwtIHllYXIyMDE4ICU+JQ0KICBzZWxlY3QoZGF0ZSwgRGF0ZSwgVGltZSwgZGF5LCBtb250aCwgeWVhciwgaG91ciwgc3RhdGlvbiwgT18zKQ0KDQptYWRyaWQgPC0gbTIwMDEgJT4lDQogIHJiaW5kKG0yMDAyKSAlPiUNCiAgcmJpbmQobTIwMDMpICU+JQ0KICByYmluZChtMjAwNCkgJT4lDQogIHJiaW5kKG0yMDA1KSAlPiUNCiAgcmJpbmQobTIwMDYpICU+JQ0KICByYmluZChtMjAwNykgJT4lDQogIHJiaW5kKG0yMDA4KSAlPiUNCiAgcmJpbmQobTIwMDkpICU+JQ0KICByYmluZChtMjAxMCkgJT4lDQogIHJiaW5kKG0yMDExKSAlPiUNCiAgcmJpbmQobTIwMTIpICU+JQ0KICByYmluZChtMjAxMykgJT4lDQogIHJiaW5kKG0yMDE0KSAlPiUNCiAgcmJpbmQobTIwMTUpICU+JQ0KICByYmluZChtMjAxNikgJT4lDQogIHJiaW5kKG0yMDE3KSAlPiUNCiAgcmJpbmQobTIwMTgpIA0KDQpyYWRhcnN0YXRpb25zIDwtIHN0YXRpb25zICU+JSBzZWxlY3QoaWQsIG5hbWUpDQptYWRyaWQgPC0gIHJpZ2h0X2pvaW4obWFkcmlkLCByYWRhcnN0YXRpb25zLCBieSA9IGMoInN0YXRpb24iID0gImlkIikpDQpwcmludChoZWFkKG1hZHJpZCkpDQoNCiM1DQptYWRyaWRfbWVhbl9kYWlseSA8LSBtYWRyaWQgJT4lIGdyb3VwX2J5KERhdGUpICU+JSBzdW1tYXJpc2UoT18zX21lYW4gPSBtZWFuKE9fMywgbmEucm0gPSBUUlVFKSkNCmdncGxvdChtYWRyaWRfbWVhbl9kYWlseSwgYWVzKHggPSBhcy5EYXRlKERhdGUpLCB5ID0gT18zX21lYW4pKSArIGdlb21fbGluZShjb2xvciA9ICdibHVlJykgKw0KICB0aGVtZV9idygpICsNCiAgbGFicyh4ID0gJ1llYXInLCB5ID0gJ096b25lIExldmVsICjOvGcvbTMpJywgdGl0bGU9J0RhaWx5IE96b25lIExldmVscyBpbiBNYWRyaWQgKEZpZ3VyZSAxKScpICsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9MTApKSArDQogIHNjYWxlX3hfZGF0ZShicmVha3MgPSBzZXEoYXMuRGF0ZSgiMjAwMS0wMS0wMSIpLCBhcy5EYXRlKCIyMDE4LTA3LTAxIiksIGJ5PSIxMiBtb250aHMiKSwgZGF0ZV9sYWJlbHMgPSAiJVkiKQ0KDQptYWRyaWRfbWVhbl9tb250aGx5IDwtIG1hZHJpZCAlPiUgZ3JvdXBfYnkoeWVhciwgbW9udGgpICU+JSBzdW1tYXJpc2UoIE9fM19tZWFuID0gbWVhbihPXzMsIG5hLnJtID0gVFJVRSkpJT4lIG11dGF0ZSh0aW1lID0gcGFzdGUoeWVhciwgIi0iLCBtb250aCwgIi0gMDEiKSkNCg0KbWFkcmlkX21lYW5fbW9udGhseSR0aW1lIDwtIGFzLkRhdGUobWFkcmlkX21lYW5fbW9udGhseSR0aW1lLCBmb3JtYXQgPSAiJVkgLSAlbSAtICVkIikNCg0KZ2dwbG90KG1hZHJpZF9tZWFuX21vbnRobHksIGFlcyh4ID0gdGltZSwgeSA9IE9fM19tZWFuKSkgKyBnZW9tX2xpbmUoY29sb3IgPSAnYmx1ZScpICsgDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsNCiAgbGFicyh4ID0gJ01vbnRoJywgeSA9ICdPem9uZSBMZXZlbCAozrxnL20zKScsIHRpdGxlPSdNb250aGx5IE96b25lIExldmVscyBpbiBNYWRyaWQgKEZpZ3VyZSAyKScpICsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9MTApKSArDQogIHNjYWxlX3hfZGF0ZShicmVha3MgPSBzZXEoYXMuRGF0ZSgiMjAwMS0wMS0wMSIpLCBhcy5EYXRlKCIyMDE4LTA3LTAxIiksIGJ5PSI2IG1vbnRocyIpLCBkYXRlX2xhYmVscyA9ICIlYi0leSIpIA0KDQojNg0KZHVtbXkxIDwtIGFzLnZlY3RvcihtYWRyaWRfbWVhbl9tb250aGx5JE9fM19tZWFuKQ0KbWFkcmlkLnRzIDwtIHRzKGR1bW15MSxzdGFydCA9IGMoMjAwMSwxKSwgZW5kID0gYygyMDE4LDUpLCBmcmVxdWVuY3kgPSAxMikNCg0KcGxvdChtYWRyaWQudHMsIHlsYWI9Ik96b25lIExldmVsICjOvGcvbTMpIiwgbWFpbiA9ICJUaW1lIHNlcmllcyBwbG90IGZvciBPMyAoRmlndXJlIDMpIikNCnBvaW50cyh5PW1hZHJpZC50cywgeD10aW1lKG1hZHJpZC50cyksIHBjaCA9IGFzLnZlY3RvcihzZWFzb24obWFkcmlkLnRzKSkpDQoNCiM2LjENCmFkZi50ZXN0KG1hZHJpZC50cykNCg0KIzYuMg0KcGFyKG1mcm93PSBjKDEsMikpDQphY2YobWFkcmlkLnRzLCBtYWluID0gIkZpZ3VyZSA0IikNCnBhY2YobWFkcmlkLnRzLCBtYWluID0gIkZpZ3VyZSA1IikNCg0KIzYuMw0KI1VzaW5nIHNlYXNvbmFsIGRpZmZlcmVuY2luZw0KZml0Lm1hZHJpZCA8LSBzdGwobWFkcmlkLnRzLCB0LndpbmRvdz0xNSwgcy53aW5kb3c9InBlcmlvZGljIiwgcm9idXN0PVRSVUUpDQpwbG90KGZpdC5tYWRyaWQsIG1haW4gPSAiRmlndXJlIDciKQ0KZml0Lm1hZHJpZC5zZWFzb25hbCA9IGZpdC5tYWRyaWQkdGltZS5zZXJpZXNbLCJzZWFzb25hbCJdIA0KDQojRXh0cmFjdCB0aGUgc2VhbnNvbmFsIGNvbXBvbmVudCBmcm9tIHRoZSBvdXRwdXQNCm1hZHJpZC5zZWFzb25hbC5hZGp1c3RlZCA9IG1hZHJpZC50cyAtIGZpdC5tYWRyaWQuc2Vhc29uYWwNCnBsb3QobWFkcmlkLnNlYXNvbmFsLmFkanVzdGVkLHhsYWI9J1RpbWUnLCB5bGFiID0nT3pvbmUgTGV2ZWxzICjOvGcvbTMpJywgbWFpbiA9ICJTZWFzb25hbCBhZGp1c3RlZCB0aW1lIHNlcmllcyAoRmlndXJlIDgpIikNCnBvaW50cyh5PW1hZHJpZC5zZWFzb25hbC5hZGp1c3RlZCx4PXRpbWUobWFkcmlkLnNlYXNvbmFsLmFkanVzdGVkKSwgcGNoPWFzLnZlY3RvcihzZWFzb24obWFkcmlkLnNlYXNvbmFsLmFkanVzdGVkKSkpDQoNCiNFeHRyYWN0IHRoZSB0cmVuZCBjb21wb25lbnQgZnJvbSB0aGUgb3V0cHV0DQpmaXQubWFkcmlkLnRyZW5kID0gZml0Lm1hZHJpZCR0aW1lLnNlcmllc1ssInRyZW5kIl0gDQptYWRyaWQuc2Vhc29uYWwudHJlbmQuYWRqdXN0ZWQgPSBtYWRyaWQudHMgLSBmaXQubWFkcmlkLnNlYXNvbmFsIC0gZml0Lm1hZHJpZC50cmVuZA0KcGxvdChtYWRyaWQuc2Vhc29uYWwudHJlbmQuYWRqdXN0ZWQseGxhYj0nVGltZScsIHlsYWIgPSdPem9uZSBMZXZlbCAozrxnL20zKScsIG1haW4gPSAiVHJlbmQgJiBzZWFzb25hbCBhZGp1c3RlZCB0aW1lIHNlcmllcyAoRmlndXJlIDkpIikNCnBvaW50cyh5PW1hZHJpZC5zZWFzb25hbC50cmVuZC5hZGp1c3RlZCx4PXRpbWUobWFkcmlkLnNlYXNvbmFsLnRyZW5kLmFkanVzdGVkKSwgcGNoPWFzLnZlY3RvcihzZWFzb24obWFkcmlkLnNlYXNvbmFsLnRyZW5kLmFkanVzdGVkKSkpDQoNCmFkZi50ZXN0KG1hZHJpZC5zZWFzb25hbC50cmVuZC5hZGp1c3RlZCkNCg0KIzcuMQ0KI0R5bmxtIE1vZGVscw0KWS50ID0gbWFkcmlkLnRzDQoNCm1vZGVsLmR5bmxtMSA9IGR5bmxtKFkudCB+IEwoWS50ICwgayA9IDEgKSArIHRyZW5kKFkudCkgKyBzZWFzb24oWS50KSkNCg0KbW9kZWwuZHlubG0yID0gZHlubG0oWS50IH4gTChZLnQgLCBrID0gMiApICsgdHJlbmQoWS50KSArIHNlYXNvbihZLnQpKQ0KDQptb2RlbC5keW5sbTMgPSBkeW5sbShZLnQgfiBMKFkudCAsIGsgPSAxICkgKyB0cmVuZChZLnQpICsgc2Vhc29uKFkudCkpICNNQVNFIDAuNDAzODk3CQ0KDQptb2RlbC5keW5sbTEuMiA9IGR5bmxtKFkudCB+IEwoWS50ICwgayA9IDEgKSArIHNlYXNvbihZLnQpKSANCg0KbW9kZWwuZHlubG0xLjMgPSBkeW5sbShZLnQgfiBMKFkudCAsIGsgPSAxICkgKyB0cmVuZChZLnQpKQ0KDQptb2RlbC5keW5sbTQuMSA9IGR5bmxtKFkudCB+IEwoWS50ICwgayA9IDEgKSArIEwoWS50ICwgayA9IDIgKSsgc2Vhc29uKFkudCkpDQoNCm1vZGVsLmR5bmxtNC4yID0gZHlubG0oWS50IH4gTChZLnQgLCBrID0gMSApICsgTChZLnQgLCBrID0gMiApICsgc2Vhc29uKFkudCkpDQoNCiNDcmVhdGluZyB0YWJsZSBzdW1tYXJ5IG9mIG1vZGVsIHJlc3VsdHMNCmFpYyA9IEFJQyhtb2RlbC5keW5sbTEsIG1vZGVsLmR5bmxtMS4yLCBtb2RlbC5keW5sbTEuMyxtb2RlbC5keW5sbTIsbW9kZWwuZHlubG0zLG1vZGVsLmR5bmxtNC4xLG1vZGVsLmR5bmxtNC4yKQ0KYmljID0gQklDKG1vZGVsLmR5bmxtMSwgbW9kZWwuZHlubG0xLjIsIG1vZGVsLmR5bmxtMS4zLG1vZGVsLmR5bmxtMixtb2RlbC5keW5sbTMsbW9kZWwuZHlubG00LjEsbW9kZWwuZHlubG00LjIpDQptYXNlID0gTUFTRShsbShtb2RlbC5keW5sbTEpLCBsbShtb2RlbC5keW5sbTEuMiksIGxtKG1vZGVsLmR5bmxtMS4zKSxsbShtb2RlbC5keW5sbTIpLGxtKG1vZGVsLmR5bmxtMyksbG0obW9kZWwuZHlubG00LjEpLGxtKG1vZGVsLmR5bmxtNC4yKSkNCg0KZHlubG1fdGFibGUgPC0gY2JpbmQoYWljLGJpYyxtYXNlKQ0KZHlubG1fdGFibGUNCiNCZXN0IG1vZGVsIGlzIG1vZGVsLmR5bmxtMQ0Kc3VtbWFyeShtb2RlbC5keW5sbTEpDQpjaGVja3Jlc2lkdWFscyhtb2RlbC5keW5sbTEpDQoNCiM3LjINCm1vZGVsLnNpbXBsZSA8LSBzZXMobWFkcmlkLnRzLGg9MipmcmVxdWVuY3kobWFkcmlkLnRzKSkjTUFTRSAxLjY0OTk0OA0KDQptb2RlbC5odzEgPC0gaHcobWFkcmlkLnRzLHNlYXNvbmFsPSJhZGRpdGl2ZSIpICNNQVNFIDAuNjg3MjgxNCANCg0KbW9kZWwuaHcyIDwtIGh3KG1hZHJpZC50cyxzZWFzb25hbD0iYWRkaXRpdmUiLGRhbXBlZCA9IFRSVUUpICNNQVNFIDAuNjg0MzQ5NSANCg0KbW9kZWwuaHczIDwtIGh3KG1hZHJpZC50cyxzZWFzb25hbD0ibXVsdGlwbGljYXRpdmUiKSAjTUFTRSAwLjY5NzY0NzUgDQoNCm1vZGVsLmh3NCA8LSBodyhtYWRyaWQudHMsc2Vhc29uYWw9Im11bHRpcGxpY2F0aXZlIixleHBvbmVudGlhbCA9IFRSVUUpICNNQVNFIDAuNzA3NTI1NCANCg0KI1RhYmxlIGNyZWF0aW9uDQpuYW1lX2VzIDwtIGMoIm1vZGVsLnNpbXBsZSIsIm1vZGVsLmh3MSIsIm1vZGVsLmh3MiIsIm1vZGVsLmh3MyIsIm1vZGVsLmh3NCIpDQptYXNlX2VzIDwtIGMoMS42NDk5NDgsMC42ODcyODEsMC42ODQzNDksMC42OTc2NDcsMC43MDc1MjUpDQoNCnRhYmxlX2VzIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQobmFtZV9lcyxtYXNlX2VzKSkNCnRhYmxlX2VzDQojQmVzdCBtb2RlbCBpcyBtb2RlbC5odzINCnN1bW1hcnkobW9kZWwuaHcyKQ0KY2hlY2tyZXNpZHVhbHMobW9kZWwuaHcyKQ0KDQojNy4zDQptb2RlbC5BTkEgPSBldHMobWFkcmlkLnRzLG1vZGVsID0gIkFOQSIpICNNQVNFIDAuNjg0NzI4DQoNCm1vZGVsLkFBQSA9IGV0cyhtYWRyaWQudHMsbW9kZWwgPSAiQUFBIikjTUFTRSAwLjY4NzI4MTQNCg0KbW9kZWwuQUFkQS5kYW1wZWQgPSBldHMobWFkcmlkLnRzLG1vZGVsID0gIkFBQSIsZGFtcGVkID0gVFJVRSkgI01BU0UgMC42ODQzNDk1DQoNCm1vZGVsLkFOTiA9IGV0cyhtYWRyaWQudHMsbW9kZWwgPSAiQU5OIikjTUFTRSAxLjY0OTU4NCANCg0KbW9kZWwuTUFNID0gZXRzKG1hZHJpZC50cyxtb2RlbCA9ICJNQU0iKSNNQVNFIDAuNjkxODk2Mg0KDQptb2RlbC5NQU0uZGFtcGVkID0gZXRzKG1hZHJpZC50cyxtb2RlbCA9ICJNQU0iLGRhbXBlZCA9IFRSVUUpICNNQVNFIDAuNjkxODk2Mg0KDQptb2RlbC5NTU0gPSBldHMobWFkcmlkLnRzLG1vZGVsID0gIk1NTSIpI01BU0UgMC42OTE5ODQ5DQoNCm1vZGVsLk1NZE0gPSBldHMobWFkcmlkLnRzLG1vZGVsID0gIk1NTSIsZGFtcGVkID0gVFJVRSkgI01BU0UgMC42OTE5ODQ5DQoNCm1vZGVsLlpaWiA9IGV0cyhtYWRyaWQudHMsIG1vZGVsPSJaWloiKSMjTUFTRSAwLjY4NDcyOA0KDQojVGFibGUgY3JlYXRpb24NCmFpY19zcyA8LSBBSUMobW9kZWwuQU5BLCBtb2RlbC5BQUEsIG1vZGVsLkFBZEEuZGFtcGVkLCBtb2RlbC5BTk4sIG1vZGVsLk1BTSwgbW9kZWwuTUFNLmRhbXBlZCwgbW9kZWwuTU1NLCBtb2RlbC5NTWRNLCBtb2RlbC5aWlopDQpiaWNfc3MgPC0gQklDKG1vZGVsLkFOQSwgbW9kZWwuQUFBLCBtb2RlbC5BQWRBLmRhbXBlZCwgbW9kZWwuQU5OLCBtb2RlbC5NQU0sIG1vZGVsLk1BTS5kYW1wZWQsIG1vZGVsLk1NTSwgbW9kZWwuTU1kTSwgbW9kZWwuWlpaKQ0KbWFzZV9zcyA8LSBjKDAuNjg0NzI4LDAuNjg3MjgxNCwwLjY4NDM0OTUsMS42NDk1ODQsMC42OTE4OTYyLDAuNjkxODk2MiwwLjY5MTk4NDksMC42OTE5ODQ5LDAuNjg0NzI4KQ0KdGFibGVfc3MgPC0gYXMuZGF0YS5mcmFtZShjYmluZChhaWNfc3MsYmljX3NzLG1hc2Vfc3MpKQ0KdGFibGVfc3MNCiNCZXN0IG1vZGVsIGlzIG1vZGVsLkFOQQ0Kc3VtbWFyeShtb2RlbC5BTkEpDQpjaGVja3Jlc2lkdWFscyhtb2RlbC5BTkEpDQoNCiM4DQojVGFibGUgY3JlYXRpb24gZm9yIGZpbmFsIG1vZGVsIHNlbGVjdGlvbg0KDQptb2RlbF9maW5hbCA8LSBjKCJtb2RlbC5keW5sbTEiLCAibW9kZWwuaHcyIiwgIm1vZGVsLkFOQSIpDQp0eXBlX2ZpbmFsIDwtIGMoIkR5bmFtaWMgTGluZWFyIiwgIkV4cG9uZW50aWFsIFNtb290aGluZyIsICJTdGF0ZS1TcGFjZSIpDQphaWNfZmluYWwgPC0gYygxMjMxLjQ5OCwgIk5BIiwgMTc3NS44NTgpDQpiaWNfZmluYWwgPC0gYygxMjgxLjU2MSwgIk5BIiwgMTgyNS45OTMpDQptYXNlX2ZpbmFsIDwtIGMoMC40MDM5MjI4LCAwLjY4NDM0OTUsIDAuNjg0NzI4MCkNCg0KdGFibGVfZmluYWwgPC0gYXMuZGF0YS5mcmFtZShjYmluZChtb2RlbF9maW5hbCx0eXBlX2ZpbmFsLGFpY19maW5hbCxiaWNfZmluYWwsbWFzZV9maW5hbCkpDQp0YWJsZV9maW5hbA0KDQojOQ0KI0R5bmxtIEZvcmVjYXN0DQpxID0gMTANCm4gPSBucm93KG1vZGVsLmR5bmxtMSRtb2RlbCkNCg0KbWFkcmlkLmZyYyA8LSBhcnJheShOQSwgKG4rcSkpDQptYWRyaWQuZnJjWzE6bl0gPC0gWS50WzE6bGVuZ3RoKFkudCldDQoNCnRyZW5kIDwtIGFycmF5KE5BLHEpDQp0cmVuZC5zdGFydCA8LSBtb2RlbC5keW5sbTEkbW9kZWxbbiwgInRyZW5kKFkudCkiXQ0KdHJlbmQgPC0gc2VxKHRyZW5kLnN0YXJ0LCB0cmVuZC5zdGFydCArIHEvMTIsIDEvMTIpDQoNClBpIDwtIGFycmF5KE5BLCBkaW0gPSBjKG4rcSwyKSkNCg0KZm9yIChpIGluIDE6cSl7DQogIG1vbnRocyA8LSBhcnJheSgwLDExKQ0KICBtb250aHNbKGktMSklJTEyXSA9IDENCiAgZGF0YS5uZXcgPSBjKDEsbWFkcmlkLmZyY1tuLTEraV0sdHJlbmRbaV0sbW9udGhzKQ0KICBtYWRyaWQuZnJjW24raV0gPSBhcy52ZWN0b3IobW9kZWwuZHlubG0xJGNvZWZmaWNpZW50cykgJSolIGRhdGEubmV3DQp9DQoNCnBhcihtZnJvdyA9IGMoMSwxKSkNCnBsb3QoWS50LHhsaW09YygyMDAxLDIwMjApLCB5bGltPWMoMCwxMDApLHlsYWI9J096b25lIExldmVsICjOvGcvbTMpJyx4bGFiPSdZZWFyJyxtYWluID0gIkR5bmxtIEZvcmVjYXN0IG9mIE96b25lIExldmVscyBpbiBNYWRyaWQgKEZpZ3VyZSAxMCkiKQ0KbGluZXModHMobWFkcmlkLmZyY1sobisxKToobitxKV0sc3RhcnQ9YygyMDE4LDYpLGZyZXF1ZW5jeSA9IDEyKSxjb2w9ImdyZWVuIikNCmxpbmVzKHRzKG1hZHJpZC5mcmNbKG4rMSk6KG4rcSldICsgMipzZChtYWRyaWQuZnJjWyhuKzEpOihuK3EpXSksIHN0YXJ0ID0gYygyMDE4LDYpLCBmcmVxdWVuY3kgPSAxMiksIGNvbCA9ICJyZWQiKQ0KbGluZXModHMobWFkcmlkLmZyY1sobisxKToobitxKV0gLSAyKnNkKG1hZHJpZC5mcmNbKG4rMSk6KG4rcSldKSwgc3RhcnQgPSBjKDIwMTgsNiksIGZyZXF1ZW5jeSA9IDEyKSwgY29sID0gImJsdWUiKQ0KbGVnZW5kKCJ0b3BsZWZ0IiwgbHR5PTEsIHBjaD0xLCBjb2w9YygiYmxhY2siLCJibHVlIiwicmVkIiwiZ3JlZW4iKSwgdGV4dC53aWR0aCA9IDQsDQogICAgICAgYygiRGF0YSIsIjUlIGxvd2VyIGxpbWl0IiwiOTUlIHVwcGVyIGxpbWl0IiwiTWVhbiBwcmVkaWN0aW9uIikpDQoNCmBgYA0KDQo=