1 Introduction

For this project, we will be creating a Time Series. We will be working on decomposing this time series and forecasting with decomposing. The data set I found for this project looks at the sale prices for homes that have been sold from 2007 to 2019 in the United States. This data set includes the sale prices of these various homes over this course of 12 years.

We will use this data set to create a monthly time series to analyze these home sale prices along with any sort of trends that there may be. Using this monthly time series, we will look at the trends in home sale prices by month, meaning we will find the average home sale price for each month over the course of 2007 to 2019. This will allow us to analyze the time series and look for trends occurring across the many months which the data was collected over the course of. We will work on decomposing this monthly time series of the average home sale prices and will use forecasting with decomposing for this analysis of the time series data.

1.1 Data Description

I found this data set on kaggle.com on the following webpage: https://www.kaggle.com/datasets/htagholdings/property-sales?select=raw_sales.csv

This data set looks at the sale prices for homes that have been recorded from 2007 to 2019. The first observation was collected on February 6, 2007, and the final observation in the data set was collected on July 26, 2019. The sale prices are given in US dollars, and were collected to look at the trends amongst the sale prices of homes in this particular region.

We will read in the data set from Github and we will call it “home”.

home <- read.csv("https://raw.githubusercontent.com/JosieGallop/STA321/refs/heads/main/dataset/raw_sales.csv")

The original data set contains multiple variables looking at things such as the postcode of the house, the type of property it is, and the number of bedrooms in the house. However, for this project, we are just looking at creating a time series with the variable of house sale prices. So, we will only be interested in the home sale price and the date of which the house was sold. For this time series project, we will look at the monthly averages of the home sale prices in order to create a monthly time series which we will use for analysis to see if there are any notable patterns we can see from the monthly time series.

1.2 Variables

The two variables which we are interested in looking at for this time series project include:

  • datesold: The date on which the house was sold. This is given in the format of year-month-day time”, for example, “2007-02-07 00:00:00”. This is a variable used for identifying each observation of house sales. We will adjust this variable to represent the year and the month of which the home sales were collected in order to create a monthly time series report.

  • price: The price for which a house was sold for, given in US dollars. This is a quantitative, numerical variable which we are interested in observing the trends of over time. We will adjust this variable to represent the average home sale price for a specific month of a specific year in order to create a monthly time series report.

We will create a monthly time series which observed and analyzes the trends and patterns seen in the average home sale prices by month over the course of 2007 to 2019.

2 Exploratory Data Analysis

Before we create our time series object, let’s ensure that there are no missing values in the original data set, “home”.

colSums(is.na(home))
    datesold     postcode        price propertyType     bedrooms 
           0            0            0            0            0 

As we can see, there are zero missing values in our data set, so that means we do not have to worry about filling in any missing observations. We can proceed with creating our time series object.

2.1 Time Series Data Prepartion

We will adjust the data to create our monthly time series. This will allow us to analyze the monthly trends in home sale prices over the years of which this data was collected.

We will start by creating a new data set called “home1” with just the variables of datesold and price.

home1 <- data.frame(home$datesold, home$price)
home1$datesold <- home1$home.datesold
home1$price <- home1$home.price
home1 <- select(home1, -1,-2)

For this time series project, we will create a monthly time series. This will take a look at the average home sale price from each month of which the data set was collected from. This will allow us to look for trends and patterns across the monthly average sale prices that have been observed from the span of 2007 to 2019.

The datesold variable includes dates that are given in the format of “Year-Month-Day hour:minute:second”. While scrolling through the data set entries, I noticed that the time portion of every data entry was given as 00:00:00. This means that all of the observations were recorded exactly at midnight. All of the observations have this exact same time as their recorded date, so we will drop the time portion from the datesold variable to make it easier to interpret, as well as to make it easier to create our monthly average time series.

We will start by dropping the time component from the observations and the date of which the home sale occurred. This will leave us with just a “Year-Month-Day” format for the entries of the datesold variable.

home1$datesold <- as.Date(ymd_hms(home1$datesold))

Next, we will calculate the average home sale price per month in order to create a data set which we can use to create a montly time series. The variable datesold will now be given in the format “Year-Month” and the price variable will represent the average home sale price for that specific month. We will create a new data set called “home2” to store this updated version of the data which we will use for our monthly time series.

home2 <- home1 %>%
  mutate(datesold = format(datesold, "%Y-%m")) %>%
  group_by(datesold) %>%
  summarise(price = mean(price, na.rm = TRUE))

There are exactly 150 observations in this revised data set which looks at the average home sale prices by month, so we do not need to drop any observations from the data set since this is an ideal amount to use for a time series.

2.2 Time Series Plot

Now, let’s create a time series object from our data and plot it to help visualize any potential trends that may be occurring within this time series object. We will call this time series object “home.ts”. Since we are creating a monthly time series looking at the average home sale prices by month, our frequency will be 12.

home.ts <- ts(home2$price, start = c(2007, 1), frequency = 12)
plot(home.ts, main="Monthly Average Home Sale Prices from 2007 to 2019", xlab = "Year", ylab = "Price")

Looking at the time series plot, it appears that there are several patterns and trends going on within this monthly time series of the home sale prices from 2007 to 2019. There appears to be some sort of seasonality which can be seen by the various peaks and drops which appears to be repeating after some period of time. We will look further into any potential seasonality in this time series with the decomposition methods.

Additionally, there appears to be a major peak and drop around the start of the time series at around 2007 to 2008. This reaches much higher than any other portion of the time series and is evidence of something unusual which could be going on at this point. It is possible that there was some major event occurring within the housing market at this point which could have led to a massive rise and then a sudden fall in the average sale prices of homes at the time.

Also, it appears that home sale prices have gradually increased from the start of the time series in 2007 to the end of the time series in 2019. We can see that the average home sale price has continuously risen over the course of this time series. This could suggest an additive or multiplicative trend. In this case, it appears to be more of a multiplicative trend as the seasonal variation does appear to have grown and gotten more dramatic over time rather than staying identical regardless of the year.

3 Forecasting with Classical Decomposing

First, let’s begin with looking at a classical decomposition of our time series data.

# Classical Decomposition
cls.decomp = decompose(home.ts)
par(mar = c(2,2,2,2))
plot(cls.decomp, xlab = "Year")

As we can see in our plot, most of the house prices range between $300,000 and $800,000.

There appears to be something interesting going on at the beginning of the time series plot. There is a very sharp peak around 2007 to 2008, with a major spike much higher than anything around it. This is in fact the observation with the highest price in the entire time series plot, reaching up to $800,000, so this is something of interest from the data. After doing some research, there was a major financial crisis which occurred from 2007 to 2008 which marked a huge economic recession. It would make sense that a big financial crisis like this would also have a significant effect on the housing market, so this is likely why there is such a sharp and sudden peak in home sale prices around 2007 to 2008.

There does appear to be some sort of seasonal trend going on within the data as seen by the various peaks and drops that can be seen within the plot. This shows evidence of some sort of seasonality occurring. This seasonal pattern appears to repeat over each year, with the highest and lowest peaks occurring within the span of each year period.

A seasonal trend would make sense for a data set relating to house sale prices as the time of year could affect the number of individuals buying a new home, and thus sale prices rising to meet this larger demand. For instance, times of year such as the summer may see an increase of buyers looking for a new house due to the ideal weather and the timing of summer break making it ideal to buy a house before the next school year begins if the buyers have children. This greater demand could lead to a rise in the sales prices of the homes, and could be a potential explanation for this seasonal trend we see in the time series plot.

Additionally, there appears to be an overall increase in home sale prices from 2007 to 2019. Looking at the trend curve, we can see that there has been an overall, gradual increase in the home sale prices from the start of this data set’s collection to the end of its collection. So, we can conclude that the home sale prices have gradually increased from what they were in 2007 to what they became in 2019.

4 Forecasting with STL Decomposing

Next, let’s use STL decomposition on our time series data.

# STL Decomposition
stl.decomp = stl(home.ts,  s.window = "periodic")
par(mar = c(2,2,2,2))
plot(stl.decomp)

Using this STL decomposition method provides several advantages to the classical decomposition method we used previously. The STL decomposition method uses locally estimated scatterplot smoothing, also known as LOESS, to estimate non-linear trends with greater accuracy in its forecasting than using the classical decomposition would provide.

These plots created with the STL decomposition method allow us to observe some of the trends and patterns of our time series data. Overall, these plots generated by the STL decomposition provide similar findings to those created in the previous classical decomposition method. We see a similar overall trend, with various peaks and falls over the course of the data being collected from 2007 to 2019 by monthly averages of the home sale prices.

We also see a similar seasonal pattern that repeats multiple times over the course of the time which the data was collected. This once again matches with the idea of an annual seasonality, as it appears like this seasonal pattern appears to repeat for each year that occurs over the course of the time series data collection. Additionally, similar to what was found in the classical decomposition method, is that there is a significant, notable peak around the start of the time series in 2007 to 2008 which shows the highest home sales prices out of the entire data set. This major peak around 2007 to 2008 is the highest average home sales prices which was observed throughout the time series data collection. Furthermore, we can see the overall trend of a gradual increase in the home sale prices from 2007 to 2019. This can be seen in the trend curve by how the average home sale prices have gradually risen and increased from the start of the time series data collection in 2007 to the end of the time series in 2019. These patterns found by the STL decomposition method match up with what was observed previously, and this STL decomposition method provides greater accuracy in its forecasting.

5 Training and Testing Data Sets

Next, let’s look into creating a training and a testing data set to forecast the time series model.

We will use the last seven observations to make up our testing data set, and we will try out four different potential sizes for the training data set. The four different sizes I will try out for the training data set are n = 100, n = 70, n= 50, and n = 35. This will be the number of observations which are used in the training data set.

data = home.ts
n0 = length(data)
train.data1 = home.ts[43:(n0-7)]
train.data2 = home.ts[73:(n0-7)]
train.data3 = home.ts[93:(n0-7)]
train.data4 = home.ts[108:(n0-7)]

# The testing data set will be the last 7 observations.
test.data = home.ts[(n0-6):n0]

# Creating the four potential training data set sizes.
train1.ts = ts(train.data1, frequency = 12, start = c(2007-02, 1))
train2.ts = ts(train.data2, frequency = 12, start = c(2010-01, 1))
train3.ts = ts(train.data3, frequency = 12, start = c(2013-01, 1))
train4.ts = ts(train.data4, frequency = 12, start = c(2015-01, 1))

stl1 = stl(train1.ts, s.window = 12)
stl2 = stl(train2.ts, s.window = 12)
stl3 = stl(train3.ts, s.window = 12)
stl4 = stl(train4.ts, s.window = 12)

Next, let’s create the objects for forecasting.

# Forecasting
fcst1 = forecast(stl1,h = 7, method = "naive")
fcst2 = forecast(stl2,h = 7, method = "naive")
fcst3 = forecast(stl3,h = 7, method = "naive")
fcst4 = forecast(stl4,h = 7, method = "naive")

We will perform error analysis to help us determine which size is best for the training data set out of the four potential sizes we are going to be choosing between. We will look at both the mean absolute prediction error (MAPE) and the mean squared error (MSE) of the potential training data sets.

PE1 = (test.data-fcst1$mean)/fcst1$mean
PE2 = (test.data-fcst2$mean)/fcst2$mean
PE3 = (test.data-fcst3$mean)/fcst3$mean
PE4 = (test.data-fcst4$mean)/fcst4$mean

# Mean Absolute Prediction Errors.
MAPE1 = mean(abs(PE1))
MAPE2 = mean(abs(PE2))
MAPE3 = mean(abs(PE3))
MAPE4 = mean(abs(PE4))

E1 = test.data-fcst1$mean
E2 = test.data-fcst2$mean
E3 = test.data-fcst3$mean
E4 = test.data-fcst4$mean

# Mean Squared Errors.
MSE1 = mean(E1^2)
MSE2 = mean(E2^2)
MSE3 = mean(E3^2)
MSE4 = mean(E4^2)

MSE = c(MSE1, MSE2, MSE3, MSE4)
MAPE = c(MAPE1, MAPE2, MAPE3, MAPE4)
accuracy = cbind(MSE = MSE, MAPE = MAPE)
row.names(accuracy) = c("n = 100", "n = 70", "n = 50", "n = 35")
kable(accuracy, caption = "Error Comparison of the Forecast Results with Different Training Data Set Sizes")
Error Comparison of the Forecast Results with Different Training Data Set Sizes
MSE MAPE
n = 100 1206113411 0.0421218
n = 70 1246521262 0.0443203
n = 50 1365242537 0.0486566
n = 35 1292631907 0.0484141

As we can see, the training data set with a size of n = 100 has the lowest of both the MSE and the MAPE out of the four potential training data set sizes that were looked at. This suggests that this size is the most ideal out of the potential options as it reduces the errors the most out of the four options that were considered.

We will create a visualization to compare these forecast errors and confirm the finding that a sample size of 100 observations reduces the errors most out of the potential sample sizes that were considered for the training data set of the time series.

First, let’s look at a plot of the mean squared errors (MSE) for each of the four potential sample sizes.

# Plot of the MSE.
plot(1:4, MSE, type = "b", col="darkorchid", ylab = "Errors", xlab = "Sample Size",
     main = "MSE", axes = FALSE)
     labs = c("n = 100", "n = 70", "n = 50", "n = 35")
     axis(1, at = 1:4, label = labs)
     axis(2)

As we can see, n = 100 observations has the lowest MSE out of the four potential sample sizes, indicating that it is the ideal choice, because it reduces the errors.

We will also look at the plot of the mean absolute prediction errors (MAPE) for each of the four potential training data set sizes.

# Plot of the MAPE.
plot(1:4, MAPE, type = "b", col="darkorchid", ylab = "Errors", xlab = "Sample Size",
     main = "MAPE", axes = FALSE)
     labs = c("n = 100", "n = 70", "n = 50", "n = 35")
     axis(1, at = 1:4, label = labs)
     axis(2)

Once again, the sample size of n = 100 observations shows the lowest value of the MAPE, showing that is the ideal choice out of the four sample sizes, because it reduces the errors.

As we can see in the plots for both the MSE and the MAPE, n = 100 observations shows the lowest errors, and as the sample size decreases in the number of observations, the errors for both the MSE and the MAPE increase, resulting in errors much greater than those of the sample size with 100 observations. This strengthens that the ideal training data set size out of the four options that were considered is a size of 100 observations. A training data set with 100 observations yields the best performance, because it reduces the errors.

So, we can conclude that from the choices of a training data set with 100, 70, 50, or 35 observations, the best choice is the training data set with 100 observations. This choice of 100 observations results in the lowest errors, and therefore, provides the best performance for forecasting our time series.

6 Forecasting the Upcoming Months

We will use forecasting to provide an estimate for the upcoming months after the end of the time series data collection. This time series collected data up until July 2019, so we will forecast the estimated home sale prices for the months which follow the end of this data collection.

We will use an exponential smoothing method for this forecasting. This will allow us to forecast the next twelve months of average home sale prices by the month. Since our time series stopped at July 2019, this forecasting will provide estimates of monthly average home sale prices up through June 2020.

We stated previosuly that there appeared to be a multiplicative trend occurring within this time series. This was seen by how the seasonal variation appeared to increase over time along with the overall gradual increase in monthly average home sales. We will reflect this multiplicative trend with the exponential smoothing forecast.

ets <- ets(home.ts, model = "MAM")
forecast <- forecast(ets, h = 12)
plot(forecast, main = "Forecast of the Average Home Sale Prices \n for the Next 12 Months")

As we can see, this plot illustrates the forecast for the next twelve months after the end of the time series. This forecast provides an estimate for what the average home sale prices will look like for the next twelve months.

We can see what the specific estimated home sale prices are for each of the next twelve months after July 2019.

forecast$mean 
          Jan      Feb      Mar      Apr      May      Jun      Jul      Aug
2019                                                       633256.4 669327.5
2020 648920.1 671477.6 728994.7 658684.8 665938.5 660994.9                  
          Sep      Oct      Nov      Dec
2019 658924.8 691939.7 671194.7 624725.1
2020                                    

We can see that the month with the highest forecasted price is March 2020 with a forecasted average home sale price of $728,994.70. The month with the lowest forecasted price is December 2019 with a forecasted average home sale price of $624,725.10.

7 Conclusion

In this project, we created a time series of the monthly average home sales prices that were collected from the span of 2007 to 2019. We analyzed the trends and patterns of this time series to make note of any findings which stood out. One notable aspect of this time series was that it showed a seasonal pattern, with what looked like an annual seasonality. It was evident that there was some sort of a seasonal pattern within the home sales prices which repeated after a certain period of time, which appeared to be annually. The time series plot showed that this pattern appeared to repeat on approximately an annual basis, with the home sales prices going through different phases of highs and lows over the course of each year. Both the classical decomposition method and the STL decomposition method confirmed the presence of this seasonal trend within the data for this time series of the home sales prices.

Another notable finding in this time series project was that there appeared to be an overall increase in the average home sale prices from the beginning of the time series data collection in 2007 to the end of the data collection in 2019. It appeared that home sale prices gradually increased over the course of this 12 year period of the data collection. The time series plots as well as the decomposition plots for the time series showed evidence of this increase in the average home sale prices from 2007 to 2019.

Additionally, we looked at four potential sample sizes to use for a training data set in order to determine which number of observations would be ideal to use. The four potential sizes for the training data set which we looked at were n = 100, 70, 50, and 35 observations. It turned out that the sample size of n = 100 observations was the ideal choice out of these four options, because it resulted in the lowest errors, as seen by how it had the lowest values for both its MSE and its MAPE. This indicates that the sample size of 100 observations provides the best utility for the training set, because it reduces the errors.

We also used exponential smoothing methods to forecast the following twelve months after the end of the time series data collection. This provided forecasted predictions for the average home sale prices up through June of 2020.

7.1 Recommendations

Some recommendations I would make for future projects include:

  • Overall, it appeared like there was an annual seasonality in this particular time series done on the observed values of the sales prices of houses over the span of 2007 to 2019. Some potential reasons were given to provide an explanation for this seasonal trend, such as more individuals buying houses in the summer leading the an increase in sales prices. To further strengthen the evidence of this seasonal trend, future projects could look further into this to see if this is indeed a common pattern with records of house sales prices.

  • Future projects could look into trying out even more different training data set sizes to see if there is another one which would work even better than the ones that we tried out in this project. We looked at four potential sizes for the training data set to see which one provided the best accuracy, and found that n = 100 observations provided the best utility by reducing the errors. However, perhaps future projects could try out even more different sizes to see if there is one which provides even better accuracy by reducing the errors.

Overall, this time series projects provided insight into some of the patterns and trends surrounding the monthly average home sale prices from the span of time from 2007 to 2019. The seasonality and trends which were observed show that the sales prices of homes is something which goes through cycles of changes, and various highs and lows throughout the span of time.

8 References

The data set I used for my time series was found on kaggle.com. Included below is the citation of the web page where I found this data set.

Holdings, H., & James, T. (2019, August 12). House Property Sales Time Series. Kaggle. https://www.kaggle.com/datasets/htagholdings/property-sales/data

LS0tDQp0aXRsZTogIkhvdXNlIFNhbGUgUHJpY2VzIGZyb20gMjAwNyB0byAyMDE5OiBUaW1lIFNlcmllcyBGb3JlY2FzdGluZyB3aXRoIERlY29tcG9zaXRpb24iDQphdXRob3I6ICJKb3NpZSBHYWxsb3AiDQpkYXRlOiAiMjAyNC0xMS0xOCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIGZpZ193aWR0aDogNg0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQoNCmBgYHs9aHRtbH0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KLyogQ2FzY2FkaW5nIFN0eWxlIFNoZWV0cyAoQ1NTKSBpcyBhIHN0eWxlc2hlZXQgbGFuZ3VhZ2UgdXNlZCB0byBkZXNjcmliZSB0aGUgcHJlc2VudGF0aW9uIG9mIGEgZG9jdW1lbnQgd3JpdHRlbiBpbiBIVE1MIG9yIFhNTC4gaXQgaXMgYSBzaW1wbGUgbWVjaGFuaXNtIGZvciBhZGRpbmcgc3R5bGUgKGUuZy4sIGZvbnRzLCBjb2xvcnMsIHNwYWNpbmcpIHRvIFdlYiBkb2N1bWVudHMuICovDQoNCmgxLnRpdGxlIHsgIC8qIFRpdGxlIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiB0aGUgcmVwb3J0IHRpdGxlICovDQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBhdXRob3JzICAqLw0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciB0aGUgZGF0ZSAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsgLyogSGVhZGVyIDEgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBsZXZlbCAxIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAyMnB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgyIHsgLyogSGVhZGVyIDIgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBsZXZlbCAyIHNlY3Rpb24gdGl0bGUgKi8NCiAgICBmb250LXNpemU6IDIwcHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgb2YgbGV2ZWwgMyBzZWN0aW9uIHRpdGxlICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCA0IHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9DQoNCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9DQoNCjwvc3R5bGU+DQpgYGANCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBEZXRlY3QsIGluc3RhbGwsIGFuZCBsb2FkIHBhY2thZ2VzIGlmIG5lZWRlZC4NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgibGVhZmxldCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJsZWFmbGV0IikNCiAgIGxpYnJhcnkobGVhZmxldCkNCn0NCmlmICghcmVxdWlyZSgiRW52U3RhdHMiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiRW52U3RhdHMiKQ0KICAgbGlicmFyeShFbnZTdGF0cykNCn0NCmlmICghcmVxdWlyZSgiTUFTUyIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJNQVNTIikNCiAgIGxpYnJhcnkoTUFTUykNCn0NCmlmICghcmVxdWlyZSgicGh5dG9vbHMiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGh5dG9vbHMiKQ0KICAgbGlicmFyeShwaHl0b29scykNCn0NCmlmKCFyZXF1aXJlKCJkcGx5ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQogICBsaWJyYXJ5KGRwbHlyKQ0KfQ0KaWYoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQppZighcmVxdWlyZSgiR0dhbGx5IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkdHYWxseSIpDQogICBsaWJyYXJ5KEdHYWxseSkNCn0NCmlmICghcmVxdWlyZSgiYm9vdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJib290IikNCiAgIGxpYnJhcnkoYm9vdCkNCn0NCmlmKCFyZXF1aXJlKCJwYW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikNCiAgIGxpYnJhcnkocGFuZGVyKQ0KfQ0KaWYoIXJlcXVpcmUoIm1sYmVuY2giKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibWxiZW5jaCIpDQogICBsaWJyYXJ5KG1sYmVuY2gpDQp9DQppZighcmVxdWlyZSgicHN5Y2giKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQ0KICAgbGlicmFyeShwc3ljaCkNCn0NCmlmKCFyZXF1aXJlKCJsdWJyaWRhdGUiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibHVicmlkYXRlIikNCiAgIGxpYnJhcnkobHVicmlkYXRlKQ0KfQ0KaWYoIXJlcXVpcmUoIkdHYWxseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJHR2FsbHkiKQ0KICAgbGlicmFyeShHR2FsbHkpDQp9DQppZiAoIXJlcXVpcmUoInBST0MiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicFJPQyIpDQogICBsaWJyYXJ5KHBST0MpDQp9DQppZiAoIXJlcXVpcmUoImZvcmVjYXN0IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImZvcmVjYXN0IikNCiAgIGxpYnJhcnkoZm9yZWNhc3QpDQp9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICANCiAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLCAgDQogICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICANCiAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEgICANCiAgICAgICAgICAgICAgICAgICAgICApICAgDQpgYGANCg0KDQojIEludHJvZHVjdGlvbg0KDQpGb3IgdGhpcyBwcm9qZWN0LCB3ZSB3aWxsIGJlIGNyZWF0aW5nIGEgVGltZSBTZXJpZXMuIFdlIHdpbGwgYmUgd29ya2luZyBvbiBkZWNvbXBvc2luZyB0aGlzIHRpbWUgc2VyaWVzIGFuZCBmb3JlY2FzdGluZyB3aXRoIGRlY29tcG9zaW5nLiBUaGUgZGF0YSBzZXQgSSBmb3VuZCBmb3IgdGhpcyBwcm9qZWN0IGxvb2tzIGF0IHRoZSBzYWxlIHByaWNlcyBmb3IgaG9tZXMgdGhhdCBoYXZlIGJlZW4gc29sZCBmcm9tIDIwMDcgdG8gMjAxOSBpbiB0aGUgVW5pdGVkIFN0YXRlcy4gVGhpcyBkYXRhIHNldCBpbmNsdWRlcyB0aGUgc2FsZSBwcmljZXMgb2YgdGhlc2UgdmFyaW91cyBob21lcyBvdmVyIHRoaXMgY291cnNlIG9mIDEyIHllYXJzLiANCg0KV2Ugd2lsbCB1c2UgdGhpcyBkYXRhIHNldCB0byBjcmVhdGUgYSBtb250aGx5IHRpbWUgc2VyaWVzIHRvIGFuYWx5emUgdGhlc2UgaG9tZSBzYWxlIHByaWNlcyBhbG9uZyB3aXRoIGFueSBzb3J0IG9mIHRyZW5kcyB0aGF0IHRoZXJlIG1heSBiZS4gVXNpbmcgdGhpcyBtb250aGx5IHRpbWUgc2VyaWVzLCB3ZSB3aWxsIGxvb2sgYXQgdGhlIHRyZW5kcyBpbiBob21lIHNhbGUgcHJpY2VzIGJ5IG1vbnRoLCBtZWFuaW5nIHdlIHdpbGwgZmluZCB0aGUgYXZlcmFnZSBob21lIHNhbGUgcHJpY2UgZm9yIGVhY2ggbW9udGggb3ZlciB0aGUgY291cnNlIG9mIDIwMDcgdG8gMjAxOS4gVGhpcyB3aWxsIGFsbG93IHVzIHRvIGFuYWx5emUgdGhlIHRpbWUgc2VyaWVzIGFuZCBsb29rIGZvciB0cmVuZHMgb2NjdXJyaW5nIGFjcm9zcyB0aGUgbWFueSBtb250aHMgd2hpY2ggdGhlIGRhdGEgd2FzIGNvbGxlY3RlZCBvdmVyIHRoZSBjb3Vyc2Ugb2YuIFdlIHdpbGwgd29yayBvbiBkZWNvbXBvc2luZyB0aGlzIG1vbnRobHkgdGltZSBzZXJpZXMgb2YgdGhlIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlcyBhbmQgd2lsbCB1c2UgZm9yZWNhc3Rpbmcgd2l0aCBkZWNvbXBvc2luZyBmb3IgdGhpcyBhbmFseXNpcyBvZiB0aGUgdGltZSBzZXJpZXMgZGF0YS4NCg0KDQoNCiMjIERhdGEgRGVzY3JpcHRpb24NCg0KSSBmb3VuZCB0aGlzIGRhdGEgc2V0IG9uIGthZ2dsZS5jb20gb24gdGhlIGZvbGxvd2luZyB3ZWJwYWdlOg0KaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9odGFnaG9sZGluZ3MvcHJvcGVydHktc2FsZXM/c2VsZWN0PXJhd19zYWxlcy5jc3YNCg0KVGhpcyBkYXRhIHNldCBsb29rcyBhdCB0aGUgc2FsZSBwcmljZXMgZm9yIGhvbWVzIHRoYXQgaGF2ZSBiZWVuIHJlY29yZGVkIGZyb20gMjAwNyB0byAyMDE5LiBUaGUgZmlyc3Qgb2JzZXJ2YXRpb24gd2FzIGNvbGxlY3RlZCBvbiBGZWJydWFyeSA2LCAyMDA3LCBhbmQgdGhlIGZpbmFsIG9ic2VydmF0aW9uIGluIHRoZSBkYXRhIHNldCB3YXMgY29sbGVjdGVkIG9uIEp1bHkgMjYsIDIwMTkuIFRoZSBzYWxlIHByaWNlcyBhcmUgZ2l2ZW4gaW4gVVMgZG9sbGFycywgYW5kIHdlcmUgY29sbGVjdGVkIHRvIGxvb2sgYXQgdGhlIHRyZW5kcyBhbW9uZ3N0IHRoZSBzYWxlIHByaWNlcyBvZiBob21lcyBpbiB0aGlzIHBhcnRpY3VsYXIgcmVnaW9uLiANCg0KV2Ugd2lsbCByZWFkIGluIHRoZSBkYXRhIHNldCBmcm9tIEdpdGh1YiBhbmQgd2Ugd2lsbCBjYWxsIGl0ICJob21lIi4gDQoNCmBgYHtyfQ0KaG9tZSA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0pvc2llR2FsbG9wL1NUQTMyMS9yZWZzL2hlYWRzL21haW4vZGF0YXNldC9yYXdfc2FsZXMuY3N2IikNCmBgYA0KDQpUaGUgb3JpZ2luYWwgZGF0YSBzZXQgY29udGFpbnMgbXVsdGlwbGUgdmFyaWFibGVzIGxvb2tpbmcgYXQgdGhpbmdzIHN1Y2ggYXMgdGhlIHBvc3Rjb2RlIG9mIHRoZSBob3VzZSwgdGhlIHR5cGUgb2YgcHJvcGVydHkgaXQgaXMsIGFuZCB0aGUgbnVtYmVyIG9mIGJlZHJvb21zIGluIHRoZSBob3VzZS4gSG93ZXZlciwgZm9yIHRoaXMgcHJvamVjdCwgd2UgYXJlIGp1c3QgbG9va2luZyBhdCBjcmVhdGluZyBhIHRpbWUgc2VyaWVzIHdpdGggdGhlIHZhcmlhYmxlIG9mIGhvdXNlIHNhbGUgcHJpY2VzLiBTbywgd2Ugd2lsbCBvbmx5IGJlIGludGVyZXN0ZWQgaW4gdGhlIGhvbWUgc2FsZSBwcmljZSBhbmQgdGhlIGRhdGUgb2Ygd2hpY2ggdGhlIGhvdXNlIHdhcyBzb2xkLiBGb3IgdGhpcyB0aW1lIHNlcmllcyBwcm9qZWN0LCB3ZSB3aWxsIGxvb2sgYXQgdGhlIG1vbnRobHkgYXZlcmFnZXMgb2YgdGhlIGhvbWUgc2FsZSBwcmljZXMgaW4gb3JkZXIgdG8gY3JlYXRlIGEgbW9udGhseSB0aW1lIHNlcmllcyB3aGljaCB3ZSB3aWxsIHVzZSBmb3IgYW5hbHlzaXMgdG8gc2VlIGlmIHRoZXJlIGFyZSBhbnkgbm90YWJsZSBwYXR0ZXJucyB3ZSBjYW4gc2VlIGZyb20gdGhlIG1vbnRobHkgdGltZSBzZXJpZXMuDQoNCg0KIyMgVmFyaWFibGVzDQoNClRoZSB0d28gdmFyaWFibGVzIHdoaWNoIHdlIGFyZSBpbnRlcmVzdGVkIGluIGxvb2tpbmcgYXQgZm9yIHRoaXMgdGltZSBzZXJpZXMgcHJvamVjdCBpbmNsdWRlOg0KDQoqIGRhdGVzb2xkOiBUaGUgZGF0ZSBvbiB3aGljaCB0aGUgaG91c2Ugd2FzIHNvbGQuIFRoaXMgaXMgZ2l2ZW4gaW4gdGhlIGZvcm1hdCBvZiB5ZWFyLW1vbnRoLWRheSB0aW1lIiwgZm9yIGV4YW1wbGUsICIyMDA3LTAyLTA3IDAwOjAwOjAwIi4gVGhpcyBpcyBhIHZhcmlhYmxlIHVzZWQgZm9yIGlkZW50aWZ5aW5nIGVhY2ggb2JzZXJ2YXRpb24gb2YgaG91c2Ugc2FsZXMuIFdlIHdpbGwgYWRqdXN0IHRoaXMgdmFyaWFibGUgdG8gcmVwcmVzZW50IHRoZSB5ZWFyIGFuZCB0aGUgbW9udGggb2Ygd2hpY2ggdGhlIGhvbWUgc2FsZXMgd2VyZSBjb2xsZWN0ZWQgaW4gb3JkZXIgdG8gY3JlYXRlIGEgbW9udGhseSB0aW1lIHNlcmllcyByZXBvcnQuDQoNCiogcHJpY2U6IFRoZSBwcmljZSBmb3Igd2hpY2ggYSBob3VzZSB3YXMgc29sZCBmb3IsIGdpdmVuIGluIFVTIGRvbGxhcnMuIFRoaXMgaXMgYSBxdWFudGl0YXRpdmUsIG51bWVyaWNhbCB2YXJpYWJsZSB3aGljaCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBvYnNlcnZpbmcgdGhlIHRyZW5kcyBvZiBvdmVyIHRpbWUuIFdlIHdpbGwgYWRqdXN0IHRoaXMgdmFyaWFibGUgdG8gcmVwcmVzZW50IHRoZSBhdmVyYWdlIGhvbWUgc2FsZSBwcmljZSBmb3IgYSBzcGVjaWZpYyBtb250aCBvZiBhIHNwZWNpZmljIHllYXIgaW4gb3JkZXIgdG8gY3JlYXRlIGEgbW9udGhseSB0aW1lIHNlcmllcyByZXBvcnQuDQoNCldlIHdpbGwgY3JlYXRlIGEgbW9udGhseSB0aW1lIHNlcmllcyB3aGljaCBvYnNlcnZlZCBhbmQgYW5hbHl6ZXMgdGhlIHRyZW5kcyBhbmQgcGF0dGVybnMgc2VlbiBpbiB0aGUgYXZlcmFnZSBob21lIHNhbGUgcHJpY2VzIGJ5IG1vbnRoIG92ZXIgdGhlIGNvdXJzZSBvZiAyMDA3IHRvIDIwMTkuIA0KDQoNCg0KDQojIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMNCg0KQmVmb3JlIHdlIGNyZWF0ZSBvdXIgdGltZSBzZXJpZXMgb2JqZWN0LCBsZXQncyBlbnN1cmUgdGhhdCB0aGVyZSBhcmUgbm8gbWlzc2luZyB2YWx1ZXMgaW4gdGhlIG9yaWdpbmFsIGRhdGEgc2V0LCAiaG9tZSIuIA0KDQpgYGB7cn0NCmNvbFN1bXMoaXMubmEoaG9tZSkpDQpgYGANCg0KQXMgd2UgY2FuIHNlZSwgdGhlcmUgYXJlIHplcm8gbWlzc2luZyB2YWx1ZXMgaW4gb3VyIGRhdGEgc2V0LCBzbyB0aGF0IG1lYW5zIHdlIGRvIG5vdCBoYXZlIHRvIHdvcnJ5IGFib3V0IGZpbGxpbmcgaW4gYW55IG1pc3Npbmcgb2JzZXJ2YXRpb25zLiBXZSBjYW4gcHJvY2VlZCB3aXRoIGNyZWF0aW5nIG91ciB0aW1lIHNlcmllcyBvYmplY3QuIA0KDQoNCg0KIyMgVGltZSBTZXJpZXMgRGF0YSBQcmVwYXJ0aW9uDQoNCldlIHdpbGwgYWRqdXN0IHRoZSBkYXRhIHRvIGNyZWF0ZSBvdXIgbW9udGhseSB0aW1lIHNlcmllcy4gVGhpcyB3aWxsIGFsbG93IHVzIHRvIGFuYWx5emUgdGhlIG1vbnRobHkgdHJlbmRzIGluIGhvbWUgc2FsZSBwcmljZXMgb3ZlciB0aGUgeWVhcnMgb2Ygd2hpY2ggdGhpcyBkYXRhIHdhcyBjb2xsZWN0ZWQuIA0KDQpXZSB3aWxsIHN0YXJ0IGJ5IGNyZWF0aW5nIGEgbmV3IGRhdGEgc2V0IGNhbGxlZCAiaG9tZTEiIHdpdGgganVzdCB0aGUgdmFyaWFibGVzIG9mIGRhdGVzb2xkIGFuZCBwcmljZS4gDQoNCmBgYHtyfQ0KaG9tZTEgPC0gZGF0YS5mcmFtZShob21lJGRhdGVzb2xkLCBob21lJHByaWNlKQ0KaG9tZTEkZGF0ZXNvbGQgPC0gaG9tZTEkaG9tZS5kYXRlc29sZA0KaG9tZTEkcHJpY2UgPC0gaG9tZTEkaG9tZS5wcmljZQ0KaG9tZTEgPC0gc2VsZWN0KGhvbWUxLCAtMSwtMikNCmBgYA0KDQpGb3IgdGhpcyB0aW1lIHNlcmllcyBwcm9qZWN0LCB3ZSB3aWxsIGNyZWF0ZSBhIG1vbnRobHkgdGltZSBzZXJpZXMuIFRoaXMgd2lsbCB0YWtlIGEgbG9vayBhdCB0aGUgYXZlcmFnZSBob21lIHNhbGUgcHJpY2UgZnJvbSBlYWNoIG1vbnRoIG9mIHdoaWNoIHRoZSBkYXRhIHNldCB3YXMgY29sbGVjdGVkIGZyb20uIFRoaXMgd2lsbCBhbGxvdyB1cyB0byBsb29rIGZvciB0cmVuZHMgYW5kIHBhdHRlcm5zIGFjcm9zcyB0aGUgbW9udGhseSBhdmVyYWdlIHNhbGUgcHJpY2VzIHRoYXQgaGF2ZSBiZWVuIG9ic2VydmVkIGZyb20gdGhlIHNwYW4gb2YgMjAwNyB0byAyMDE5LiANCg0KVGhlIGRhdGVzb2xkIHZhcmlhYmxlIGluY2x1ZGVzIGRhdGVzIHRoYXQgYXJlIGdpdmVuIGluIHRoZSBmb3JtYXQgb2YgIlllYXItTW9udGgtRGF5IGhvdXI6bWludXRlOnNlY29uZCIuIFdoaWxlIHNjcm9sbGluZyB0aHJvdWdoIHRoZSBkYXRhIHNldCBlbnRyaWVzLCBJIG5vdGljZWQgdGhhdCB0aGUgdGltZSBwb3J0aW9uIG9mIGV2ZXJ5IGRhdGEgZW50cnkgd2FzIGdpdmVuIGFzIDAwOjAwOjAwLiBUaGlzIG1lYW5zIHRoYXQgYWxsIG9mIHRoZSBvYnNlcnZhdGlvbnMgd2VyZSByZWNvcmRlZCBleGFjdGx5IGF0IG1pZG5pZ2h0LiBBbGwgb2YgdGhlIG9ic2VydmF0aW9ucyBoYXZlIHRoaXMgZXhhY3Qgc2FtZSB0aW1lIGFzIHRoZWlyIHJlY29yZGVkIGRhdGUsIHNvIHdlIHdpbGwgZHJvcCB0aGUgdGltZSBwb3J0aW9uIGZyb20gdGhlIGRhdGVzb2xkIHZhcmlhYmxlIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGludGVycHJldCwgYXMgd2VsbCBhcyB0byBtYWtlIGl0IGVhc2llciB0byBjcmVhdGUgb3VyIG1vbnRobHkgYXZlcmFnZSB0aW1lIHNlcmllcy4gDQoNCldlIHdpbGwgc3RhcnQgYnkgZHJvcHBpbmcgdGhlIHRpbWUgY29tcG9uZW50IGZyb20gdGhlIG9ic2VydmF0aW9ucyBhbmQgdGhlIGRhdGUgb2Ygd2hpY2ggdGhlIGhvbWUgc2FsZSBvY2N1cnJlZC4gVGhpcyB3aWxsIGxlYXZlIHVzIHdpdGgganVzdCBhICJZZWFyLU1vbnRoLURheSIgZm9ybWF0IGZvciB0aGUgZW50cmllcyBvZiB0aGUgZGF0ZXNvbGQgdmFyaWFibGUuIA0KDQpgYGB7cn0NCmhvbWUxJGRhdGVzb2xkIDwtIGFzLkRhdGUoeW1kX2htcyhob21lMSRkYXRlc29sZCkpDQpgYGANCg0KTmV4dCwgd2Ugd2lsbCBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlIHBlciBtb250aCBpbiBvcmRlciB0byBjcmVhdGUgYSBkYXRhIHNldCB3aGljaCB3ZSBjYW4gdXNlIHRvIGNyZWF0ZSBhIG1vbnRseSB0aW1lIHNlcmllcy4gVGhlIHZhcmlhYmxlIGRhdGVzb2xkIHdpbGwgbm93IGJlIGdpdmVuIGluIHRoZSBmb3JtYXQgIlllYXItTW9udGgiIGFuZCB0aGUgcHJpY2UgdmFyaWFibGUgd2lsbCByZXByZXNlbnQgdGhlIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlIGZvciB0aGF0IHNwZWNpZmljIG1vbnRoLiBXZSB3aWxsIGNyZWF0ZSBhIG5ldyBkYXRhIHNldCBjYWxsZWQgImhvbWUyIiB0byBzdG9yZSB0aGlzIHVwZGF0ZWQgdmVyc2lvbiBvZiB0aGUgZGF0YSB3aGljaCB3ZSB3aWxsIHVzZSBmb3Igb3VyIG1vbnRobHkgdGltZSBzZXJpZXMuIA0KDQpgYGB7cn0NCmhvbWUyIDwtIGhvbWUxICU+JQ0KICBtdXRhdGUoZGF0ZXNvbGQgPSBmb3JtYXQoZGF0ZXNvbGQsICIlWS0lbSIpKSAlPiUNCiAgZ3JvdXBfYnkoZGF0ZXNvbGQpICU+JQ0KICBzdW1tYXJpc2UocHJpY2UgPSBtZWFuKHByaWNlLCBuYS5ybSA9IFRSVUUpKQ0KYGBgDQoNClRoZXJlIGFyZSBleGFjdGx5IDE1MCBvYnNlcnZhdGlvbnMgaW4gdGhpcyByZXZpc2VkIGRhdGEgc2V0IHdoaWNoIGxvb2tzIGF0IHRoZSBhdmVyYWdlIGhvbWUgc2FsZSBwcmljZXMgYnkgbW9udGgsIHNvIHdlIGRvIG5vdCBuZWVkIHRvIGRyb3AgYW55IG9ic2VydmF0aW9ucyBmcm9tIHRoZSBkYXRhIHNldCBzaW5jZSB0aGlzIGlzIGFuIGlkZWFsIGFtb3VudCB0byB1c2UgZm9yIGEgdGltZSBzZXJpZXMuIA0KDQoNCg0KIyMgVGltZSBTZXJpZXMgUGxvdA0KDQpOb3csIGxldCdzIGNyZWF0ZSBhIHRpbWUgc2VyaWVzIG9iamVjdCBmcm9tIG91ciBkYXRhIGFuZCBwbG90IGl0IHRvIGhlbHAgdmlzdWFsaXplIGFueSBwb3RlbnRpYWwgdHJlbmRzIHRoYXQgbWF5IGJlIG9jY3VycmluZyB3aXRoaW4gdGhpcyB0aW1lIHNlcmllcyBvYmplY3QuIFdlIHdpbGwgY2FsbCB0aGlzIHRpbWUgc2VyaWVzIG9iamVjdCAiaG9tZS50cyIuIFNpbmNlIHdlIGFyZSBjcmVhdGluZyBhIG1vbnRobHkgdGltZSBzZXJpZXMgbG9va2luZyBhdCB0aGUgYXZlcmFnZSBob21lIHNhbGUgcHJpY2VzIGJ5IG1vbnRoLCBvdXIgZnJlcXVlbmN5IHdpbGwgYmUgMTIuIA0KDQpgYGB7cn0NCmhvbWUudHMgPC0gdHMoaG9tZTIkcHJpY2UsIHN0YXJ0ID0gYygyMDA3LCAxKSwgZnJlcXVlbmN5ID0gMTIpDQpwbG90KGhvbWUudHMsIG1haW49Ik1vbnRobHkgQXZlcmFnZSBIb21lIFNhbGUgUHJpY2VzIGZyb20gMjAwNyB0byAyMDE5IiwgeGxhYiA9ICJZZWFyIiwgeWxhYiA9ICJQcmljZSIpDQpgYGANCg0KTG9va2luZyBhdCB0aGUgdGltZSBzZXJpZXMgcGxvdCwgaXQgYXBwZWFycyB0aGF0IHRoZXJlIGFyZSBzZXZlcmFsIHBhdHRlcm5zIGFuZCB0cmVuZHMgZ29pbmcgb24gd2l0aGluIHRoaXMgbW9udGhseSB0aW1lIHNlcmllcyBvZiB0aGUgaG9tZSBzYWxlIHByaWNlcyBmcm9tIDIwMDcgdG8gMjAxOS4gVGhlcmUgYXBwZWFycyB0byBiZSBzb21lIHNvcnQgb2Ygc2Vhc29uYWxpdHkgd2hpY2ggY2FuIGJlIHNlZW4gYnkgdGhlIHZhcmlvdXMgcGVha3MgYW5kIGRyb3BzIHdoaWNoIGFwcGVhcnMgdG8gYmUgcmVwZWF0aW5nIGFmdGVyIHNvbWUgcGVyaW9kIG9mIHRpbWUuIFdlIHdpbGwgbG9vayBmdXJ0aGVyIGludG8gYW55IHBvdGVudGlhbCBzZWFzb25hbGl0eSBpbiB0aGlzIHRpbWUgc2VyaWVzIHdpdGggdGhlIGRlY29tcG9zaXRpb24gbWV0aG9kcy4gDQoNCkFkZGl0aW9uYWxseSwgdGhlcmUgYXBwZWFycyB0byBiZSBhIG1ham9yIHBlYWsgYW5kIGRyb3AgYXJvdW5kIHRoZSBzdGFydCBvZiB0aGUgdGltZSBzZXJpZXMgYXQgYXJvdW5kIDIwMDcgdG8gMjAwOC4gVGhpcyByZWFjaGVzIG11Y2ggaGlnaGVyIHRoYW4gYW55IG90aGVyIHBvcnRpb24gb2YgdGhlIHRpbWUgc2VyaWVzIGFuZCBpcyBldmlkZW5jZSBvZiBzb21ldGhpbmcgdW51c3VhbCB3aGljaCBjb3VsZCBiZSBnb2luZyBvbiBhdCB0aGlzIHBvaW50LiBJdCBpcyBwb3NzaWJsZSB0aGF0IHRoZXJlIHdhcyBzb21lIG1ham9yIGV2ZW50IG9jY3VycmluZyB3aXRoaW4gdGhlIGhvdXNpbmcgbWFya2V0IGF0IHRoaXMgcG9pbnQgd2hpY2ggY291bGQgaGF2ZSBsZWQgdG8gYSBtYXNzaXZlIHJpc2UgYW5kIHRoZW4gYSBzdWRkZW4gZmFsbCBpbiB0aGUgYXZlcmFnZSBzYWxlIHByaWNlcyBvZiBob21lcyBhdCB0aGUgdGltZS4NCg0KQWxzbywgaXQgYXBwZWFycyB0aGF0IGhvbWUgc2FsZSBwcmljZXMgaGF2ZSBncmFkdWFsbHkgaW5jcmVhc2VkIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB0aW1lIHNlcmllcyBpbiAyMDA3IHRvIHRoZSBlbmQgb2YgdGhlIHRpbWUgc2VyaWVzIGluIDIwMTkuIFdlIGNhbiBzZWUgdGhhdCB0aGUgYXZlcmFnZSBob21lIHNhbGUgcHJpY2UgaGFzIGNvbnRpbnVvdXNseSByaXNlbiBvdmVyIHRoZSBjb3Vyc2Ugb2YgdGhpcyB0aW1lIHNlcmllcy4gVGhpcyBjb3VsZCBzdWdnZXN0IGFuIGFkZGl0aXZlIG9yIG11bHRpcGxpY2F0aXZlIHRyZW5kLiBJbiB0aGlzIGNhc2UsIGl0IGFwcGVhcnMgdG8gYmUgbW9yZSBvZiBhIG11bHRpcGxpY2F0aXZlIHRyZW5kIGFzIHRoZSBzZWFzb25hbCB2YXJpYXRpb24gZG9lcyBhcHBlYXIgdG8gaGF2ZSBncm93biBhbmQgZ290dGVuIG1vcmUgZHJhbWF0aWMgb3ZlciB0aW1lIHJhdGhlciB0aGFuIHN0YXlpbmcgaWRlbnRpY2FsIHJlZ2FyZGxlc3Mgb2YgdGhlIHllYXIuIA0KDQoNCg0KIyBGb3JlY2FzdGluZyB3aXRoIENsYXNzaWNhbCBEZWNvbXBvc2luZw0KDQpGaXJzdCwgbGV0J3MgYmVnaW4gd2l0aCBsb29raW5nIGF0IGEgY2xhc3NpY2FsIGRlY29tcG9zaXRpb24gb2Ygb3VyIHRpbWUgc2VyaWVzIGRhdGEuIA0KDQpgYGB7cn0NCiMgQ2xhc3NpY2FsIERlY29tcG9zaXRpb24NCmNscy5kZWNvbXAgPSBkZWNvbXBvc2UoaG9tZS50cykNCnBhcihtYXIgPSBjKDIsMiwyLDIpKQ0KcGxvdChjbHMuZGVjb21wLCB4bGFiID0gIlllYXIiKQ0KYGBgDQoNCkFzIHdlIGNhbiBzZWUgaW4gb3VyIHBsb3QsIG1vc3Qgb2YgdGhlIGhvdXNlIHByaWNlcyByYW5nZSBiZXR3ZWVuICQzMDAsMDAwIGFuZCAkODAwLDAwMC4gDQoNClRoZXJlIGFwcGVhcnMgdG8gYmUgc29tZXRoaW5nIGludGVyZXN0aW5nIGdvaW5nIG9uIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRpbWUgc2VyaWVzIHBsb3QuIFRoZXJlIGlzIGEgdmVyeSBzaGFycCBwZWFrIGFyb3VuZCAyMDA3IHRvIDIwMDgsIHdpdGggYSBtYWpvciBzcGlrZSBtdWNoIGhpZ2hlciB0aGFuIGFueXRoaW5nIGFyb3VuZCBpdC4gVGhpcyBpcyBpbiBmYWN0IHRoZSBvYnNlcnZhdGlvbiB3aXRoIHRoZSBoaWdoZXN0IHByaWNlIGluIHRoZSBlbnRpcmUgdGltZSBzZXJpZXMgcGxvdCwgcmVhY2hpbmcgdXAgdG8gJDgwMCwwMDAsIHNvIHRoaXMgaXMgc29tZXRoaW5nIG9mIGludGVyZXN0IGZyb20gdGhlIGRhdGEuIEFmdGVyIGRvaW5nIHNvbWUgcmVzZWFyY2gsIHRoZXJlIHdhcyBhIG1ham9yIGZpbmFuY2lhbCBjcmlzaXMgd2hpY2ggb2NjdXJyZWQgZnJvbSAyMDA3IHRvIDIwMDggd2hpY2ggbWFya2VkIGEgaHVnZSBlY29ub21pYyByZWNlc3Npb24uIEl0IHdvdWxkIG1ha2Ugc2Vuc2UgdGhhdCBhIGJpZyBmaW5hbmNpYWwgY3Jpc2lzIGxpa2UgdGhpcyB3b3VsZCBhbHNvIGhhdmUgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gdGhlIGhvdXNpbmcgbWFya2V0LCBzbyB0aGlzIGlzIGxpa2VseSB3aHkgdGhlcmUgaXMgc3VjaCBhIHNoYXJwIGFuZCBzdWRkZW4gcGVhayBpbiBob21lIHNhbGUgcHJpY2VzIGFyb3VuZCAyMDA3IHRvIDIwMDguIA0KDQpUaGVyZSBkb2VzIGFwcGVhciB0byBiZSBzb21lIHNvcnQgb2Ygc2Vhc29uYWwgdHJlbmQgZ29pbmcgb24gd2l0aGluIHRoZSBkYXRhIGFzIHNlZW4gYnkgdGhlIHZhcmlvdXMgcGVha3MgYW5kIGRyb3BzIHRoYXQgY2FuIGJlIHNlZW4gd2l0aGluIHRoZSBwbG90LiBUaGlzIHNob3dzIGV2aWRlbmNlIG9mIHNvbWUgc29ydCBvZiBzZWFzb25hbGl0eSBvY2N1cnJpbmcuIFRoaXMgc2Vhc29uYWwgcGF0dGVybiBhcHBlYXJzIHRvIHJlcGVhdCBvdmVyIGVhY2ggeWVhciwgd2l0aCB0aGUgaGlnaGVzdCBhbmQgbG93ZXN0IHBlYWtzIG9jY3VycmluZyB3aXRoaW4gdGhlIHNwYW4gb2YgZWFjaCB5ZWFyIHBlcmlvZC4gDQoNCkEgc2Vhc29uYWwgdHJlbmQgd291bGQgbWFrZSBzZW5zZSBmb3IgYSBkYXRhIHNldCByZWxhdGluZyB0byBob3VzZSBzYWxlIHByaWNlcyBhcyB0aGUgdGltZSBvZiB5ZWFyIGNvdWxkIGFmZmVjdCB0aGUgbnVtYmVyIG9mIGluZGl2aWR1YWxzIGJ1eWluZyBhIG5ldyBob21lLCBhbmQgdGh1cyBzYWxlIHByaWNlcyByaXNpbmcgdG8gbWVldCB0aGlzIGxhcmdlciBkZW1hbmQuIEZvciBpbnN0YW5jZSwgdGltZXMgb2YgeWVhciBzdWNoIGFzIHRoZSBzdW1tZXIgbWF5IHNlZSBhbiBpbmNyZWFzZSBvZiBidXllcnMgbG9va2luZyBmb3IgYSBuZXcgaG91c2UgZHVlIHRvIHRoZSBpZGVhbCB3ZWF0aGVyIGFuZCB0aGUgdGltaW5nIG9mIHN1bW1lciBicmVhayBtYWtpbmcgaXQgaWRlYWwgdG8gYnV5IGEgaG91c2UgYmVmb3JlIHRoZSBuZXh0IHNjaG9vbCB5ZWFyIGJlZ2lucyBpZiB0aGUgYnV5ZXJzIGhhdmUgY2hpbGRyZW4uIFRoaXMgZ3JlYXRlciBkZW1hbmQgY291bGQgbGVhZCB0byBhIHJpc2UgaW4gdGhlIHNhbGVzIHByaWNlcyBvZiB0aGUgaG9tZXMsIGFuZCBjb3VsZCBiZSBhIHBvdGVudGlhbCBleHBsYW5hdGlvbiBmb3IgdGhpcyBzZWFzb25hbCB0cmVuZCB3ZSBzZWUgaW4gdGhlIHRpbWUgc2VyaWVzIHBsb3QuIA0KDQpBZGRpdGlvbmFsbHksIHRoZXJlIGFwcGVhcnMgdG8gYmUgYW4gb3ZlcmFsbCBpbmNyZWFzZSBpbiBob21lIHNhbGUgcHJpY2VzIGZyb20gMjAwNyB0byAyMDE5LiBMb29raW5nIGF0IHRoZSB0cmVuZCBjdXJ2ZSwgd2UgY2FuIHNlZSB0aGF0IHRoZXJlIGhhcyBiZWVuIGFuIG92ZXJhbGwsIGdyYWR1YWwgaW5jcmVhc2UgaW4gdGhlIGhvbWUgc2FsZSBwcmljZXMgZnJvbSB0aGUgc3RhcnQgb2YgdGhpcyBkYXRhIHNldCdzIGNvbGxlY3Rpb24gdG8gdGhlIGVuZCBvZiBpdHMgY29sbGVjdGlvbi4gU28sIHdlIGNhbiBjb25jbHVkZSB0aGF0IHRoZSBob21lIHNhbGUgcHJpY2VzIGhhdmUgZ3JhZHVhbGx5IGluY3JlYXNlZCBmcm9tIHdoYXQgdGhleSB3ZXJlIGluIDIwMDcgdG8gd2hhdCB0aGV5IGJlY2FtZSBpbiAyMDE5LiANCg0KDQoNCg0KIyBGb3JlY2FzdGluZyB3aXRoIFNUTCBEZWNvbXBvc2luZyANCg0KTmV4dCwgbGV0J3MgdXNlIFNUTCBkZWNvbXBvc2l0aW9uIG9uIG91ciB0aW1lIHNlcmllcyBkYXRhLg0KDQpgYGB7cn0NCiMgU1RMIERlY29tcG9zaXRpb24NCnN0bC5kZWNvbXAgPSBzdGwoaG9tZS50cywgIHMud2luZG93ID0gInBlcmlvZGljIikNCnBhcihtYXIgPSBjKDIsMiwyLDIpKQ0KcGxvdChzdGwuZGVjb21wKQ0KYGBgDQoNClVzaW5nIHRoaXMgU1RMIGRlY29tcG9zaXRpb24gbWV0aG9kIHByb3ZpZGVzIHNldmVyYWwgYWR2YW50YWdlcyB0byB0aGUgY2xhc3NpY2FsIGRlY29tcG9zaXRpb24gbWV0aG9kIHdlIHVzZWQgcHJldmlvdXNseS4gVGhlIFNUTCBkZWNvbXBvc2l0aW9uIG1ldGhvZCB1c2VzIGxvY2FsbHkgZXN0aW1hdGVkIHNjYXR0ZXJwbG90IHNtb290aGluZywgYWxzbyBrbm93biBhcyBMT0VTUywgdG8gZXN0aW1hdGUgbm9uLWxpbmVhciB0cmVuZHMgd2l0aCBncmVhdGVyIGFjY3VyYWN5IGluIGl0cyBmb3JlY2FzdGluZyB0aGFuIHVzaW5nIHRoZSBjbGFzc2ljYWwgZGVjb21wb3NpdGlvbiB3b3VsZCBwcm92aWRlLiANCg0KVGhlc2UgcGxvdHMgY3JlYXRlZCB3aXRoIHRoZSBTVEwgZGVjb21wb3NpdGlvbiBtZXRob2QgYWxsb3cgdXMgdG8gb2JzZXJ2ZSBzb21lIG9mIHRoZSB0cmVuZHMgYW5kIHBhdHRlcm5zIG9mIG91ciB0aW1lIHNlcmllcyBkYXRhLiBPdmVyYWxsLCB0aGVzZSBwbG90cyBnZW5lcmF0ZWQgYnkgdGhlIFNUTCBkZWNvbXBvc2l0aW9uIHByb3ZpZGUgc2ltaWxhciBmaW5kaW5ncyB0byB0aG9zZSBjcmVhdGVkIGluIHRoZSBwcmV2aW91cyBjbGFzc2ljYWwgZGVjb21wb3NpdGlvbiBtZXRob2QuIFdlIHNlZSBhIHNpbWlsYXIgb3ZlcmFsbCB0cmVuZCwgd2l0aCB2YXJpb3VzIHBlYWtzIGFuZCBmYWxscyBvdmVyIHRoZSBjb3Vyc2Ugb2YgdGhlIGRhdGEgYmVpbmcgY29sbGVjdGVkIGZyb20gMjAwNyB0byAyMDE5IGJ5IG1vbnRobHkgYXZlcmFnZXMgb2YgdGhlIGhvbWUgc2FsZSBwcmljZXMuIA0KDQpXZSBhbHNvIHNlZSBhIHNpbWlsYXIgc2Vhc29uYWwgcGF0dGVybiB0aGF0IHJlcGVhdHMgbXVsdGlwbGUgdGltZXMgb3ZlciB0aGUgY291cnNlIG9mIHRoZSB0aW1lIHdoaWNoIHRoZSBkYXRhIHdhcyBjb2xsZWN0ZWQuIFRoaXMgb25jZSBhZ2FpbiBtYXRjaGVzIHdpdGggdGhlIGlkZWEgb2YgYW4gYW5udWFsIHNlYXNvbmFsaXR5LCBhcyBpdCBhcHBlYXJzIGxpa2UgdGhpcyBzZWFzb25hbCBwYXR0ZXJuIGFwcGVhcnMgdG8gcmVwZWF0IGZvciBlYWNoIHllYXIgdGhhdCBvY2N1cnMgb3ZlciB0aGUgY291cnNlIG9mIHRoZSB0aW1lIHNlcmllcyBkYXRhIGNvbGxlY3Rpb24uIEFkZGl0aW9uYWxseSwgc2ltaWxhciB0byB3aGF0IHdhcyBmb3VuZCBpbiB0aGUgY2xhc3NpY2FsIGRlY29tcG9zaXRpb24gbWV0aG9kLCBpcyB0aGF0IHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQsIG5vdGFibGUgcGVhayBhcm91bmQgdGhlIHN0YXJ0IG9mIHRoZSB0aW1lIHNlcmllcyBpbiAyMDA3IHRvIDIwMDggd2hpY2ggc2hvd3MgdGhlIGhpZ2hlc3QgaG9tZSBzYWxlcyBwcmljZXMgb3V0IG9mIHRoZSBlbnRpcmUgZGF0YSBzZXQuIFRoaXMgbWFqb3IgcGVhayBhcm91bmQgMjAwNyB0byAyMDA4IGlzIHRoZSBoaWdoZXN0IGF2ZXJhZ2UgaG9tZSBzYWxlcyBwcmljZXMgd2hpY2ggd2FzIG9ic2VydmVkIHRocm91Z2hvdXQgdGhlIHRpbWUgc2VyaWVzIGRhdGEgY29sbGVjdGlvbi4gRnVydGhlcm1vcmUsIHdlIGNhbiBzZWUgdGhlIG92ZXJhbGwgdHJlbmQgb2YgYSBncmFkdWFsIGluY3JlYXNlIGluIHRoZSBob21lIHNhbGUgcHJpY2VzIGZyb20gMjAwNyB0byAyMDE5LiBUaGlzIGNhbiBiZSBzZWVuIGluIHRoZSB0cmVuZCBjdXJ2ZSBieSBob3cgdGhlIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlcyBoYXZlIGdyYWR1YWxseSByaXNlbiBhbmQgaW5jcmVhc2VkIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSB0aW1lIHNlcmllcyBkYXRhIGNvbGxlY3Rpb24gaW4gMjAwNyB0byB0aGUgZW5kIG9mIHRoZSB0aW1lIHNlcmllcyBpbiAyMDE5LiBUaGVzZSBwYXR0ZXJucyBmb3VuZCBieSB0aGUgU1RMIGRlY29tcG9zaXRpb24gbWV0aG9kIG1hdGNoIHVwIHdpdGggd2hhdCB3YXMgb2JzZXJ2ZWQgcHJldmlvdXNseSwgYW5kIHRoaXMgU1RMIGRlY29tcG9zaXRpb24gbWV0aG9kIHByb3ZpZGVzIGdyZWF0ZXIgYWNjdXJhY3kgaW4gaXRzIGZvcmVjYXN0aW5nLiANCg0KDQoNCg0KIyBUcmFpbmluZyBhbmQgVGVzdGluZyBEYXRhIFNldHMNCg0KTmV4dCwgbGV0J3MgbG9vayBpbnRvIGNyZWF0aW5nIGEgdHJhaW5pbmcgYW5kIGEgdGVzdGluZyBkYXRhIHNldCB0byBmb3JlY2FzdCB0aGUgdGltZSBzZXJpZXMgbW9kZWwuIA0KDQpXZSB3aWxsIHVzZSB0aGUgbGFzdCBzZXZlbiBvYnNlcnZhdGlvbnMgdG8gbWFrZSB1cCBvdXIgdGVzdGluZyBkYXRhIHNldCwgYW5kIHdlIHdpbGwgdHJ5IG91dCBmb3VyIGRpZmZlcmVudCBwb3RlbnRpYWwgc2l6ZXMgZm9yIHRoZSB0cmFpbmluZyBkYXRhIHNldC4gVGhlIGZvdXIgZGlmZmVyZW50IHNpemVzIEkgd2lsbCB0cnkgb3V0IGZvciB0aGUgdHJhaW5pbmcgZGF0YSBzZXQgYXJlIG4gPSAxMDAsIG4gPSA3MCwgbj0gNTAsIGFuZCBuID0gMzUuIFRoaXMgd2lsbCBiZSB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyB3aGljaCBhcmUgdXNlZCBpbiB0aGUgdHJhaW5pbmcgZGF0YSBzZXQuIA0KDQoNCmBgYHtyfQ0KZGF0YSA9IGhvbWUudHMNCm4wID0gbGVuZ3RoKGRhdGEpDQp0cmFpbi5kYXRhMSA9IGhvbWUudHNbNDM6KG4wLTcpXQ0KdHJhaW4uZGF0YTIgPSBob21lLnRzWzczOihuMC03KV0NCnRyYWluLmRhdGEzID0gaG9tZS50c1s5MzoobjAtNyldDQp0cmFpbi5kYXRhNCA9IGhvbWUudHNbMTA4OihuMC03KV0NCg0KIyBUaGUgdGVzdGluZyBkYXRhIHNldCB3aWxsIGJlIHRoZSBsYXN0IDcgb2JzZXJ2YXRpb25zLg0KdGVzdC5kYXRhID0gaG9tZS50c1sobjAtNik6bjBdDQoNCiMgQ3JlYXRpbmcgdGhlIGZvdXIgcG90ZW50aWFsIHRyYWluaW5nIGRhdGEgc2V0IHNpemVzLg0KdHJhaW4xLnRzID0gdHModHJhaW4uZGF0YTEsIGZyZXF1ZW5jeSA9IDEyLCBzdGFydCA9IGMoMjAwNy0wMiwgMSkpDQp0cmFpbjIudHMgPSB0cyh0cmFpbi5kYXRhMiwgZnJlcXVlbmN5ID0gMTIsIHN0YXJ0ID0gYygyMDEwLTAxLCAxKSkNCnRyYWluMy50cyA9IHRzKHRyYWluLmRhdGEzLCBmcmVxdWVuY3kgPSAxMiwgc3RhcnQgPSBjKDIwMTMtMDEsIDEpKQ0KdHJhaW40LnRzID0gdHModHJhaW4uZGF0YTQsIGZyZXF1ZW5jeSA9IDEyLCBzdGFydCA9IGMoMjAxNS0wMSwgMSkpDQoNCnN0bDEgPSBzdGwodHJhaW4xLnRzLCBzLndpbmRvdyA9IDEyKQ0Kc3RsMiA9IHN0bCh0cmFpbjIudHMsIHMud2luZG93ID0gMTIpDQpzdGwzID0gc3RsKHRyYWluMy50cywgcy53aW5kb3cgPSAxMikNCnN0bDQgPSBzdGwodHJhaW40LnRzLCBzLndpbmRvdyA9IDEyKQ0KYGBgDQoNCk5leHQsIGxldCdzIGNyZWF0ZSB0aGUgb2JqZWN0cyBmb3IgZm9yZWNhc3RpbmcuDQoNCmBgYHtyfQ0KIyBGb3JlY2FzdGluZw0KZmNzdDEgPSBmb3JlY2FzdChzdGwxLGggPSA3LCBtZXRob2QgPSAibmFpdmUiKQ0KZmNzdDIgPSBmb3JlY2FzdChzdGwyLGggPSA3LCBtZXRob2QgPSAibmFpdmUiKQ0KZmNzdDMgPSBmb3JlY2FzdChzdGwzLGggPSA3LCBtZXRob2QgPSAibmFpdmUiKQ0KZmNzdDQgPSBmb3JlY2FzdChzdGw0LGggPSA3LCBtZXRob2QgPSAibmFpdmUiKQ0KYGBgDQoNCldlIHdpbGwgcGVyZm9ybSBlcnJvciBhbmFseXNpcyB0byBoZWxwIHVzIGRldGVybWluZSB3aGljaCBzaXplIGlzIGJlc3QgZm9yIHRoZSB0cmFpbmluZyBkYXRhIHNldCBvdXQgb2YgdGhlIGZvdXIgcG90ZW50aWFsIHNpemVzIHdlIGFyZSBnb2luZyB0byBiZSBjaG9vc2luZyBiZXR3ZWVuLiBXZSB3aWxsIGxvb2sgYXQgYm90aCB0aGUgbWVhbiBhYnNvbHV0ZSBwcmVkaWN0aW9uIGVycm9yIChNQVBFKSBhbmQgdGhlIG1lYW4gc3F1YXJlZCBlcnJvciAoTVNFKSBvZiB0aGUgcG90ZW50aWFsIHRyYWluaW5nIGRhdGEgc2V0cy4gDQoNCmBgYHtyfQ0KUEUxID0gKHRlc3QuZGF0YS1mY3N0MSRtZWFuKS9mY3N0MSRtZWFuDQpQRTIgPSAodGVzdC5kYXRhLWZjc3QyJG1lYW4pL2Zjc3QyJG1lYW4NClBFMyA9ICh0ZXN0LmRhdGEtZmNzdDMkbWVhbikvZmNzdDMkbWVhbg0KUEU0ID0gKHRlc3QuZGF0YS1mY3N0NCRtZWFuKS9mY3N0NCRtZWFuDQoNCiMgTWVhbiBBYnNvbHV0ZSBQcmVkaWN0aW9uIEVycm9ycy4NCk1BUEUxID0gbWVhbihhYnMoUEUxKSkNCk1BUEUyID0gbWVhbihhYnMoUEUyKSkNCk1BUEUzID0gbWVhbihhYnMoUEUzKSkNCk1BUEU0ID0gbWVhbihhYnMoUEU0KSkNCg0KRTEgPSB0ZXN0LmRhdGEtZmNzdDEkbWVhbg0KRTIgPSB0ZXN0LmRhdGEtZmNzdDIkbWVhbg0KRTMgPSB0ZXN0LmRhdGEtZmNzdDMkbWVhbg0KRTQgPSB0ZXN0LmRhdGEtZmNzdDQkbWVhbg0KDQojIE1lYW4gU3F1YXJlZCBFcnJvcnMuDQpNU0UxID0gbWVhbihFMV4yKQ0KTVNFMiA9IG1lYW4oRTJeMikNCk1TRTMgPSBtZWFuKEUzXjIpDQpNU0U0ID0gbWVhbihFNF4yKQ0KDQpNU0UgPSBjKE1TRTEsIE1TRTIsIE1TRTMsIE1TRTQpDQpNQVBFID0gYyhNQVBFMSwgTUFQRTIsIE1BUEUzLCBNQVBFNCkNCmFjY3VyYWN5ID0gY2JpbmQoTVNFID0gTVNFLCBNQVBFID0gTUFQRSkNCnJvdy5uYW1lcyhhY2N1cmFjeSkgPSBjKCJuID0gMTAwIiwgIm4gPSA3MCIsICJuID0gNTAiLCAibiA9IDM1IikNCmthYmxlKGFjY3VyYWN5LCBjYXB0aW9uID0gIkVycm9yIENvbXBhcmlzb24gb2YgdGhlIEZvcmVjYXN0IFJlc3VsdHMgd2l0aCBEaWZmZXJlbnQgVHJhaW5pbmcgRGF0YSBTZXQgU2l6ZXMiKQ0KYGBgDQoNCkFzIHdlIGNhbiBzZWUsIHRoZSB0cmFpbmluZyBkYXRhIHNldCB3aXRoIGEgc2l6ZSBvZiBuID0gMTAwIGhhcyB0aGUgbG93ZXN0IG9mIGJvdGggdGhlIE1TRSBhbmQgdGhlIE1BUEUgb3V0IG9mIHRoZSBmb3VyIHBvdGVudGlhbCB0cmFpbmluZyBkYXRhIHNldCBzaXplcyB0aGF0IHdlcmUgbG9va2VkIGF0LiBUaGlzIHN1Z2dlc3RzIHRoYXQgdGhpcyBzaXplIGlzIHRoZSBtb3N0IGlkZWFsIG91dCBvZiB0aGUgcG90ZW50aWFsIG9wdGlvbnMgYXMgaXQgcmVkdWNlcyB0aGUgZXJyb3JzIHRoZSBtb3N0IG91dCBvZiB0aGUgZm91ciBvcHRpb25zIHRoYXQgd2VyZSBjb25zaWRlcmVkLiANCg0KV2Ugd2lsbCBjcmVhdGUgYSB2aXN1YWxpemF0aW9uIHRvIGNvbXBhcmUgdGhlc2UgZm9yZWNhc3QgZXJyb3JzIGFuZCBjb25maXJtIHRoZSBmaW5kaW5nIHRoYXQgYSBzYW1wbGUgc2l6ZSBvZiAxMDAgb2JzZXJ2YXRpb25zIHJlZHVjZXMgdGhlIGVycm9ycyBtb3N0IG91dCBvZiB0aGUgcG90ZW50aWFsIHNhbXBsZSBzaXplcyB0aGF0IHdlcmUgY29uc2lkZXJlZCBmb3IgdGhlIHRyYWluaW5nIGRhdGEgc2V0IG9mIHRoZSB0aW1lIHNlcmllcy4NCg0KRmlyc3QsIGxldCdzIGxvb2sgYXQgYSBwbG90IG9mIHRoZSBtZWFuIHNxdWFyZWQgZXJyb3JzIChNU0UpIGZvciBlYWNoIG9mIHRoZSBmb3VyIHBvdGVudGlhbCBzYW1wbGUgc2l6ZXMuIA0KDQpgYGB7cn0NCiMgUGxvdCBvZiB0aGUgTVNFLg0KcGxvdCgxOjQsIE1TRSwgdHlwZSA9ICJiIiwgY29sPSJkYXJrb3JjaGlkIiwgeWxhYiA9ICJFcnJvcnMiLCB4bGFiID0gIlNhbXBsZSBTaXplIiwNCiAgICAgbWFpbiA9ICJNU0UiLCBheGVzID0gRkFMU0UpDQogICAgIGxhYnMgPSBjKCJuID0gMTAwIiwgIm4gPSA3MCIsICJuID0gNTAiLCAibiA9IDM1IikNCiAgICAgYXhpcygxLCBhdCA9IDE6NCwgbGFiZWwgPSBsYWJzKQ0KICAgICBheGlzKDIpDQpgYGANCg0KQXMgd2UgY2FuIHNlZSwgbiA9IDEwMCBvYnNlcnZhdGlvbnMgaGFzIHRoZSBsb3dlc3QgTVNFIG91dCBvZiB0aGUgZm91ciBwb3RlbnRpYWwgc2FtcGxlIHNpemVzLCBpbmRpY2F0aW5nIHRoYXQgaXQgaXMgdGhlIGlkZWFsIGNob2ljZSwgYmVjYXVzZSBpdCByZWR1Y2VzIHRoZSBlcnJvcnMuIA0KDQpXZSB3aWxsIGFsc28gbG9vayBhdCB0aGUgcGxvdCBvZiB0aGUgbWVhbiBhYnNvbHV0ZSBwcmVkaWN0aW9uIGVycm9ycyAoTUFQRSkgZm9yIGVhY2ggb2YgdGhlIGZvdXIgcG90ZW50aWFsIHRyYWluaW5nIGRhdGEgc2V0IHNpemVzLiANCg0KYGBge3J9DQojIFBsb3Qgb2YgdGhlIE1BUEUuDQpwbG90KDE6NCwgTUFQRSwgdHlwZSA9ICJiIiwgY29sPSJkYXJrb3JjaGlkIiwgeWxhYiA9ICJFcnJvcnMiLCB4bGFiID0gIlNhbXBsZSBTaXplIiwNCiAgICAgbWFpbiA9ICJNQVBFIiwgYXhlcyA9IEZBTFNFKQ0KICAgICBsYWJzID0gYygibiA9IDEwMCIsICJuID0gNzAiLCAibiA9IDUwIiwgIm4gPSAzNSIpDQogICAgIGF4aXMoMSwgYXQgPSAxOjQsIGxhYmVsID0gbGFicykNCiAgICAgYXhpcygyKQ0KYGBgDQoNCk9uY2UgYWdhaW4sIHRoZSBzYW1wbGUgc2l6ZSBvZiBuID0gMTAwIG9ic2VydmF0aW9ucyBzaG93cyB0aGUgbG93ZXN0IHZhbHVlIG9mIHRoZSBNQVBFLCBzaG93aW5nIHRoYXQgaXMgdGhlIGlkZWFsIGNob2ljZSBvdXQgb2YgdGhlIGZvdXIgc2FtcGxlIHNpemVzLCBiZWNhdXNlIGl0IHJlZHVjZXMgdGhlIGVycm9ycy4gDQoNCkFzIHdlIGNhbiBzZWUgaW4gdGhlIHBsb3RzIGZvciBib3RoIHRoZSBNU0UgYW5kIHRoZSBNQVBFLCBuID0gMTAwIG9ic2VydmF0aW9ucyBzaG93cyB0aGUgbG93ZXN0IGVycm9ycywgYW5kICBhcyB0aGUgc2FtcGxlIHNpemUgZGVjcmVhc2VzIGluIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zLCB0aGUgZXJyb3JzIGZvciBib3RoIHRoZSBNU0UgYW5kIHRoZSBNQVBFIGluY3JlYXNlLCByZXN1bHRpbmcgaW4gZXJyb3JzIG11Y2ggZ3JlYXRlciB0aGFuIHRob3NlIG9mIHRoZSBzYW1wbGUgc2l6ZSB3aXRoIDEwMCBvYnNlcnZhdGlvbnMuIFRoaXMgc3RyZW5ndGhlbnMgdGhhdCB0aGUgaWRlYWwgdHJhaW5pbmcgZGF0YSBzZXQgc2l6ZSBvdXQgb2YgdGhlIGZvdXIgb3B0aW9ucyB0aGF0IHdlcmUgY29uc2lkZXJlZCBpcyBhIHNpemUgb2YgMTAwIG9ic2VydmF0aW9ucy4gQSB0cmFpbmluZyBkYXRhIHNldCB3aXRoIDEwMCBvYnNlcnZhdGlvbnMgeWllbGRzIHRoZSBiZXN0IHBlcmZvcm1hbmNlLCBiZWNhdXNlIGl0IHJlZHVjZXMgdGhlIGVycm9ycy4gDQoNClNvLCB3ZSBjYW4gY29uY2x1ZGUgdGhhdCBmcm9tIHRoZSBjaG9pY2VzIG9mIGEgdHJhaW5pbmcgZGF0YSBzZXQgd2l0aCAxMDAsIDcwLCA1MCwgb3IgMzUgb2JzZXJ2YXRpb25zLCB0aGUgYmVzdCBjaG9pY2UgaXMgdGhlIHRyYWluaW5nIGRhdGEgc2V0IHdpdGggMTAwIG9ic2VydmF0aW9ucy4gVGhpcyBjaG9pY2Ugb2YgMTAwIG9ic2VydmF0aW9ucyByZXN1bHRzIGluIHRoZSBsb3dlc3QgZXJyb3JzLCBhbmQgdGhlcmVmb3JlLCBwcm92aWRlcyB0aGUgYmVzdCBwZXJmb3JtYW5jZSBmb3IgZm9yZWNhc3Rpbmcgb3VyIHRpbWUgc2VyaWVzLiANCg0KDQoNCiMgRm9yZWNhc3RpbmcgdGhlIFVwY29taW5nIE1vbnRocw0KDQpXZSB3aWxsIHVzZSBmb3JlY2FzdGluZyB0byBwcm92aWRlIGFuIGVzdGltYXRlIGZvciB0aGUgdXBjb21pbmcgbW9udGhzIGFmdGVyIHRoZSBlbmQgb2YgdGhlIHRpbWUgc2VyaWVzIGRhdGEgY29sbGVjdGlvbi4gVGhpcyB0aW1lIHNlcmllcyBjb2xsZWN0ZWQgZGF0YSB1cCB1bnRpbCBKdWx5IDIwMTksIHNvIHdlIHdpbGwgZm9yZWNhc3QgdGhlIGVzdGltYXRlZCBob21lIHNhbGUgcHJpY2VzIGZvciB0aGUgbW9udGhzIHdoaWNoIGZvbGxvdyB0aGUgZW5kIG9mIHRoaXMgZGF0YSBjb2xsZWN0aW9uLg0KDQpXZSB3aWxsIHVzZSBhbiBleHBvbmVudGlhbCBzbW9vdGhpbmcgbWV0aG9kIGZvciB0aGlzIGZvcmVjYXN0aW5nLiBUaGlzIHdpbGwgYWxsb3cgdXMgdG8gZm9yZWNhc3QgdGhlIG5leHQgdHdlbHZlIG1vbnRocyBvZiBhdmVyYWdlIGhvbWUgc2FsZSBwcmljZXMgYnkgdGhlIG1vbnRoLiBTaW5jZSBvdXIgdGltZSBzZXJpZXMgc3RvcHBlZCBhdCBKdWx5IDIwMTksIHRoaXMgZm9yZWNhc3Rpbmcgd2lsbCBwcm92aWRlIGVzdGltYXRlcyBvZiBtb250aGx5IGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlcyB1cCB0aHJvdWdoIEp1bmUgMjAyMC4NCg0KV2Ugc3RhdGVkIHByZXZpb3N1bHkgdGhhdCB0aGVyZSBhcHBlYXJlZCB0byBiZSBhIG11bHRpcGxpY2F0aXZlIHRyZW5kIG9jY3VycmluZyB3aXRoaW4gdGhpcyB0aW1lIHNlcmllcy4gVGhpcyB3YXMgc2VlbiBieSBob3cgdGhlIHNlYXNvbmFsIHZhcmlhdGlvbiBhcHBlYXJlZCB0byBpbmNyZWFzZSBvdmVyIHRpbWUgYWxvbmcgd2l0aCB0aGUgb3ZlcmFsbCBncmFkdWFsIGluY3JlYXNlIGluIG1vbnRobHkgYXZlcmFnZSBob21lIHNhbGVzLiBXZSB3aWxsIHJlZmxlY3QgdGhpcyBtdWx0aXBsaWNhdGl2ZSB0cmVuZCB3aXRoIHRoZSBleHBvbmVudGlhbCBzbW9vdGhpbmcgZm9yZWNhc3QuIA0KDQpgYGB7cn0NCmV0cyA8LSBldHMoaG9tZS50cywgbW9kZWwgPSAiTUFNIikNCmZvcmVjYXN0IDwtIGZvcmVjYXN0KGV0cywgaCA9IDEyKQ0KcGxvdChmb3JlY2FzdCwgbWFpbiA9ICJGb3JlY2FzdCBvZiB0aGUgQXZlcmFnZSBIb21lIFNhbGUgUHJpY2VzIFxuIGZvciB0aGUgTmV4dCAxMiBNb250aHMiKQ0KYGBgDQoNCkFzIHdlIGNhbiBzZWUsIHRoaXMgcGxvdCBpbGx1c3RyYXRlcyB0aGUgZm9yZWNhc3QgZm9yIHRoZSBuZXh0IHR3ZWx2ZSBtb250aHMgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgdGltZSBzZXJpZXMuIFRoaXMgZm9yZWNhc3QgcHJvdmlkZXMgYW4gZXN0aW1hdGUgZm9yIHdoYXQgdGhlIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlcyB3aWxsIGxvb2sgbGlrZSBmb3IgdGhlIG5leHQgdHdlbHZlIG1vbnRocy4gDQoNCldlIGNhbiBzZWUgd2hhdCB0aGUgc3BlY2lmaWMgZXN0aW1hdGVkIGhvbWUgc2FsZSBwcmljZXMgYXJlIGZvciBlYWNoIG9mIHRoZSBuZXh0IHR3ZWx2ZSBtb250aHMgYWZ0ZXIgSnVseSAyMDE5LiANCg0KYGBge3J9DQpmb3JlY2FzdCRtZWFuIA0KYGBgDQoNCldlIGNhbiBzZWUgdGhhdCB0aGUgbW9udGggd2l0aCB0aGUgaGlnaGVzdCBmb3JlY2FzdGVkIHByaWNlIGlzIE1hcmNoIDIwMjAgd2l0aCBhIGZvcmVjYXN0ZWQgYXZlcmFnZSBob21lIHNhbGUgcHJpY2Ugb2YgJDcyOCw5OTQuNzAuIFRoZSBtb250aCB3aXRoIHRoZSBsb3dlc3QgZm9yZWNhc3RlZCBwcmljZSBpcyBEZWNlbWJlciAyMDE5IHdpdGggYSBmb3JlY2FzdGVkIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlIG9mICQ2MjQsNzI1LjEwLiANCg0KDQoNCiMgQ29uY2x1c2lvbg0KDQpJbiB0aGlzIHByb2plY3QsIHdlIGNyZWF0ZWQgYSB0aW1lIHNlcmllcyBvZiB0aGUgbW9udGhseSBhdmVyYWdlIGhvbWUgc2FsZXMgcHJpY2VzIHRoYXQgd2VyZSBjb2xsZWN0ZWQgZnJvbSB0aGUgc3BhbiBvZiAyMDA3IHRvIDIwMTkuIFdlIGFuYWx5emVkIHRoZSB0cmVuZHMgYW5kIHBhdHRlcm5zIG9mIHRoaXMgdGltZSBzZXJpZXMgdG8gbWFrZSBub3RlIG9mIGFueSBmaW5kaW5ncyB3aGljaCBzdG9vZCBvdXQuIE9uZSBub3RhYmxlIGFzcGVjdCBvZiB0aGlzIHRpbWUgc2VyaWVzIHdhcyB0aGF0IGl0IHNob3dlZCBhIHNlYXNvbmFsIHBhdHRlcm4sIHdpdGggd2hhdCBsb29rZWQgbGlrZSBhbiBhbm51YWwgc2Vhc29uYWxpdHkuIEl0IHdhcyBldmlkZW50IHRoYXQgdGhlcmUgd2FzIHNvbWUgc29ydCBvZiBhIHNlYXNvbmFsIHBhdHRlcm4gd2l0aGluIHRoZSBob21lIHNhbGVzIHByaWNlcyB3aGljaCByZXBlYXRlZCBhZnRlciBhIGNlcnRhaW4gcGVyaW9kIG9mIHRpbWUsIHdoaWNoIGFwcGVhcmVkIHRvIGJlIGFubnVhbGx5LiBUaGUgdGltZSBzZXJpZXMgcGxvdCBzaG93ZWQgdGhhdCB0aGlzIHBhdHRlcm4gYXBwZWFyZWQgdG8gcmVwZWF0IG9uIGFwcHJveGltYXRlbHkgYW4gYW5udWFsIGJhc2lzLCB3aXRoIHRoZSBob21lIHNhbGVzIHByaWNlcyBnb2luZyB0aHJvdWdoIGRpZmZlcmVudCBwaGFzZXMgb2YgaGlnaHMgYW5kIGxvd3Mgb3ZlciB0aGUgY291cnNlIG9mIGVhY2ggeWVhci4gQm90aCB0aGUgY2xhc3NpY2FsIGRlY29tcG9zaXRpb24gbWV0aG9kIGFuZCB0aGUgU1RMIGRlY29tcG9zaXRpb24gbWV0aG9kIGNvbmZpcm1lZCB0aGUgcHJlc2VuY2Ugb2YgdGhpcyBzZWFzb25hbCB0cmVuZCB3aXRoaW4gdGhlIGRhdGEgZm9yIHRoaXMgdGltZSBzZXJpZXMgb2YgdGhlIGhvbWUgc2FsZXMgcHJpY2VzLiANCg0KQW5vdGhlciBub3RhYmxlIGZpbmRpbmcgaW4gdGhpcyB0aW1lIHNlcmllcyBwcm9qZWN0IHdhcyB0aGF0IHRoZXJlIGFwcGVhcmVkIHRvIGJlIGFuIG92ZXJhbGwgaW5jcmVhc2UgaW4gdGhlIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlcyBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRpbWUgc2VyaWVzIGRhdGEgY29sbGVjdGlvbiBpbiAyMDA3IHRvIHRoZSBlbmQgb2YgdGhlIGRhdGEgY29sbGVjdGlvbiBpbiAyMDE5LiBJdCBhcHBlYXJlZCB0aGF0IGhvbWUgc2FsZSBwcmljZXMgZ3JhZHVhbGx5IGluY3JlYXNlZCBvdmVyIHRoZSBjb3Vyc2Ugb2YgdGhpcyAxMiB5ZWFyIHBlcmlvZCBvZiB0aGUgZGF0YSBjb2xsZWN0aW9uLiBUaGUgdGltZSBzZXJpZXMgcGxvdHMgYXMgd2VsbCBhcyB0aGUgZGVjb21wb3NpdGlvbiBwbG90cyBmb3IgdGhlIHRpbWUgc2VyaWVzIHNob3dlZCBldmlkZW5jZSBvZiB0aGlzIGluY3JlYXNlIGluIHRoZSBhdmVyYWdlIGhvbWUgc2FsZSBwcmljZXMgZnJvbSAyMDA3IHRvIDIwMTkuDQoNCkFkZGl0aW9uYWxseSwgd2UgbG9va2VkIGF0IGZvdXIgcG90ZW50aWFsIHNhbXBsZSBzaXplcyB0byB1c2UgZm9yIGEgdHJhaW5pbmcgZGF0YSBzZXQgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lIHdoaWNoIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgd291bGQgYmUgaWRlYWwgdG8gdXNlLiBUaGUgZm91ciBwb3RlbnRpYWwgc2l6ZXMgZm9yIHRoZSB0cmFpbmluZyBkYXRhIHNldCB3aGljaCB3ZSBsb29rZWQgYXQgd2VyZSBuID0gMTAwLCA3MCwgNTAsIGFuZCAzNSBvYnNlcnZhdGlvbnMuIEl0IHR1cm5lZCBvdXQgdGhhdCB0aGUgc2FtcGxlIHNpemUgb2YgbiA9IDEwMCBvYnNlcnZhdGlvbnMgd2FzIHRoZSBpZGVhbCBjaG9pY2Ugb3V0IG9mIHRoZXNlIGZvdXIgb3B0aW9ucywgYmVjYXVzZSBpdCByZXN1bHRlZCBpbiB0aGUgbG93ZXN0IGVycm9ycywgYXMgc2VlbiBieSBob3cgaXQgaGFkIHRoZSBsb3dlc3QgdmFsdWVzIGZvciBib3RoIGl0cyBNU0UgYW5kIGl0cyBNQVBFLiBUaGlzIGluZGljYXRlcyB0aGF0IHRoZSBzYW1wbGUgc2l6ZSBvZiAxMDAgb2JzZXJ2YXRpb25zIHByb3ZpZGVzIHRoZSBiZXN0IHV0aWxpdHkgZm9yIHRoZSB0cmFpbmluZyBzZXQsIGJlY2F1c2UgaXQgcmVkdWNlcyB0aGUgZXJyb3JzLiANCg0KV2UgYWxzbyB1c2VkIGV4cG9uZW50aWFsIHNtb290aGluZyBtZXRob2RzIHRvIGZvcmVjYXN0IHRoZSBmb2xsb3dpbmcgdHdlbHZlIG1vbnRocyBhZnRlciB0aGUgZW5kIG9mIHRoZSB0aW1lIHNlcmllcyBkYXRhIGNvbGxlY3Rpb24uIFRoaXMgcHJvdmlkZWQgZm9yZWNhc3RlZCBwcmVkaWN0aW9ucyBmb3IgdGhlIGF2ZXJhZ2UgaG9tZSBzYWxlIHByaWNlcyB1cCB0aHJvdWdoIEp1bmUgb2YgMjAyMC4gDQoNCg0KIyMgUmVjb21tZW5kYXRpb25zDQoNClNvbWUgcmVjb21tZW5kYXRpb25zIEkgd291bGQgbWFrZSBmb3IgZnV0dXJlIHByb2plY3RzIGluY2x1ZGU6DQoNCiogT3ZlcmFsbCwgaXQgYXBwZWFyZWQgbGlrZSB0aGVyZSB3YXMgYW4gYW5udWFsIHNlYXNvbmFsaXR5IGluIHRoaXMgcGFydGljdWxhciB0aW1lIHNlcmllcyBkb25lIG9uIHRoZSBvYnNlcnZlZCB2YWx1ZXMgb2YgdGhlIHNhbGVzIHByaWNlcyBvZiBob3VzZXMgb3ZlciB0aGUgc3BhbiBvZiAyMDA3IHRvIDIwMTkuIFNvbWUgcG90ZW50aWFsIHJlYXNvbnMgd2VyZSBnaXZlbiB0byBwcm92aWRlIGFuIGV4cGxhbmF0aW9uIGZvciB0aGlzIHNlYXNvbmFsIHRyZW5kLCBzdWNoIGFzIG1vcmUgaW5kaXZpZHVhbHMgYnV5aW5nIGhvdXNlcyBpbiB0aGUgc3VtbWVyIGxlYWRpbmcgdGhlIGFuIGluY3JlYXNlIGluIHNhbGVzIHByaWNlcy4gVG8gZnVydGhlciBzdHJlbmd0aGVuIHRoZSBldmlkZW5jZSBvZiB0aGlzIHNlYXNvbmFsIHRyZW5kLCBmdXR1cmUgcHJvamVjdHMgY291bGQgbG9vayBmdXJ0aGVyIGludG8gdGhpcyB0byBzZWUgaWYgdGhpcyBpcyBpbmRlZWQgYSBjb21tb24gcGF0dGVybiB3aXRoIHJlY29yZHMgb2YgaG91c2Ugc2FsZXMgcHJpY2VzLiANCg0KKiBGdXR1cmUgcHJvamVjdHMgY291bGQgbG9vayBpbnRvIHRyeWluZyBvdXQgZXZlbiBtb3JlIGRpZmZlcmVudCB0cmFpbmluZyBkYXRhIHNldCBzaXplcyB0byBzZWUgaWYgdGhlcmUgaXMgYW5vdGhlciBvbmUgd2hpY2ggd291bGQgd29yayBldmVuIGJldHRlciB0aGFuIHRoZSBvbmVzIHRoYXQgd2UgdHJpZWQgb3V0IGluIHRoaXMgcHJvamVjdC4gV2UgbG9va2VkIGF0IGZvdXIgcG90ZW50aWFsIHNpemVzIGZvciB0aGUgdHJhaW5pbmcgZGF0YSBzZXQgdG8gc2VlIHdoaWNoIG9uZSBwcm92aWRlZCB0aGUgYmVzdCBhY2N1cmFjeSwgYW5kIGZvdW5kIHRoYXQgbiA9IDEwMCBvYnNlcnZhdGlvbnMgcHJvdmlkZWQgdGhlIGJlc3QgdXRpbGl0eSBieSByZWR1Y2luZyB0aGUgZXJyb3JzLiBIb3dldmVyLCBwZXJoYXBzIGZ1dHVyZSBwcm9qZWN0cyBjb3VsZCB0cnkgb3V0IGV2ZW4gbW9yZSBkaWZmZXJlbnQgc2l6ZXMgdG8gc2VlIGlmIHRoZXJlIGlzIG9uZSB3aGljaCBwcm92aWRlcyBldmVuIGJldHRlciBhY2N1cmFjeSBieSByZWR1Y2luZyB0aGUgZXJyb3JzLiAgDQoNCg0KT3ZlcmFsbCwgdGhpcyB0aW1lIHNlcmllcyBwcm9qZWN0cyBwcm92aWRlZCBpbnNpZ2h0IGludG8gc29tZSBvZiB0aGUgcGF0dGVybnMgYW5kIHRyZW5kcyBzdXJyb3VuZGluZyB0aGUgbW9udGhseSBhdmVyYWdlIGhvbWUgc2FsZSBwcmljZXMgZnJvbSB0aGUgc3BhbiBvZiB0aW1lIGZyb20gMjAwNyB0byAyMDE5LiBUaGUgc2Vhc29uYWxpdHkgYW5kIHRyZW5kcyB3aGljaCB3ZXJlIG9ic2VydmVkIHNob3cgdGhhdCB0aGUgc2FsZXMgcHJpY2VzIG9mIGhvbWVzIGlzIHNvbWV0aGluZyB3aGljaCBnb2VzIHRocm91Z2ggY3ljbGVzIG9mIGNoYW5nZXMsIGFuZCB2YXJpb3VzIGhpZ2hzIGFuZCBsb3dzIHRocm91Z2hvdXQgdGhlIHNwYW4gb2YgdGltZS4gDQoNCg0KDQojIFJlZmVyZW5jZXMNCg0KVGhlIGRhdGEgc2V0IEkgdXNlZCBmb3IgbXkgdGltZSBzZXJpZXMgd2FzIGZvdW5kIG9uIGthZ2dsZS5jb20uIEluY2x1ZGVkIGJlbG93IGlzIHRoZSBjaXRhdGlvbiBvZiB0aGUgd2ViIHBhZ2Ugd2hlcmUgSSBmb3VuZCB0aGlzIGRhdGEgc2V0LiANCg0KSG9sZGluZ3MsIEguLCAmIEphbWVzLCBULiAoMjAxOSwgQXVndXN0IDEyKS4gSG91c2UgUHJvcGVydHkgU2FsZXMgVGltZSBTZXJpZXMuIEthZ2dsZS4gaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9odGFnaG9sZGluZ3MvcHJvcGVydHktc2FsZXMvZGF0YSANCg==