Homework 2

find the full version here https://rpubs.com/TCML/1245841

Question 1

\[ r_t = -0.3 + 0.8 r_{t-1} -0.2 r_{t-2} + \epsilon_t \]

####a) the mean of the stock return

this is an AR(2) process with \(\alpha_0 = -0.3, \alpha_1 = 0.8, \alpha_2 = -0.2\), assuming this is stationary then,

\[ \mu = \frac{\alpha_0}{1-\alpha_1-\alpha_2} = \frac{-0.3}{(1-0.8+0.2)}=\frac{-0.3}{0.4}=-0.75 \]

####b) the variance of stock return

the variance \(\gamma_0\) of an AR(2) process is given by

\[ \gamma_0 = \frac{\sigma_n^2+2\alpha_1\alpha_2\gamma_1}{1-\alpha_1^2-\alpha_2^2} =\frac{4+2(0.8)(-0.2)\gamma_1}{1-0.64-0.04}= \frac{16-0.32\gamma_1}{0.32} \]

furthermore, we also have the eqution \[ \gamma_1 = \frac{\alpha_1\gamma_0}{1-\alpha_2}=\frac{0.8}{1.2}\gamma_0=\frac{2}{3}\gamma_0 \] from \(\gamma(j=1)=\alpha_2\gamma_{j-2}+\alpha_1\gamma_{j-1}, \gamma_{-1}=\gamma_1\)

substituting this into

\[ 0.32\gamma_0 -0.3= 4-0.32(\frac{2}{3}\gamma_0)\\ 0.32\gamma_0(1-\frac{2}{3}) = 4-0.32\gamma_1\\ \gamma_0 =\frac{4}{0.32}(3)=37.5 \]

c) based on the results is the process stationary?

both the mean and the variance exists and well behaved, therefore it is likely that it is stationary, but we need to check the poles of the system

####d) is there business ciclicality in the system?

first re-arrange the returns into the following form, and solve for the characteristic polynomial

\[ r_t +0.8 r\_{t-1} - 0.2 r\_{t-2} = 0\\ \Rightarrow (z^{2}+0.8z-0.2)R_z = 0\\ 5z^2+4z-1 = 0 \]

solving for \(z\) in this equation gives us the poles to the charateristic equation

\[ z_p=\frac{-4\pm\sqrt{16+4(5)}}{2(5)}=\frac{-4\pm\sqrt{36}}{10} = \frac{-2\pm3}{5} \\ z_p = 0.2 , z_p = -1 \]

poles are within the unit circle, and are real, therefore there is no cyclicality, and is marginally stable (hence stationary)

e) 1 step ahead predictions

\[ \hat{r}_{h+1|h} = -0.3+0.8r_h-0.2r_{h-1}\\ =-0.3+0.8(0.5)-0.2(0.5)=-0.3+0.4-0.1\\ \hat{r}_{h+1|h} = 0 \]

f) 2 step ahead predictions

\[ \hat{r}_{h+2|h} = -0.3+0.8\hat{r}_{h+1|h}-0.2r_{h} \\ = -0.3+0.8(0)-0.2(0.5) = -0.3-0.1\\ \hat{r}_{h+2|h} = -0.4 \]

f) 3 step ahead predictions

\[ \hat{r}_{h+3|h} = -0.3+0.8\hat{r}_{h+2|h}-0.2\hat{r}_{h+1|h} \\ =-0.3+0.8(0.4)-0.2(0)=-0.3-0.32\\ \hat{r}_{h+3|h} =-0.62 \]

Question 2

a & b) download and print summary statistics for the raw data

assuming the raw data refers to the (prices)


library("quantmod")
library("tidyverse")
library('e1071')
library('TSA')
library('tseries')

setwd("D:/RstudioTemp/HW2")
getSymbols("MMM",from='2009-01-01',to='2024-10-23')
[1] "MMM"
SLR = log(MMM)
SLR = SLR - lag(SLR)

Mean

apply(MMM,2,mean,na.rm=TRUE)
    MMM.Open     MMM.High      MMM.Low    MMM.Close   MMM.Volume MMM.Adjusted 
1.158938e+02 1.168100e+02 1.149263e+02 1.158998e+02 3.804437e+06 9.075854e+01 

Variance

apply(MMM,2,var,na.rm=TRUE)
    MMM.Open     MMM.High      MMM.Low    MMM.Close   MMM.Volume MMM.Adjusted 
1.499258e+03 1.515998e+03 1.479781e+03 1.497798e+03 8.550265e+12 1.183841e+03 

Excess kurtosis

apply(MMM,2,kurtosis,na.rm=TRUE)-3
    MMM.Open     MMM.High      MMM.Low    MMM.Close   MMM.Volume MMM.Adjusted 
   -3.973097    -3.974175    -3.972540    -3.974739   110.357639    -4.098584 

Skew

apply(MMM,2,skewness,na.rm=TRUE)
    MMM.Open     MMM.High      MMM.Low    MMM.Close   MMM.Volume MMM.Adjusted 
  0.09703695   0.09594662   0.09658766   0.09651089   8.31144900  -0.10050693 

c) build an AR model with PACF

from here on, we will use then adjusted log returns for our model

data <- SLR$MMM.Adjusted
data <-data %>% na.omit() %>% as.numeric()

n_ahead=15

# spliting data into working and testing datasets
wdata = head(data,length(data)-n_ahead+1)
tdata = tail(data,n_ahead)

PACF method,

sing the PACF, it suggest an AR model order of up to 7 as it seems significant,

pacf_data<-pacf(wdata)

AIC Method here for the AIC method, order p = 10 returns the lowest AIC value hence t is suggested, we will use order p = 10 from the AIC method

# fitting AR model using an AIC selection 
m=ar(wdata,na.rm=TRUE,method = "mle")
m_order=m$order
m_aic=m$aic

# plotting AIC for different models
plot(m_aic, type = 'o',xlab="aic",ylab='lags',main='aic on different lags')

d) estimate model and provide forecasts

# training AR model using p=10 form the AIC method 
m_ar =arima(wdata,order = c(m_order,0,0))


# function to plot predictions 
plot_predictions <- function(model, data, len, n_ahead, p) {
  # Generate predictions
  pred <- predict(model, n.ahead = n_ahead)
  
  # Indices for predictions
  idx <- ((len + 1):(len + n_ahead))
  
  # calculate the stdval given a p, this assumes twin tails
  q = 1-(1-p)/2
  stdval = qnorm(q)
  
  # Determine y-axis range
  ymin <- min(pred$pred - stdval * pred$se,tail(data, len),na.rm=TRUE)
  ymax <- max(pred$pred + stdval * pred$se,tail(data, len),na.rm=TRUE)
  
  # Plot the original data (last 'len' points)
  plot(
    tail(data, len), type = 'l',
    xlab = 'Time', ylab = 'values',
    main = 'Predicted values',
    xlim = c(0, len + n_ahead), ylim = c(ymin, ymax)
  )
  
  # Plot predictions
  lines(c(len, idx), c(tail(data, 1), pred$pred), col = 'blue', lwd = 2)
  
  # Plot confidence intervals
  lines(idx, pred$pred + stdval * pred$se, col = 'red', lwd = 2)
  lines(idx, pred$pred - stdval * pred$se, col = 'red', lwd = 2)
}

# function to evaluate model adequacy
eval_model <- function(m, data,len,n_ahead,CI){
    
    # print model
    m 
    
    # LB test 
    lagval = 12
    ans = Box.test(m$residuals,type = 'Ljung',lag=lagval)
    
    print(ans)
  
  if (ans$p.value>= 0.05) {
    HTresult = "cannot"
    HTword = "IS NOT"
  }else{
    HTresult = "can"
    HTword = "IS"
  }
  
  text = sprintf("Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for %s lags. The  p value for the test returns p =  %s, we %s reject the Null Hypothesis at 5 percent level; that is there %s serial dependancies in the residual",lagval,round(ans$p.value,6),HTresult, HTword)
  print(text)
  
  
  
  # visualise residual and plot residual acf
  plot(m$residuals, main = 'model residuals', ylab = 'residuals', xlab = 'time')
  acf(m$residuals)
  
  # visualise predictions
  plot_predictions(m,data,len,n_ahead,CI) 
  
}

plotting and evaluating model adequacy for 95% CI, predicted returns and actual returns seems reasonably similar

len = 40


plot_predictions(m_ar,wdata,len,n_ahead,0.95)

# comparing with actual returns 
idx = ((len):(len+n_ahead))
lines(idx,c(tail(wdata,1),tdata))

e) MA model

For MA models we expect a significant auto correlation, before a sharp drop off at lag q, therefore we should be able to visually select q based on the ACF , by looking for a drop off in auto-correlations

looking at the ACF of our data, we see significant values at q = 1 & 7 for our candidate models.

here I propose q = 7, as after 7 we see there’s no more significant auto correlations until lag = 22

acf(wdata)

q = 7

m_ma=arima(wdata,order=c(0,0,q))

f) estimate returns

again results are reasonably good, but qualitatively indistinguishable from our AR model

plot_predictions(m_ma,wdata,len,n_ahead,0.99)

# comparing with actual returns 
idx = ((len):(len+n_ahead))
lines(idx,c(tail(wdata,1),tdata))

g) model adequacy

AR model the AR model, doesn’t show any significant serial dependencies in the residuals, and the LB test confirms this. the ACF of the results indicate there might be some significant values remaining (ACF of white noise is the Dirac delta function), but only for higher lags and not significant for the LB test

overall the model seem adequate

eval_model(m_ar,wdata,len,n_ahead,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 1.5092, df = 12, p-value = 0.9999

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0.999865, we cannot reject the Null Hypothesis at 5 percent level; that is there IS NOT serial dependancies in the residual"

MA model Again the MA model, doesn’t show any significant serial dependencies in the residuals, and the LB test confirms this.

the ACF of the results indicate there might be some significant values remaining, again not significant for the LB test, but the order of lag seems to be lower, and for more lags than the AR model

overall the model also seem adequate, but the AR model seems to be better, and the AIC values confirms this

eval_model(m_ma,wdata,len,n_ahead,0.99)

    Box-Ljung test

data:  m$residuals
X-squared = 6.8339, df = 12, p-value = 0.8684

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0.86839, we cannot reject the Null Hypothesis at 5 percent level; that is there IS NOT serial dependancies in the residual"

print(sprintf("AIC : AR MODEL = %s; MA MODEL = %s",round(m_ar$aic,6),round(m_ma$aic,6)))
[1] "AIC : AR MODEL = -22061.696818; MA MODEL = -22059.595214"

Question 3

a & b) download and interpret the meaning of the VIX

VIX is the volatility index for the next 30 days for the S&P 500, and is calculated based on various put and call options. it can be interpreted as the level of the expectation of near term risks in the market, and have been called the “fear gauge”

getSymbols("VIX",from='2009-01-01',to= '2024-10-23')
Warning: VIX contains missing values. Some functions will not work if objects contain missing values in the middle of the series. Consider using na.omit(), na.approx(), na.fill(), etc to remove or replace them.
[1] "VIX"
VIX = na.omit(VIX)

VIXR = log(VIX)
VIXR = VIXR - lag(VIXR)

c & d) plot the distribution & ACF of the VIX, is it stationary?

here we uses the closing data of the VIX. Visual inspection of the raw data, and the distribution suggest it is non stationary.

to confirm this we run the ADF Test. The Null hypothesis states that the time series is non-stationary. our p-value is much greater than 5% hence we cannot reject the null hypothesis, which confirms our observations

 
det_lag <- function(data){
  data = na.omit(data)
  nobs = length(data)
  p = ceiling(12*(nobs/100)^0.25)
  return(p)
}


plot(VIX$VIX.Close)



wdata_vix = VIX$VIX.Close
wdata_vix <- as.numeric(wdata_vix)

lagval = det_lag(wdata_vix)

plot(density(wdata_vix))

adf.test(wdata_vix,k=lagval)

    Augmented Dickey-Fuller Test

data:  wdata_vix
Dickey-Fuller = -2.6982, Lag order = 21, p-value = 0.2828
alternative hypothesis: stationary

e) is the differenced VIX Value stationary?

yes, again using the ADF test, here the p value is << 5% hence we can reject the null hypothesis, this means that the time series is stationary

wdata_dvix = wdata_vix - lag(wdata_vix)
wdata_dvix <- na.omit(wdata_dvix)

plot(density(wdata_dvix))

adf.test(wdata_dvix,k=lagval)
Warning in adf.test(wdata_dvix, k = lagval) :
  p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  wdata_dvix
Dickey-Fuller = -6.6889, Lag order = 21, p-value = 0.01
alternative hypothesis: stationary

f) build an ARMA model on the differenced data

here we used the eacf method. it gave two viable candidates ARMA(0,1) and (2,1)

eacf(wdata_dvix)
AR/MA
  0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 x o o o x o x o o o o  o  o  o 
1 x x o o x o o o o o o  o  o  o 
2 x o o o x o o o o o o  o  o  o 
3 x x o o o o x x o o o  o  o  o 
4 x x x x o o o o o o o  o  o  o 
5 x x o x x o o o o o o  o  o  o 
6 x x o x x x x o o o o  o  o  o 
7 x x o x x o x o o o o  o  o  o 
m1_vix = arima(wdata_vix,order = c(0,1,1))
m2_vix = arima(wdata_vix,order = c(2,1,1))

evaluating the first model, we see that we fail to reject the null hypothesis for our ARMA(1,0) model at 5%, therefore there are likely serial dependencies in the residuals

hence the model is inadequate

eval_model(m1_vix,wdata_vix,100,15,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 19.17, df = 12, p-value = 0.0845

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0.084498, we cannot reject the Null Hypothesis at 5 percent level; that is there IS NOT serial dependancies in the residual"

evaluating the second model, the LB test shows that there are like no serial dependency in the residuals, and hence seems to be adequate

eval_model(m2_vix,wdata_vix,100,15,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 22.02, df = 12, p-value = 0.0373

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0.037301, we can reject the Null Hypothesis at 5 percent level; that is there IS serial dependancies in the residual"

Question 4

a) plot the monthly temperature and 1st differenced series

temperature

in_data <- read.table("m-globaltemp.txt",header=T)
wdata_tp <- in_data[,2:13]
wdata_tp <- c(t(wdata_tp))

plot(wdata_tp/100,type='l',main='tempurature against time',ylab = 'temperature(degrees C)',xlab = 'time')

plot(density(wdata_tp/100))

NA
NA

1st differneced temperature

wdata_dtp <- diff(wdata_tp)
plot(wdata_dtp/100,type='l',main = 'differenced tempurature against time', xlab = 'time', ylab = 'differenced temp (degrees C)')

plot(density(wdata_dtp/100))

b & c) is there a unit root in the temperature series?

Here we conduct the ADF test on the temperature (wdata_tp) and 1st differenced series (wdata_dtp)

from our ADF test, we see that we cannot reject our null hypothesis (where the time series is stationary) at the 5% level for the temperature series. this suggest that there is a unit root

on the other hand we see that we can reject our null hypothesis (where the time series is stationary) at the 5% level for the 1st difference series. this suggest that there is no unit root


lag_k = det_lag(wdata_tp)
adf.test(wdata_tp,k=lag_k)

    Augmented Dickey-Fuller Test

data:  wdata_tp
Dickey-Fuller = -3.0256, Lag order = 25, p-value = 0.1442
alternative hypothesis: stationary
adf.test(wdata_dtp,k=lag_k)
Warning in adf.test(wdata_dtp, k = lag_k) :
  p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  wdata_dtp
Dickey-Fuller = -11.405, Lag order = 25, p-value = 0.01
alternative hypothesis: stationary

d) fit AR model for the difference data

we use the MLE method for the differenced data, which suggest a model order of p = 11

# AR model to fit the differenced data (z_t = x_t - x_t-1)

m = ar(wdata_dtp, method='mle')

plot((0:(length(m$aic)-1)),m$aic,type='o')


print(sprintf("order p = %s",m$order))
[1] "order p = 11"
m_ar_dtp = arima(wdata_tp , order = c(m$order,1,0))

plot_predictions(m_ar_dtp,wdata_tp,100,12,0.95)

e & f) fit AR model for the original data, and plot the forecast

we use the MLE method for the original data, which suggest a model order of p = 12

Note think there’s a typo in the question? shouldn’t it be \(arima(x_t, order = c(p,\color{red}{\bf{0}},0))\) ? as we are working with the original data?

# AR model to fit the original data (x_t)

m = ar(wdata_tp, method='mle')

plot((0:(length(m$aic)-1)),m$aic,type='o')


print(sprintf("order p = %s",m$order))
[1] "order p = 12"
m_ar_tp = arima(wdata_tp , order = c(m$order,0,0))

plot_predictions(m_ar_tp,wdata_tp,100,12,0.95)

g & h) fit a ARMA model on the differenced data and model adequacy

the eacf produced a prime candidate of ARIMA(0,1,1), yet the LB test shows the model is not adequate. we see that there are still serial dependencies every 6 and 12 periods. this could be because there exists seasonality in the data

# eacf for an arma to fit the differenced data (z_t)

eacf(wdata_dtp)
AR/MA
  0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 x o o o o o o o o o o  x  o  o 
1 x x o o o o o o o o o  x  o  o 
2 x x x o o o o o o o o  o  o  o 
3 x x x x o o o o o o o  o  o  o 
4 x x x x x o o o o o o  o  o  o 
5 x x x o x x o o o o o  o  o  o 
6 x x x x o o o o o o o  o  o  o 
7 x x x x o o o o o o o  o  o  o 
lag_k = det_lag(wdata_dtp)

m_arma1_dtp = arima(wdata_tp , order = c(0,1,1))

eval_model(m_arma1_dtp,wdata_tp,100,n_ahead,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 95.303, df = 12, p-value = 4.552e-15

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0, we can reject the Null Hypothesis at 5 percent level; that is there IS serial dependancies in the residual"

i) refined model with seasonalities

here the model is still inadequate as the LB test shows that there are still serial dependencies, specifically the ACF shows highly significant values at lag 12 and 24, suggesting our seasonal terms are unable to capture the seasonal effects

m_arima_s1_tp = arima(wdata_tp,order = c(1,1,2), seasonal = list(order=c(1,1,0),period=12))  

eval_model(m_arima_s1_tp,wdata_tp,200,15,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 55.704, df = 12, p-value = 1.353e-07

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0, we can reject the Null Hypothesis at 5 percent level; that is there IS serial dependancies in the residual"

j) updated model

we assume that we are working on the original data (xt)

Note I think there’s also a typo here? shouldn’t it be \[ (1-\color{red}{\mathbf{sar_1}}L^{12})(1-\color{red}{\mathbf{ar_1}}L)x_t= (1-ma_1L)(1-sma_1L^{12})\epsilon_t\\ \] also according to this model, I think the code should be as follows? \[ m = arima(x_t, order = c(\color{red}{\bf{1}},\color{red}{\bf{0}},1),seasonal = list(order = c(\color{red}{\bf{1}},\color{red}{\bf{0}},1), period = 12) \] testing assuming there is a typo, the model is inadequate as the LB test shows serial dependencies in the residual


m_arima_s2_tp = arima(wdata_tp,order = c(1,0,1), seasonal = list(order=c(1,0,1),period=12))  

eval_model(m_arima_s2_tp,wdata_tp,200,15,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 23.519, df = 12, p-value = 0.02363

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0.023627, we can reject the Null Hypothesis at 5 percent level; that is there IS serial dependancies in the residual"

testing assuming there isn’t a typo in the code, the model is also inadequate as the LB test shows serial dependencies in the residual


m_arima_s3_tp = arima(wdata_tp,order = c(0,1,1), seasonal = list(order=c(0,1,1),period=12))  

eval_model(m_arima_s3_tp,wdata_tp,200,15,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 41.874, df = 12, p-value = 3.498e-05

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  3.5e-05, we can reject the Null Hypothesis at 5 percent level; that is there IS serial dependancies in the residual"

suggestion: from part (i) we saw that the model returns good results except for highly significant non-zero auto correlations at lag 12 & 24 which suggest the annual seasonality is not sufficiently captured. instead we can try to use an more seasonal terms to capture these seasonal effects.

let’s try introducing a seasonal MA term, here we saw the results produce a more adequate model, at least in the sense that LB test shows no serial dependencies in the residual, and also a smaller AIC in all the models so far


m_arima_sa_tp = arima(wdata_tp,order = c(1,1,2), seasonal = list(order=c(1,1,1),period=12))  

eval_model(m_arima_sa_tp,wdata_tp,200,15,0.95)

    Box-Ljung test

data:  m$residuals
X-squared = 10.56, df = 12, p-value = 0.5669

[1] "Ljung-Box test: Null Hypothesis states there is no serial dependancies (auto-correlations) in the residual for 12 lags. The  p value for the test returns p =  0.56693, we cannot reject the Null Hypothesis at 5 percent level; that is there IS NOT serial dependancies in the residual"

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIEhvbWV3b3JrIDINCg0KZmluZCB0aGUgZnVsbCB2ZXJzaW9uIGhlcmUgPGh0dHBzOi8vcnB1YnMuY29tL1RDTUwvMTI0NTg0MT4NCg0KIyMjIFF1ZXN0aW9uIDENCg0KJCQNCnJfdCA9IC0wLjMgKyAwLjggcl97dC0xfSAtMC4yIHJfe3QtMn0gKyBcZXBzaWxvbl90DQokJA0KDQojIyMjYSkgdGhlIG1lYW4gb2YgdGhlIHN0b2NrIHJldHVybg0KDQp0aGlzIGlzIGFuIEFSKDIpIHByb2Nlc3Mgd2l0aCAkXGFscGhhXzAgPSAtMC4zLCBcYWxwaGFfMSA9IDAuOCwgXGFscGhhXzIgPSAtMC4yJCwgYXNzdW1pbmcgdGhpcyBpcyBzdGF0aW9uYXJ5IHRoZW4sDQoNCiQkDQpcbXUgPSBcZnJhY3tcYWxwaGFfMH17MS1cYWxwaGFfMS1cYWxwaGFfMn0gPSBcZnJhY3stMC4zfXsoMS0wLjgrMC4yKX09XGZyYWN7LTAuM317MC40fT0tMC43NQ0KJCQNCg0KIyMjI2IpIHRoZSB2YXJpYW5jZSBvZiBzdG9jayByZXR1cm4NCg0KdGhlIHZhcmlhbmNlICRcZ2FtbWFfMCQgb2YgYW4gQVIoMikgcHJvY2VzcyBpcyBnaXZlbiBieQ0KDQokJA0KXGdhbW1hXzAgPSBcZnJhY3tcc2lnbWFfbl4yKzJcYWxwaGFfMVxhbHBoYV8yXGdhbW1hXzF9ezEtXGFscGhhXzFeMi1cYWxwaGFfMl4yfSA9XGZyYWN7NCsyKDAuOCkoLTAuMilcZ2FtbWFfMX17MS0wLjY0LTAuMDR9PSBcZnJhY3sxNi0wLjMyXGdhbW1hXzF9ezAuMzJ9DQokJA0KDQpmdXJ0aGVybW9yZSwgd2UgYWxzbyBoYXZlIHRoZSBlcXV0aW9uICQkDQpcZ2FtbWFfMSA9IFxmcmFje1xhbHBoYV8xXGdhbW1hXzB9ezEtXGFscGhhXzJ9PVxmcmFjezAuOH17MS4yfVxnYW1tYV8wPVxmcmFjezJ9ezN9XGdhbW1hXzANCiQkIGZyb20gJFxnYW1tYShqPTEpPVxhbHBoYV8yXGdhbW1hX3tqLTJ9K1xhbHBoYV8xXGdhbW1hX3tqLTF9LCBcZ2FtbWFfey0xfT1cZ2FtbWFfMSQNCg0Kc3Vic3RpdHV0aW5nIHRoaXMgaW50bw0KDQokJA0KMC4zMlxnYW1tYV8wIC0wLjM9IDQtMC4zMihcZnJhY3syfXszfVxnYW1tYV8wKVxcDQowLjMyXGdhbW1hXzAoMS1cZnJhY3syfXszfSkgPSA0LTAuMzJcZ2FtbWFfMVxcDQpcZ2FtbWFfMCA9XGZyYWN7NH17MC4zMn0oMyk9MzcuNQ0KJCQNCg0KIyMjIyBjKSBiYXNlZCBvbiB0aGUgcmVzdWx0cyBpcyB0aGUgcHJvY2VzcyBzdGF0aW9uYXJ5Pw0KDQpib3RoIHRoZSBtZWFuIGFuZCB0aGUgdmFyaWFuY2UgZXhpc3RzIGFuZCB3ZWxsIGJlaGF2ZWQsIHRoZXJlZm9yZSBpdCBpcyBsaWtlbHkgdGhhdCBpdCBpcyBzdGF0aW9uYXJ5LCBidXQgd2UgbmVlZCB0byBjaGVjayB0aGUgcG9sZXMgb2YgdGhlIHN5c3RlbQ0KDQojIyMjZCkgaXMgdGhlcmUgYnVzaW5lc3MgY2ljbGljYWxpdHkgaW4gdGhlIHN5c3RlbT8NCg0KZmlyc3QgcmUtYXJyYW5nZSB0aGUgcmV0dXJucyBpbnRvIHRoZSBmb2xsb3dpbmcgZm9ybSwgYW5kIHNvbHZlIGZvciB0aGUgY2hhcmFjdGVyaXN0aWMgcG9seW5vbWlhbA0KDQokJCANCnJfdCArMC44IHJcX3t0LTF9IC0gMC4yIHJcX3t0LTJ9ID0gMFxcIA0KXFJpZ2h0YXJyb3cgKHpeezJ9KzAuOHotMC4yKVJfeiA9IDBcXCA1el4yKzR6LTEgPSAwDQokJA0KDQpzb2x2aW5nIGZvciAkeiQgaW4gdGhpcyBlcXVhdGlvbiBnaXZlcyB1cyB0aGUgcG9sZXMgdG8gdGhlIGNoYXJhdGVyaXN0aWMgZXF1YXRpb24NCg0KJCQgDQp6X3A9XGZyYWN7LTRccG1cc3FydHsxNis0KDUpfX17Mig1KX09XGZyYWN7LTRccG1cc3FydHszNn19ezEwfSA9IFxmcmFjey0yXHBtM317NX0gXFwNCnpfcCA9IDAuMiAsIHpfcCA9IC0xIA0KJCQNCg0KcG9sZXMgYXJlIHdpdGhpbiB0aGUgdW5pdCBjaXJjbGUsIGFuZCBhcmUgcmVhbCwgdGhlcmVmb3JlIHRoZXJlIGlzIG5vIGN5Y2xpY2FsaXR5LCBhbmQgaXMgbWFyZ2luYWxseSBzdGFibGUgKGhlbmNlIHN0YXRpb25hcnkpDQoNCiMjIyMgZSkgMSBzdGVwIGFoZWFkIHByZWRpY3Rpb25zDQoNCiQkDQpcaGF0e3J9X3toKzF8aH0gPSAtMC4zKzAuOHJfaC0wLjJyX3toLTF9XFwNCj0tMC4zKzAuOCgwLjUpLTAuMigwLjUpPS0wLjMrMC40LTAuMVxcDQpcaGF0e3J9X3toKzF8aH0gPSAwDQokJA0KDQojIyMjIGYpIDIgc3RlcCBhaGVhZCBwcmVkaWN0aW9ucw0KDQokJCANClxoYXR7cn1fe2grMnxofSA9IC0wLjMrMC44XGhhdHtyfV97aCsxfGh9LTAuMnJfe2h9IFxcID0gLTAuMyswLjgoMCktMC4yKDAuNSkgPSAtMC4zLTAuMVxcIA0KXGhhdHtyfV97aCsyfGh9ID0gLTAuNA0KJCQNCg0KIyMjIyBmKSAzIHN0ZXAgYWhlYWQgcHJlZGljdGlvbnMNCg0KJCQNClxoYXR7cn1fe2grM3xofSA9IC0wLjMrMC44XGhhdHtyfV97aCsyfGh9LTAuMlxoYXR7cn1fe2grMXxofSBcXA0KPS0wLjMrMC44KDAuNCktMC4yKDApPS0wLjMtMC4zMlxcDQpcaGF0e3J9X3toKzN8aH0gPS0wLjYyDQokJA0KDQojIyMgUXVlc3Rpb24gMg0KDQojIyMjIGEgJiBiKSBkb3dubG9hZCBhbmQgcHJpbnQgc3VtbWFyeSBzdGF0aXN0aWNzIGZvciB0aGUgcmF3IGRhdGENCg0KYXNzdW1pbmcgdGhlIHJhdyBkYXRhIHJlZmVycyB0byB0aGUgKHByaWNlcykNCg0KYGBge3J9DQoNCmxpYnJhcnkoInF1YW50bW9kIikNCmxpYnJhcnkoInRpZHl2ZXJzZSIpDQpsaWJyYXJ5KCdlMTA3MScpDQpsaWJyYXJ5KCdUU0EnKQ0KbGlicmFyeSgndHNlcmllcycpDQoNCnNldHdkKCJEOi9Sc3R1ZGlvVGVtcC9IVzIiKQ0KYGBgDQoNCmBgYHtyfQ0KZ2V0U3ltYm9scygiTU1NIixmcm9tPScyMDA5LTAxLTAxJyx0bz0nMjAyNC0xMC0yMycpDQoNClNMUiA9IGxvZyhNTU0pDQpTTFIgPSBTTFIgLSBsYWcoU0xSKQ0KDQpgYGANCg0KKipNZWFuKioNCg0KYGBge3J9DQphcHBseShNTU0sMixtZWFuLG5hLnJtPVRSVUUpDQpgYGANCg0KKipWYXJpYW5jZSoqDQoNCmBgYHtyfQ0KYXBwbHkoTU1NLDIsdmFyLG5hLnJtPVRSVUUpDQpgYGANCg0KKipFeGNlc3Mga3VydG9zaXMqKg0KDQpgYGB7cn0NCmFwcGx5KE1NTSwyLGt1cnRvc2lzLG5hLnJtPVRSVUUpLTMNCmBgYA0KDQoqKlNrZXcqKg0KDQpgYGB7cn0NCmFwcGx5KE1NTSwyLHNrZXduZXNzLG5hLnJtPVRSVUUpDQpgYGANCg0KIyMjIyBjKSBidWlsZCBhbiBBUiBtb2RlbCB3aXRoIFBBQ0YNCg0KZnJvbSBoZXJlIG9uLCB3ZSB3aWxsIHVzZSB0aGVuIGFkanVzdGVkIGxvZyByZXR1cm5zIGZvciBvdXIgbW9kZWwNCg0KYGBge3J9DQpkYXRhIDwtIFNMUiRNTU0uQWRqdXN0ZWQNCmRhdGEgPC1kYXRhICU+JSBuYS5vbWl0KCkgJT4lIGFzLm51bWVyaWMoKQ0KDQpuX2FoZWFkPTE1DQoNCiMgc3BsaXRpbmcgZGF0YSBpbnRvIHdvcmtpbmcgYW5kIHRlc3RpbmcgZGF0YXNldHMNCndkYXRhID0gaGVhZChkYXRhLGxlbmd0aChkYXRhKS1uX2FoZWFkKzEpDQp0ZGF0YSA9IHRhaWwoZGF0YSxuX2FoZWFkKQ0KDQpgYGANCg0KKipQQUNGIG1ldGhvZCwqKg0KDQpzaW5nIHRoZSBQQUNGLCBpdCBzdWdnZXN0IGFuIEFSIG1vZGVsIG9yZGVyIG9mIHVwIHRvIDcgYXMgaXQgc2VlbXMgc2lnbmlmaWNhbnQsDQoNCmBgYHtyfQ0KcGFjZl9kYXRhPC1wYWNmKHdkYXRhKQ0KDQpgYGANCg0KKipBSUMgTWV0aG9kKiogaGVyZSBmb3IgdGhlIEFJQyBtZXRob2QsIG9yZGVyIHAgPSAxMCByZXR1cm5zIHRoZSBsb3dlc3QgQUlDIHZhbHVlIGhlbmNlIHQgaXMgc3VnZ2VzdGVkLCB3ZSB3aWxsIHVzZSBvcmRlciBwID0gMTAgZnJvbSB0aGUgQUlDIG1ldGhvZA0KDQpgYGB7cn0NCiMgZml0dGluZyBBUiBtb2RlbCB1c2luZyBhbiBBSUMgc2VsZWN0aW9uIA0KbT1hcih3ZGF0YSxuYS5ybT1UUlVFLG1ldGhvZCA9ICJtbGUiKQ0KbV9vcmRlcj1tJG9yZGVyDQptX2FpYz1tJGFpYw0KDQojIHBsb3R0aW5nIEFJQyBmb3IgZGlmZmVyZW50IG1vZGVscw0KcGxvdChtX2FpYywgdHlwZSA9ICdvJyx4bGFiPSJhaWMiLHlsYWI9J2xhZ3MnLG1haW49J2FpYyBvbiBkaWZmZXJlbnQgbGFncycpDQoNCmBgYA0KDQojIyMjIGQpIGVzdGltYXRlIG1vZGVsIGFuZCBwcm92aWRlIGZvcmVjYXN0cw0KDQpgYGB7cn0NCiMgdHJhaW5pbmcgQVIgbW9kZWwgdXNpbmcgcD0xMCBmb3JtIHRoZSBBSUMgbWV0aG9kIA0KbV9hciA9YXJpbWEod2RhdGEsb3JkZXIgPSBjKG1fb3JkZXIsMCwwKSkNCg0KDQojIGZ1bmN0aW9uIHRvIHBsb3QgcHJlZGljdGlvbnMgDQpwbG90X3ByZWRpY3Rpb25zIDwtIGZ1bmN0aW9uKG1vZGVsLCBkYXRhLCBsZW4sIG5fYWhlYWQsIHApIHsNCiAgIyBHZW5lcmF0ZSBwcmVkaWN0aW9ucw0KICBwcmVkIDwtIHByZWRpY3QobW9kZWwsIG4uYWhlYWQgPSBuX2FoZWFkKQ0KICANCiAgIyBJbmRpY2VzIGZvciBwcmVkaWN0aW9ucw0KICBpZHggPC0gKChsZW4gKyAxKToobGVuICsgbl9haGVhZCkpDQogIA0KICAjIGNhbGN1bGF0ZSB0aGUgc3RkdmFsIGdpdmVuIGEgcCwgdGhpcyBhc3N1bWVzIHR3aW4gdGFpbHMNCiAgcSA9IDEtKDEtcCkvMg0KICBzdGR2YWwgPSBxbm9ybShxKQ0KICANCiAgIyBEZXRlcm1pbmUgeS1heGlzIHJhbmdlDQogIHltaW4gPC0gbWluKHByZWQkcHJlZCAtIHN0ZHZhbCAqIHByZWQkc2UsdGFpbChkYXRhLCBsZW4pLG5hLnJtPVRSVUUpDQogIHltYXggPC0gbWF4KHByZWQkcHJlZCArIHN0ZHZhbCAqIHByZWQkc2UsdGFpbChkYXRhLCBsZW4pLG5hLnJtPVRSVUUpDQogIA0KICAjIFBsb3QgdGhlIG9yaWdpbmFsIGRhdGEgKGxhc3QgJ2xlbicgcG9pbnRzKQ0KICBwbG90KA0KICAgIHRhaWwoZGF0YSwgbGVuKSwgdHlwZSA9ICdsJywNCiAgICB4bGFiID0gJ1RpbWUnLCB5bGFiID0gJ3ZhbHVlcycsDQogICAgbWFpbiA9ICdQcmVkaWN0ZWQgdmFsdWVzJywNCiAgICB4bGltID0gYygwLCBsZW4gKyBuX2FoZWFkKSwgeWxpbSA9IGMoeW1pbiwgeW1heCkNCiAgKQ0KICANCiAgIyBQbG90IHByZWRpY3Rpb25zDQogIGxpbmVzKGMobGVuLCBpZHgpLCBjKHRhaWwoZGF0YSwgMSksIHByZWQkcHJlZCksIGNvbCA9ICdibHVlJywgbHdkID0gMikNCiAgDQogICMgUGxvdCBjb25maWRlbmNlIGludGVydmFscw0KICBsaW5lcyhpZHgsIHByZWQkcHJlZCArIHN0ZHZhbCAqIHByZWQkc2UsIGNvbCA9ICdyZWQnLCBsd2QgPSAyKQ0KICBsaW5lcyhpZHgsIHByZWQkcHJlZCAtIHN0ZHZhbCAqIHByZWQkc2UsIGNvbCA9ICdyZWQnLCBsd2QgPSAyKQ0KfQ0KDQojIGZ1bmN0aW9uIHRvIGV2YWx1YXRlIG1vZGVsIGFkZXF1YWN5DQpldmFsX21vZGVsIDwtIGZ1bmN0aW9uKG0sIGRhdGEsbGVuLG5fYWhlYWQsQ0kpew0KICAgIA0KICAgICMgcHJpbnQgbW9kZWwNCiAgICBtIA0KICAgIA0KICAgICMgTEIgdGVzdCANCiAgICBsYWd2YWwgPSAxMg0KICAgIGFucyA9IEJveC50ZXN0KG0kcmVzaWR1YWxzLHR5cGUgPSAnTGp1bmcnLGxhZz1sYWd2YWwpDQogICAgDQogICAgcHJpbnQoYW5zKQ0KICANCiAgaWYgKGFucyRwLnZhbHVlPj0gMC4wNSkgew0KICAgIEhUcmVzdWx0ID0gImNhbm5vdCINCiAgICBIVHdvcmQgPSAiSVMgTk9UIg0KICB9ZWxzZXsNCiAgICBIVHJlc3VsdCA9ICJjYW4iDQogICAgSFR3b3JkID0gIklTIg0KICB9DQogIA0KICB0ZXh0ID0gc3ByaW50ZigiTGp1bmctQm94IHRlc3Q6IE51bGwgSHlwb3RoZXNpcyBzdGF0ZXMgdGhlcmUgaXMgbm8gc2VyaWFsIGRlcGVuZGFuY2llcyAoYXV0by1jb3JyZWxhdGlvbnMpIGluIHRoZSByZXNpZHVhbCBmb3IgJXMgbGFncy4gVGhlICBwIHZhbHVlIGZvciB0aGUgdGVzdCByZXR1cm5zIHAgPSAgJXMsIHdlICVzIHJlamVjdCB0aGUgTnVsbCBIeXBvdGhlc2lzIGF0IDUgcGVyY2VudCBsZXZlbDsgdGhhdCBpcyB0aGVyZSAlcyBzZXJpYWwgZGVwZW5kYW5jaWVzIGluIHRoZSByZXNpZHVhbCIsbGFndmFsLHJvdW5kKGFucyRwLnZhbHVlLDYpLEhUcmVzdWx0LCBIVHdvcmQpDQogIHByaW50KHRleHQpDQogIA0KICANCiAgDQogICMgdmlzdWFsaXNlIHJlc2lkdWFsIGFuZCBwbG90IHJlc2lkdWFsIGFjZg0KICBwbG90KG0kcmVzaWR1YWxzLCBtYWluID0gJ21vZGVsIHJlc2lkdWFscycsIHlsYWIgPSAncmVzaWR1YWxzJywgeGxhYiA9ICd0aW1lJykNCiAgYWNmKG0kcmVzaWR1YWxzKQ0KICANCiAgIyB2aXN1YWxpc2UgcHJlZGljdGlvbnMNCiAgcGxvdF9wcmVkaWN0aW9ucyhtLGRhdGEsbGVuLG5fYWhlYWQsQ0kpIA0KICANCn0NCg0KDQpgYGANCg0KcGxvdHRpbmcgYW5kIGV2YWx1YXRpbmcgbW9kZWwgYWRlcXVhY3kgZm9yIDk1JSBDSSwgcHJlZGljdGVkIHJldHVybnMgYW5kIGFjdHVhbCByZXR1cm5zIHNlZW1zIHJlYXNvbmFibHkgc2ltaWxhcg0KDQpgYGB7cn0NCmxlbiA9IDQwDQoNCg0KcGxvdF9wcmVkaWN0aW9ucyhtX2FyLHdkYXRhLGxlbixuX2FoZWFkLDAuOTUpDQoNCiMgY29tcGFyaW5nIHdpdGggYWN0dWFsIHJldHVybnMgDQppZHggPSAoKGxlbik6KGxlbituX2FoZWFkKSkNCmxpbmVzKGlkeCxjKHRhaWwod2RhdGEsMSksdGRhdGEpKQ0KYGBgDQoNCiMjIyMgZSkgTUEgbW9kZWwNCg0KRm9yIE1BIG1vZGVscyB3ZSBleHBlY3QgYSBzaWduaWZpY2FudCBhdXRvIGNvcnJlbGF0aW9uLCBiZWZvcmUgYSBzaGFycCBkcm9wIG9mZiBhdCBsYWcgcSwgdGhlcmVmb3JlIHdlIHNob3VsZCBiZSBhYmxlIHRvIHZpc3VhbGx5IHNlbGVjdCBxIGJhc2VkIG9uIHRoZSBBQ0YgLCBieSBsb29raW5nIGZvciBhIGRyb3Agb2ZmIGluIGF1dG8tY29ycmVsYXRpb25zDQoNCmxvb2tpbmcgYXQgdGhlIEFDRiBvZiBvdXIgZGF0YSwgd2Ugc2VlIHNpZ25pZmljYW50IHZhbHVlcyBhdCBxID0gMSAmIDcgZm9yIG91ciBjYW5kaWRhdGUgbW9kZWxzLg0KDQpoZXJlIEkgcHJvcG9zZSBxID0gNywgYXMgYWZ0ZXIgNyB3ZSBzZWUgdGhlcmUncyBubyBtb3JlIHNpZ25pZmljYW50IGF1dG8gY29ycmVsYXRpb25zIHVudGlsIGxhZyA9IDIyDQoNCmBgYHtyfQ0KYWNmKHdkYXRhKQ0KcSA9IDcNCg0KbV9tYT1hcmltYSh3ZGF0YSxvcmRlcj1jKDAsMCxxKSkNCmBgYA0KDQojIyMjIGYpIGVzdGltYXRlIHJldHVybnMNCg0KYWdhaW4gcmVzdWx0cyBhcmUgcmVhc29uYWJseSBnb29kLCBidXQgcXVhbGl0YXRpdmVseSBpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tIG91ciBBUiBtb2RlbA0KDQpgYGB7cn0NCnBsb3RfcHJlZGljdGlvbnMobV9tYSx3ZGF0YSxsZW4sbl9haGVhZCwwLjk5KQ0KDQojIGNvbXBhcmluZyB3aXRoIGFjdHVhbCByZXR1cm5zIA0KaWR4ID0gKChsZW4pOihsZW4rbl9haGVhZCkpDQpsaW5lcyhpZHgsYyh0YWlsKHdkYXRhLDEpLHRkYXRhKSkNCmBgYA0KDQojIyMjIGcpIG1vZGVsIGFkZXF1YWN5DQoNCioqQVIgbW9kZWwqKiB0aGUgQVIgbW9kZWwsIGRvZXNuJ3Qgc2hvdyBhbnkgc2lnbmlmaWNhbnQgc2VyaWFsIGRlcGVuZGVuY2llcyBpbiB0aGUgcmVzaWR1YWxzLCBhbmQgdGhlIExCIHRlc3QgY29uZmlybXMgdGhpcy4gdGhlIEFDRiBvZiB0aGUgcmVzdWx0cyBpbmRpY2F0ZSB0aGVyZSBtaWdodCBiZSBzb21lIHNpZ25pZmljYW50IHZhbHVlcyByZW1haW5pbmcgKEFDRiBvZiB3aGl0ZSBub2lzZSBpcyB0aGUgRGlyYWMgZGVsdGEgZnVuY3Rpb24pLCBidXQgb25seSBmb3IgaGlnaGVyIGxhZ3MgYW5kIG5vdCBzaWduaWZpY2FudCBmb3IgdGhlIExCIHRlc3QNCg0Kb3ZlcmFsbCB0aGUgbW9kZWwgc2VlbSBhZGVxdWF0ZQ0KDQpgYGB7cn0NCmV2YWxfbW9kZWwobV9hcix3ZGF0YSxsZW4sbl9haGVhZCwwLjk1KQ0KDQpgYGANCg0KKipNQSBtb2RlbCoqIEFnYWluIHRoZSBNQSBtb2RlbCwgZG9lc24ndCBzaG93IGFueSBzaWduaWZpY2FudCBzZXJpYWwgZGVwZW5kZW5jaWVzIGluIHRoZSByZXNpZHVhbHMsIGFuZCB0aGUgTEIgdGVzdCBjb25maXJtcyB0aGlzLg0KDQp0aGUgQUNGIG9mIHRoZSByZXN1bHRzIGluZGljYXRlIHRoZXJlIG1pZ2h0IGJlIHNvbWUgc2lnbmlmaWNhbnQgdmFsdWVzIHJlbWFpbmluZywgYWdhaW4gbm90IHNpZ25pZmljYW50IGZvciB0aGUgTEIgdGVzdCwgYnV0IHRoZSBvcmRlciBvZiBsYWcgc2VlbXMgdG8gYmUgbG93ZXIsIGFuZCBmb3IgbW9yZSBsYWdzIHRoYW4gdGhlIEFSIG1vZGVsDQoNCm92ZXJhbGwgdGhlIG1vZGVsIGFsc28gc2VlbSBhZGVxdWF0ZSwgYnV0IHRoZSBBUiBtb2RlbCBzZWVtcyB0byBiZSBiZXR0ZXIsIGFuZCB0aGUgQUlDIHZhbHVlcyBjb25maXJtcyB0aGlzDQoNCmBgYHtyfQ0KZXZhbF9tb2RlbChtX21hLHdkYXRhLGxlbixuX2FoZWFkLDAuOTkpDQpwcmludChzcHJpbnRmKCJBSUMgOiBBUiBNT0RFTCA9ICVzOyBNQSBNT0RFTCA9ICVzIixyb3VuZChtX2FyJGFpYyw2KSxyb3VuZChtX21hJGFpYyw2KSkpDQoNCmBgYA0KDQojIyMgUXVlc3Rpb24gMw0KDQojIyMjIGEgJiBiKSBkb3dubG9hZCBhbmQgaW50ZXJwcmV0IHRoZSBtZWFuaW5nIG9mIHRoZSBWSVgNCg0KVklYIGlzIHRoZSB2b2xhdGlsaXR5IGluZGV4IGZvciB0aGUgbmV4dCAzMCBkYXlzIGZvciB0aGUgUyZQIDUwMCwgYW5kIGlzIGNhbGN1bGF0ZWQgYmFzZWQgb24gdmFyaW91cyBwdXQgYW5kIGNhbGwgb3B0aW9ucy4gaXQgY2FuIGJlIGludGVycHJldGVkIGFzIHRoZSBsZXZlbCBvZiB0aGUgZXhwZWN0YXRpb24gb2YgbmVhciB0ZXJtIHJpc2tzIGluIHRoZSBtYXJrZXQsIGFuZCBoYXZlIGJlZW4gY2FsbGVkIHRoZSAiZmVhciBnYXVnZSINCg0KYGBge3J9DQpnZXRTeW1ib2xzKCJWSVgiLGZyb209JzIwMDktMDEtMDEnLHRvPSAnMjAyNC0xMC0yMycpDQpWSVggPSBuYS5vbWl0KFZJWCkNCg0KVklYUiA9IGxvZyhWSVgpDQpWSVhSID0gVklYUiAtIGxhZyhWSVhSKQ0KDQpgYGANCg0KIyMjIyBjICYgZCkgcGxvdCB0aGUgZGlzdHJpYnV0aW9uICYgQUNGIG9mIHRoZSBWSVgsIGlzIGl0IHN0YXRpb25hcnk/DQoNCmhlcmUgd2UgdXNlcyB0aGUgY2xvc2luZyBkYXRhIG9mIHRoZSBWSVguIFZpc3VhbCBpbnNwZWN0aW9uIG9mIHRoZSByYXcgZGF0YSwgYW5kIHRoZSBkaXN0cmlidXRpb24gc3VnZ2VzdCBpdCBpcyBub24gc3RhdGlvbmFyeS4NCg0KdG8gY29uZmlybSB0aGlzIHdlIHJ1biB0aGUgQURGIFRlc3QuIFRoZSBOdWxsIGh5cG90aGVzaXMgc3RhdGVzIHRoYXQgdGhlIHRpbWUgc2VyaWVzIGlzIG5vbi1zdGF0aW9uYXJ5LiBvdXIgcC12YWx1ZSBpcyBtdWNoIGdyZWF0ZXIgdGhhbiA1JSBoZW5jZSB3ZSBjYW5ub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMsIHdoaWNoIGNvbmZpcm1zIG91ciBvYnNlcnZhdGlvbnMNCg0KYGBge3J9DQogDQpkZXRfbGFnIDwtIGZ1bmN0aW9uKGRhdGEpew0KICBkYXRhID0gbmEub21pdChkYXRhKQ0KICBub2JzID0gbGVuZ3RoKGRhdGEpDQogIHAgPSBjZWlsaW5nKDEyKihub2JzLzEwMCleMC4yNSkNCiAgcmV0dXJuKHApDQp9DQoNCg0KcGxvdChWSVgkVklYLkNsb3NlKQ0KDQoNCndkYXRhX3ZpeCA9IFZJWCRWSVguQ2xvc2UNCndkYXRhX3ZpeCA8LSBhcy5udW1lcmljKHdkYXRhX3ZpeCkNCg0KbGFndmFsID0gZGV0X2xhZyh3ZGF0YV92aXgpDQoNCnBsb3QoZGVuc2l0eSh3ZGF0YV92aXgpKQ0KYWRmLnRlc3Qod2RhdGFfdml4LGs9bGFndmFsKQ0KDQpgYGANCg0KIyMjIyBlKSBpcyB0aGUgZGlmZmVyZW5jZWQgVklYIFZhbHVlIHN0YXRpb25hcnk/DQoNCnllcywgYWdhaW4gdXNpbmcgdGhlIEFERiB0ZXN0LCBoZXJlIHRoZSBwIHZhbHVlIGlzIFw8XDwgNSUgaGVuY2Ugd2UgY2FuIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzLCB0aGlzIG1lYW5zIHRoYXQgdGhlIHRpbWUgc2VyaWVzIGlzIHN0YXRpb25hcnkNCg0KYGBge3J9DQp3ZGF0YV9kdml4ID0gd2RhdGFfdml4IC0gbGFnKHdkYXRhX3ZpeCkNCndkYXRhX2R2aXggPC0gbmEub21pdCh3ZGF0YV9kdml4KQ0KDQpwbG90KGRlbnNpdHkod2RhdGFfZHZpeCkpDQphZGYudGVzdCh3ZGF0YV9kdml4LGs9bGFndmFsKQ0KYGBgDQoNCiMjIyMgZikgYnVpbGQgYW4gQVJNQSBtb2RlbCBvbiB0aGUgZGlmZmVyZW5jZWQgZGF0YQ0KDQpoZXJlIHdlIHVzZWQgdGhlIGVhY2YgbWV0aG9kLiBpdCBnYXZlIHR3byB2aWFibGUgY2FuZGlkYXRlcyBBUk1BKDAsMSkgYW5kICgyLDEpDQoNCmBgYHtyfQ0KZWFjZih3ZGF0YV9kdml4KQ0KDQptMV92aXggPSBhcmltYSh3ZGF0YV92aXgsb3JkZXIgPSBjKDAsMSwxKSkNCm0yX3ZpeCA9IGFyaW1hKHdkYXRhX3ZpeCxvcmRlciA9IGMoMiwxLDEpKQ0KDQpgYGANCg0KZXZhbHVhdGluZyB0aGUgZmlyc3QgbW9kZWwsIHdlIHNlZSB0aGF0IHdlIGZhaWwgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgZm9yIG91ciBBUk1BKDEsMCkgbW9kZWwgYXQgNSUsIHRoZXJlZm9yZSB0aGVyZSBhcmUgbGlrZWx5IHNlcmlhbCBkZXBlbmRlbmNpZXMgaW4gdGhlIHJlc2lkdWFscw0KDQpoZW5jZSB0aGUgbW9kZWwgaXMgaW5hZGVxdWF0ZQ0KDQpgYGB7cn0NCmV2YWxfbW9kZWwobTFfdml4LHdkYXRhX3ZpeCwxMDAsMTUsMC45NSkNCmBgYA0KDQpldmFsdWF0aW5nIHRoZSBzZWNvbmQgbW9kZWwsIHRoZSBMQiB0ZXN0IHNob3dzIHRoYXQgdGhlcmUgYXJlIGxpa2Ugbm8gc2VyaWFsIGRlcGVuZGVuY3kgaW4gdGhlIHJlc2lkdWFscywgYW5kIGhlbmNlIHNlZW1zIHRvIGJlIGFkZXF1YXRlDQoNCmBgYHtyfQ0KZXZhbF9tb2RlbChtMl92aXgsd2RhdGFfdml4LDEwMCwxNSwwLjk1KQ0KYGBgDQoNCiMjIyBRdWVzdGlvbiA0DQoNCiMjIyMgYSkgcGxvdCB0aGUgbW9udGhseSB0ZW1wZXJhdHVyZSBhbmQgMXN0IGRpZmZlcmVuY2VkIHNlcmllcw0KDQoqKnRlbXBlcmF0dXJlKioNCg0KYGBge3J9DQppbl9kYXRhIDwtIHJlYWQudGFibGUoIm0tZ2xvYmFsdGVtcC50eHQiLGhlYWRlcj1UKQ0Kd2RhdGFfdHAgPC0gaW5fZGF0YVssMjoxM10NCndkYXRhX3RwIDwtIGModCh3ZGF0YV90cCkpDQoNCnBsb3Qod2RhdGFfdHAvMTAwLHR5cGU9J2wnLG1haW49J3RlbXB1cmF0dXJlIGFnYWluc3QgdGltZScseWxhYiA9ICd0ZW1wZXJhdHVyZShkZWdyZWVzIEMpJyx4bGFiID0gJ3RpbWUnKQ0KcGxvdChkZW5zaXR5KHdkYXRhX3RwLzEwMCkpDQoNCg0KYGBgDQoNCioqMXN0IGRpZmZlcm5lY2VkIHRlbXBlcmF0dXJlKioNCg0KYGBge3J9DQp3ZGF0YV9kdHAgPC0gZGlmZih3ZGF0YV90cCkNCnBsb3Qod2RhdGFfZHRwLzEwMCx0eXBlPSdsJyxtYWluID0gJ2RpZmZlcmVuY2VkIHRlbXB1cmF0dXJlIGFnYWluc3QgdGltZScsIHhsYWIgPSAndGltZScsIHlsYWIgPSAnZGlmZmVyZW5jZWQgdGVtcCAoZGVncmVlcyBDKScpDQpwbG90KGRlbnNpdHkod2RhdGFfZHRwLzEwMCkpDQpgYGANCg0KIyMjIyBiICYgYykgaXMgdGhlcmUgYSB1bml0IHJvb3QgaW4gdGhlIHRlbXBlcmF0dXJlIHNlcmllcz8NCg0KSGVyZSB3ZSBjb25kdWN0IHRoZSBBREYgdGVzdCBvbiB0aGUgdGVtcGVyYXR1cmUgKHdkYXRhX3RwKSBhbmQgMXN0IGRpZmZlcmVuY2VkIHNlcmllcyAod2RhdGFfZHRwKQ0KDQpmcm9tIG91ciBBREYgdGVzdCwgd2Ugc2VlIHRoYXQgd2UgKipjYW5ub3QqKiByZWplY3Qgb3VyIG51bGwgaHlwb3RoZXNpcyAod2hlcmUgdGhlIHRpbWUgc2VyaWVzIGlzIHN0YXRpb25hcnkpIGF0IHRoZSA1JSBsZXZlbCBmb3IgdGhlICoqdGVtcGVyYXR1cmUgc2VyaWVzKiouIHRoaXMgc3VnZ2VzdCB0aGF0IHRoZXJlIGlzIGEgdW5pdCByb290DQoNCm9uIHRoZSBvdGhlciBoYW5kIHdlIHNlZSB0aGF0IHdlICoqY2FuKiogcmVqZWN0IG91ciBudWxsIGh5cG90aGVzaXMgKHdoZXJlIHRoZSB0aW1lIHNlcmllcyBpcyBzdGF0aW9uYXJ5KSBhdCB0aGUgNSUgbGV2ZWwgZm9yIHRoZSAqKjFzdCBkaWZmZXJlbmNlIHNlcmllcyoqLiB0aGlzIHN1Z2dlc3QgdGhhdCB0aGVyZSBpcyBubyB1bml0IHJvb3QNCg0KYGBge3J9DQoNCmxhZ19rID0gZGV0X2xhZyh3ZGF0YV90cCkNCmFkZi50ZXN0KHdkYXRhX3RwLGs9bGFnX2spDQoNCmFkZi50ZXN0KHdkYXRhX2R0cCxrPWxhZ19rKQ0KYGBgDQoNCiMjIyMgZCkgZml0IEFSIG1vZGVsIGZvciB0aGUgZGlmZmVyZW5jZSBkYXRhDQoNCndlIHVzZSB0aGUgTUxFIG1ldGhvZCBmb3IgdGhlIGRpZmZlcmVuY2VkIGRhdGEsIHdoaWNoIHN1Z2dlc3QgYSBtb2RlbCBvcmRlciBvZiBwID0gMTENCg0KYGBge3J9DQojIEFSIG1vZGVsIHRvIGZpdCB0aGUgZGlmZmVyZW5jZWQgZGF0YSAoel90ID0geF90IC0geF90LTEpDQoNCm0gPSBhcih3ZGF0YV9kdHAsIG1ldGhvZD0nbWxlJykNCg0KcGxvdCgoMDoobGVuZ3RoKG0kYWljKS0xKSksbSRhaWMsdHlwZT0nbycpDQoNCnByaW50KHNwcmludGYoIm9yZGVyIHAgPSAlcyIsbSRvcmRlcikpDQoNCm1fYXJfZHRwID0gYXJpbWEod2RhdGFfdHAgLCBvcmRlciA9IGMobSRvcmRlciwxLDApKQ0KDQpwbG90X3ByZWRpY3Rpb25zKG1fYXJfZHRwLHdkYXRhX3RwLDEwMCwxMiwwLjk1KQ0KDQpgYGANCg0KIyMjIyBlICYgZikgZml0IEFSIG1vZGVsIGZvciB0aGUgb3JpZ2luYWwgZGF0YSwgYW5kIHBsb3QgdGhlIGZvcmVjYXN0DQoNCndlIHVzZSB0aGUgTUxFIG1ldGhvZCBmb3IgdGhlIG9yaWdpbmFsIGRhdGEsIHdoaWNoIHN1Z2dlc3QgYSBtb2RlbCBvcmRlciBvZiBwID0gMTINCg0KKipOb3RlKiogdGhpbmsgdGhlcmUncyBhIHR5cG8gaW4gdGhlIHF1ZXN0aW9uPyBzaG91bGRuJ3QgaXQgYmUgJGFyaW1hKHhfdCwgb3JkZXIgPSBjKHAsXGNvbG9ye3JlZH17XGJmezB9fSwwKSkkID8gYXMgd2UgYXJlIHdvcmtpbmcgd2l0aCB0aGUgb3JpZ2luYWwgZGF0YT8NCg0KYGBge3J9DQojIEFSIG1vZGVsIHRvIGZpdCB0aGUgb3JpZ2luYWwgZGF0YSAoeF90KQ0KDQptID0gYXIod2RhdGFfdHAsIG1ldGhvZD0nbWxlJykNCg0KcGxvdCgoMDoobGVuZ3RoKG0kYWljKS0xKSksbSRhaWMsdHlwZT0nbycpDQoNCnByaW50KHNwcmludGYoIm9yZGVyIHAgPSAlcyIsbSRvcmRlcikpDQoNCm1fYXJfdHAgPSBhcmltYSh3ZGF0YV90cCAsIG9yZGVyID0gYyhtJG9yZGVyLDAsMCkpDQoNCnBsb3RfcHJlZGljdGlvbnMobV9hcl90cCx3ZGF0YV90cCwxMDAsMTIsMC45NSkNCmBgYA0KDQojIyMjIGcgJiBoKSBmaXQgYSBBUk1BIG1vZGVsIG9uIHRoZSBkaWZmZXJlbmNlZCBkYXRhIGFuZCBtb2RlbCBhZGVxdWFjeQ0KDQp0aGUgZWFjZiBwcm9kdWNlZCBhIHByaW1lIGNhbmRpZGF0ZSBvZiBBUklNQSgwLDEsMSksIHlldCB0aGUgTEIgdGVzdCBzaG93cyB0aGUgbW9kZWwgaXMgbm90IGFkZXF1YXRlLiB3ZSBzZWUgdGhhdCB0aGVyZSBhcmUgc3RpbGwgc2VyaWFsIGRlcGVuZGVuY2llcyBldmVyeSA2IGFuZCAxMiBwZXJpb2RzLiB0aGlzIGNvdWxkIGJlIGJlY2F1c2UgdGhlcmUgZXhpc3RzIHNlYXNvbmFsaXR5IGluIHRoZSBkYXRhDQoNCmBgYHtyfQ0KIyBlYWNmIGZvciBhbiBhcm1hIHRvIGZpdCB0aGUgZGlmZmVyZW5jZWQgZGF0YSAoel90KQ0KDQplYWNmKHdkYXRhX2R0cCkNCmxhZ19rID0gZGV0X2xhZyh3ZGF0YV9kdHApDQoNCm1fYXJtYTFfZHRwID0gYXJpbWEod2RhdGFfdHAgLCBvcmRlciA9IGMoMCwxLDEpKQ0KDQpldmFsX21vZGVsKG1fYXJtYTFfZHRwLHdkYXRhX3RwLDEwMCxuX2FoZWFkLDAuOTUpDQoNCmBgYA0KDQojIyMjIGkpIHJlZmluZWQgbW9kZWwgd2l0aCBzZWFzb25hbGl0aWVzDQoNCmhlcmUgdGhlIG1vZGVsIGlzIHN0aWxsIGluYWRlcXVhdGUgYXMgdGhlIExCIHRlc3Qgc2hvd3MgdGhhdCB0aGVyZSBhcmUgc3RpbGwgc2VyaWFsIGRlcGVuZGVuY2llcywgc3BlY2lmaWNhbGx5IHRoZSBBQ0Ygc2hvd3MgaGlnaGx5IHNpZ25pZmljYW50IHZhbHVlcyBhdCBsYWcgMTIgYW5kIDI0LCBzdWdnZXN0aW5nIG91ciBzZWFzb25hbCB0ZXJtcyBhcmUgdW5hYmxlIHRvIGNhcHR1cmUgdGhlIHNlYXNvbmFsIGVmZmVjdHMNCg0KYGBge3J9DQptX2FyaW1hX3MxX3RwID0gYXJpbWEod2RhdGFfdHAsb3JkZXIgPSBjKDEsMSwyKSwgc2Vhc29uYWwgPSBsaXN0KG9yZGVyPWMoMSwxLDApLHBlcmlvZD0xMikpICANCg0KZXZhbF9tb2RlbChtX2FyaW1hX3MxX3RwLHdkYXRhX3RwLDIwMCwxNSwwLjk1KQ0KDQpgYGANCg0KIyMjIyBqKSB1cGRhdGVkIG1vZGVsDQoNCndlIGFzc3VtZSB0aGF0IHdlIGFyZSB3b3JraW5nIG9uIHRoZSBvcmlnaW5hbCBkYXRhICh4dCkNCg0KKipOb3RlKiogSSB0aGluayB0aGVyZSdzIGFsc28gYSB0eXBvIGhlcmU/IHNob3VsZG4ndCBpdCBiZSAkJA0KKDEtXGNvbG9ye3JlZH17XG1hdGhiZntzYXJfMX19TF57MTJ9KSgxLVxjb2xvcntyZWR9e1xtYXRoYmZ7YXJfMX19TCl4X3Q9ICgxLW1hXzFMKSgxLXNtYV8xTF57MTJ9KVxlcHNpbG9uX3RcXA0KJCQgYWxzbyBhY2NvcmRpbmcgdG8gdGhpcyBtb2RlbCwgSSB0aGluayB0aGUgY29kZSBzaG91bGQgYmUgYXMgZm9sbG93cz8gJCQNCm0gPSBhcmltYSh4X3QsIG9yZGVyID0gYyhcY29sb3J7cmVkfXtcYmZ7MX19LFxjb2xvcntyZWR9e1xiZnswfX0sMSksc2Vhc29uYWwgPSBsaXN0KG9yZGVyID0gYyhcY29sb3J7cmVkfXtcYmZ7MX19LFxjb2xvcntyZWR9e1xiZnswfX0sMSksIHBlcmlvZCA9IDEyKQ0KJCQgdGVzdGluZyBhc3N1bWluZyB0aGVyZSBpcyBhIHR5cG8sIHRoZSBtb2RlbCBpcyBpbmFkZXF1YXRlIGFzIHRoZSBMQiB0ZXN0IHNob3dzIHNlcmlhbCBkZXBlbmRlbmNpZXMgaW4gdGhlIHJlc2lkdWFsDQoNCmBgYHtyfQ0KDQptX2FyaW1hX3MyX3RwID0gYXJpbWEod2RhdGFfdHAsb3JkZXIgPSBjKDEsMCwxKSwgc2Vhc29uYWwgPSBsaXN0KG9yZGVyPWMoMSwwLDEpLHBlcmlvZD0xMikpICANCg0KZXZhbF9tb2RlbChtX2FyaW1hX3MyX3RwLHdkYXRhX3RwLDIwMCwxNSwwLjk1KQ0KYGBgDQoNCnRlc3RpbmcgYXNzdW1pbmcgdGhlcmUgaXNuJ3QgYSB0eXBvIGluIHRoZSBjb2RlLCB0aGUgbW9kZWwgaXMgKiphbHNvKiogaW5hZGVxdWF0ZSBhcyB0aGUgTEIgdGVzdCBzaG93cyBzZXJpYWwgZGVwZW5kZW5jaWVzIGluIHRoZSByZXNpZHVhbA0KDQpgYGB7cn0NCg0KbV9hcmltYV9zM190cCA9IGFyaW1hKHdkYXRhX3RwLG9yZGVyID0gYygwLDEsMSksIHNlYXNvbmFsID0gbGlzdChvcmRlcj1jKDAsMSwxKSxwZXJpb2Q9MTIpKSAgDQoNCmV2YWxfbW9kZWwobV9hcmltYV9zM190cCx3ZGF0YV90cCwyMDAsMTUsMC45NSkNCg0KDQpgYGANCg0KKipzdWdnZXN0aW9uOioqIGZyb20gKipwYXJ0IChpKSoqIHdlIHNhdyB0aGF0IHRoZSBtb2RlbCByZXR1cm5zIGdvb2QgcmVzdWx0cyBleGNlcHQgZm9yIGhpZ2hseSBzaWduaWZpY2FudCBub24temVybyBhdXRvIGNvcnJlbGF0aW9ucyBhdCBsYWcgMTIgJiAyNCB3aGljaCBzdWdnZXN0IHRoZSBhbm51YWwgc2Vhc29uYWxpdHkgaXMgbm90IHN1ZmZpY2llbnRseSBjYXB0dXJlZC4gaW5zdGVhZCB3ZSBjYW4gdHJ5IHRvIHVzZSBhbiBtb3JlIHNlYXNvbmFsIHRlcm1zIHRvIGNhcHR1cmUgdGhlc2Ugc2Vhc29uYWwgZWZmZWN0cy4NCg0KbGV0J3MgdHJ5IGludHJvZHVjaW5nIGEgc2Vhc29uYWwgTUEgdGVybSwgaGVyZSB3ZSBzYXcgdGhlIHJlc3VsdHMgcHJvZHVjZSBhIG1vcmUgYWRlcXVhdGUgbW9kZWwsIGF0IGxlYXN0IGluIHRoZSBzZW5zZSB0aGF0IExCIHRlc3Qgc2hvd3Mgbm8gc2VyaWFsIGRlcGVuZGVuY2llcyBpbiB0aGUgcmVzaWR1YWwsIGFuZCBhbHNvIGEgc21hbGxlciBBSUMgaW4gYWxsIHRoZSBtb2RlbHMgc28gZmFyDQoNCmBgYHtyfQ0KDQptX2FyaW1hX3NhX3RwID0gYXJpbWEod2RhdGFfdHAsb3JkZXIgPSBjKDEsMSwyKSwgc2Vhc29uYWwgPSBsaXN0KG9yZGVyPWMoMSwxLDEpLHBlcmlvZD0xMikpICANCg0KZXZhbF9tb2RlbChtX2FyaW1hX3NhX3RwLHdkYXRhX3RwLDIwMCwxNSwwLjk1KQ0KDQoNCmBgYA0K