Using monthly data from January 2014M1 to 2017M12 estimate the followings: 1. Select at least five stocks from different industries (for the list of the firms in different industries see, https://biz.yahoo.com/p/sum_conameu.html).
#QC'd
###The original stocks significantly underperformed the risk free rate. So, found a hnadful of stocks with returns close to or above the risk free rate so don't have to deal with a negative sharpe ratio###
#New Stocks for Portfolio
#Amazon.com, Inc. (AMZN)- Speciality Retail
#Facebook, Inc. (FB) - Internet Content & Information
#The Procter & Gamble Company (PG) - Household & Personal Products
#Costco Wholesale Corporation (COST) - Discount Stores
#Cigna Corporation (CI) - Health Care Plans
#Clean Environment
rm(list=ls(all=TRUE))
cat("\014")
library("fPortfolio")
library("quantmod")
library("timeSeries")
library("tseries")
library("stats")
#Import stock data from yahoo (see Q6 assignment 1)
#to=Sys.Date()
#make sure 12-02 so that the data includes the month of 12/2017, 12/01 excludes 12/2017
YahooData <- getSymbols.yahoo(c("AMZN","FB","PG","COST","CI","^TNX","SPY"),.GlobalEnv, from = "2014-01-01", to= "2017-12-02", periodicity="monthly", return.class = "timeSeries")
- Construct a portfolio of the selected stocks and graph the efficient frontier.
2a. Find the optimum weights using MPT.
cat("The optimal weights of the portfolio:")
The optimal weights of the portfolio:
print(optimalweight_matrix)
[,1]
AMZN 0.11961207
FB 0.37405787
PG 0.03631253
COST 0.17368825
CI 0.29632928
#Test that all weights add to 1:
#cat("Test that all weights add to 1:")
#print(colSums(optimalweight_matrix))
2b. and 2c. Using the optimum weights and daily adjusted closing prices at the end of 2017 allocate $100.00 among among the selected stocks. On 1/1/2014, the portfolio will have a value of 100 as an index.
#Import daily stock adj closing prices from yahoo
YahooData_Daily <- getSymbols.yahoo(c("AMZN","FB","PG","COST","CI"),.GlobalEnv, from = "2014-01-02", to = "2018-10-31", periodicity="daily", return.class = "timeSeries")
#Calculate Daily Adjusted Returns
#Note, since day 1 you have $100, and it isn't affected by the return of the previous day, left out the first day of the returns when importing data)
daily_rAMZN <- diff(log(AMZN$AMZN.Adjusted))
daily_rFB <- diff(log(FB$FB.Adjusted))
daily_rPG <- diff(log(PG$PG.Adjusted))
daily_rCOST <- diff(log(COST$COST.Adjusted))
daily_rCI <- diff(log(CI$CI.Adjusted))
#Create equation for daily optimal returns of the portfolio
return_optimal_portfolio_daily = optimalweight_matrix[1,1]*daily_rAMZN + optimalweight_matrix[2,1]*daily_rFB + optimalweight_matrix[3,1]*daily_rPG + optimalweight_matrix[4,1]*daily_rCOST + optimalweight_matrix[5,1]*daily_rCI
mean_return <- mean(return_optimal_portfolio_daily)*252*4
# round(return_optimal_portfolio_daily,5)
# 100*(1+return_optimal_portfolio_daily[1])*(1+return_optimal_portfolio_daily[2])*(1+return_optimal_portfolio_daily[3])
# class(return_optimal_portfolio_daily)
#Use for loop to generate holding values for every day of the data series:
#######################################################################
newreturn = 1 + return_optimal_portfolio_daily
newreturn[1] <- newreturn[1]*100 #the value of the second day
# head(newreturn)
# tail(newreturn)
newdailyreturn = cumprod(newreturn)
#head(newdailyreturn)
#tail(newdailyreturn)
#length(newdailyreturn)
#length(AMZN[,1])
#######################################################################
newdailyreturn2=c(newdailyreturn)
#head(newdailyreturn2)
returnwithdate= cbind(AMZN[,1],newdailyreturn2)
#tail(returnwithdate)
#head(returnwithdate)
# print(returnwithdate[,2])
#tail(returnwithdate[,2])
print("ss.1 column represents the holding value of the portfolio")
[1] "ss.1 column represents the holding value of the portfolio"
returnwithdate
GMT
AMZN.Open SS.1
2014-01-02 398.80 99.83901
2014-01-03 398.29 101.30262
2014-01-06 395.85 102.62884
2014-01-07 395.04 102.46624
2014-01-08 398.47 103.18915
2014-01-09 403.71 103.17600
2014-01-10 402.53 100.95463
2014-01-13 397.98 102.87094
2014-01-14 392.13 102.84933
2014-01-15 398.94 102.10209
2014-01-16 393.68 101.91754
2014-01-17 394.26 103.64125
2014-01-21 403.00 102.53339
2014-01-22 408.00 101.56272
2014-01-23 401.00 98.66167
2014-01-24 398.16 98.21961
2014-01-27 390.50 99.40708
2014-01-28 387.40 97.57683
2014-01-29 392.16 103.58041
2014-01-30 393.77 102.52654
2014-01-31 371.76 100.38556
2014-02-03 358.98 101.49730
2014-02-04 349.59 101.10384
2014-02-05 346.00 102.07947
2014-02-06 347.40 100.65346
2014-02-07 358.98 99.91535
2014-02-10 361.61 101.09760
2014-02-11 361.84 99.89278
2014-02-12 356.43 102.03801
2014-02-13 347.70 102.64373
2014-02-14 359.34 102.40720
2014-02-18 355.28 102.10368
2014-02-19 352.64 103.33227
2014-02-20 348.80 102.44620
2014-02-21 352.44 104.65663
2014-02-24 345.19 104.21698
2014-02-25 353.00 103.93542
2014-02-26 359.86 103.74866
2014-02-27 357.22 104.35682
2014-02-28 360.60 103.06916
2014-03-03 358.74 104.60608
2014-03-04 363.90 106.38755
2014-03-05 364.13 105.20581
2014-03-06 374.05 104.66683
2014-03-07 374.58 106.28163
2014-03-10 372.69 105.30136
2014-03-11 370.99 105.63416
2014-03-12 366.40 103.72777
2014-03-13 376.62 102.55897
2014-03-14 372.80 103.70142
2014-03-17 375.72 104.10021
2014-03-18 377.32 104.18329
2014-03-19 378.77 104.28609
2014-03-20 370.64 103.96187
2014-03-21 371.00 101.32948
2014-03-24 360.09 101.81212
2014-03-25 354.03 98.32478
2014-03-26 357.13 97.51387
2014-03-27 343.15 97.58487
2014-03-28 340.05 99.23006
2014-03-31 342.40 100.67596
2014-04-01 338.09 100.43989
2014-04-02 345.99 98.36953
2014-04-03 341.82 95.64622
2014-04-04 335.15 95.31309
2014-04-07 320.99 96.88087
2014-04-08 321.88 99.74062
2014-04-09 328.47 96.12147
2014-04-10 330.60 94.80340
2014-04-11 314.00 95.33169
2014-04-14 317.67 95.37899
2014-04-15 316.70 96.07128
2014-04-16 321.17 95.22272
2014-04-17 319.76 97.11714
2014-04-21 323.97 98.38302
2014-04-22 332.00 97.42753
2014-04-23 333.06 98.42860
2014-04-24 329.67 95.05403
2014-04-25 316.25 93.51827
2014-04-28 304.00 94.87603
2014-04-29 296.44 96.82243
2014-04-30 298.10 98.47057
2014-05-01 304.13 98.19423
2014-05-02 310.42 99.01459
2014-05-05 306.37 96.61136
2014-05-06 309.53 96.13950
2014-05-07 295.56 96.05353
2014-05-08 290.82 96.91111
2014-05-09 290.57 99.73289
2014-05-12 294.30 99.72130
2014-05-13 302.60 98.92365
2014-05-14 302.50 97.54376
2014-05-15 298.02 97.89226
2014-05-16 292.80 99.01216
2014-05-19 295.76 98.58482
2014-05-20 297.10 100.10977
2014-05-21 302.21 100.02679
2014-05-22 305.05 101.00308
2014-05-23 305.46 102.01303
2014-05-27 314.41 102.18201
...
[ reached getRmetricsOption('max.print') | getOption('max.print') -- omitted 1117 rows ]]
- Calculate the CAL equation and graph CAL and the efficient frontier.
#Calculating portfolio variance:
#https://zerodha.com/varsity/chapter/risk-part-4-correlation-matrix-portfolio-variance/
#Portfolio Variance = Sqrt (Transpose (Wt.SD) * Correlation Matrix * Wt. SD
#Calculate the standard deviation of the five assets' returns:
sd_rAMZN <- sd(rAMZN)
sd_rFB <- sd(rFB)
sd_rPG <- sd(rPG)
sd_rCOST <- sd(rCOST)
sd_rCI <- sd(rCI)
sd_matrix <- matrix(c(sd_rAMZN, sd_rFB, sd_rPG, sd_rCOST, sd_rCI))
range.names = c("AMZN", "FB", "PG", "COST", "CI")
cat("Standard Deviations")
Standard Deviations
dimnames(sd_matrix) = list(range.names)
sd_matrix
[,1]
AMZN 0.07515593
FB 0.05422324
PG 0.03537648
COST 0.04786995
CI 0.06180077
#Calculate weighted standard deviations
weighted_sd_matrix <- matrix(c(sd_rAMZN*optimalweight_matrix[1,1], sd_rFB*optimalweight_matrix[2,1], sd_rPG*optimalweight_matrix[3,1], sd_rCOST*optimalweight_matrix[4,1], sd_rCI*optimalweight_matrix[5,1]))
range.names = c("AMZN", "FB", "PG", "COST", "CI")
cat("Weighted Standard Deviations")
Weighted Standard Deviations
dimnames(weighted_sd_matrix) = list(range.names)
weighted_sd_matrix
[,1]
AMZN 0.008964656
FB 0.020963438
PG 0.000126609
COST 0.008132532
CI 0.019815722
#Compute the portfolio variance, when optimal wieghts are used, using this formula: "Portfolio Variance = Sqrt (Transpose (Wt.SD) * Correlation Matrix * Wt. SD"
Portfolio_Variance <- sqrt(t(weighted_sd_matrix)%*%cor_matrix%*%weighted_sd_matrix)
Portfolio_Variance
[,1]
[1,] 0.0328645
Portfolio_SD <- sqrt(Portfolio_Variance)
Portfolio_SD
[,1]
[1,] 0.1812857
#Mean return of optimal portfolio, using monthly returns:
return_optimal_portfolio_mean = optimalweight_matrix[1,1]*mean_rAMZN + optimalweight_matrix[2,1]*mean_rFB + optimalweight_matrix[3,1]*mean_rPG + optimalweight_matrix[4,1]*mean_rCOST + optimalweight_matrix[5,1]*mean_rCI
return_optimal_portfolio_mean
AMZN
0.02036808
#Calculate the sharpe ratio:
sharpe_ratio <- (return_optimal_portfolio_mean - Rf)/(Portfolio_SD)
print(sharpe_ratio)
[,1]
[1,] 0.1023876
#Put it all together to create the CAL:
cat("The capital allocation line:", "E(r) =" , Rf,"+", sharpe_ratio, "* Standard Deviation")
The capital allocation line: E(r) = 0.001806667 + 0.1023876 * Standard Deviation
#Now graph the CAL:
#Create discrete deviations for plotting purposes
basic_standard_deviation <- c(0,1,2,3)
rCAL <- Rf + sharpe_ratio*basic_standard_deviation
Recycling array of length 1 in array-vector arithmetic is deprecated.
Use c() or as.vector() instead.
plot(basic_standard_deviation, rCAL, col="Green", xlab="Standard Deviation", ylab="Expected Return", type="l")

#Plot Portfolio possibilities curve (efficient frontier):
rP = mean_rAMZN + mean_rFB + mean_rPG + mean_rCOST + mean_rCI
- Estimate the CAPM model of your portfolio using 1/2/2018-10/30/2018 data. Compare the estimated beta of the your CAPM model with market beta. Are they statistically different from each other?
*you are doing a regression of the risk premium of the portfolio to the risk premium of the market
riskprem_SPY_CAPM <- rSPY_CAPM - rF_CAPM
longer object length is not a multiple of shorter object length
- Graph the SML and compare the estimated Beta of the CAPM and the average return of your portfolio as a point relative to SML. Comment on performance of your portfolio.
#Graph the SML by calculating the average rf and mrp using the actual data.
#This method uses the average data to get the SML, but we should use the regression model to graph the CAPM
cat("The CAPM Formula is: ", mean(rTNX_CAPM), " + beta * ", mean(riskprem_SPY_CAPM))
The CAPM Formula is: 0.001797593 + beta * -0.001823117
SML_MRP = mean(rSPY_CAPM) - mean(rTNX_CAPM)
SML_MRP
[1] -0.001823762
beta_range = c(0,1,2,3,4,5)
SML_Line = mean(rTNX_CAPM) + beta_range*mean(riskprem_SPY_CAPM)
#This is the CAPM estimate of the optimal portfolios return
SML_Portfolio = mean(rTNX_CAPM) + Beta_Portfolio*mean(riskprem_SPY_CAPM)
plot(beta_range, SML_Line, col="Green", xlab="Beta", ylab="Expected Return", type="p")
#This is the CAPM estimate of the optimal portfolios return graphed
points(Beta_Portfolio, SML_Portfolio, type = "p")
#This is the actual return of the optimal portfolio graphed with the regression estimate of the optimal portfolios beta coefficient
points(Beta_Portfolio, mean(rP_CAPM), col="Red")

cat("The red dot indicates the actual return of the optimal portfolio graphed with the regression estimate of the portfolio's beta coefficient", "The black dot represents the CAPM estimate of the portfolios return graphed with the same beta estimate", "The actual portfolio rests below the SML. This indicates that the portfolio is overvalued. That is, the portfolio is receiving a lesser return for the same amount of risk. Based on CAPM theory, demand for the portfolio should decline, resulting in a lower price of the portfolios underlying returns. As a result, the return of the portfolio would increase until the portfolios point rests on the SML.")
The red dot indicates the actual return of the optimal portfolio graphed with the regression estimate of the portfolio's beta coefficient The black dot represents the CAPM estimate of the portfolios return graphed with the same beta estimate The actual portfolio rests below the SML. This indicates that the portfolio is overvalued. That is, the portfolio is receiving a lesser return for the same amount of risk. Based on CAPM theory, demand for the portfolio should decline, resulting in a lower price of the portfolios underlying returns. As a result, the return of the portfolio would increase until the portfolios point rests on the SML.
- Calculate CV, Sharpe, Treynor, and Sortino ratios for your portfolio and compare them to a similarly diversified portfolio of Vanguard, Fidelity, or any other similar portfolio.
library("PerformanceAnalytics")
Package PerformanceAnalytics (1.5.2) loaded.
Copyright (c) 2004-2018 Peter Carl and Brian G. Peterson, GPL-2 | GPL-3
https://github.com/braverock/PerformanceAnalytics
Attaching package: ‘PerformanceAnalytics’
The following objects are masked from ‘package:timeDate’:
kurtosis, skewness
The following object is masked from ‘package:graphics’:
legend
#Calculate the sharpe ratio:
sharpe_ratio <- (return_optimal_portfolio_mean - Rf)/(Portfolio_SD)
print(sharpe_ratio)
[,1]
[1,] 0.1023876
cat("The sharpe ratio is:", sharpe_ratio, " ")
The sharpe ratio is: 0.1023876
#Calculate Sortino Ratio
#http://braverock.com/brian/R/PerformanceAnalytics/html/SortinoRatio.html
#get monthly optimal returns to the portfolio
return_optimal_portfolio_monthly = optimalweight_matrix[1,1]*rAMZN + optimalweight_matrix[2,1]*rFB + optimalweight_matrix[3,1]*rPG + optimalweight_matrix[4,1]*rCOST + optimalweight_matrix[5,1]*rCI
sortino <- (SortinoRatio(return_optimal_portfolio_monthly, MAR = 0))
cat("The sortino ratio is:", sortino, " " )
The sortino ratio is: 1.605637
#treynor ratio = (rP - rF)/betaP
#Calculate Beta of the Portfolio
#remember beta measure volatility relative to the market. So FB is theoretically 30% less volatile than the market
Beta_AMZN <- 1.87
Beta_FB <- 0.70
Beta_PG <- 0.32
Beta_COST <- 1.17
Beta_CI <- 0.79
Weighted_Beta_Portfolio <- optimalweight_matrix[1,1]*Beta_AMZN + optimalweight_matrix[2,1]*Beta_FB + optimalweight_matrix[3,1]*Beta_PG + optimalweight_matrix[4,1]*Beta_COST + optimalweight_matrix[5,1]*Beta_CI
cat("The Beta of the Portfolio is:", Weighted_Beta_Portfolio, ". Thus,the portolio's returns are theoretically 17% more volatile than the market. ")
The Beta of the Portfolio is: 0.9469034 . Thus,the portolio's returns are theoretically 17% more volatile than the market.
treynor <- ((return_optimal_portfolio_mean-Rf)/Weighted_Beta_Portfolio)
cat("The treynor ratio is:", treynor, " ")
The treynor ratio is: 0.01960222
- Calculate 2% VaR as a percentage of the mean return of your portfolio when the risk horizon is one day and one month.
#Reimport data for intuitiveness:
YahooData <- getSymbols.yahoo(c("AMZN","FB","PG","COST","CI","^TNX","SPY"),.GlobalEnv, from = "2014-01-01", to= "2017-12-01", periodicity="monthly", return.class = "timeSeries")
pausing 1 second between requests for more than 5 symbols
pausing 1 second between requests for more than 5 symbols
pausing 1 second between requests for more than 5 symbols
#Calculate Stock Returns and Risk Premiums (Stock Return - Rf); Rf is rTNX
rAMZN <- diff(log(AMZN$AMZN.Adjusted))
rFB <- diff(log(FB$FB.Adjusted))
rPG <- diff(log(PG$PG.Adjusted))
rCOST <- diff(log(COST$COST.Adjusted))
rCI <- diff(log(CI$CI.Adjusted))
rTNX <- TNX$TNX.Adjusted/100/12
#override TNX, start at index two and go down from there, remember when calculating returns for AAPL in excel you got rid of the first value, same thing here
rTNX <- rTNX[2:length(rTNX)]
rSPY <- diff(log(SPY$SPY.Adjusted))
cat("From Question 2: The optimal weights of the portfolio:")
From Question 2: The optimal weights of the portfolio:
print(optimalweight_matrix)
[,1]
AMZN 0.119280757
FB 0.386613531
PG 0.003578903
COST 0.169888036
CI 0.320638772
#Derive the monthly returns and monthly standard defivation for the portfolio:
return_optimal_portfolio_monthly = optimalweight_matrix[1,1]*rAMZN + optimalweight_matrix[2,1]*rFB + optimalweight_matrix[3,1]*rPG + optimalweight_matrix[4,1]*rCOST + optimalweight_matrix[5,1]*rCI
return_optimal_portfolio_monthly
[1] 1.662481e-02 -4.905518e-02 -2.320710e-02 6.264793e-02 3.509477e-02 2.183685e-02 4.259766e-02 7.565185e-03
[9] 1.388802e-02 4.749194e-02 -8.730609e-03 1.846446e-02 6.991908e-02 4.396754e-02 -2.349331e-02 4.319699e-02
[17] 6.788134e-02 3.536462e-02 -3.718295e-02 -6.992076e-03 8.578983e-02 2.141323e-02 3.015053e-02 -3.025680e-02
[25] -1.304242e-02 3.709029e-02 1.669268e-02 -8.854597e-03 -7.171281e-03 5.149245e-02 1.417516e-03 1.197530e-02
[33] -3.381541e-02 -2.395472e-03 -1.594587e-06 9.001858e-02 3.744152e-02 9.679979e-03 5.734957e-02 2.439250e-02
[41] -5.745289e-03 5.681409e-02 1.880125e-02 1.211983e-02 5.051999e-02 4.717530e-02
#Monthly values:
monthly_return_portfolio <- mean(return_optimal_portfolio_monthly)
monthly_sd_portfolio <- sd(return_optimal_portfolio_monthly)
#Annual values:
annual_return_portfolio <- mean(return_optimal_portfolio_monthly)*(12)
annual_SD_portfolio <- sd(return_optimal_portfolio_monthly)*sqrt(12)
#10 day values (250 trading days):
tenday_return_portfolio <- annual_return_portfolio*(10/250)
tenday_sd_portfolio <- annual_SD_portfolio*sqrt(10/250)
#Derive mean monthly returns and monthly sd to the market (SPY):
#Monthly values:
monthly_return_SPY <- mean(rSPY)
monthly_sd_SPY <- sd(rSPY)
#Annual values:
annual_return_SPY <- mean(rSPY)*(12)
annual_SD_SPY <- sd(rSPY)*sqrt(12)
#10 day values (250 trading days):
tenday_return_SPY <- annual_return_SPY*(10/250)
tenday_sd_SPY <- annual_SD_SPY*sqrt(10/250)
#need a function that gives inverse of normal cumulative distributio. pnorm gives CDF and qnorm gives the inverse CDF
#Calculate Mothly VaR for the Market (SPY) and the optimal portfolio
#2% VaR for Optimal Portfolio with monthly time horizon
cat(" 2% VaR for Optimal Portfolio with monthly time horizon is: ",
qnorm(.02,monthly_return_portfolio,monthly_sd_portfolio))
2% VaR for Optimal Portfolio with monthly time horizon is: -0.04712735
cat("
")
#2% VaR for Optimal Portfolio with 10 day time horizon
cat("2% VaR for Optimal Portfolio with 10 day time horizon is:",
qnorm(.02,tenday_return_portfolio,tenday_sd_portfolio))
2% VaR for Optimal Portfolio with 10 day time horizon is: -0.03698553
- Using the CAPM equation of your portfolio do a five periods ex-post forecasting of the returns to your portfolio and compare your forecast to the actual returns. Find and report MAD, MAP, MASE, and RMS for your forecast.
AND
- Using the CAPM equation of your portfolio do a five periods ex-ante forecasting of the returns to your portfolio. Find and report MAD, MAP, MASE, and RMS of your forecast. You may use ES to forecast the risk premium of S&P500 for the required five periods.
#First, put your x and y into a data frame to simplify the forecasting code
question_9_data_Part1 <- data.frame(riskprem_portfolio_CAPM[1:203], riskprem_SPY_CAPM[1:203])
question_9_data_Part2 <- data.frame(riskprem_portfolio_CAPM[204:208], riskprem_SPY_CAPM[204:208])
question_9_data_Fullrange <- data.frame(riskprem_portfolio_CAPM, riskprem_SPY_CAPM)
############################################################################################
#Run the regression for ex-post forecast
reg_expost <- lm(riskprem_portfolio_CAPM ~ riskprem_SPY_CAPM, data=question_9_data_Part1)
#Ex-post forecast
pred <- predict(reg, newdata=question_9_data_Part2, se.fit=TRUE)
Error in predict(reg, newdata = question_9_data_Part2, se.fit = TRUE) :
object 'reg' not found
- Do a Naïve, MA3, MA5, WMA5, and ES of the returns to your portfolio for the period 10/30/ 2018 on. Find MAD, MAPE, MASE and RMS of your forecasts. Compare the forecasting efficiency criterion of your CAPM with smoothing techniques. Which one results in a better forecasting outcome?
library("fPortfolio")
library("quantmod")
library("timeSeries")
library("tseries")
library("stats")
#Import daily stock adj closing prices from yahoo
YahooData_Daily <- getSymbols.yahoo(c("AMZN","FB","PG","COST","CI", "SPY", "^TNX"),.GlobalEnv, from = "2018-10-30", to= Sys.Date(), periodicity="daily", return.class = "timeSeries")
#Calculate Daily Adjusted Returns
#Note, since day 1 you have $100, and it isn't affected by the return of the previous day, left out the first day of the returns when importing data)
rAMZN_smoothing <- diff(log(AMZN$AMZN.Adjusted))
rFB_smoothing <- diff(log(FB$FB.Adjusted))
rPG_smoothing <- diff(log(PG$PG.Adjusted))
rCOST_smoothing <- diff(log(COST$COST.Adjusted))
rCI_smoothing <- diff(log(CI$CI.Adjusted))
rTNX_smoothing <- TNX$TNX.Adjusted/100/12
#override TNX, start at index two and go down from there, remember when calculating returns for AAPL in excel you got rid of the first value, same thing here
rTNX_smoothing <- rTNX[2:length(rTNX)]
rSPY_smoothing <- diff(log(SPY$SPY.Adjusted))
(rF_smoothing <- rTNX_smoothing)
#Get daily returns of your portfolio for this date range:
rP_smoothing <- optimalweight_matrix[1,1]*rAMZN_smoothing + optimalweight_matrix[2,1]*rFB_smoothing + optimalweight_matrix[3,1]*rPG_smoothing + optimalweight_matrix[4,1]*rCOST_smoothing + optimalweight_matrix[5,1]*rCI_smoothing
rP_smoothing
#Naive Forecast:
library(forecast)
Naive_forecast <- plot(snaive(rP_smoothing,2))
snaive(rP_smoothing,2)
accuracy(snaive(rP_smoothing,2))
#MA3 Forecast
library(forecast)
ma3 <- ma(rP_smoothing, order=2)
ma3
plot(rP_smoothing)
lines(ma(rP_smoothing, order=2), col="red")
#Do we need to do this way or harsh's way?
accuracy(ma3, rP_smoothing)
#MA5 Forecast
ma5 <- ma(rP_smoothing, order=5)
plot(rP_smoothing)
lines(ma(rP_smoothing, order=5), col="red")
accuracy(ma5, rP_smoothing)
#ES - Expontential Smoothing
#Alpha is the dampenining parameter
fit1 <- ses(rP_smoothing, alpha=0.2, initial="simple", h=3)
fit2 <- ses(rP_smoothing, alpha=0.6, initial="simple", h=3)
fit3 <- ses(rP_smoothing, h=3)
plot(fit1, main="", fcol="white", type="o")
lines(fitted(fit1), col="blue", type="o")
lines(fitted(fit2), col="red", type="o")
lines(fitted(fit3), col="green", type="o")
lines(fit1$mean, col="blue", type="o")
lines(fit2$mean, col="red", type="o")
lines(fit3$mean, col="green", type="o")
legend("topleft",lty=1, col=c(1,"blue","red","green"),
c("data", expression(alpha == 0.2), expression(alpha == 0.6),
expression(alpha == 0.89)),pch=1)
#Accuracy Measures to get MAD MASE, etc.
accuracy(fit1)
accuracy(fit2)
accuracy(fit3)
#Compare the accuracy of all the forecasting models
#CAPM_regression error
accuracy(CAPM_regression)
#Error in Naive Forecasting Model
print("Naive Forecasting Model")
accuracy(snaive(rP_smoothing,3))
#Error in MA3 Forecasting Model
print("MA3 Forecasting Model")
accuracy(ma3, rP_smoothing)
#Error in MA5 Forecasting Model
print("MA5 Forecasting Model")
accuracy(ma5, rP_smoothing)
#Error in Exponential Smoothing Forecast Model
print("Exponential Smoothing Forecast Model")
accuracy(fit1)
accuracy(fit2)
accuracy(fit3)
#cat("
#","The forecasting models have different error levels. It appears that the MA3 model has to smallest RMSE")
#Compare the accuracy of all the forecasting models
#CAPM_regression error
print("CAPM Model")
accuracy(CAPM_regression)
#CAPM Ex-post forecast error
accuracy(reg_expost)
#Error in Naive Forecasting Model
print("Naive Forecasting Model")
accuracy(snaive(rP_smoothing,3))
#Error in MA3 Forecasting Model
print("MA3 Forecasting Model")
accuracy(ma3, rP_smoothing)
#Error in MA5 Forecasting Model
print("MA5 Forecasting Model")
accuracy(ma5, rP_smoothing)
#Error in Exponential Smoothing Forecast Model
print("Exponential Smoothing Forecast Model")
accuracy(fit1)
accuracy(fit2)
accuracy(fit3)
#cat("
#","The forecasting models have different error levels. It appears that the MA3 model has to smallest RMSE")
LS0tCnRpdGxlOiAiRkJFIDUwNkIgU2VtZXN0ZXIgUHJvamVjdCAtIERSQUZUIDIwMTgtMTAtMTggLSBwb3NpdGl2ZSByaXNrIHByZW1pdW0gZWRpdCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKLS0tCnRpdGxlOiAiRkJFIDUwNkIgU2VtZXN0ZXIgUHJvamVjdCAtIERSQUZUIDIwMTgtMTAtMTUiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KClVzaW5nIG1vbnRobHkgZGF0YSBmcm9tIEphbnVhcnkgMjAxNE0xIHRvIDIwMTdNMTIgZXN0aW1hdGUgdGhlIGZvbGxvd2luZ3M6CjEuIFNlbGVjdCBhdCBsZWFzdCBmaXZlIHN0b2NrcyBmcm9tIGRpZmZlcmVudCBpbmR1c3RyaWVzIChmb3IgdGhlIGxpc3Qgb2YgdGhlIGZpcm1zIGluIGRpZmZlcmVudCBpbmR1c3RyaWVzIHNlZSwgaHR0cHM6Ly9iaXoueWFob28uY29tL3Avc3VtX2NvbmFtZXUuaHRtbCkuCgpgYGB7cn0KCiNRQydkIAoKCiMjI1RoZSBvcmlnaW5hbCBzdG9ja3Mgc2lnbmlmaWNhbnRseSB1bmRlcnBlcmZvcm1lZCB0aGUgcmlzayBmcmVlIHJhdGUuIFNvLCBmb3VuZCBhIGhuYWRmdWwgb2Ygc3RvY2tzIHdpdGggcmV0dXJucyBjbG9zZSB0byBvciBhYm92ZSB0aGUgcmlzayBmcmVlIHJhdGUgc28gZG9uJ3QgaGF2ZSB0byBkZWFsIHdpdGggYSBuZWdhdGl2ZSBzaGFycGUgcmF0aW8jIyMgIAoKI05ldyBTdG9ja3MgZm9yIFBvcnRmb2xpbwojQW1hem9uLmNvbSwgSW5jLiAoQU1aTiktIFNwZWNpYWxpdHkgUmV0YWlsIAojRmFjZWJvb2ssIEluYy4gKEZCKSAtIEludGVybmV0IENvbnRlbnQgJiBJbmZvcm1hdGlvbiAKI1RoZSBQcm9jdGVyICYgR2FtYmxlIENvbXBhbnkgKFBHKSAtIEhvdXNlaG9sZCAmIFBlcnNvbmFsIFByb2R1Y3RzICAKI0Nvc3RjbyBXaG9sZXNhbGUgQ29ycG9yYXRpb24gKENPU1QpIC0gRGlzY291bnQgU3RvcmVzICAKI0NpZ25hIENvcnBvcmF0aW9uIChDSSkgLSBIZWFsdGggQ2FyZSBQbGFucwoKI0NsZWFuIEVudmlyb25tZW50CnJtKGxpc3Q9bHMoYWxsPVRSVUUpKQpjYXQoIlwwMTQiKQoKbGlicmFyeSgiZlBvcnRmb2xpbyIpCmxpYnJhcnkoInF1YW50bW9kIikKbGlicmFyeSgidGltZVNlcmllcyIpCmxpYnJhcnkoInRzZXJpZXMiKQpsaWJyYXJ5KCJzdGF0cyIpCgoKI0ltcG9ydCBzdG9jayBkYXRhIGZyb20geWFob28gKHNlZSBRNiBhc3NpZ25tZW50IDEpCiN0bz1TeXMuRGF0ZSgpCiNtYWtlIHN1cmUgMTItMDIgc28gdGhhdCB0aGUgZGF0YSBpbmNsdWRlcyB0aGUgbW9udGggb2YgMTIvMjAxNywgMTIvMDEgZXhjbHVkZXMgMTIvMjAxNwpZYWhvb0RhdGEgPC0gZ2V0U3ltYm9scy55YWhvbyhjKCJBTVpOIiwiRkIiLCJQRyIsIkNPU1QiLCJDSSIsIl5UTlgiLCJTUFkiKSwuR2xvYmFsRW52LCBmcm9tID0gIjIwMTQtMDEtMDEiLCB0bz0gIjIwMTctMTItMDIiLCBwZXJpb2RpY2l0eT0ibW9udGhseSIsIHJldHVybi5jbGFzcyA9ICJ0aW1lU2VyaWVzIikKCmBgYAoKCjIuIENvbnN0cnVjdCBhIHBvcnRmb2xpbyBvZiB0aGUgc2VsZWN0ZWQgc3RvY2tzIGFuZCBncmFwaCB0aGUgZWZmaWNpZW50IGZyb250aWVyLgoKICAyYS4gRmluZCB0aGUgb3B0aW11bSB3ZWlnaHRzIHVzaW5nIE1QVC4KCmBgYHtyfQojUUM6IG5lZWQgdG8gZmluZCBlZmZpY2llbnQgZnJvbnRpZXIsIGRpZCBldmVyeW9uZSBlbHNlIGdldCAuMDAxOCBhcyBSRj8gYW5kIC4wMDggYXMgdGhlIG1hcmtldCByaXNrIHByZW1pdW0/IAoKCiNDYWxjdWxhdGUgU3RvY2sgUmV0dXJucyBhbmQgUmlzayBQcmVtaXVtcyAoU3RvY2sgUmV0dXJuIC0gUmYpOyBSZiBpcyByVE5YIApyQU1aTiA8LSBkaWZmKGxvZyhBTVpOJEFNWk4uQWRqdXN0ZWQpKQpyRkIgPC0gZGlmZihsb2coRkIkRkIuQWRqdXN0ZWQpKQpyUEcgPC0gZGlmZihsb2coUEckUEcuQWRqdXN0ZWQpKQpyQ09TVCA8LSBkaWZmKGxvZyhDT1NUJENPU1QuQWRqdXN0ZWQpKQpyQ0kgPC0gZGlmZihsb2coQ0kkQ0kuQWRqdXN0ZWQpKQpyVE5YIDwtIFROWCRUTlguQWRqdXN0ZWQvMTAwLzEyCiNvdmVycmlkZSBUTlgsIHN0YXJ0IGF0IGluZGV4IHR3byBhbmQgZ28gZG93biBmcm9tIHRoZXJlLCByZW1lbWJlciB3aGVuIGNhbGN1bGF0aW5nIHJldHVybnMgZm9yIEFBUEwgaW4gZXhjZWwgeW91IGdvdCByaWQgb2YgdGhlIGZpcnN0IHZhbHVlLCBzYW1lIHRoaW5nIGhlcmUgIApyVE5YIDwtIHJUTlhbMjpsZW5ndGgoclROWCldCnJTUFkgPC0gZGlmZihsb2coU1BZJFNQWS5BZGp1c3RlZCkpCgoKI0ZpbmQgdGhlIG1lYW4gcmV0dXJucyBvZiBlYWNoIHN0b2NrIGFuZCB0aGUgcmlzayBwcmVtaXVtIAptZWFuX3JBTVpOIDwtIG1lYW4ockFNWk4pCm1lYW5fckZCIDwtIG1lYW4ockZCKQptZWFuX3JQRyA8LSBtZWFuKHJQRykKbWVhbl9yQ09TVCA8LSBtZWFuKHJDT1NUKQptZWFuX3JDSSA8LSBtZWFuKHJDSSkKUm0gPC0gbWVhbihyU1BZKQpSZiA8LSBtZWFuKHJUTlgpCk1hcmtldF9SaXNrUHJlbSA8LSBSbSAtIFJmIApwcmVtQU1aTiA8LSBtZWFuX3JBTVpOLSBSZgpwcmVtRkIgPC0gbWVhbl9yRkItIFJmCnByZW1QRyA8LSBtZWFuX3JQRyAtIFJmCnByZW1DT1NUIDwtIG1lYW5fckNPU1QgLSBSZgpwcmVtQ0kgPC0gbWVhbl9yQ0kgLSBSZgoKI0NyZWF0ZSBhIGNvdmFyaWFuY2UgbWF0cml4IGZyb20gd2hpY2ggeW91IGNhbiBidWlsZCBvdXQgdGhlIGVmZmljaWVudCBmcm9udGllcjoKI2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9aHFRVllscTFubWsKCgpwb3J0Zm9saW8gPC0gZGF0YS5mcmFtZShyQU1aTiwgckZCLCByUEcsckNPU1QsckNJKQpyYW5nZS5uYW1lcyA9IGMoIkFNWk4iLCAiRkIiLCAiUEciLCAiQ09TVCIsICJDSSIpCm5hbWVzKHBvcnRmb2xpbykgPSByYW5nZS5uYW1lcwpjb3ZtYXRyaXggPSBtYXRyaXgoYyhjb3YocG9ydGZvbGlvKSksIG5yb3c9IDUsIG5jb2w9NSkKY292bWF0cml4CmRpbW5hbWVzKGNvdm1hdHJpeCkgPSBsaXN0KHJhbmdlLm5hbWVzLCByYW5nZS5uYW1lcykKaW52ZXJzZV9jb3ZtYXRyaXggPC0gc29sdmUoY292bWF0cml4KQppbnZlcnNlX2Nvdm1hdHJpeAoKI0NvbnZlcnQgdG8gY29ycmVsYXRpb24gbWF0cml4IHRvIGNvbmZpcm0gbnVtYmVycyBsaW5lIHVwCmNvcl9tYXRyaXggPC0gY292MmNvcihjb3ZtYXRyaXgpCgoKCiNDcmVhdGUgUmlzayBQcmVtaXVtIFZlY3RvciwgTk9URTogdGhlIG9yZGVyIG9mIGVsZW1lbnRzIGluIHRoZSB2ZWN0b3IgPSBvcmRlciBvZiBlbGVtZW50cyBpbiBjb3YgbWF0cml4IAoKcmlza19wcmVtdmVjdG9yIDwtIG1hdHJpeChjKHByZW1BTVpOLCBwcmVtRkIsIHByZW1QRywgcHJlbUNPU1QsIHByZW1DSSksIG5yb3c9NSxuY29sPTEpCnJpc2tfcHJlbXZlY3RvcgoKCiNNdWx0aXBseSBpbnZlcnNlIGNvdiBtYXRyaXggYnkgcmlzayBwcmVtaXVtIHZlY3RvciB0byBnZXQgdW5zdGFuZGFyZGl6ZCBvcHRpbWFsIHdlaWdodHMgb2YgdGhlIHBvcnRmb2xpbzogCgp1bnN0YW5kYXJkaXplZF93ZWlnaHRzIDwtIGludmVyc2VfY292bWF0cml4ICUqJSByaXNrX3ByZW12ZWN0b3IKdW5zdGFuZGFyZGl6ZWRfd2VpZ2h0cyAKI0FkZCBhbGwgZWxlbWVudHMgaW4gdGhlIHVuc3RhbmRhcmRpemVkIHdlaWdodCB2ZWN0b3IKCmNvbFN1bXModW5zdGFuZGFyZGl6ZWRfd2VpZ2h0cykKCiNOb3cgY2FsY3VsYXRlIG9wdGltYWwgd2VpZ2h0cwp3X0FNWk4gPC0gdW5zdGFuZGFyZGl6ZWRfd2VpZ2h0c1sxLDFdIC8gY29sU3Vtcyh1bnN0YW5kYXJkaXplZF93ZWlnaHRzKQp3X0ZCIDwtIHVuc3RhbmRhcmRpemVkX3dlaWdodHNbMiwxXSAvIGNvbFN1bXModW5zdGFuZGFyZGl6ZWRfd2VpZ2h0cykKd19QRyA8LSB1bnN0YW5kYXJkaXplZF93ZWlnaHRzWzMsMV0gLyBjb2xTdW1zKHVuc3RhbmRhcmRpemVkX3dlaWdodHMpCndfQ09TVCA8LSB1bnN0YW5kYXJkaXplZF93ZWlnaHRzWzQsMV0gLyBjb2xTdW1zKHVuc3RhbmRhcmRpemVkX3dlaWdodHMpCndfQ0kgPC0gdW5zdGFuZGFyZGl6ZWRfd2VpZ2h0c1s1LDFdIC8gY29sU3Vtcyh1bnN0YW5kYXJkaXplZF93ZWlnaHRzKQpvcHRpbWFsd2VpZ2h0X21hdHJpeCA8LSBtYXRyaXgoYyh3X0FNWk4sIHdfRkIsIHdfUEcsIHdfQ09TVCwgd19DSSksIG5yb3c9NSwgbmNvbD0xKQpyYW5nZS5uYW1lcyA9IGMoIkFNWk4iLCAiRkIiLCAiUEciLCAiQ09TVCIsICJDSSIpCmRpbW5hbWVzKG9wdGltYWx3ZWlnaHRfbWF0cml4KSA9IGxpc3QocmFuZ2UubmFtZXMpCgoKY2F0KCJUaGUgb3B0aW1hbCB3ZWlnaHRzIG9mIHRoZSBwb3J0Zm9saW86IikKcHJpbnQob3B0aW1hbHdlaWdodF9tYXRyaXgpCgojVGVzdCB0aGF0IGFsbCB3ZWlnaHRzIGFkZCB0byAxOiAKI2NhdCgiVGVzdCB0aGF0IGFsbCB3ZWlnaHRzIGFkZCB0byAxOiIpCiNwcmludChjb2xTdW1zKG9wdGltYWx3ZWlnaHRfbWF0cml4KSkKCmBgYAoKICAyYi4gYW5kIDJjLiBVc2luZyB0aGUgb3B0aW11bSB3ZWlnaHRzIGFuZCBkYWlseSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBhdCB0aGUgZW5kIG9mIDIwMTcgYWxsb2NhdGUgJDEwMC4wMCAgICAgICAgICAgIGFtb25nIGFtb25nIHRoZSBzZWxlY3RlZCBzdG9ja3MuIE9uIDEvMS8yMDE0LCB0aGUgcG9ydGZvbGlvIHdpbGwgaGF2ZSBhIHZhbHVlIG9mIDEwMCBhcyBhbiBpbmRleC4gIAoKYGBge3J9CgojSW1wb3J0IGRhaWx5IHN0b2NrIGFkaiBjbG9zaW5nIHByaWNlcyBmcm9tIHlhaG9vIApZYWhvb0RhdGFfRGFpbHkgPC0gZ2V0U3ltYm9scy55YWhvbyhjKCJBTVpOIiwiRkIiLCJQRyIsIkNPU1QiLCJDSSIpLC5HbG9iYWxFbnYsIGZyb20gPSAiMjAxNC0wMS0wMiIsIHRvID0gIjIwMTgtMTAtMzEiLCBwZXJpb2RpY2l0eT0iZGFpbHkiLCByZXR1cm4uY2xhc3MgPSAidGltZVNlcmllcyIpCgojQ2FsY3VsYXRlIERhaWx5IEFkanVzdGVkIFJldHVybnMgCiNOb3RlLCBzaW5jZSBkYXkgMSB5b3UgaGF2ZSAkMTAwLCBhbmQgaXQgaXNuJ3QgYWZmZWN0ZWQgYnkgdGhlIHJldHVybiBvZiB0aGUgcHJldmlvdXMgZGF5LCBsZWZ0IG91dCB0aGUgZmlyc3QgZGF5IG9mIHRoZSByZXR1cm5zIHdoZW4gaW1wb3J0aW5nIGRhdGEpCgpkYWlseV9yQU1aTiA8LSBkaWZmKGxvZyhBTVpOJEFNWk4uQWRqdXN0ZWQpKSAKZGFpbHlfckZCIDwtIGRpZmYobG9nKEZCJEZCLkFkanVzdGVkKSkKZGFpbHlfclBHIDwtIGRpZmYobG9nKFBHJFBHLkFkanVzdGVkKSkKZGFpbHlfckNPU1QgPC0gZGlmZihsb2coQ09TVCRDT1NULkFkanVzdGVkKSkKZGFpbHlfckNJIDwtIGRpZmYobG9nKENJJENJLkFkanVzdGVkKSkKCgoKI0NyZWF0ZSBlcXVhdGlvbiBmb3IgZGFpbHkgb3B0aW1hbCByZXR1cm5zIG9mIHRoZSBwb3J0Zm9saW8KCnJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19kYWlseSA9IG9wdGltYWx3ZWlnaHRfbWF0cml4WzEsMV0qZGFpbHlfckFNWk4gKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFsyLDFdKmRhaWx5X3JGQiArIG9wdGltYWx3ZWlnaHRfbWF0cml4WzMsMV0qZGFpbHlfclBHICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbNCwxXSpkYWlseV9yQ09TVCArIG9wdGltYWx3ZWlnaHRfbWF0cml4WzUsMV0qZGFpbHlfckNJIAptZWFuX3JldHVybiA8LSBtZWFuKHJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19kYWlseSkqMjUyKjQKCiMgcm91bmQocmV0dXJuX29wdGltYWxfcG9ydGZvbGlvX2RhaWx5LDUpCiMgMTAwKigxK3JldHVybl9vcHRpbWFsX3BvcnRmb2xpb19kYWlseVsxXSkqKDErcmV0dXJuX29wdGltYWxfcG9ydGZvbGlvX2RhaWx5WzJdKSooMStyZXR1cm5fb3B0aW1hbF9wb3J0Zm9saW9fZGFpbHlbM10pCgojIGNsYXNzKHJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19kYWlseSkKCiNVc2UgZm9yIGxvb3AgdG8gZ2VuZXJhdGUgaG9sZGluZyB2YWx1ZXMgZm9yIGV2ZXJ5IGRheSBvZiB0aGUgZGF0YSBzZXJpZXM6CgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKbmV3cmV0dXJuID0gMSArIHJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19kYWlseQpuZXdyZXR1cm5bMV0gPC0gbmV3cmV0dXJuWzFdKjEwMCAjdGhlIHZhbHVlIG9mIHRoZSBzZWNvbmQgZGF5CiMgaGVhZChuZXdyZXR1cm4pCiMgdGFpbChuZXdyZXR1cm4pCm5ld2RhaWx5cmV0dXJuID0gY3VtcHJvZChuZXdyZXR1cm4pCiNoZWFkKG5ld2RhaWx5cmV0dXJuKQojdGFpbChuZXdkYWlseXJldHVybikKI2xlbmd0aChuZXdkYWlseXJldHVybikKI2xlbmd0aChBTVpOWywxXSkKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCm5ld2RhaWx5cmV0dXJuMj1jKG5ld2RhaWx5cmV0dXJuKQojaGVhZChuZXdkYWlseXJldHVybjIpCnJldHVybndpdGhkYXRlPSBjYmluZChBTVpOWywxXSxuZXdkYWlseXJldHVybjIpCiN0YWlsKHJldHVybndpdGhkYXRlKQojaGVhZChyZXR1cm53aXRoZGF0ZSkKIyBwcmludChyZXR1cm53aXRoZGF0ZVssMl0pCiN0YWlsKHJldHVybndpdGhkYXRlWywyXSkKcHJpbnQoInNzLjEgY29sdW1uIHJlcHJlc2VudHMgdGhlIGhvbGRpbmcgdmFsdWUgb2YgdGhlIHBvcnRmb2xpbyIpCnJldHVybndpdGhkYXRlICAgICAgICAgICAKCmBgYAoKMy4gQ2FsY3VsYXRlIHRoZSBDQUwgZXF1YXRpb24gYW5kIGdyYXBoIENBTCBhbmQgdGhlIGVmZmljaWVudCBmcm9udGllci4KCmBgYHtyfQoKI0NhbGN1bGF0aW5nIHBvcnRmb2xpbyB2YXJpYW5jZTogCiNodHRwczovL3plcm9kaGEuY29tL3ZhcnNpdHkvY2hhcHRlci9yaXNrLXBhcnQtNC1jb3JyZWxhdGlvbi1tYXRyaXgtcG9ydGZvbGlvLXZhcmlhbmNlLwoKI1BvcnRmb2xpbyBWYXJpYW5jZSA9IFNxcnQgKFRyYW5zcG9zZSAoV3QuU0QpICogQ29ycmVsYXRpb24gTWF0cml4ICogV3QuIFNECgojQ2FsY3VsYXRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIGZpdmUgYXNzZXRzJyByZXR1cm5zOiAKCnNkX3JBTVpOIDwtIHNkKHJBTVpOKQpzZF9yRkIgPC0gc2QockZCKQpzZF9yUEcgPC0gc2QoclBHKQpzZF9yQ09TVCA8LSBzZChyQ09TVCkKc2RfckNJIDwtIHNkKHJDSSkKc2RfbWF0cml4IDwtIG1hdHJpeChjKHNkX3JBTVpOLCBzZF9yRkIsIHNkX3JQRywgc2RfckNPU1QsIHNkX3JDSSkpIApyYW5nZS5uYW1lcyA9IGMoIkFNWk4iLCAiRkIiLCAiUEciLCAiQ09TVCIsICJDSSIpCmNhdCgiU3RhbmRhcmQgRGV2aWF0aW9ucyIpCmRpbW5hbWVzKHNkX21hdHJpeCkgPSBsaXN0KHJhbmdlLm5hbWVzKQpzZF9tYXRyaXgKCiNDYWxjdWxhdGUgd2VpZ2h0ZWQgc3RhbmRhcmQgZGV2aWF0aW9ucyAKCndlaWdodGVkX3NkX21hdHJpeCA8LSBtYXRyaXgoYyhzZF9yQU1aTipvcHRpbWFsd2VpZ2h0X21hdHJpeFsxLDFdLCBzZF9yRkIqb3B0aW1hbHdlaWdodF9tYXRyaXhbMiwxXSwgc2RfclBHKm9wdGltYWx3ZWlnaHRfbWF0cml4WzMsMV0sIHNkX3JDT1NUKm9wdGltYWx3ZWlnaHRfbWF0cml4WzQsMV0sIHNkX3JDSSpvcHRpbWFsd2VpZ2h0X21hdHJpeFs1LDFdKSkgCnJhbmdlLm5hbWVzID0gYygiQU1aTiIsICJGQiIsICJQRyIsICJDT1NUIiwgIkNJIikKY2F0KCJXZWlnaHRlZCBTdGFuZGFyZCBEZXZpYXRpb25zIikKZGltbmFtZXMod2VpZ2h0ZWRfc2RfbWF0cml4KSA9IGxpc3QocmFuZ2UubmFtZXMpCndlaWdodGVkX3NkX21hdHJpeAoKI0NvbXB1dGUgdGhlIHBvcnRmb2xpbyB2YXJpYW5jZSwgd2hlbiBvcHRpbWFsIHdpZWdodHMgYXJlIHVzZWQsIHVzaW5nIHRoaXMgZm9ybXVsYTogIlBvcnRmb2xpbyBWYXJpYW5jZSA9IFNxcnQgKFRyYW5zcG9zZSAoV3QuU0QpICogQ29ycmVsYXRpb24gTWF0cml4ICogV3QuIFNEIgoKUG9ydGZvbGlvX1ZhcmlhbmNlIDwtIHNxcnQodCh3ZWlnaHRlZF9zZF9tYXRyaXgpJSolY29yX21hdHJpeCUqJXdlaWdodGVkX3NkX21hdHJpeCkKUG9ydGZvbGlvX1ZhcmlhbmNlClBvcnRmb2xpb19TRCA8LSBzcXJ0KFBvcnRmb2xpb19WYXJpYW5jZSkKUG9ydGZvbGlvX1NEIAoKI01lYW4gcmV0dXJuIG9mIG9wdGltYWwgcG9ydGZvbGlvLCB1c2luZyBtb250aGx5IHJldHVybnM6CgpyZXR1cm5fb3B0aW1hbF9wb3J0Zm9saW9fbWVhbiA9IG9wdGltYWx3ZWlnaHRfbWF0cml4WzEsMV0qbWVhbl9yQU1aTiArIG9wdGltYWx3ZWlnaHRfbWF0cml4WzIsMV0qbWVhbl9yRkIgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFszLDFdKm1lYW5fclBHICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbNCwxXSptZWFuX3JDT1NUICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbNSwxXSptZWFuX3JDSQpyZXR1cm5fb3B0aW1hbF9wb3J0Zm9saW9fbWVhbgoKCiNDYWxjdWxhdGUgdGhlIHNoYXJwZSByYXRpbzogCgpzaGFycGVfcmF0aW8gPC0gKHJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19tZWFuIC0gUmYpLyhQb3J0Zm9saW9fU0QpCnByaW50KHNoYXJwZV9yYXRpbykKCiNQdXQgaXQgYWxsIHRvZ2V0aGVyIHRvIGNyZWF0ZSB0aGUgQ0FMOiAKCmNhdCgiVGhlIGNhcGl0YWwgYWxsb2NhdGlvbiBsaW5lOiIsICJFKHIpID0iICwgUmYsIisiLCBzaGFycGVfcmF0aW8sICIqIFN0YW5kYXJkIERldmlhdGlvbiIpIAoKI05vdyBncmFwaCB0aGUgQ0FMOiAKCiNDcmVhdGUgZGlzY3JldGUgZGV2aWF0aW9ucyBmb3IgcGxvdHRpbmcgcHVycG9zZXMKYmFzaWNfc3RhbmRhcmRfZGV2aWF0aW9uIDwtIGMoMCwxLDIsMykKckNBTCA8LSBSZiArIHNoYXJwZV9yYXRpbypiYXNpY19zdGFuZGFyZF9kZXZpYXRpb24KcGxvdChiYXNpY19zdGFuZGFyZF9kZXZpYXRpb24sIHJDQUwsIGNvbD0iR3JlZW4iLCB4bGFiPSJTdGFuZGFyZCBEZXZpYXRpb24iLCB5bGFiPSJFeHBlY3RlZCBSZXR1cm4iLCB0eXBlPSJsIikKCiNQbG90IFBvcnRmb2xpbyBwb3NzaWJpbGl0aWVzIGN1cnZlIChlZmZpY2llbnQgZnJvbnRpZXIpOgoKclAgPSBtZWFuX3JBTVpOICsgbWVhbl9yRkIgKyBtZWFuX3JQRyArIG1lYW5fckNPU1QgKyBtZWFuX3JDSQoKCgpgYGAKCgo0LiBFc3RpbWF0ZSB0aGUgQ0FQTSBtb2RlbCBvZiB5b3VyIHBvcnRmb2xpbyB1c2luZyAxLzIvMjAxOC0xMC8zMC8yMDE4IGRhdGEuICBDb21wYXJlIHRoZSBlc3RpbWF0ZWQgYmV0YSBvZiB0aGUgeW91ciBDQVBNIG1vZGVsIHdpdGggbWFya2V0IGJldGEuIEFyZSB0aGV5IHN0YXRpc3RpY2FsbHkgZGlmZmVyZW50IGZyb20gZWFjaCBvdGhlcj8gCgoKKnlvdSBhcmUgZG9pbmcgYSByZWdyZXNzaW9uIG9mIHRoZSByaXNrIHByZW1pdW0gb2YgdGhlIHBvcnRmb2xpbyB0byB0aGUgcmlzayBwcmVtaXVtIG9mIHRoZSBtYXJrZXQgCgpgYGB7cn0KCmxpYnJhcnkoImZQb3J0Zm9saW8iKQpsaWJyYXJ5KCJxdWFudG1vZCIpCmxpYnJhcnkoInRpbWVTZXJpZXMiKQpsaWJyYXJ5KCJ0c2VyaWVzIikKbGlicmFyeSgic3RhdHMiKQoKI0ltcG9ydCBkYWlseSBzdG9jayBhZGogY2xvc2luZyBwcmljZXMgZnJvbSB5YWhvbyAKWWFob29EYXRhX0RhaWx5IDwtIGdldFN5bWJvbHMueWFob28oYygiQU1aTiIsIkZCIiwiUEciLCJDT1NUIiwiQ0kiLCAiU1BZIiwgIl5UTlgiKSwuR2xvYmFsRW52LCBmcm9tID0gIjIwMTgtMDEtMDIiLCB0bz0iMjAxOC0xMC0zMCIsIHBlcmlvZGljaXR5PSJkYWlseSIsIHJldHVybi5jbGFzcyA9ICJ0aW1lU2VyaWVzIikKCiNDYWxjdWxhdGUgRGFpbHkgQWRqdXN0ZWQgUmV0dXJucyAKI05vdGUsIHNpbmNlIGRheSAxIHlvdSBoYXZlICQxMDAsIGFuZCBpdCBpc24ndCBhZmZlY3RlZCBieSB0aGUgcmV0dXJuIG9mIHRoZSBwcmV2aW91cyBkYXksIGxlZnQgb3V0IHRoZSBmaXJzdCBkYXkgb2YgdGhlIHJldHVybnMgd2hlbiBpbXBvcnRpbmcgZGF0YSkKCnJBTVpOX0NBUE0gPC0gZGlmZihsb2coQU1aTiRBTVpOLkFkanVzdGVkKSkgIApyRkJfQ0FQTSA8LSBkaWZmKGxvZyhGQiRGQi5BZGp1c3RlZCkpCnJQR19DQVBNIDwtIGRpZmYobG9nKFBHJFBHLkFkanVzdGVkKSkKckNPU1RfQ0FQTSA8LSBkaWZmKGxvZyhDT1NUJENPU1QuQWRqdXN0ZWQpKQpyQ0lfQ0FQTSA8LSBkaWZmKGxvZyhDSSRDSS5BZGp1c3RlZCkpCnJUTlhfQ0FQTSA8LSBUTlgkVE5YLkFkanVzdGVkLzEwMC8xMgojb3ZlcnJpZGUgVE5YLCBzdGFydCBhdCBpbmRleCB0d28gYW5kIGdvIGRvd24gZnJvbSB0aGVyZSwgcmVtZW1iZXIgd2hlbiBjYWxjdWxhdGluZyByZXR1cm5zIGZvciBBQVBMIGluIGV4Y2VsIHlvdSBnb3QgcmlkIG9mIHRoZSBmaXJzdCB2YWx1ZSwgc2FtZSB0aGluZyBoZXJlCnJUTlhfQ0FQTSA8LSByVE5YWzI6bGVuZ3RoKHJUTlgpXQpyU1BZX0NBUE0gPC0gZGlmZihsb2coU1BZJFNQWS5BZGp1c3RlZCkpCihyRl9DQVBNIDwtIHJUTlhfQ0FQTSkKCgojVGhpcyBpcyB0aGUgYWN0dWFsIHJldHVybiB0byB0aGUgcG9ydGZvbGlvCnJQX0NBUE0gPC0gb3B0aW1hbHdlaWdodF9tYXRyaXhbMSwxXSpyQU1aTl9DQVBNICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbMiwxXSpyRkJfQ0FQTSArIG9wdGltYWx3ZWlnaHRfbWF0cml4WzMsMV0qclBHX0NBUE0gKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFs0LDFdKnJDT1NUX0NBUE0gKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFs1LDFdKnJDSV9DQVBNCnJQX0NBUE0KCnJpc2twcmVtX3BvcnRmb2xpb19DQVBNIDwtIHJQX0NBUE0gLSByRl9DQVBNCgojcmlzayBwcmVtaXVtIG9mIFNQWSBpcyB0aGUgbWFya2V0IHJpc2sgcHJlbWl1bSAKcmlza3ByZW1fU1BZX0NBUE0gPC0gclNQWV9DQVBNIC0gckZfQ0FQTQoKCiNOb3cgdGhhdCB5b3UgaGF2ZSB5b3VyIGluZGVwZW5kZW50IGFuZCBkZXBlbmRlbnQgdmFyaWFibGVzICh4PXJpc2sgcHJlbWl1biBtYXJrZXQsIHk9IHJpc2sgcHJlbWl1bSBvZiB0aGUgcG9ydGZvbGlvKSwgcmVncmVzcyB0aGUgZGF0YSB0byBmaW5kIHRoZSBiZXRhIGVzdGltYXRlIGZvciB5b3VyIHBvcnRmb2xpbzogCgpDQVBNX3JlZ3Jlc3Npb24gPC0gbG0ocmlza3ByZW1fcG9ydGZvbGlvX0NBUE0gfiByaXNrcHJlbV9TUFlfQ0FQTSkKc3VtbWFyeShDQVBNX3JlZ3Jlc3Npb24pCgojU3VtbWFyeSBub3RlcyBvZiB0aGUgcmVncmVzc2lvbiBzaG93IHRoYXQgdGhlIGFscGhhIGFuZCBiZXRhIG9mIENBUE0gYXJlOgpBbHBoYSA8LSAgLTAuMDAwODA2CkJldGFfUG9ydGZvbGlvIDwtIDAuNTI3NjkxCgpjYXQoIlRoZSBDQVBNIEZvcm11bGEgaXM6ICIsIG1lYW4oclROWF9DQVBNKSwgIiArIGJldGEgKiAiLCBtZWFuKHJpc2twcmVtX1NQWV9DQVBNKSkKCgojVGVzdCB0aGF0IHRoZSBCZXRhIG9mIHRoZSBwb3J0Zm9saW8gaXMgbm90IHN0YXRpc3RpY2FsbHkgZGlmZmVyZW50IHRoYXQgdGhlIGJldGEgKDEpIG9mIHRoZSBtYXJrZXQKQmV0YV9NYXJrZXQgPC0gMQpTRV9CZXRhX1BvcnRmb2xpbyA8LSAwLjA2MzA1MwoKY2F0KCAiQ2FsY3VsYXRlIHRoZSB0IHN0YXRpc3RpYyB0byB0ZXN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCBCZXRhIG9mIHRoZSBwb3J0Zm9saW8gaXMgbm90IHN0YXRpc3RpY2FsbHkgZGlmZmVyZW50IHRoYW4gYmV0YSBvZiB0aGUgbWFya2V0IikgCgp0c3RhdCA8LSAoQmV0YV9Qb3J0Zm9saW8tQmV0YV9NYXJrZXQpLyhTRV9CZXRhX1BvcnRmb2xpbykKdHN0YXQKCmNhdCgiVGhlIHQtc3RhdCBpcyIsIHRzdGF0LCAiICAgICIpCgojSG86IEJldGFfUG9ydGZvbGlvID0gMQojSGE6IEJfUG9ydGZvbGlvICE9IDEgCgpjYXQoIlNpbmNlIHN1bW1hcnkgcmVncmVzc2lvbiBzaG93cyB0LXZhbHVlIG9mIGJldGExIGlzIDcuNDkgPiAxLjk2LCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcywgdGh1cywgQmV0YSBvZiB0aGUgcG9ydGZvbGlvIGlzIHN0YXRpc3RpY2FsbHkgZGlmZmVyZW50IHRoYW4gdGhlIEJldGEgb2YgdGhlIG1hcmtldCIpCgpgYGAKNS4gIEdyYXBoIHRoZSBTTUwgYW5kIGNvbXBhcmUgdGhlIGVzdGltYXRlZCBCZXRhIG9mIHRoZSBDQVBNIGFuZCB0aGUgYXZlcmFnZSByZXR1cm4gb2YgeW91ciBwb3J0Zm9saW8gYXMgYSBwb2ludCByZWxhdGl2ZSB0byBTTUwuIENvbW1lbnQgb24gcGVyZm9ybWFuY2Ugb2YgeW91ciBwb3J0Zm9saW8uCgpgYGB7cn0KCiNHcmFwaCB0aGUgU01MIGJ5IGNhbGN1bGF0aW5nIHRoZSBhdmVyYWdlIHJmIGFuZCBtcnAgdXNpbmcgdGhlIGFjdHVhbCBkYXRhLiAKCgoKI1RoaXMgbWV0aG9kIHVzZXMgdGhlIGF2ZXJhZ2UgZGF0YSB0byBnZXQgdGhlIFNNTCwgYnV0IHdlIHNob3VsZCB1c2UgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgdG8gZ3JhcGggdGhlIENBUE0KCmNhdCgiVGhlIENBUE0gRm9ybXVsYSBpczogIiwgbWVhbihyVE5YX0NBUE0pLCAiICsgYmV0YSAqICIsIG1lYW4ocmlza3ByZW1fU1BZX0NBUE0pKQoKU01MX01SUCA9IG1lYW4oclNQWV9DQVBNKSAtIG1lYW4oclROWF9DQVBNKQpTTUxfTVJQCmJldGFfcmFuZ2UgPSBjKDAsMSwyLDMsNCw1KSAKU01MX0xpbmUgPSBtZWFuKHJUTlhfQ0FQTSkgKyBiZXRhX3JhbmdlKm1lYW4ocmlza3ByZW1fU1BZX0NBUE0pCiNUaGlzIGlzIHRoZSBDQVBNIGVzdGltYXRlIG9mIHRoZSBvcHRpbWFsIHBvcnRmb2xpb3MgcmV0dXJuClNNTF9Qb3J0Zm9saW8gPSBtZWFuKHJUTlhfQ0FQTSkgKyBCZXRhX1BvcnRmb2xpbyptZWFuKHJpc2twcmVtX1NQWV9DQVBNKQpwbG90KGJldGFfcmFuZ2UsIFNNTF9MaW5lLCBjb2w9IkdyZWVuIiwgeGxhYj0iQmV0YSIsIHlsYWI9IkV4cGVjdGVkIFJldHVybiIsIHR5cGU9InAiKQojVGhpcyBpcyB0aGUgQ0FQTSBlc3RpbWF0ZSBvZiB0aGUgb3B0aW1hbCBwb3J0Zm9saW9zIHJldHVybiBncmFwaGVkCnBvaW50cyhCZXRhX1BvcnRmb2xpbywgU01MX1BvcnRmb2xpbywgdHlwZSA9ICJwIikKI1RoaXMgaXMgdGhlIGFjdHVhbCByZXR1cm4gb2YgdGhlIG9wdGltYWwgcG9ydGZvbGlvIGdyYXBoZWQgd2l0aCB0aGUgcmVncmVzc2lvbiBlc3RpbWF0ZSBvZiB0aGUgb3B0aW1hbCBwb3J0Zm9saW9zIGJldGEgY29lZmZpY2llbnQKcG9pbnRzKEJldGFfUG9ydGZvbGlvLCBtZWFuKHJQX0NBUE0pLCBjb2w9IlJlZCIpCgpjYXQoIlRoZSByZWQgZG90IGluZGljYXRlcyB0aGUgYWN0dWFsIHJldHVybiBvZiB0aGUgb3B0aW1hbCBwb3J0Zm9saW8gZ3JhcGhlZCB3aXRoIHRoZSByZWdyZXNzaW9uIGVzdGltYXRlIG9mIHRoZSBwb3J0Zm9saW8ncyBiZXRhIGNvZWZmaWNpZW50IiwgIlRoZSBibGFjayBkb3QgcmVwcmVzZW50cyB0aGUgQ0FQTSBlc3RpbWF0ZSBvZiB0aGUgcG9ydGZvbGlvcyByZXR1cm4gZ3JhcGhlZCB3aXRoIHRoZSBzYW1lIGJldGEgZXN0aW1hdGUiLCAiVGhlIGFjdHVhbCBwb3J0Zm9saW8gcmVzdHMgYmVsb3cgdGhlIFNNTC4gVGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgcG9ydGZvbGlvIGlzIG92ZXJ2YWx1ZWQuIFRoYXQgaXMsIHRoZSBwb3J0Zm9saW8gaXMgcmVjZWl2aW5nIGEgbGVzc2VyIHJldHVybiBmb3IgdGhlIHNhbWUgYW1vdW50IG9mIHJpc2suIEJhc2VkIG9uIENBUE0gdGhlb3J5LCBkZW1hbmQgZm9yIHRoZSBwb3J0Zm9saW8gc2hvdWxkIGRlY2xpbmUsIHJlc3VsdGluZyBpbiBhIGxvd2VyIHByaWNlIG9mIHRoZSBwb3J0Zm9saW9zIHVuZGVybHlpbmcgcmV0dXJucy4gQXMgYSByZXN1bHQsIHRoZSByZXR1cm4gb2YgdGhlIHBvcnRmb2xpbyB3b3VsZCBpbmNyZWFzZSB1bnRpbCB0aGUgcG9ydGZvbGlvcyBwb2ludCByZXN0cyBvbiB0aGUgU01MLiIpCgpgYGAKCgo2LiBDYWxjdWxhdGUgQ1YsIFNoYXJwZSwgVHJleW5vciwgYW5kIFNvcnRpbm8gcmF0aW9zIGZvciB5b3VyIHBvcnRmb2xpbyBhbmQgY29tcGFyZSB0aGVtIHRvIGEgc2ltaWxhcmx5IGRpdmVyc2lmaWVkIHBvcnRmb2xpbyBvZiBWYW5ndWFyZCwgRmlkZWxpdHksIG9yIGFueSBvdGhlciBzaW1pbGFyIHBvcnRmb2xpby4KCmBgYHtyfQoKbGlicmFyeSgiUGVyZm9ybWFuY2VBbmFseXRpY3MiKQoKCiNDYWxjdWxhdGUgdGhlIHNoYXJwZSByYXRpbzogCgpzaGFycGVfcmF0aW8gPC0gKHJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19tZWFuIC0gUmYpLyhQb3J0Zm9saW9fU0QpCnByaW50KHNoYXJwZV9yYXRpbykKCmNhdCgiVGhlIHNoYXJwZSByYXRpbyBpczoiLCBzaGFycGVfcmF0aW8sICIgICAgICIpCgojQ2FsY3VsYXRlIFNvcnRpbm8gUmF0aW8gCiNodHRwOi8vYnJhdmVyb2NrLmNvbS9icmlhbi9SL1BlcmZvcm1hbmNlQW5hbHl0aWNzL2h0bWwvU29ydGlub1JhdGlvLmh0bWwKCiNnZXQgbW9udGhseSBvcHRpbWFsIHJldHVybnMgdG8gdGhlIHBvcnRmb2xpbwoKcmV0dXJuX29wdGltYWxfcG9ydGZvbGlvX21vbnRobHkgPSBvcHRpbWFsd2VpZ2h0X21hdHJpeFsxLDFdKnJBTVpOICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbMiwxXSpyRkIgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFszLDFdKnJQRyArIG9wdGltYWx3ZWlnaHRfbWF0cml4WzQsMV0qckNPU1QgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFs1LDFdKnJDSQoKIApzb3J0aW5vIDwtIChTb3J0aW5vUmF0aW8ocmV0dXJuX29wdGltYWxfcG9ydGZvbGlvX21vbnRobHksIE1BUiA9IDApKQoKY2F0KCJUaGUgc29ydGlubyByYXRpbyBpczoiLCBzb3J0aW5vLCAiICAgICAiICkKCiN0cmV5bm9yIHJhdGlvID0gKHJQIC0gckYpL2JldGFQIAoKI0NhbGN1bGF0ZSBCZXRhIG9mIHRoZSBQb3J0Zm9saW8KI3JlbWVtYmVyIGJldGEgbWVhc3VyZSB2b2xhdGlsaXR5IHJlbGF0aXZlIHRvIHRoZSBtYXJrZXQuIFNvIEZCIGlzIHRoZW9yZXRpY2FsbHkgMzAlIGxlc3Mgdm9sYXRpbGUgdGhhbiB0aGUgbWFya2V0IAoKQmV0YV9BTVpOIDwtIDEuODcKQmV0YV9GQiA8LSAwLjcwCkJldGFfUEcgPC0gMC4zMgpCZXRhX0NPU1QgPC0gMS4xNyAKQmV0YV9DSSA8LSAwLjc5CldlaWdodGVkX0JldGFfUG9ydGZvbGlvIDwtIG9wdGltYWx3ZWlnaHRfbWF0cml4WzEsMV0qQmV0YV9BTVpOICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbMiwxXSpCZXRhX0ZCICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbMywxXSpCZXRhX1BHICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbNCwxXSpCZXRhX0NPU1QgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFs1LDFdKkJldGFfQ0kKY2F0KCJUaGUgQmV0YSBvZiB0aGUgUG9ydGZvbGlvIGlzOiIsIFdlaWdodGVkX0JldGFfUG9ydGZvbGlvLCAiLiBUaHVzLHRoZSBwb3J0b2xpbydzIHJldHVybnMgYXJlIHRoZW9yZXRpY2FsbHkgMTclIG1vcmUgdm9sYXRpbGUgdGhhbiB0aGUgbWFya2V0LiAgICAgIikKCnRyZXlub3IgPC0gKChyZXR1cm5fb3B0aW1hbF9wb3J0Zm9saW9fbWVhbi1SZikvV2VpZ2h0ZWRfQmV0YV9Qb3J0Zm9saW8pCmNhdCgiVGhlIHRyZXlub3IgcmF0aW8gaXM6IiwgdHJleW5vciwgIiAgICAgIikKCmBgYAoKCjcuIENhbGN1bGF0ZSAyJSBWYVIgYXMgYSBwZXJjZW50YWdlIG9mIHRoZSBtZWFuIHJldHVybiBvZiB5b3VyIHBvcnRmb2xpbyB3aGVuIHRoZSByaXNrIGhvcml6b24gaXMgb25lIGRheSBhbmQgb25lIG1vbnRoLiAKCmBgYHtyfQojUmVpbXBvcnQgZGF0YSBmb3IgaW50dWl0aXZlbmVzczogIAoKWWFob29EYXRhIDwtIGdldFN5bWJvbHMueWFob28oYygiQU1aTiIsIkZCIiwiUEciLCJDT1NUIiwiQ0kiLCJeVE5YIiwiU1BZIiksLkdsb2JhbEVudiwgZnJvbSA9ICIyMDE0LTAxLTAxIiwgdG89ICIyMDE3LTEyLTAxIiwgcGVyaW9kaWNpdHk9Im1vbnRobHkiLCByZXR1cm4uY2xhc3MgPSAidGltZVNlcmllcyIpCgojQ2FsY3VsYXRlIFN0b2NrIFJldHVybnMgYW5kIFJpc2sgUHJlbWl1bXMgKFN0b2NrIFJldHVybiAtIFJmKTsgUmYgaXMgclROWCAKckFNWk4gPC0gZGlmZihsb2coQU1aTiRBTVpOLkFkanVzdGVkKSkKckZCIDwtIGRpZmYobG9nKEZCJEZCLkFkanVzdGVkKSkKclBHIDwtIGRpZmYobG9nKFBHJFBHLkFkanVzdGVkKSkKckNPU1QgPC0gZGlmZihsb2coQ09TVCRDT1NULkFkanVzdGVkKSkKckNJIDwtIGRpZmYobG9nKENJJENJLkFkanVzdGVkKSkKclROWCA8LSBUTlgkVE5YLkFkanVzdGVkLzEwMC8xMgojb3ZlcnJpZGUgVE5YLCBzdGFydCBhdCBpbmRleCB0d28gYW5kIGdvIGRvd24gZnJvbSB0aGVyZSwgcmVtZW1iZXIgd2hlbiBjYWxjdWxhdGluZyByZXR1cm5zIGZvciBBQVBMIGluIGV4Y2VsIHlvdSBnb3QgcmlkIG9mIHRoZSBmaXJzdCB2YWx1ZSwgc2FtZSB0aGluZyBoZXJlICAKclROWCA8LSByVE5YWzI6bGVuZ3RoKHJUTlgpXQpyU1BZIDwtIGRpZmYobG9nKFNQWSRTUFkuQWRqdXN0ZWQpKQoKY2F0KCJGcm9tIFF1ZXN0aW9uIDI6IFRoZSBvcHRpbWFsIHdlaWdodHMgb2YgdGhlIHBvcnRmb2xpbzoiKQpwcmludChvcHRpbWFsd2VpZ2h0X21hdHJpeCkKCiNEZXJpdmUgdGhlIG1vbnRobHkgcmV0dXJucyBhbmQgbW9udGhseSBzdGFuZGFyZCBkZWZpdmF0aW9uIGZvciB0aGUgcG9ydGZvbGlvOiAKCnJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19tb250aGx5ID0gb3B0aW1hbHdlaWdodF9tYXRyaXhbMSwxXSpyQU1aTiArIG9wdGltYWx3ZWlnaHRfbWF0cml4WzIsMV0qckZCICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbMywxXSpyUEcgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFs0LDFdKnJDT1NUICsgb3B0aW1hbHdlaWdodF9tYXRyaXhbNSwxXSpyQ0kgCnJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19tb250aGx5CgojTW9udGhseSB2YWx1ZXM6Cm1vbnRobHlfcmV0dXJuX3BvcnRmb2xpbyA8LSBtZWFuKHJldHVybl9vcHRpbWFsX3BvcnRmb2xpb19tb250aGx5KQptb250aGx5X3NkX3BvcnRmb2xpbyA8LSBzZChyZXR1cm5fb3B0aW1hbF9wb3J0Zm9saW9fbW9udGhseSkKI0FubnVhbCB2YWx1ZXM6CmFubnVhbF9yZXR1cm5fcG9ydGZvbGlvIDwtICAgbWVhbihyZXR1cm5fb3B0aW1hbF9wb3J0Zm9saW9fbW9udGhseSkqKDEyKQphbm51YWxfU0RfcG9ydGZvbGlvIDwtICBzZChyZXR1cm5fb3B0aW1hbF9wb3J0Zm9saW9fbW9udGhseSkqc3FydCgxMikKIzEwIGRheSB2YWx1ZXMgKDI1MCB0cmFkaW5nIGRheXMpOiAKdGVuZGF5X3JldHVybl9wb3J0Zm9saW8gPC0gYW5udWFsX3JldHVybl9wb3J0Zm9saW8qKDEwLzI1MCkKdGVuZGF5X3NkX3BvcnRmb2xpbyA8LSBhbm51YWxfU0RfcG9ydGZvbGlvKnNxcnQoMTAvMjUwKQoKCiNEZXJpdmUgbWVhbiBtb250aGx5IHJldHVybnMgYW5kIG1vbnRobHkgc2QgdG8gdGhlIG1hcmtldCAoU1BZKTogCgojTW9udGhseSB2YWx1ZXM6Cm1vbnRobHlfcmV0dXJuX1NQWSA8LSBtZWFuKHJTUFkpCm1vbnRobHlfc2RfU1BZIDwtIHNkKHJTUFkpCiNBbm51YWwgdmFsdWVzOgphbm51YWxfcmV0dXJuX1NQWSA8LSBtZWFuKHJTUFkpKigxMikKYW5udWFsX1NEX1NQWSA8LSAgc2QoclNQWSkqc3FydCgxMikKIzEwIGRheSB2YWx1ZXMgKDI1MCB0cmFkaW5nIGRheXMpOiAKdGVuZGF5X3JldHVybl9TUFkgPC0gYW5udWFsX3JldHVybl9TUFkqKDEwLzI1MCkKdGVuZGF5X3NkX1NQWSA8LSBhbm51YWxfU0RfU1BZKnNxcnQoMTAvMjUwKQoKI25lZWQgYSBmdW5jdGlvbiB0aGF0IGdpdmVzIGludmVyc2Ugb2Ygbm9ybWFsIGN1bXVsYXRpdmUgZGlzdHJpYnV0aW8uIHBub3JtIGdpdmVzIENERiBhbmQgcW5vcm0gZ2l2ZXMgdGhlIGludmVyc2UgQ0RGCgojQ2FsY3VsYXRlIE1vdGhseSBWYVIgZm9yIHRoZSBNYXJrZXQgKFNQWSkgYW5kIHRoZSBvcHRpbWFsIHBvcnRmb2xpbwoKIzIlIFZhUiBmb3IgT3B0aW1hbCBQb3J0Zm9saW8gd2l0aCBtb250aGx5IHRpbWUgaG9yaXpvbiAKY2F0KCIgICAyJSBWYVIgZm9yIE9wdGltYWwgUG9ydGZvbGlvIHdpdGggbW9udGhseSB0aW1lIGhvcml6b24gaXM6ICIsIApxbm9ybSguMDIsbW9udGhseV9yZXR1cm5fcG9ydGZvbGlvLG1vbnRobHlfc2RfcG9ydGZvbGlvKSkKCmNhdCgiCiAgICAiKQoKIzIlIFZhUiBmb3IgT3B0aW1hbCBQb3J0Zm9saW8gd2l0aCAxMCBkYXkgdGltZSBob3Jpem9uIApjYXQoIjIlIFZhUiBmb3IgT3B0aW1hbCBQb3J0Zm9saW8gd2l0aCAxMCBkYXkgdGltZSBob3Jpem9uIGlzOiIsCnFub3JtKC4wMix0ZW5kYXlfcmV0dXJuX3BvcnRmb2xpbyx0ZW5kYXlfc2RfcG9ydGZvbGlvKSkKCgoKCmBgYAoKCgo5LiAgVXNpbmcgdGhlIENBUE0gZXF1YXRpb24gb2YgeW91ciBwb3J0Zm9saW8gZG8gYSBmaXZlIHBlcmlvZHMgZXgtcG9zdCBmb3JlY2FzdGluZyBvZiB0aGUgcmV0dXJucyB0byB5b3VyIHBvcnRmb2xpbyBhbmQgY29tcGFyZSB5b3VyIGZvcmVjYXN0IHRvIHRoZSBhY3R1YWwgcmV0dXJucy4gRmluZCBhbmQgcmVwb3J0IE1BRCwgTUFQLCBNQVNFLCBhbmQgUk1TIGZvciB5b3VyIGZvcmVjYXN0LgoKQU5ECgoxMC4gVXNpbmcgdGhlIENBUE0gZXF1YXRpb24gb2YgeW91ciBwb3J0Zm9saW8gZG8gYSBmaXZlIHBlcmlvZHMgZXgtYW50ZSBmb3JlY2FzdGluZyBvZiB0aGUgcmV0dXJucyB0byB5b3VyIHBvcnRmb2xpby4gRmluZCBhbmQgcmVwb3J0IE1BRCwgTUFQLCBNQVNFLCBhbmQgUk1TIG9mIHlvdXIgZm9yZWNhc3QuIFlvdSBtYXkgdXNlIEVTIHRvIGZvcmVjYXN0IHRoZSByaXNrIHByZW1pdW0gb2YgUyZQNTAwIGZvciB0aGUgcmVxdWlyZWQgZml2ZSBwZXJpb2RzLgoKYGBge3J9CgojRmlyc3QsIHB1dCB5b3VyIHggYW5kIHkgaW50byBhIGRhdGEgZnJhbWUgdG8gc2ltcGxpZnkgdGhlIGZvcmVjYXN0aW5nIGNvZGUgCgpxdWVzdGlvbl85X2RhdGFfUGFydDEgPC0gZGF0YS5mcmFtZShyaXNrcHJlbV9wb3J0Zm9saW9fQ0FQTVsxOjIwM10sIHJpc2twcmVtX1NQWV9DQVBNWzE6MjAzXSkKcXVlc3Rpb25fOV9kYXRhX1BhcnQyIDwtIGRhdGEuZnJhbWUocmlza3ByZW1fcG9ydGZvbGlvX0NBUE1bMjA0OjIwOF0sIHJpc2twcmVtX1NQWV9DQVBNWzIwNDoyMDhdKQpxdWVzdGlvbl85X2RhdGFfRnVsbHJhbmdlIDwtIGRhdGEuZnJhbWUocmlza3ByZW1fcG9ydGZvbGlvX0NBUE0sIHJpc2twcmVtX1NQWV9DQVBNKQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCiNSdW4gdGhlIHJlZ3Jlc3Npb24gZm9yIGV4LXBvc3QgZm9yZWNhc3QgICAKcmVnX2V4cG9zdCA8LSBsbShyaXNrcHJlbV9wb3J0Zm9saW9fQ0FQTSB+IHJpc2twcmVtX1NQWV9DQVBNLCBkYXRhPXF1ZXN0aW9uXzlfZGF0YV9QYXJ0MSkKI0V4LXBvc3QgZm9yZWNhc3QgCnByZWQgPC0gcHJlZGljdChyZWcsIG5ld2RhdGE9cXVlc3Rpb25fOV9kYXRhX1BhcnQyLCBzZS5maXQ9VFJVRSkgCnByZWQKCnBsb3Qocmlza3ByZW1fcG9ydGZvbGlvX0NBUE0sIHR5cGU9ImwiLCBjb2w9InJlZCIpCmxpbmVzKHJlZyRmaXR0ZWQudmFsdWVzLCBjb2w9ImJsdWUiKQoKYWNjdXJhY3kocmVnX2V4cG9zdCkKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgojUnVuIHRoZSByZWdyZXNzaW9uIGZvciBleC1hbnRlIGZvcmVjYXN0CgojRm9yIEV4LWFudGUgRm9yZWNhc3RpbmcgVXNlIGFsbCB0aGUgRGF0YSBpbiBTYW1wbGUgKGRhdGEpIGFuZCBydW4gdGhlIHJlZ3Jlc3Npb24KcmVnX2V4YW50ZSA8LSBsbShyaXNrcHJlbV9wb3J0Zm9saW9fQ0FQTSB+IHJpc2twcmVtX1NQWV9DQVBNLCBkYXRhPXF1ZXN0aW9uXzlfZGF0YV9GdWxscmFuZ2UpCiNCZWZvcmUgRm9yZWNhc3RpbmcgYWRkICJmb3JlY2FzdCIgdG8gdGhlIExpYnJhcnkgdGhlbiBGb3JlY2FzdApsaWJyYXJ5KCJmb3JlY2FzdCIpCmZvcmVfZXhhbnRlIDwtIGZvcmVjYXN0KHJlZ19leGFudGUsIG5ld2RhdGE9ZGF0YS5mcmFtZShxdWVzdGlvbl85X2RhdGFfRnVsbHJhbmdlKSwgc2UsZml0PVRSVUUpCmZvcmVfZXhhbnRlCmFjY3VyYWN5KHJlZ19leGFudGUpCnBsb3QoZm9yZV9leGFudGUsIHR5cGU9ImwiKQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKYGBgCgoKMTEuIERvIGEgTmHDr3ZlLCBNQTMsIE1BNSwgV01BNSwgYW5kIEVTIG9mIHRoZSByZXR1cm5zIHRvIHlvdXIgcG9ydGZvbGlvIGZvciB0aGUgcGVyaW9kIDEwLzMwLyAyMDE4IG9uLiBGaW5kIE1BRCwgTUFQRSwgTUFTRSBhbmQgUk1TIG9mIHlvdXIgZm9yZWNhc3RzLiBDb21wYXJlIHRoZSBmb3JlY2FzdGluZyBlZmZpY2llbmN5IGNyaXRlcmlvbiBvZiB5b3VyIENBUE0gd2l0aCBzbW9vdGhpbmcgdGVjaG5pcXVlcy4gV2hpY2ggb25lIHJlc3VsdHMgaW4gYSBiZXR0ZXIgZm9yZWNhc3Rpbmcgb3V0Y29tZT8KCmBgYHtyfQoKbGlicmFyeSgiZlBvcnRmb2xpbyIpCmxpYnJhcnkoInF1YW50bW9kIikKbGlicmFyeSgidGltZVNlcmllcyIpCmxpYnJhcnkoInRzZXJpZXMiKQpsaWJyYXJ5KCJzdGF0cyIpCgojSW1wb3J0IGRhaWx5IHN0b2NrIGFkaiBjbG9zaW5nIHByaWNlcyBmcm9tIHlhaG9vIApZYWhvb0RhdGFfRGFpbHkgPC0gZ2V0U3ltYm9scy55YWhvbyhjKCJBTVpOIiwiRkIiLCJQRyIsIkNPU1QiLCJDSSIsICJTUFkiLCAiXlROWCIpLC5HbG9iYWxFbnYsIGZyb20gPSAiMjAxOC0xMC0zMCIsIHRvPSBTeXMuRGF0ZSgpLCBwZXJpb2RpY2l0eT0iZGFpbHkiLCByZXR1cm4uY2xhc3MgPSAidGltZVNlcmllcyIpCgojQ2FsY3VsYXRlIERhaWx5IEFkanVzdGVkIFJldHVybnMgCiNOb3RlLCBzaW5jZSBkYXkgMSB5b3UgaGF2ZSAkMTAwLCBhbmQgaXQgaXNuJ3QgYWZmZWN0ZWQgYnkgdGhlIHJldHVybiBvZiB0aGUgcHJldmlvdXMgZGF5LCBsZWZ0IG91dCB0aGUgZmlyc3QgZGF5IG9mIHRoZSByZXR1cm5zIHdoZW4gaW1wb3J0aW5nIGRhdGEpCgpyQU1aTl9zbW9vdGhpbmcgPC0gZGlmZihsb2coQU1aTiRBTVpOLkFkanVzdGVkKSkgIApyRkJfc21vb3RoaW5nIDwtIGRpZmYobG9nKEZCJEZCLkFkanVzdGVkKSkKclBHX3Ntb290aGluZyA8LSBkaWZmKGxvZyhQRyRQRy5BZGp1c3RlZCkpCnJDT1NUX3Ntb290aGluZyA8LSBkaWZmKGxvZyhDT1NUJENPU1QuQWRqdXN0ZWQpKQpyQ0lfc21vb3RoaW5nIDwtIGRpZmYobG9nKENJJENJLkFkanVzdGVkKSkKclROWF9zbW9vdGhpbmcgPC0gVE5YJFROWC5BZGp1c3RlZC8xMDAvMTIKI292ZXJyaWRlIFROWCwgc3RhcnQgYXQgaW5kZXggdHdvIGFuZCBnbyBkb3duIGZyb20gdGhlcmUsIHJlbWVtYmVyIHdoZW4gY2FsY3VsYXRpbmcgcmV0dXJucyBmb3IgQUFQTCBpbiBleGNlbCB5b3UgZ290IHJpZCBvZiB0aGUgZmlyc3QgdmFsdWUsIHNhbWUgdGhpbmcgaGVyZQpyVE5YX3Ntb290aGluZyA8LSByVE5YWzI6bGVuZ3RoKHJUTlgpXQpyU1BZX3Ntb290aGluZyA8LSBkaWZmKGxvZyhTUFkkU1BZLkFkanVzdGVkKSkKKHJGX3Ntb290aGluZyA8LSByVE5YX3Ntb290aGluZykKCgojR2V0IGRhaWx5IHJldHVybnMgb2YgeW91ciBwb3J0Zm9saW8gZm9yIHRoaXMgZGF0ZSByYW5nZTogCgpyUF9zbW9vdGhpbmcgPC0gb3B0aW1hbHdlaWdodF9tYXRyaXhbMSwxXSpyQU1aTl9zbW9vdGhpbmcgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFsyLDFdKnJGQl9zbW9vdGhpbmcgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFszLDFdKnJQR19zbW9vdGhpbmcgKyBvcHRpbWFsd2VpZ2h0X21hdHJpeFs0LDFdKnJDT1NUX3Ntb290aGluZyArIG9wdGltYWx3ZWlnaHRfbWF0cml4WzUsMV0qckNJX3Ntb290aGluZwpyUF9zbW9vdGhpbmcKCiNOYWl2ZSBGb3JlY2FzdDogCmxpYnJhcnkoZm9yZWNhc3QpCk5haXZlX2ZvcmVjYXN0IDwtIHBsb3Qoc25haXZlKHJQX3Ntb290aGluZywyKSkKc25haXZlKHJQX3Ntb290aGluZywyKQphY2N1cmFjeShzbmFpdmUoclBfc21vb3RoaW5nLDIpKQoKI01BMyBGb3JlY2FzdCAKbGlicmFyeShmb3JlY2FzdCkKbWEzIDwtIG1hKHJQX3Ntb290aGluZywgb3JkZXI9MikKbWEzCnBsb3QoclBfc21vb3RoaW5nKQpsaW5lcyhtYShyUF9zbW9vdGhpbmcsIG9yZGVyPTIpLCBjb2w9InJlZCIpCiNEbyB3ZSBuZWVkIHRvIGRvIHRoaXMgd2F5IG9yIGhhcnNoJ3Mgd2F5PwphY2N1cmFjeShtYTMsIHJQX3Ntb290aGluZykKCiNNQTUgRm9yZWNhc3QgCgptYTUgPC0gbWEoclBfc21vb3RoaW5nLCBvcmRlcj01KQpwbG90KHJQX3Ntb290aGluZykKbGluZXMobWEoclBfc21vb3RoaW5nLCBvcmRlcj01KSwgY29sPSJyZWQiKQphY2N1cmFjeShtYTUsIHJQX3Ntb290aGluZykKCiNFUyAtIEV4cG9udGVudGlhbCBTbW9vdGhpbmcgCgojQWxwaGEgaXMgdGhlIGRhbXBlbmluaW5nIHBhcmFtZXRlcgpmaXQxIDwtIHNlcyhyUF9zbW9vdGhpbmcsIGFscGhhPTAuMiwgaW5pdGlhbD0ic2ltcGxlIiwgaD0zKQpmaXQyIDwtIHNlcyhyUF9zbW9vdGhpbmcsIGFscGhhPTAuNiwgaW5pdGlhbD0ic2ltcGxlIiwgaD0zKQpmaXQzIDwtIHNlcyhyUF9zbW9vdGhpbmcsIGg9MykKcGxvdChmaXQxLCBtYWluPSIiLCBmY29sPSJ3aGl0ZSIsIHR5cGU9Im8iKQpsaW5lcyhmaXR0ZWQoZml0MSksIGNvbD0iYmx1ZSIsIHR5cGU9Im8iKQpsaW5lcyhmaXR0ZWQoZml0MiksIGNvbD0icmVkIiwgdHlwZT0ibyIpCmxpbmVzKGZpdHRlZChmaXQzKSwgY29sPSJncmVlbiIsIHR5cGU9Im8iKQpsaW5lcyhmaXQxJG1lYW4sIGNvbD0iYmx1ZSIsIHR5cGU9Im8iKQpsaW5lcyhmaXQyJG1lYW4sIGNvbD0icmVkIiwgdHlwZT0ibyIpCmxpbmVzKGZpdDMkbWVhbiwgY29sPSJncmVlbiIsIHR5cGU9Im8iKQpsZWdlbmQoInRvcGxlZnQiLGx0eT0xLCBjb2w9YygxLCJibHVlIiwicmVkIiwiZ3JlZW4iKSwgCiAgICAgICBjKCJkYXRhIiwgZXhwcmVzc2lvbihhbHBoYSA9PSAwLjIpLCBleHByZXNzaW9uKGFscGhhID09IDAuNiksCiAgICAgICAgIGV4cHJlc3Npb24oYWxwaGEgPT0gMC44OSkpLHBjaD0xKQoKI0FjY3VyYWN5IE1lYXN1cmVzIHRvIGdldCBNQUQgTUFTRSwgZXRjLiAKYWNjdXJhY3koZml0MSkKYWNjdXJhY3koZml0MikKYWNjdXJhY3koZml0MykKCgojQ29tcGFyZSB0aGUgYWNjdXJhY3kgb2YgYWxsIHRoZSBmb3JlY2FzdGluZyBtb2RlbHMKCgojQ0FQTV9yZWdyZXNzaW9uIGVycm9yIAoKYWNjdXJhY3koQ0FQTV9yZWdyZXNzaW9uKQoKI0Vycm9yIGluIE5haXZlIEZvcmVjYXN0aW5nIE1vZGVsIApwcmludCgiTmFpdmUgRm9yZWNhc3RpbmcgTW9kZWwiKQphY2N1cmFjeShzbmFpdmUoclBfc21vb3RoaW5nLDMpKQoKCiNFcnJvciBpbiBNQTMgRm9yZWNhc3RpbmcgTW9kZWwKcHJpbnQoIk1BMyBGb3JlY2FzdGluZyBNb2RlbCIpCmFjY3VyYWN5KG1hMywgclBfc21vb3RoaW5nKQoKI0Vycm9yIGluIE1BNSBGb3JlY2FzdGluZyBNb2RlbCAKcHJpbnQoIk1BNSBGb3JlY2FzdGluZyBNb2RlbCIpCmFjY3VyYWN5KG1hNSwgclBfc21vb3RoaW5nKQoKI0Vycm9yIGluIEV4cG9uZW50aWFsIFNtb290aGluZyBGb3JlY2FzdCBNb2RlbCAKcHJpbnQoIkV4cG9uZW50aWFsIFNtb290aGluZyBGb3JlY2FzdCBNb2RlbCIpCmFjY3VyYWN5KGZpdDEpCmFjY3VyYWN5KGZpdDIpCmFjY3VyYWN5KGZpdDMpCgoKI2NhdCgiCiAgICAjIiwiVGhlIGZvcmVjYXN0aW5nIG1vZGVscyBoYXZlIGRpZmZlcmVudCBlcnJvciBsZXZlbHMuIEl0IGFwcGVhcnMgdGhhdCB0aGUgTUEzIG1vZGVsIGhhcyB0byBzbWFsbGVzdCBSTVNFIikKCgpgYGAKCgpgYGB7cn0KCiNDb21wYXJlIHRoZSBhY2N1cmFjeSBvZiBhbGwgdGhlIGZvcmVjYXN0aW5nIG1vZGVscwoKI0NBUE1fcmVncmVzc2lvbiBlcnJvciAKCnByaW50KCJDQVBNIE1vZGVsIikKYWNjdXJhY3koQ0FQTV9yZWdyZXNzaW9uKQoKI0NBUE0gRXgtcG9zdCBmb3JlY2FzdCBlcnJvcgoKYWNjdXJhY3kocmVnX2V4cG9zdCkKCiNFcnJvciBpbiBOYWl2ZSBGb3JlY2FzdGluZyBNb2RlbCAKcHJpbnQoIk5haXZlIEZvcmVjYXN0aW5nIE1vZGVsIikKYWNjdXJhY3koc25haXZlKHJQX3Ntb290aGluZywzKSkKCgojRXJyb3IgaW4gTUEzIEZvcmVjYXN0aW5nIE1vZGVsCnByaW50KCJNQTMgRm9yZWNhc3RpbmcgTW9kZWwiKQphY2N1cmFjeShtYTMsIHJQX3Ntb290aGluZykKCiNFcnJvciBpbiBNQTUgRm9yZWNhc3RpbmcgTW9kZWwgCnByaW50KCJNQTUgRm9yZWNhc3RpbmcgTW9kZWwiKQphY2N1cmFjeShtYTUsIHJQX3Ntb290aGluZykKCiNFcnJvciBpbiBFeHBvbmVudGlhbCBTbW9vdGhpbmcgRm9yZWNhc3QgTW9kZWwgCnByaW50KCJFeHBvbmVudGlhbCBTbW9vdGhpbmcgRm9yZWNhc3QgTW9kZWwiKQphY2N1cmFjeShmaXQxKQphY2N1cmFjeShmaXQyKQphY2N1cmFjeShmaXQzKQoKCiNjYXQoIgogICAgIyIsIlRoZSBmb3JlY2FzdGluZyBtb2RlbHMgaGF2ZSBkaWZmZXJlbnQgZXJyb3IgbGV2ZWxzLiBJdCBhcHBlYXJzIHRoYXQgdGhlIE1BMyBtb2RlbCBoYXMgdG8gc21hbGxlc3QgUk1TRSIpCgpgYGAKCgoKCgo=