Create a time-series matrix

Get stock price from Yahoo Finance

library(quantmod)
date.start <- 20000101
date.end <- 20170531
syb <- getSymbols(c("^GSPC", "GE", "BAC", 'VIAV',"XOM"),adjust = T, from = as.Date('2000-01-01'), to = as.Date('2017-05-31'))
SP500 <- GSPC
chartSeries(SP500[, 1:5])
chartSeries(GE[, 1:5])
chartSeries(BAC[, 1:5])
chartSeries(VIAV[, 1:5])
chartSeries(XOM[, 1:5])

Get bond yield data from FRED

# 1.2 Federal Reserve Economic Data (FRED) from the St. Louis Federal Reserve
#       Apply quantmod  function 
#           getSymbols( seriesname, src="FRED")
#
#             Returns historical data for any symbol at the website
#               http://research.stlouisfed.org/fred2/
#
# Series name | Description
# 
# DGS3MO      | 3-Month Treasury, constant maturity rate
# DGS1        | 1-Year Treasury, constant maturity rate
# DGS5        | 5-Year Treasury, constant maturity rate
# DGS10       | 10-Year Treasury, constant maturity rate
#
# DAAA        | Moody's Seasoned Aaa Corporate Bond Yield 
# DBAA        | Moody's Seasoned Baa Corporate Bond Yield 
#
# DCOILWTICO  | Crude Oil Prices: West Text Intermediate (WTI) - Cushing, Oklahoma

getSymbols("DGS3MO", src = "FRED")
getSymbols("DGS1", src="FRED")
getSymbols("DGS5", src="FRED")
getSymbols("DGS10", src="FRED")

getSymbols("DAAA", src="FRED")
getSymbols("DBAA", src="FRED")
getSymbols("DCOILWTICO", src="FRED")

Now merge the data of bond YTM

 # Important zoo functions
        # coredata() extracts or replaces core data
        # index() extracts or replaces the index of the object
fred.data0 <- merge(DGS3MO,
        DGS1,
        DGS5,
        DGS10,
        DAAA,
        DBAA,
        DCOILWTICO)['2000::2017-05']
apply(is.na(fred.data0), 2, sum)

library(ggfortify)
autoplot(fred.data0[, 1:6]) + ggtitle("FRED Data: Treasury Rates")
autoplot(fred.data0[, 1:6], facets = F) + ggtitle("FRED Data: Treasury Rates")
chartSeries(to.monthly(fred.data0[,"DCOILWTICO"]), main="FRED Data: Crude Oil (WTI)")
chartSeries(to.monthly(XOM[,1:5]))

Now merge the colsed price of stock

yahoo.data0 <- merge(
        BAC$BAC.Close,
        GE$GE.Close,
        VIAV$VIAV.Close,
        XOM$XOM.Close,
        SP500$GSPC.Close)
names(yahoo.data0) <- c("BAC", "GE", "VIAV", "XOM", "SP500")
# convert the data into zoo format
yahoo.data0.0 <- zoo(x = coredata(yahoo.data0), order.by = time(yahoo.data0))

now merge the fred data and stock data

casestudy1.data0 <- merge(yahoo.data0.0, fred.data0)
index.no <- which(is.na(coredata(casestudy1.data0$SP500))==FALSE)
CS1.0 <- casestudy1.data0[index.no,]

apply(is.na(CS1.0), 2, sum)
# Remaining missing values are for interest rates and the crude oil spot price
#   There are days when the stock market is open but the bond market and/or commodities market
#   is closed 
# For the rates and commodity data, replace NAs with previoius non-NA values

cs1.1 <- na.locf(CS1.0)
apply(is.na(cs1.1), 2, sum)

Save the Data

save(file = 'cs1_1.RData', list = ls())

After we collect the data, we can use cs1.1 to do regression analysis.

1 Linear Regression Models for Asset pricing

1.1 CAPM theory

Sharpe (1964) and Lintner (1965) developed the Capital Asset Priciing Model for a market in which investors have the same expectations, hold portfolios of risky assets that are mean-variance efficient, and can borrow and lend the money freely at the same risk-free rate. in such a market, the expected return of asset \(j\) is \[ E[R_j] = R_{riskfree} + {\beta}_j(E[R_{Market}] - R_{riskfree})\] \[{\beta}_j = \frac{Cov[R_j, R_{Market}]}{Var[R_{Market}]}\] where \(R_{market}\) is the return on the market portfolio and \(R_{riskfree}\) is the return on the risk-free asset.

Consider fitting the simple linear regression model of a stock’s daily excess return on the market-portfolio daily excess return, using the S&P500 Index as the proxy for the market return and the 3-month Treasury constant maturity rate as the risk-free rate. the linear model is given by: \[R_{j,t}^* = {\alpha}_j + {\beta}_jR_{Market,t}^* + {\epsilon}_{j,t} \ \ \ \ t = 1,2,...\] where \({\epsilon}_{j,t}\) are white noise:\(WN(0, {\sigma}^2)\).

1.2 Historical Financial Data

library(zoo)
library(quantmod)
library(graphics)
library(ggfortify)
library(knitr)
load(file = "/Users/Michael/Library/Mobile Documents/com~apple~CloudDocs/CMSE/R/Econometrics/cs1_1.RData")
head(cs1.1)

We first plot the raw data for the stock GE, the market-portfolio index SP500, and the risk-free interest rate.

autoplot(cs1.1[, "GE"]) + ylab("Price") + ggtitle("GE Stock") + xlab("Year")

autoplot(cs1.1[,"SP500"]) + ylab("Value") + xlab("Year") + ggtitle("S&P500 Index")

autoplot(cs1.1[, "DGS3MO"]) + ylab("Freerisk rate") + ggtitle("3-Month Treasury Rate")

Now we construct the variables with the log daily returns of GE and the SP500 index as well as the risk-free asset returns.

r.daily.GE <- zoo(x = as.matrix(diff(log(cs1.1[, "GE"]))), order.by = time(cs1.1[-1]))
dimnames(r.daily.GE)[[2]] <- "r.daily.GE"
r.daily.SP500 <- zoo(x = as.matrix(diff(log(cs1.1[, "SP500"]))), order.by = time(cs1.1[-1]))
dimnames(r.daily.SP500)[[2]] <- "r.daily.SP500"
r.daily.riskfree <- log(1+0.01*coredata(cs1.1[-1, "DGS3MO"])* diff(as.numeric(time(cs1.1)))/360)
dimnames(r.daily.riskfree)[[2]] <- "r.daily.riskfree"
# compute the difference 
r.daily.GE.0 <- r.daily.GE - r.daily.riskfree
dimnames(r.daily.GE.0)[[2]] <- "r.daily.GE.0"
r.daily.SP500.0 <- r.daily.SP500 - r.daily.riskfree
dimnames(r.daily.SP500.0)[[2]] <- "r.daily.SP500.0"
r.daily.data0 <- merge(
        r.daily.GE,
        r.daily.SP500,
        r.daily.riskfree,
        r.daily.GE.0,
        r.daily.SP500.0
)

Now we plot the excess returns of GE vs those of the SP500

plot(x = r.daily.data0$r.daily.SP500.0, y = r.daily.data0$r.daily.GE.0)

1.3 Fitting the linear Regression for CAPM

the linear regression model is fit using the R-function lm()

limfit0 <- lm(r.daily.GE.0 ~ r.daily.SP500.0, data = r.daily.data0)
summary(limfit0)

Call:
lm(formula = r.daily.GE.0 ~ r.daily.SP500.0, data = r.daily.data0)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.151232 -0.005252 -0.000344  0.004989  0.137031 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)     -0.0001405  0.0001917  -0.733    0.464    
r.daily.SP500.0  1.1667718  0.0155527  75.021   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.01268 on 4376 degrees of freedom
Multiple R-squared:  0.5626,    Adjusted R-squared:  0.5625 
F-statistic:  5628 on 1 and 4376 DF,  p-value: < 2.2e-16

Note that the t-statistic for the intercept is not significant.

1.4 Regression Diagnostics

some useful R functions

anova.lm() conduct an Analysis of Variance for the linear regression model, detailing the computation of the F-statistic for no regression structure.

influence.measures() compute the regression diagnostics evaluating case influence for the linear regression model; includes ‘hat’ matrix, case-deletion statistics for the regression coefficients and for the residual standard deviation.

limfit0.inflm <- influence.measures(limfit0)
head(limfit0.inflm$infmat)
head(limfit0.inflm$is.inf)

replot data adding fitted regression line

plot(r.daily.SP500.0, r.daily.GE.0, main = "GE vs SP500")
abline(h = 0, v = 0)
abline(limfit0, col = 3, lwd = 3)
index.inf.hat <- which(limfit0.inflm$is.inf[, "hat"] == T)
points(r.daily.SP500.0[index.inf.hat], r.daily.GE.0[index.inf.hat], col = 2, pch = "o")
index.inf.cook.d <- which(limfit0.inflm$is.inf[, "cook.d"] == T)
points(r.daily.SP500.0[index.inf.cook.d], r.daily.GE.0[index.inf.cook.d], col = 4, pch = "X", cex = 2)

The R function plot.lm() generates a useful 2x2 display of plots for various regression diagnostic statistics:

layout(matrix(c(1,2,3,4), 2,2))
plot(limfit0)

1.5 Adding Macro-economic Factors to CAPM

A stock’s return can also depend on macro-economic factors, such as commodity prices, interest rates, and economic growth (GDP).

r.daily.DCOI <- zoo(x = as.matrix(diff(log(cs1.1[, "DCOILWTICO"]))), order.by = time(cs1.1)[-1])
dimnames(r.daily.DCOI) [[2]] <- "r.daily.DCOIL"
r.daily.data0.0 <- merge(
        r.daily.data0,
        r.daily.DCOI
)
lmfit1 <- lm(r.daily.GE.0 ~ r.daily.SP500.0 + r.daily.DCOIL, data = r.daily.data0.0)
summary.lm(lmfit1)

the regression coefficient for the oil factor is statistically significant and negative. over the analysis period, price chagnes in GE stock are negatively related to he price changes in oil.

save(file = 'cs1_1.RData', list = ls())

Regression Analysis: Case Study 2

2.1 collect and tidy the data


library("quantmod")  
library("tseries")  
library("vars")  
library("fxregime")  
library("moments")  
library("rugarch") 

options(stringsAsFactors=FALSE)
fred.fxrates <- read.csv(
        file = "/Users/Michael/Library/Mobile Documents/com~apple~CloudDocs/CMSE/R/Econometrics/fred_fxrates.txt",
        header = TRUE,
        stringsAsFactors = FALSE,
        strip.white = T
)
dimnames(fred.fxrates)[[2]] <- "filename"
fred.fxrates.symbol0<-substring(fred.fxrates[,'filename'], first=1, last=7)

fred.fxrates.doc<-data.frame(symbol0=fred.fxrates.symbol0, fred.fxrates)
fred.fxrates.doc<-fred.fxrates.doc[1:23,]

# collect all symbol data

for(symbol0 in fred.fxrates.doc[,"symbol0"]) {
        # print(symbol0)
        getSymbols(symbol0, src = "FRED")
}

Merge all time sereis data and subset days when EUR/USD are availiable


# one way to merge together 
mergecommand0<-paste("merge(",
        paste(fred.fxrates.doc[,"symbol0"],collapse=","),
                     ")", collapse="")
fred.fxrates.0<-eval(parse(text=mergecommand0))

# another one to merge together 
fed.fx <- get(as.character(fred.fxrates.doc[1,1]))
for(symbol0 in fred.fxrates.doc [ , "symbol0"]) {
        fed.fx.3 <- get(as.character(symbol0))
        fed.fx <- merge(fed.fx, fed.fx.3)
}
fed.fx <- fed.fx[, c(1, 3:24)]

# Subset out only days when EURO is available 

fred.fxrates.00<-fred.fxrates.0[ is.na(fred.fxrates.0[,'DEXUSEU']) == FALSE,]

fed.fx.0 <- fed.fx[is.na(fed.fx[, "DEXUSEU"]) == FALSE, ]
fn <- "/Users/Michael/Library/Mobile Documents/com~apple~CloudDocs/CMSE/R/Econometrics/FXrates.csv"
write.zoo(fed.fx.0, sep = ",", file =fn)
save(file="cs1_2.Rdata", list=ls())

Regression Analysis Case Study 2

1.2 Exchange rate regimes for the Chinese Yuan

The Chinese Yuan was pegged to the US Dollar prior to July 2005. Then, China announced that the exchange rate would be set with reference to a basket of other currencies, allowing for a movement of up to 0.3% movement within any given day. Over the past decade, the government has gradually allowed the trading band to widen, starting at +/-0.3% and finally reaching +/-2% by March 2014.

From an empirical standpoint, there are several important questions:

  • For any given period, what is the implicit reference basket for the Chinese currency?
  • Has the reference basket changed over time?
  • Has the Chinese currency depreciated with respect to the dollar? if so, how much and when?

Frankel and Wei (1994) detail methodology for evaluating the implicit exchange rate regime of a currency. The approach regresses changes in the target currency on changes in the values of possible currencies in the reference market.

To apply this methodology we re-express the dollar-based exchange rates using another currency, the Swiss Franc. This allows currency moves of the dollar to be used to explain moves in the Yuan. The choice of Swiss Franc is consistent with evaluations with respect to a stable, developed-market currency.

1.3 Converting from USD Base to Swiss Franc Base

1.4 Linear Regression models of currency returns

Compute daily price changes on the log scale

fxrates.1.log <- diff(log(fxrates1))
par(mfcol=c(2,2))
for (cn2 in c(1:ncol(fxrates.1.log))) {
        plot(fxrates.1.log[, cn2], main = names(fxrates.1.log)[cn2])
}

First, we fit the regression model for the period prior to July 2005 when the Chinese currency was pegged to the US dollar.

lmfit.period1 <- lm(CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR,
        data = window(fxrates.1.log, start = as.Date("2001-01-01"), end = as.Date("2005-06-30")))
summary(lmfit.period1)

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR, 
    data = window(fxrates.1.log, start = as.Date("2001-01-01"), 
        end = as.Date("2005-06-30")))

Residuals:
       Min         1Q     Median         3Q        Max 
-1.086e-03 -1.136e-05  1.500e-07  1.103e-05  1.137e-03 

Coefficients:
              Estimate Std. Error  t value Pr(>|t|)    
(Intercept) -1.170e-07  2.486e-06   -0.047    0.962    
USD_SFR      1.000e+00  5.440e-04 1838.910   <2e-16 ***
YEN_SFR     -3.226e-04  4.712e-04   -0.685    0.494    
EUR_SFR     -5.396e-04  1.210e-03   -0.446    0.656    
GBP_SFR     -2.183e-05  7.075e-04   -0.031    0.975    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 8.354e-05 on 1126 degrees of freedom
Multiple R-squared:  0.9999,    Adjusted R-squared:  0.9999 
F-statistic: 1.894e+06 on 4 and 1126 DF,  p-value: < 2.2e-16

The regression fit identifies the pegging of the Yuan (CNR_SFR) to the US Dollar (USD_SFR). The R-Squared is nearly 1.0. Second, we fit the regression model for the first six months following the announcement of the change in currency policy.

lmfit.period2 <- lm(CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + WON_SFR + MYR_SFR + THB_SFR,
        data = window(fxrates.1.log, start = as.Date("2005-07-01"), end = as.Date("2005-12-31")))
summary(lmfit.period2)

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = window(fxrates.1.log, 
    start = as.Date("2005-07-01"), end = as.Date("2005-12-31")))

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0132690 -0.0004520  0.0000850  0.0005842  0.0032820 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.0001198  0.0001382  -0.867    0.387    
USD_SFR      0.1948616  0.1528495   1.275    0.205    
YEN_SFR     -0.0082667  0.0381872  -0.216    0.829    
EUR_SFR      0.0697740  0.0937341   0.744    0.458    
GBP_SFR     -0.0255185  0.0455883  -0.560    0.577    
WON_SFR      0.1785894  0.0362880   4.921 2.84e-06 ***
MYR_SFR      0.7526919  0.1471344   5.116 1.24e-06 ***
THB_SFR     -0.0693646  0.0609775  -1.138    0.258    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001522 on 117 degrees of freedom
Multiple R-squared:  0.9491,    Adjusted R-squared:  0.946 
F-statistic: 311.4 on 7 and 117 DF,  p-value: < 2.2e-16

During this six-month period, there is evidence of the Yuan departing from a US Dollar peg. The exchange rates with the statsitically significant regression parameters are for the Korean Won and the Malaysian Ringgit.

To examine for further changes in the implicit reference basket, we fit the same model for the annual periods from 2006 through 2012 and for the first 6 months of 2017.

library(xts)
fxrates.1.log.ts <- as.xts(fxrates.1.log)
for (year0 in as.character(c(2006:2017))) {
        # year0 <- "2012"
        lmfit.year0 <- lm(CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR
                + GBP_SFR + WON_SFR + MYR_SFR + THB_SFR, 
                data = fxrates.1.log.ts[year0])
        
        cat("\n\n --------------------------\n");
        cat(year0);
        cat(":\n")
        print(summary.lm(lmfit.year0))
        rate.appreciation.usd <- round(exp(252*log(1+lmfit.year0$coefficients[1]))-1, digits = 3)
        cat("\n");cat(year0);
        cat("\t Annualized apprediation rate to implied reference basket:", rate.appreciation.usd)
}


 --------------------------
2006:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-2.413e-03 -2.625e-04  5.131e-05  3.899e-04  2.504e-03 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.173e-04  4.228e-05  -2.773 0.005979 ** 
USD_SFR      9.222e-01  1.859e-02  49.614  < 2e-16 ***
YEN_SFR     -5.226e-03  1.121e-02  -0.466 0.641520    
EUR_SFR     -1.841e-02  2.927e-02  -0.629 0.529985    
GBP_SFR     -1.693e-02  1.695e-02  -0.999 0.318732    
WON_SFR      2.906e-02  1.201e-02   2.420 0.016245 *  
MYR_SFR      6.909e-02  1.904e-02   3.628 0.000348 ***
THB_SFR     -8.371e-03  1.100e-02  -0.761 0.447360    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0006512 on 243 degrees of freedom
Multiple R-squared:  0.9866,    Adjusted R-squared:  0.9862 
F-statistic:  2553 on 7 and 243 DF,  p-value: < 2.2e-16


2006     Annualized apprediation rate to implied reference basket: -0.029

 --------------------------
2007:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0043388 -0.0006900  0.0001165  0.0006523  0.0035492 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -2.477e-04  7.111e-05  -3.484 0.000585 ***
USD_SFR      9.201e-01  3.655e-02  25.172  < 2e-16 ***
YEN_SFR     -1.847e-02  1.774e-02  -1.041 0.298850    
EUR_SFR      1.629e-02  4.971e-02   0.328 0.743357    
GBP_SFR      4.861e-03  2.268e-02   0.214 0.830452    
WON_SFR      2.148e-02  2.709e-02   0.793 0.428514    
MYR_SFR      1.227e-02  2.907e-02   0.422 0.673389    
THB_SFR      1.411e-03  8.770e-03   0.161 0.872287    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001109 on 246 degrees of freedom
Multiple R-squared:  0.9332,    Adjusted R-squared:  0.9313 
F-statistic: 491.2 on 7 and 246 DF,  p-value: < 2.2e-16


2007     Annualized apprediation rate to implied reference basket: -0.061

 --------------------------
2008:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0103217 -0.0008105  0.0000162  0.0007503  0.0098093 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.0002996  0.0001222  -2.452  0.01492 *  
USD_SFR      0.9124811  0.0369556  24.691  < 2e-16 ***
YEN_SFR     -0.0010178  0.0173259  -0.059  0.95320    
EUR_SFR      0.0415111  0.0342314   1.213  0.22643    
GBP_SFR      0.0163507  0.0193508   0.845  0.39896    
WON_SFR     -0.0192298  0.0073131  -2.629  0.00909 ** 
MYR_SFR      0.0739607  0.0307166   2.408  0.01679 *  
THB_SFR      0.0114822  0.0208899   0.550  0.58306    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001906 on 244 degrees of freedom
Multiple R-squared:  0.9621,    Adjusted R-squared:  0.9611 
F-statistic: 885.8 on 7 and 244 DF,  p-value: < 2.2e-16


2008     Annualized apprediation rate to implied reference basket: -0.073

 --------------------------
2009:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-1.994e-03 -1.400e-04  1.770e-06  1.305e-04  1.221e-03 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  7.771e-06  2.176e-05   0.357 0.721273    
USD_SFR      9.405e-01  9.676e-03  97.201  < 2e-16 ***
YEN_SFR      5.974e-03  2.960e-03   2.018 0.044641 *  
EUR_SFR     -1.549e-02  6.958e-03  -2.227 0.026879 *  
GBP_SFR      4.148e-03  3.014e-03   1.376 0.170055    
WON_SFR     -1.672e-03  2.669e-03  -0.626 0.531606    
MYR_SFR      2.530e-02  6.950e-03   3.640 0.000333 ***
THB_SFR      3.102e-02  1.239e-02   2.504 0.012946 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0003438 on 244 degrees of freedom
Multiple R-squared:  0.9984,    Adjusted R-squared:  0.9983 
F-statistic: 2.165e+04 on 7 and 244 DF,  p-value: < 2.2e-16


2009     Annualized apprediation rate to implied reference basket: 0.002

 --------------------------
2010:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0051398 -0.0002402  0.0000951  0.0003745  0.0036134 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -9.527e-05  6.374e-05  -1.495   0.1363    
USD_SFR      9.116e-01  3.078e-02  29.613   <2e-16 ***
YEN_SFR      1.170e-03  1.048e-02   0.112   0.9112    
EUR_SFR      2.072e-02  1.441e-02   1.439   0.1516    
GBP_SFR     -3.160e-02  1.248e-02  -2.532   0.0120 *  
WON_SFR      2.656e-03  1.066e-02   0.249   0.8035    
MYR_SFR      2.359e-02  1.801e-02   1.310   0.1915    
THB_SFR      6.507e-02  3.372e-02   1.930   0.0548 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0009746 on 242 degrees of freedom
Multiple R-squared:  0.9805,    Adjusted R-squared:  0.9799 
F-statistic:  1739 on 7 and 242 DF,  p-value: < 2.2e-16


2010     Annualized apprediation rate to implied reference basket: -0.024

 --------------------------
2011:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0048725 -0.0005380  0.0000138  0.0005746  0.0061446 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.968e-04  8.079e-05  -2.436   0.0156 *  
USD_SFR      8.702e-01  2.834e-02  30.705  < 2e-16 ***
YEN_SFR      7.857e-03  1.519e-02   0.517   0.6054    
EUR_SFR     -3.959e-04  1.670e-02  -0.024   0.9811    
GBP_SFR      4.297e-02  2.092e-02   2.054   0.0410 *  
WON_SFR     -2.590e-02  1.696e-02  -1.527   0.1281    
MYR_SFR      9.535e-02  2.351e-02   4.056 6.73e-05 ***
THB_SFR      1.743e-02  3.329e-02   0.523   0.6011    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001275 on 243 degrees of freedom
Multiple R-squared:  0.9837,    Adjusted R-squared:  0.9832 
F-statistic:  2097 on 7 and 243 DF,  p-value: < 2.2e-16


2011     Annualized apprediation rate to implied reference basket: -0.048

 --------------------------
2012:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0042900 -0.0003965  0.0000060  0.0004424  0.0044475 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.951e-05  6.105e-05  -0.320   0.7495    
USD_SFR      9.064e-01  2.669e-02  33.957  < 2e-16 ***
YEN_SFR     -5.759e-03  1.323e-02  -0.435   0.6637    
EUR_SFR     -1.320e-01  5.985e-02  -2.205   0.0284 *  
GBP_SFR     -8.758e-03  2.132e-02  -0.411   0.6816    
WON_SFR      1.777e-03  2.282e-02   0.078   0.9380    
MYR_SFR      1.103e-01  2.216e-02   4.979 1.21e-06 ***
THB_SFR      1.895e-03  2.880e-02   0.066   0.9476    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0009568 on 243 degrees of freedom
Multiple R-squared:  0.9711,    Adjusted R-squared:  0.9702 
F-statistic:  1165 on 7 and 243 DF,  p-value: < 2.2e-16


2012     Annualized apprediation rate to implied reference basket: -0.005

 --------------------------
2013:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-2.481e-03 -3.231e-04  7.906e-05  3.651e-04  2.120e-03 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.180e-04  4.207e-05  -2.804 0.005451 ** 
USD_SFR      9.592e-01  1.449e-02  66.180  < 2e-16 ***
YEN_SFR      5.346e-03  6.989e-03   0.765 0.445113    
EUR_SFR      9.269e-03  1.979e-02   0.468 0.639953    
GBP_SFR      4.652e-03  1.165e-02   0.399 0.690109    
WON_SFR      4.186e-02  1.197e-02   3.498 0.000558 ***
MYR_SFR      3.817e-03  1.131e-02   0.338 0.735993    
THB_SFR     -2.935e-03  1.337e-02  -0.220 0.826367    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.0006573 on 243 degrees of freedom
Multiple R-squared:  0.9877,    Adjusted R-squared:  0.9873 
F-statistic:  2786 on 7 and 243 DF,  p-value: < 2.2e-16


2013     Annualized apprediation rate to implied reference basket: -0.029

 --------------------------
2014:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0044526 -0.0005935 -0.0000288  0.0004714  0.0048882 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  7.071e-05  7.669e-05   0.922    0.357    
USD_SFR      9.098e-01  3.687e-02  24.676  < 2e-16 ***
YEN_SFR      1.563e-02  1.941e-02   0.805    0.421    
EUR_SFR     -1.634e-02  7.117e-02  -0.230    0.819    
GBP_SFR      1.304e-02  2.665e-02   0.489    0.625    
WON_SFR     -2.206e-03  1.990e-02  -0.111    0.912    
MYR_SFR      1.019e-01  2.501e-02   4.075 6.25e-05 ***
THB_SFR     -2.070e-02  3.485e-02  -0.594    0.553    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001188 on 242 degrees of freedom
Multiple R-squared:  0.9257,    Adjusted R-squared:  0.9236 
F-statistic:   431 on 7 and 242 DF,  p-value: < 2.2e-16


2014     Annualized apprediation rate to implied reference basket: 0.018

 --------------------------
2015:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0062825 -0.0006603 -0.0001296  0.0004162  0.0167241 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.0001492  0.0001105   1.351  0.17795    
USD_SFR      0.9702366  0.0389356  24.919  < 2e-16 ***
YEN_SFR      0.0109606  0.0251084   0.437  0.66284    
EUR_SFR     -0.0142560  0.0205770  -0.693  0.48909    
GBP_SFR     -0.0259592  0.0255953  -1.014  0.31149    
WON_SFR      0.0681982  0.0218014   3.128  0.00197 ** 
MYR_SFR      0.0438288  0.0175764   2.494  0.01331 *  
THB_SFR     -0.0560714  0.0464097  -1.208  0.22815    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001729 on 243 degrees of freedom
Multiple R-squared:  0.9785,    Adjusted R-squared:  0.9779 
F-statistic:  1580 on 7 and 243 DF,  p-value: < 2.2e-16


2015     Annualized apprediation rate to implied reference basket: 0.038

 --------------------------
2016:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0100653 -0.0009281  0.0000832  0.0007611  0.0064512 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 0.0002326  0.0001018   2.283  0.02327 *  
USD_SFR     0.6683204  0.0383657  17.420  < 2e-16 ***
YEN_SFR     0.0324970  0.0162778   1.996  0.04701 *  
EUR_SFR     0.0731703  0.0421944   1.734  0.08416 .  
GBP_SFR     0.0399118  0.0153716   2.596  0.00999 ** 
WON_SFR     0.0372150  0.0223416   1.666  0.09706 .  
MYR_SFR     0.0668376  0.0219333   3.047  0.00256 ** 
THB_SFR     0.1148165  0.0493501   2.327  0.02081 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001606 on 243 degrees of freedom
Multiple R-squared:  0.8912,    Adjusted R-squared:  0.888 
F-statistic: 284.2 on 7 and 243 DF,  p-value: < 2.2e-16


2016     Annualized apprediation rate to implied reference basket: 0.06

 --------------------------
2017:

Call:
lm(formula = CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year0])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0052488 -0.0005666  0.0000554  0.0007079  0.0039820 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 4.343e-06  1.391e-04   0.031   0.9751    
USD_SFR     6.093e-01  8.589e-02   7.094 1.47e-10 ***
YEN_SFR     5.733e-02  3.131e-02   1.831   0.0699 .  
EUR_SFR     4.958e-02  5.994e-02   0.827   0.4100    
GBP_SFR     3.676e-02  3.084e-02   1.192   0.2359    
WON_SFR     5.467e-02  3.206e-02   1.705   0.0911 .  
MYR_SFR     7.191e-02  9.289e-02   0.774   0.4405    
THB_SFR     7.431e-02  7.799e-02   0.953   0.3428    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.001438 on 107 degrees of freedom
Multiple R-squared:  0.864, Adjusted R-squared:  0.8551 
F-statistic: 97.08 on 7 and 107 DF,  p-value: < 2.2e-16


2017     Annualized apprediation rate to implied reference basket: 0.001

Now we will illustrate some additional features of exchange rate regime modelling using the reference basket implied by the data for 2012.

First, we plot the currency returns for the Yuan and all currencies included in the analysis.

year1 <- "2012"
par(mfcol=c(1,1))
ts.plot(cumsum(fxrates.1.log.ts["2012"]), 
        col = rainbow(NCOL(fxrates.1.log.ts)),
        main = "2012 Currency Return"
        )
legend(x = 150, y =0.15, legend = dimnames(fxrates.1.log.ts)[[2]], lty = rep(1, times = ncol(fxrates.1.log.ts)), 
        col = rainbow(NCOL(fxrates.1.log.ts)),
        cex = 0.7)

Then we plot the currency return of the Yuan and that of the implied reference basket specified by the regression:

lmfit.year1 <- lm( CNY_SFR ~ USD_SFR + YEN_SFR + EUR_SFR + GBP_SFR + 
    WON_SFR + MYR_SFR + THB_SFR, data = fxrates.1.log.ts[year1])
y0.actual <- fxrates.1.log.ts["2012"][, "CNY_SFR"]
y0.fit <- y0.actual - lmfit.year1$residuals
ts.plot(cumsum(cbind(y0.actual, y0.fit)),
        col = rainbow(NCOL(fxrates.1.log.ts))[c(1,5)],
        main = "2012 Currency Returns \nCNY_SFR and Implied Basket")

Note how closely the reference basket tracks the Yuan. This is to be expected given the high R-squared of the regression.

Finally, we apply the R function inflence.measures()

layout(matrix(c(1,2,3,4),2,2))
plot(lmfit.year1)

These diagnostics indicates: the residuals appear well-behaved as they related to the size of the fitted values.

LS0tCnRpdGxlOiAiUmVncmVzc2lvbiBBbmFseXNpczogQ2FzZSBTdHVkeSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgQ3JlYXRlIGEgdGltZS1zZXJpZXMgbWF0cml4CgojIyMgR2V0IHN0b2NrIHByaWNlIGZyb20gWWFob28gRmluYW5jZSAKCmBgYHtyLCBldmFsPUZBTFNFfQpsaWJyYXJ5KHF1YW50bW9kKQpkYXRlLnN0YXJ0IDwtIDIwMDAwMTAxCmRhdGUuZW5kIDwtIDIwMTcwNTMxCnN5YiA8LSBnZXRTeW1ib2xzKGMoIl5HU1BDIiwgIkdFIiwgIkJBQyIsICdWSUFWJywiWE9NIiksYWRqdXN0ID0gVCwgZnJvbSA9IGFzLkRhdGUoJzIwMDAtMDEtMDEnKSwgdG8gPSBhcy5EYXRlKCcyMDE3LTA1LTMxJykpClNQNTAwIDwtIEdTUEMKY2hhcnRTZXJpZXMoU1A1MDBbLCAxOjVdKQpjaGFydFNlcmllcyhHRVssIDE6NV0pCmNoYXJ0U2VyaWVzKEJBQ1ssIDE6NV0pCmNoYXJ0U2VyaWVzKFZJQVZbLCAxOjVdKQpjaGFydFNlcmllcyhYT01bLCAxOjVdKQpgYGAKCiMjIyBHZXQgYm9uZCB5aWVsZCBkYXRhIGZyb20gRlJFRAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgMS4yIEZlZGVyYWwgUmVzZXJ2ZSBFY29ub21pYyBEYXRhIChGUkVEKSBmcm9tIHRoZSBTdC4gTG91aXMgRmVkZXJhbCBSZXNlcnZlCiMgICAgICAgQXBwbHkgcXVhbnRtb2QgIGZ1bmN0aW9uIAojICAgICAgICAgICBnZXRTeW1ib2xzKCBzZXJpZXNuYW1lLCBzcmM9IkZSRUQiKQojCiMgICAgICAgICAgICAgUmV0dXJucyBoaXN0b3JpY2FsIGRhdGEgZm9yIGFueSBzeW1ib2wgYXQgdGhlIHdlYnNpdGUKIyAgICAgICAgICAgICAgIGh0dHA6Ly9yZXNlYXJjaC5zdGxvdWlzZmVkLm9yZy9mcmVkMi8KIwojIFNlcmllcyBuYW1lIHwgRGVzY3JpcHRpb24KIyAKIyBER1MzTU8gICAgICB8IDMtTW9udGggVHJlYXN1cnksIGNvbnN0YW50IG1hdHVyaXR5IHJhdGUKIyBER1MxICAgICAgICB8IDEtWWVhciBUcmVhc3VyeSwgY29uc3RhbnQgbWF0dXJpdHkgcmF0ZQojIERHUzUgICAgICAgIHwgNS1ZZWFyIFRyZWFzdXJ5LCBjb25zdGFudCBtYXR1cml0eSByYXRlCiMgREdTMTAgICAgICAgfCAxMC1ZZWFyIFRyZWFzdXJ5LCBjb25zdGFudCBtYXR1cml0eSByYXRlCiMKIyBEQUFBICAgICAgICB8IE1vb2R5J3MgU2Vhc29uZWQgQWFhIENvcnBvcmF0ZSBCb25kIFlpZWxkIAojIERCQUEgICAgICAgIHwgTW9vZHkncyBTZWFzb25lZCBCYWEgQ29ycG9yYXRlIEJvbmQgWWllbGQgCiMKIyBEQ09JTFdUSUNPICB8IENydWRlIE9pbCBQcmljZXM6IFdlc3QgVGV4dCBJbnRlcm1lZGlhdGUgKFdUSSkgLSBDdXNoaW5nLCBPa2xhaG9tYQoKZ2V0U3ltYm9scygiREdTM01PIiwgc3JjID0gIkZSRUQiKQpnZXRTeW1ib2xzKCJER1MxIiwgc3JjPSJGUkVEIikKZ2V0U3ltYm9scygiREdTNSIsIHNyYz0iRlJFRCIpCmdldFN5bWJvbHMoIkRHUzEwIiwgc3JjPSJGUkVEIikKCmdldFN5bWJvbHMoIkRBQUEiLCBzcmM9IkZSRUQiKQpnZXRTeW1ib2xzKCJEQkFBIiwgc3JjPSJGUkVEIikKZ2V0U3ltYm9scygiRENPSUxXVElDTyIsIHNyYz0iRlJFRCIpCmBgYAoKIyMjIE5vdyBtZXJnZSB0aGUgZGF0YSBvZiBib25kIFlUTQoKYGBge3IsIGV2YWw9RkFMU0V9CiAjIEltcG9ydGFudCB6b28gZnVuY3Rpb25zCiAgICAgICAgIyBjb3JlZGF0YSgpIGV4dHJhY3RzIG9yIHJlcGxhY2VzIGNvcmUgZGF0YQogICAgICAgICMgaW5kZXgoKSBleHRyYWN0cyBvciByZXBsYWNlcyB0aGUgaW5kZXggb2YgdGhlIG9iamVjdApmcmVkLmRhdGEwIDwtIG1lcmdlKERHUzNNTywKICAgICAgICBER1MxLAogICAgICAgIERHUzUsCiAgICAgICAgREdTMTAsCiAgICAgICAgREFBQSwKICAgICAgICBEQkFBLAogICAgICAgIERDT0lMV1RJQ08pWycyMDAwOjoyMDE3LTA1J10KYXBwbHkoaXMubmEoZnJlZC5kYXRhMCksIDIsIHN1bSkKCmxpYnJhcnkoZ2dmb3J0aWZ5KQphdXRvcGxvdChmcmVkLmRhdGEwWywgMTo2XSkgKyBnZ3RpdGxlKCJGUkVEIERhdGE6IFRyZWFzdXJ5IFJhdGVzIikKYXV0b3Bsb3QoZnJlZC5kYXRhMFssIDE6Nl0sIGZhY2V0cyA9IEYpICsgZ2d0aXRsZSgiRlJFRCBEYXRhOiBUcmVhc3VyeSBSYXRlcyIpCmNoYXJ0U2VyaWVzKHRvLm1vbnRobHkoZnJlZC5kYXRhMFssIkRDT0lMV1RJQ08iXSksIG1haW49IkZSRUQgRGF0YTogQ3J1ZGUgT2lsIChXVEkpIikKY2hhcnRTZXJpZXModG8ubW9udGhseShYT01bLDE6NV0pKQpgYGAKCiMjIyBOb3cgbWVyZ2UgdGhlIGNvbHNlZCBwcmljZSBvZiBzdG9jayAKCmBgYHtyLCBldmFsPUZBTFNFfQp5YWhvby5kYXRhMCA8LSBtZXJnZSgKICAgICAgICBCQUMkQkFDLkNsb3NlLAogICAgICAgIEdFJEdFLkNsb3NlLAogICAgICAgIFZJQVYkVklBVi5DbG9zZSwKICAgICAgICBYT00kWE9NLkNsb3NlLAogICAgICAgIFNQNTAwJEdTUEMuQ2xvc2UpCm5hbWVzKHlhaG9vLmRhdGEwKSA8LSBjKCJCQUMiLCAiR0UiLCAiVklBViIsICJYT00iLCAiU1A1MDAiKQojIGNvbnZlcnQgdGhlIGRhdGEgaW50byB6b28gZm9ybWF0CnlhaG9vLmRhdGEwLjAgPC0gem9vKHggPSBjb3JlZGF0YSh5YWhvby5kYXRhMCksIG9yZGVyLmJ5ID0gdGltZSh5YWhvby5kYXRhMCkpCmBgYAoKIyMjIG5vdyBtZXJnZSB0aGUgZnJlZCBkYXRhIGFuZCBzdG9jayBkYXRhCgpgYGB7ciwgZXZhbD1GQUxTRX0KY2FzZXN0dWR5MS5kYXRhMCA8LSBtZXJnZSh5YWhvby5kYXRhMC4wLCBmcmVkLmRhdGEwKQppbmRleC5ubyA8LSB3aGljaChpcy5uYShjb3JlZGF0YShjYXNlc3R1ZHkxLmRhdGEwJFNQNTAwKSk9PUZBTFNFKQpDUzEuMCA8LSBjYXNlc3R1ZHkxLmRhdGEwW2luZGV4Lm5vLF0KCmFwcGx5KGlzLm5hKENTMS4wKSwgMiwgc3VtKQojIFJlbWFpbmluZyBtaXNzaW5nIHZhbHVlcyBhcmUgZm9yIGludGVyZXN0IHJhdGVzIGFuZCB0aGUgY3J1ZGUgb2lsIHNwb3QgcHJpY2UKIyAgIFRoZXJlIGFyZSBkYXlzIHdoZW4gdGhlIHN0b2NrIG1hcmtldCBpcyBvcGVuIGJ1dCB0aGUgYm9uZCBtYXJrZXQgYW5kL29yIGNvbW1vZGl0aWVzIG1hcmtldAojICAgaXMgY2xvc2VkIAojIEZvciB0aGUgcmF0ZXMgYW5kIGNvbW1vZGl0eSBkYXRhLCByZXBsYWNlIE5BcyB3aXRoIHByZXZpb2l1cyBub24tTkEgdmFsdWVzCgpjczEuMSA8LSBuYS5sb2NmKENTMS4wKQphcHBseShpcy5uYShjczEuMSksIDIsIHN1bSkKYGBgCgojIyMgU2F2ZSB0aGUgRGF0YSAKCmBgYHtyLCBldmFsPUZBTFNFfQpzYXZlKGZpbGUgPSAnY3MxXzEuUkRhdGEnLCBsaXN0ID0gbHMoKSkKYGBgCgpBZnRlciB3ZSBjb2xsZWN0IHRoZSBkYXRhLCB3ZSBjYW4gdXNlIGNzMS4xIHRvIGRvIHJlZ3Jlc3Npb24gYW5hbHlzaXMuCgojIyAxIExpbmVhciBSZWdyZXNzaW9uIE1vZGVscyBmb3IgQXNzZXQgcHJpY2luZyAKCiMjIzEuMSBDQVBNIHRoZW9yeSAKClNoYXJwZSAoMTk2NCkgYW5kIExpbnRuZXIgKDE5NjUpIGRldmVsb3BlZCB0aGUgQ2FwaXRhbCBBc3NldCBQcmljaWluZyBNb2RlbCBmb3IgYSBtYXJrZXQgaW4gd2hpY2ggaW52ZXN0b3JzIGhhdmUgdGhlIHNhbWUgZXhwZWN0YXRpb25zLCBob2xkIHBvcnRmb2xpb3Mgb2Ygcmlza3kgYXNzZXRzIHRoYXQgYXJlIG1lYW4tdmFyaWFuY2UgZWZmaWNpZW50LCBhbmQgY2FuIGJvcnJvdyBhbmQgbGVuZCB0aGUgbW9uZXkgZnJlZWx5IGF0IHRoZSBzYW1lIHJpc2stZnJlZSByYXRlLiBpbiBzdWNoIGEgbWFya2V0LCB0aGUgZXhwZWN0ZWQgcmV0dXJuIG9mIGFzc2V0ICRqJCBpcyAKJCQgRVtSX2pdID0gUl97cmlza2ZyZWV9ICsge1xiZXRhfV9qKEVbUl97TWFya2V0fV0gLSBSX3tyaXNrZnJlZX0pJCQKJCR7XGJldGF9X2ogPSBcZnJhY3tDb3ZbUl9qLCBSX3tNYXJrZXR9XX17VmFyW1Jfe01hcmtldH1dfSQkCndoZXJlICRSX3ttYXJrZXR9JCBpcyB0aGUgcmV0dXJuIG9uIHRoZSBtYXJrZXQgcG9ydGZvbGlvIGFuZCAkUl97cmlza2ZyZWV9JCBpcyB0aGUgcmV0dXJuIG9uIHRoZSByaXNrLWZyZWUgYXNzZXQuIAoKQ29uc2lkZXIgZml0dGluZyB0aGUgc2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIG9mIGEgc3RvY2sncyBkYWlseSBleGNlc3MgcmV0dXJuIG9uIHRoZSBtYXJrZXQtcG9ydGZvbGlvIGRhaWx5IGV4Y2VzcyByZXR1cm4sIHVzaW5nIHRoZSBTJlA1MDAgSW5kZXggYXMgdGhlIHByb3h5IGZvciB0aGUgbWFya2V0IHJldHVybiBhbmQgdGhlIDMtbW9udGggVHJlYXN1cnkgY29uc3RhbnQgbWF0dXJpdHkgcmF0ZSBhcyB0aGUgcmlzay1mcmVlIHJhdGUuIHRoZSBsaW5lYXIgbW9kZWwgaXMgZ2l2ZW4gYnk6IAokJFJfe2osdH1eKiA9IHtcYWxwaGF9X2ogKyB7XGJldGF9X2pSX3tNYXJrZXQsdH1eKiArIHtcZXBzaWxvbn1fe2osdH0gICAgICAgICBcIFwgXCBcIHQgPSAxLDIsLi4uJCQKd2hlcmUgJHtcZXBzaWxvbn1fe2osdH0kIGFyZSB3aGl0ZSBub2lzZTokV04oMCwge1xzaWdtYX1eMikkLgoKIyMjMS4yIEhpc3RvcmljYWwgRmluYW5jaWFsIERhdGEgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0V9CmxpYnJhcnkoem9vKQpsaWJyYXJ5KHF1YW50bW9kKQpsaWJyYXJ5KGdyYXBoaWNzKQpsaWJyYXJ5KGdnZm9ydGlmeSkKbGlicmFyeShrbml0cikKbG9hZChmaWxlID0gIi9Vc2Vycy9NaWNoYWVsL0xpYnJhcnkvTW9iaWxlIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL0NNU0UvUi9FY29ub21ldHJpY3MvY3MxXzEuUkRhdGEiKQpoZWFkKGNzMS4xKQpgYGAKCldlIGZpcnN0IHBsb3QgdGhlIHJhdyBkYXRhIGZvciB0aGUgc3RvY2sgR0UsIHRoZSBtYXJrZXQtcG9ydGZvbGlvIGluZGV4IFNQNTAwLCBhbmQgdGhlIHJpc2stZnJlZSBpbnRlcmVzdCByYXRlLiAKCmBgYHtyfQphdXRvcGxvdChjczEuMVssICJHRSJdKSArIHlsYWIoIlByaWNlIikgKyBnZ3RpdGxlKCJHRSBTdG9jayIpICsgeGxhYigiWWVhciIpCmF1dG9wbG90KGNzMS4xWywiU1A1MDAiXSkgKyB5bGFiKCJWYWx1ZSIpICsgeGxhYigiWWVhciIpICsgZ2d0aXRsZSgiUyZQNTAwIEluZGV4IikKYXV0b3Bsb3QoY3MxLjFbLCAiREdTM01PIl0pICsgeWxhYigiRnJlZXJpc2sgcmF0ZSIpICsgZ2d0aXRsZSgiMy1Nb250aCBUcmVhc3VyeSBSYXRlIikKYGBgCgpOb3cgd2UgY29uc3RydWN0IHRoZSB2YXJpYWJsZXMgd2l0aCB0aGUgbG9nIGRhaWx5IHJldHVybnMgb2YgR0UgYW5kIHRoZSBTUDUwMCBpbmRleCBhcyB3ZWxsIGFzIHRoZSByaXNrLWZyZWUgYXNzZXQgcmV0dXJucy4gCgpgYGB7cn0Kci5kYWlseS5HRSA8LSB6b28oeCA9IGFzLm1hdHJpeChkaWZmKGxvZyhjczEuMVssICJHRSJdKSkpLCBvcmRlci5ieSA9IHRpbWUoY3MxLjFbLTFdKSkKZGltbmFtZXMoci5kYWlseS5HRSlbWzJdXSA8LSAici5kYWlseS5HRSIKci5kYWlseS5TUDUwMCA8LSB6b28oeCA9IGFzLm1hdHJpeChkaWZmKGxvZyhjczEuMVssICJTUDUwMCJdKSkpLCBvcmRlci5ieSA9IHRpbWUoY3MxLjFbLTFdKSkKZGltbmFtZXMoci5kYWlseS5TUDUwMClbWzJdXSA8LSAici5kYWlseS5TUDUwMCIKci5kYWlseS5yaXNrZnJlZSA8LSBsb2coMSswLjAxKmNvcmVkYXRhKGNzMS4xWy0xLCAiREdTM01PIl0pKiBkaWZmKGFzLm51bWVyaWModGltZShjczEuMSkpKS8zNjApCmRpbW5hbWVzKHIuZGFpbHkucmlza2ZyZWUpW1syXV0gPC0gInIuZGFpbHkucmlza2ZyZWUiCiMgY29tcHV0ZSB0aGUgZGlmZmVyZW5jZSAKCnIuZGFpbHkuR0UuMCA8LSByLmRhaWx5LkdFIC0gci5kYWlseS5yaXNrZnJlZQpkaW1uYW1lcyhyLmRhaWx5LkdFLjApW1syXV0gPC0gInIuZGFpbHkuR0UuMCIKci5kYWlseS5TUDUwMC4wIDwtIHIuZGFpbHkuU1A1MDAgLSByLmRhaWx5LnJpc2tmcmVlCmRpbW5hbWVzKHIuZGFpbHkuU1A1MDAuMClbWzJdXSA8LSAici5kYWlseS5TUDUwMC4wIgpyLmRhaWx5LmRhdGEwIDwtIG1lcmdlKAogICAgICAgIHIuZGFpbHkuR0UsCiAgICAgICAgci5kYWlseS5TUDUwMCwKICAgICAgICByLmRhaWx5LnJpc2tmcmVlLAogICAgICAgIHIuZGFpbHkuR0UuMCwKICAgICAgICByLmRhaWx5LlNQNTAwLjAKKQpgYGAKCk5vdyB3ZSBwbG90IHRoZSBleGNlc3MgcmV0dXJucyBvZiBHRSB2cyB0aG9zZSBvZiB0aGUgU1A1MDAKCmBgYHtyfQpwbG90KHggPSByLmRhaWx5LmRhdGEwJHIuZGFpbHkuU1A1MDAuMCwgeSA9IHIuZGFpbHkuZGF0YTAkci5kYWlseS5HRS4wKQpgYGAKCiMjIyAxLjMgRml0dGluZyB0aGUgbGluZWFyIFJlZ3Jlc3Npb24gZm9yIENBUE0KCnRoZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCBpcyBmaXQgdXNpbmcgdGhlIFItZnVuY3Rpb24gbG0oKQoKYGBge3J9CmxpbWZpdDAgPC0gbG0oci5kYWlseS5HRS4wIH4gci5kYWlseS5TUDUwMC4wLCBkYXRhID0gci5kYWlseS5kYXRhMCkKc3VtbWFyeShsaW1maXQwKQpgYGAKCk5vdGUgdGhhdCB0aGUgdC1zdGF0aXN0aWMgZm9yIHRoZSBpbnRlcmNlcHQgaXMgbm90IHNpZ25pZmljYW50LiAKCiMjIyAxLjQgUmVncmVzc2lvbiBEaWFnbm9zdGljcwoKc29tZSB1c2VmdWwgUiBmdW5jdGlvbnMKCmBhbm92YS5sbSgpYCBjb25kdWN0IGFuIEFuYWx5c2lzIG9mIFZhcmlhbmNlIGZvciB0aGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwsIGRldGFpbGluZyB0aGUgY29tcHV0YXRpb24gb2YgdGhlIEYtc3RhdGlzdGljIGZvciBubyByZWdyZXNzaW9uIHN0cnVjdHVyZS4gCgpgaW5mbHVlbmNlLm1lYXN1cmVzKClgIGNvbXB1dGUgdGhlIHJlZ3Jlc3Npb24gZGlhZ25vc3RpY3MgZXZhbHVhdGluZyBjYXNlIGluZmx1ZW5jZSBmb3IgdGhlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsOyBpbmNsdWRlcyAnaGF0JyBtYXRyaXgsIGNhc2UtZGVsZXRpb24gc3RhdGlzdGljcyBmb3IgdGhlIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGFuZCBmb3IgdGhlIHJlc2lkdWFsIHN0YW5kYXJkIGRldmlhdGlvbi4gCgpgYGB7cn0KbGltZml0MC5pbmZsbSA8LSBpbmZsdWVuY2UubWVhc3VyZXMobGltZml0MCkKaGVhZChsaW1maXQwLmluZmxtJGluZm1hdCkKaGVhZChsaW1maXQwLmluZmxtJGlzLmluZikKYGBgCgpyZXBsb3QgZGF0YSBhZGRpbmcgZml0dGVkIHJlZ3Jlc3Npb24gbGluZSAKCmBgYHtyfQpwbG90KHIuZGFpbHkuU1A1MDAuMCwgci5kYWlseS5HRS4wLCBtYWluID0gIkdFIHZzIFNQNTAwIikKYWJsaW5lKGggPSAwLCB2ID0gMCkKYWJsaW5lKGxpbWZpdDAsIGNvbCA9IDMsIGx3ZCA9IDMpCmluZGV4LmluZi5oYXQgPC0gd2hpY2gobGltZml0MC5pbmZsbSRpcy5pbmZbLCAiaGF0Il0gPT0gVCkKcG9pbnRzKHIuZGFpbHkuU1A1MDAuMFtpbmRleC5pbmYuaGF0XSwgci5kYWlseS5HRS4wW2luZGV4LmluZi5oYXRdLCBjb2wgPSAyLCBwY2ggPSAibyIpCmluZGV4LmluZi5jb29rLmQgPC0gd2hpY2gobGltZml0MC5pbmZsbSRpcy5pbmZbLCAiY29vay5kIl0gPT0gVCkKcG9pbnRzKHIuZGFpbHkuU1A1MDAuMFtpbmRleC5pbmYuY29vay5kXSwgci5kYWlseS5HRS4wW2luZGV4LmluZi5jb29rLmRdLCBjb2wgPSA0LCBwY2ggPSAiWCIsIGNleCA9IDIpCgpgYGAKClRoZSBSIGZ1bmN0aW9uIHBsb3QubG0oKSBnZW5lcmF0ZXMgYSB1c2VmdWwgMngyIGRpc3BsYXkgb2YgcGxvdHMgZm9yIHZhcmlvdXMgcmVncmVzc2lvbiBkaWFnbm9zdGljIHN0YXRpc3RpY3M6IAoKYGBge3J9CmxheW91dChtYXRyaXgoYygxLDIsMyw0KSwgMiwyKSkKcGxvdChsaW1maXQwKQpgYGAKCgojIyMgMS41IEFkZGluZyBNYWNyby1lY29ub21pYyBGYWN0b3JzIHRvIENBUE0gCgpBIHN0b2NrJ3MgcmV0dXJuIGNhbiBhbHNvIGRlcGVuZCBvbiBtYWNyby1lY29ub21pYyBmYWN0b3JzLCBzdWNoIGFzIGNvbW1vZGl0eSBwcmljZXMsIGludGVyZXN0IHJhdGVzLCBhbmQgZWNvbm9taWMgZ3Jvd3RoIChHRFApLiAKCmBgYHtyfQpyLmRhaWx5LkRDT0kgPC0gem9vKHggPSBhcy5tYXRyaXgoZGlmZihsb2coY3MxLjFbLCAiRENPSUxXVElDTyJdKSkpLCBvcmRlci5ieSA9IHRpbWUoY3MxLjEpWy0xXSkKZGltbmFtZXMoci5kYWlseS5EQ09JKSBbWzJdXSA8LSAici5kYWlseS5EQ09JTCIKci5kYWlseS5kYXRhMC4wIDwtIG1lcmdlKAogICAgICAgIHIuZGFpbHkuZGF0YTAsCiAgICAgICAgci5kYWlseS5EQ09JCikKbG1maXQxIDwtIGxtKHIuZGFpbHkuR0UuMCB+IHIuZGFpbHkuU1A1MDAuMCArIHIuZGFpbHkuRENPSUwsIGRhdGEgPSByLmRhaWx5LmRhdGEwLjApCnN1bW1hcnkubG0obG1maXQxKQpgYGAKCnRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50IGZvciB0aGUgb2lsIGZhY3RvciBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGFuZCBuZWdhdGl2ZS4gb3ZlciB0aGUgYW5hbHlzaXMgcGVyaW9kLCBwcmljZSBjaGFnbmVzIGluIEdFIHN0b2NrIGFyZSBuZWdhdGl2ZWx5IHJlbGF0ZWQgdG8gaGUgcHJpY2UgY2hhbmdlcyBpbiBvaWwuIAoKYGBge3J9CnNhdmUoZmlsZSA9ICdjczFfMS5SRGF0YScsIGxpc3QgPSBscygpKQpgYGAKCiMjIFJlZ3Jlc3Npb24gQW5hbHlzaXM6IENhc2UgU3R1ZHkgMiAKCiMjIyAyLjEgY29sbGVjdCBhbmQgdGlkeSB0aGUgZGF0YSAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQoKbGlicmFyeSgicXVhbnRtb2QiKSAgCmxpYnJhcnkoInRzZXJpZXMiKSAgCmxpYnJhcnkoInZhcnMiKSAgCmxpYnJhcnkoImZ4cmVnaW1lIikgIApsaWJyYXJ5KCJtb21lbnRzIikgIApsaWJyYXJ5KCJydWdhcmNoIikgCgpvcHRpb25zKHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpCmZyZWQuZnhyYXRlcyA8LSByZWFkLmNzdigKICAgICAgICBmaWxlID0gIi9Vc2Vycy9NaWNoYWVsL0xpYnJhcnkvTW9iaWxlIERvY3VtZW50cy9jb21+YXBwbGV+Q2xvdWREb2NzL0NNU0UvUi9FY29ub21ldHJpY3MvZnJlZF9meHJhdGVzLnR4dCIsCiAgICAgICAgaGVhZGVyID0gVFJVRSwKICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UsCiAgICAgICAgc3RyaXAud2hpdGUgPSBUCikKZGltbmFtZXMoZnJlZC5meHJhdGVzKVtbMl1dIDwtICJmaWxlbmFtZSIKZnJlZC5meHJhdGVzLnN5bWJvbDA8LXN1YnN0cmluZyhmcmVkLmZ4cmF0ZXNbLCdmaWxlbmFtZSddLCBmaXJzdD0xLCBsYXN0PTcpCgpmcmVkLmZ4cmF0ZXMuZG9jPC1kYXRhLmZyYW1lKHN5bWJvbDA9ZnJlZC5meHJhdGVzLnN5bWJvbDAsIGZyZWQuZnhyYXRlcykKZnJlZC5meHJhdGVzLmRvYzwtZnJlZC5meHJhdGVzLmRvY1sxOjIzLF0KCiMgY29sbGVjdCBhbGwgc3ltYm9sIGRhdGEKCmZvcihzeW1ib2wwIGluIGZyZWQuZnhyYXRlcy5kb2NbLCJzeW1ib2wwIl0pIHsKICAgICAgICAjIHByaW50KHN5bWJvbDApCiAgICAgICAgZ2V0U3ltYm9scyhzeW1ib2wwLCBzcmMgPSAiRlJFRCIpCn0KYGBgCgojIyMgTWVyZ2UgYWxsIHRpbWUgc2VyZWlzIGRhdGEgYW5kIHN1YnNldCBkYXlzIHdoZW4gRVVSL1VTRCBhcmUgYXZhaWxpYWJsZQoKYGBge3J9CgojIG9uZSB3YXkgdG8gbWVyZ2UgdG9nZXRoZXIgCm1lcmdlY29tbWFuZDA8LXBhc3RlKCJtZXJnZSgiLAogICAgICAgIHBhc3RlKGZyZWQuZnhyYXRlcy5kb2NbLCJzeW1ib2wwIl0sY29sbGFwc2U9IiwiKSwKICAgICAgICAgICAgICAgICAgICAgIikiLCBjb2xsYXBzZT0iIikKZnJlZC5meHJhdGVzLjA8LWV2YWwocGFyc2UodGV4dD1tZXJnZWNvbW1hbmQwKSkKCiMgYW5vdGhlciBvbmUgdG8gbWVyZ2UgdG9nZXRoZXIgCmZlZC5meCA8LSBnZXQoYXMuY2hhcmFjdGVyKGZyZWQuZnhyYXRlcy5kb2NbMSwxXSkpCmZvcihzeW1ib2wwIGluIGZyZWQuZnhyYXRlcy5kb2MgWyAsICJzeW1ib2wwIl0pIHsKICAgICAgICBmZWQuZnguMyA8LSBnZXQoYXMuY2hhcmFjdGVyKHN5bWJvbDApKQogICAgICAgIGZlZC5meCA8LSBtZXJnZShmZWQuZngsIGZlZC5meC4zKQp9CmZlZC5meCA8LSBmZWQuZnhbLCBjKDEsIDM6MjQpXQoKIyBTdWJzZXQgb3V0IG9ubHkgZGF5cyB3aGVuIEVVUk8gaXMgYXZhaWxhYmxlIAoKZnJlZC5meHJhdGVzLjAwPC1mcmVkLmZ4cmF0ZXMuMFsgaXMubmEoZnJlZC5meHJhdGVzLjBbLCdERVhVU0VVJ10pID09IEZBTFNFLF0KCmZlZC5meC4wIDwtIGZlZC5meFtpcy5uYShmZWQuZnhbLCAiREVYVVNFVSJdKSA9PSBGQUxTRSwgXQpmbiA8LSAiL1VzZXJzL01pY2hhZWwvTGlicmFyeS9Nb2JpbGUgRG9jdW1lbnRzL2NvbX5hcHBsZX5DbG91ZERvY3MvQ01TRS9SL0Vjb25vbWV0cmljcy9GWHJhdGVzLmNzdiIKd3JpdGUuem9vKGZlZC5meC4wLCBzZXAgPSAiLCIsIGZpbGUgPWZuKQpzYXZlKGZpbGU9ImNzMV8yLlJkYXRhIiwgbGlzdD1scygpKQpgYGAKCiMjIFJlZ3Jlc3Npb24gQW5hbHlzaXMgQ2FzZSBTdHVkeSAyCgpgYGB7cn0KIyBleHRyYWN0IHRpbWUgc2VyaWVzIG1hdHJpeCBvZiBleGNoYW5nZSByYXRlcyBmb3Igc3ltYm9scyAKCmZ4cmF0ZXMgPC0gcmVhZC56b28oZmlsZSA9ICIvVXNlcnMvTWljaGFlbC9MaWJyYXJ5L01vYmlsZSBEb2N1bWVudHMvY29tfmFwcGxlfkNsb3VkRG9jcy9DTVNFL1IvRWNvbm9tZXRyaWNzL0ZYcmF0ZXMuY3N2IiwgaGVhZGVyID0gVCwgc2VwID0gIiwiKQoKbGlzdC5zeW1vYmwwIDwtIGMoIkRFWENIVVMiLCAiREVYSlBVUyIsICJERVhLT1VTIiwgIkRFWE1BVVMiLAogICAgICAgICJERVhVU0VVIiwgIkRFWFVTVUsiLCAiREVYVEhVUyIsICJERVhTWlVTIikKZnhyYXRlczAgPC0gZnhyYXRlc1ssIGxpc3Quc3ltb2JsMF0KcGFyKG1mY29sID0gYygyLDIgKSkKCmZvciAoY24gaW4gYygxOm5jb2woZnhyYXRlczApKSl7CiAgICAgICAgcGxvdChmeHJhdGVzMFssIGNuXSwgbWFpbiA9IG5hbWVzKGZ4cmF0ZXMwKVtjbl0pCn0KYGBgCgojIyMgMS4yIEV4Y2hhbmdlIHJhdGUgcmVnaW1lcyBmb3IgdGhlIENoaW5lc2UgWXVhbiAKClRoZSBDaGluZXNlIFl1YW4gd2FzIHBlZ2dlZCB0byB0aGUgVVMgRG9sbGFyIHByaW9yIHRvIEp1bHkgMjAwNS4gVGhlbiwgQ2hpbmEgYW5ub3VuY2VkIHRoYXQgdGhlIGV4Y2hhbmdlIHJhdGUgd291bGQgYmUgc2V0IHdpdGggcmVmZXJlbmNlIHRvIGEgYmFza2V0IG9mIG90aGVyIGN1cnJlbmNpZXMsIGFsbG93aW5nIGZvciBhIG1vdmVtZW50IG9mIHVwIHRvIDAuMyUgbW92ZW1lbnQgd2l0aGluIGFueSBnaXZlbiBkYXkuIE92ZXIgdGhlIHBhc3QgZGVjYWRlLCB0aGUgZ292ZXJubWVudCBoYXMgZ3JhZHVhbGx5IGFsbG93ZWQgdGhlIHRyYWRpbmcgYmFuZCB0byB3aWRlbiwgc3RhcnRpbmcgYXQgKy8tMC4zJSBhbmQgZmluYWxseSByZWFjaGluZyArLy0yJSBieSBNYXJjaCAyMDE0LiAKCkZyb20gYW4gZW1waXJpY2FsIHN0YW5kcG9pbnQsIHRoZXJlIGFyZSBzZXZlcmFsIGltcG9ydGFudCBxdWVzdGlvbnM6CgoqIEZvciBhbnkgZ2l2ZW4gcGVyaW9kLCB3aGF0IGlzIHRoZSBpbXBsaWNpdCByZWZlcmVuY2UgYmFza2V0IGZvciB0aGUgQ2hpbmVzZSBjdXJyZW5jeT8KKiBIYXMgdGhlIHJlZmVyZW5jZSBiYXNrZXQgY2hhbmdlZCBvdmVyIHRpbWU/CiogSGFzIHRoZSBDaGluZXNlIGN1cnJlbmN5IGRlcHJlY2lhdGVkIHdpdGggcmVzcGVjdCB0byB0aGUgZG9sbGFyPyBpZiBzbywgaG93IG11Y2ggYW5kIHdoZW4/CgpGcmFua2VsIGFuZCBXZWkgKDE5OTQpIGRldGFpbCBtZXRob2RvbG9neSBmb3IgZXZhbHVhdGluZyB0aGUgaW1wbGljaXQgZXhjaGFuZ2UgcmF0ZSByZWdpbWUgb2YgYSBjdXJyZW5jeS4gVGhlIGFwcHJvYWNoIHJlZ3Jlc3NlcyBjaGFuZ2VzIGluIHRoZSB0YXJnZXQgY3VycmVuY3kgb24gY2hhbmdlcyBpbiB0aGUgdmFsdWVzIG9mIHBvc3NpYmxlIGN1cnJlbmNpZXMgaW4gdGhlIHJlZmVyZW5jZSBtYXJrZXQuIAoKVG8gYXBwbHkgdGhpcyBtZXRob2RvbG9neSB3ZSByZS1leHByZXNzIHRoZSBkb2xsYXItYmFzZWQgZXhjaGFuZ2UgcmF0ZXMgdXNpbmcgYW5vdGhlciBjdXJyZW5jeSwgdGhlIFN3aXNzIEZyYW5jLiBUaGlzIGFsbG93cyBjdXJyZW5jeSBtb3ZlcyBvZiB0aGUgZG9sbGFyIHRvIGJlIHVzZWQgdG8gZXhwbGFpbiBtb3ZlcyBpbiB0aGUgWXVhbi4gVGhlIGNob2ljZSBvZiBTd2lzcyBGcmFuYyBpcyBjb25zaXN0ZW50IHdpdGggZXZhbHVhdGlvbnMgd2l0aCByZXNwZWN0IHRvIGEgc3RhYmxlLCBkZXZlbG9wZWQtbWFya2V0IGN1cnJlbmN5LiAKCiMjIyAxLjMgQ29udmVydGluZyBmcm9tIFVTRCBCYXNlIHRvIFN3aXNzIEZyYW5jIEJhc2UgCgpgYGB7cn0KZnhyYXRlczEgPC0gZnhyYXRlczAKIyBmb3IgZXhjaGFuZ2UgcmF0ZXMgd2l0aCAxIFVTIGluIGJhc2UsIGRpdmlkZSBieSBERVhTWlVTCgpmb3IgKGNuMSBpbiBjKDEsIDIsIDMsIDQsIDcpKSB7CiAgICAgICAgY29yZWRhdGEoZnhyYXRlczEpWywgY24xXSA8LSBjb3JlZGF0YShmeHJhdGVzMVssIGNuMV0pIC8gY29yZWRhdGEoZnhyYXRlczFbLCA4XSkKfQoKIyBmb3IgZXhjaGFuZ2UgcmF0ZXMgd2l0aCAxIFVTIGluIG51bWVyYXRvciwgZGl2aWRlIGludmVyc2UgYnkgREVYU1pVUyAKCmZvciAoY24xIGluIGMoNSwgNikpIHsKICAgICAgICBjb3JlZGF0YShmeHJhdGVzMSlbLCBjbjFdIDwtIGNvcmVkYXRhKDEvZnhyYXRlczFbLCBjbjFdKS9jb3JlZGF0YShmeHJhdGVzMVssIDhdKQp9CgojIGZvciBVU0QsIGRpdmlkZSAkMSBieSB0aGUgREVYQVpVUyByYXRlIAoKY29yZWRhdGEoZnhyYXRlczEpWywgOF0gPC0gMS9jb3JlZGF0YShmeHJhdGVzMSlbLCA4XQoKIyByZW5hbWUgc2VyaWVzIAoKbHMubmFtZSA8LSBjICgiQ05ZIiwgIllFTiIsICJXT04iLCAiTVlSIiwgIkVVUiIsICJHQlAiLCAiVEhCIiwgIlVTRCIpCm5hbWVzKGZ4cmF0ZXMxKSA8LSBwYXN0ZShscy5uYW1lLCAiX1NGUiIsIHNlcCA9ICIiKQojcGxvdCBleGNoYW5nZSByYXRlIHRpbWUgc2VyaWVzIGluIDJ4NCBwYW5lbAoKcGFyKG1mY29sID0gYygyLDIpKQpmb3IgKGNuMiBpbiBjKDE6bmNvbChmeHJhdGVzMSkpKXsKICAgICAgICBwbG90KGZ4cmF0ZXMxWywgY24yXSwgbWFpbiA9IG5hbWVzKGZ4cmF0ZXMxKVtjbjJdKQp9CmBgYAoKIyMjIDEuNCBMaW5lYXIgUmVncmVzc2lvbiBtb2RlbHMgb2YgY3VycmVuY3kgcmV0dXJucyAKCkNvbXB1dGUgZGFpbHkgcHJpY2UgY2hhbmdlcyBvbiB0aGUgbG9nIHNjYWxlIAoKYGBge3J9CmZ4cmF0ZXMuMS5sb2cgPC0gZGlmZihsb2coZnhyYXRlczEpKQpwYXIobWZjb2w9YygyLDIpKQpmb3IgKGNuMiBpbiBjKDE6bmNvbChmeHJhdGVzLjEubG9nKSkpIHsKICAgICAgICBwbG90KGZ4cmF0ZXMuMS5sb2dbLCBjbjJdLCBtYWluID0gbmFtZXMoZnhyYXRlcy4xLmxvZylbY24yXSkKfQpgYGAKCkZpcnN0LCB3ZSBmaXQgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoZSBwZXJpb2QgcHJpb3IgdG8gSnVseSAyMDA1IHdoZW4gdGhlIENoaW5lc2UgY3VycmVuY3kgd2FzIHBlZ2dlZCB0byB0aGUgVVMgZG9sbGFyLiAKCmBgYHtyfQpsbWZpdC5wZXJpb2QxIDwtIGxtKENOWV9TRlIgfiBVU0RfU0ZSICsgWUVOX1NGUiArIEVVUl9TRlIgKyBHQlBfU0ZSLAogICAgICAgIGRhdGEgPSB3aW5kb3coZnhyYXRlcy4xLmxvZywgc3RhcnQgPSBhcy5EYXRlKCIyMDAxLTAxLTAxIiksIGVuZCA9IGFzLkRhdGUoIjIwMDUtMDYtMzAiKSkpCnN1bW1hcnkobG1maXQucGVyaW9kMSkKYGBgCgpUaGUgcmVncmVzc2lvbiBmaXQgaWRlbnRpZmllcyB0aGUgcGVnZ2luZyBvZiB0aGUgWXVhbiAoQ05SX1NGUikgdG8gdGhlIFVTIERvbGxhciAoVVNEX1NGUikuIFRoZSBSLVNxdWFyZWQgaXMgbmVhcmx5IDEuMC4gU2Vjb25kLCB3ZSBmaXQgdGhlIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoZSBmaXJzdCBzaXggbW9udGhzIGZvbGxvd2luZyB0aGUgYW5ub3VuY2VtZW50IG9mIHRoZSBjaGFuZ2UgaW4gY3VycmVuY3kgcG9saWN5LiAKCmBgYHtyfQpsbWZpdC5wZXJpb2QyIDwtIGxtKENOWV9TRlIgfiBVU0RfU0ZSICsgWUVOX1NGUiArIEVVUl9TRlIgKyBHQlBfU0ZSICsgV09OX1NGUiArIE1ZUl9TRlIgKyBUSEJfU0ZSLAogICAgICAgIGRhdGEgPSB3aW5kb3coZnhyYXRlcy4xLmxvZywgc3RhcnQgPSBhcy5EYXRlKCIyMDA1LTA3LTAxIiksIGVuZCA9IGFzLkRhdGUoIjIwMDUtMTItMzEiKSkpCnN1bW1hcnkobG1maXQucGVyaW9kMikKYGBgCgpEdXJpbmcgdGhpcyBzaXgtbW9udGggcGVyaW9kLCB0aGVyZSBpcyBldmlkZW5jZSBvZiB0aGUgWXVhbiBkZXBhcnRpbmcgZnJvbSBhIFVTIERvbGxhciBwZWcuIFRoZSBleGNoYW5nZSByYXRlcyB3aXRoIHRoZSBzdGF0c2l0aWNhbGx5IHNpZ25pZmljYW50IHJlZ3Jlc3Npb24gcGFyYW1ldGVycyBhcmUgZm9yIHRoZSBLb3JlYW4gV29uIGFuZCB0aGUgTWFsYXlzaWFuIFJpbmdnaXQuIAoKVG8gZXhhbWluZSBmb3IgZnVydGhlciBjaGFuZ2VzIGluIHRoZSBpbXBsaWNpdCByZWZlcmVuY2UgYmFza2V0LCB3ZSBmaXQgdGhlIHNhbWUgbW9kZWwgZm9yIHRoZSBhbm51YWwgcGVyaW9kcyBmcm9tIDIwMDYgdGhyb3VnaCAyMDEyIGFuZCBmb3IgdGhlIGZpcnN0IDYgbW9udGhzIG9mIDIwMTcuIAoKYGBge3J9CmxpYnJhcnkoeHRzKQpmeHJhdGVzLjEubG9nLnRzIDwtIGFzLnh0cyhmeHJhdGVzLjEubG9nKQpmb3IgKHllYXIwIGluIGFzLmNoYXJhY3RlcihjKDIwMDY6MjAxNykpKSB7CiAgICAgICAgIyB5ZWFyMCA8LSAiMjAxMiIKICAgICAgICBsbWZpdC55ZWFyMCA8LSBsbShDTllfU0ZSIH4gVVNEX1NGUiArIFlFTl9TRlIgKyBFVVJfU0ZSCiAgICAgICAgICAgICAgICArIEdCUF9TRlIgKyBXT05fU0ZSICsgTVlSX1NGUiArIFRIQl9TRlIsIAogICAgICAgICAgICAgICAgZGF0YSA9IGZ4cmF0ZXMuMS5sb2cudHNbeWVhcjBdKQogICAgICAgIAogICAgICAgIGNhdCgiXG5cbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIik7CiAgICAgICAgY2F0KHllYXIwKTsKICAgICAgICBjYXQoIjpcbiIpCiAgICAgICAgcHJpbnQoc3VtbWFyeS5sbShsbWZpdC55ZWFyMCkpCiAgICAgICAgcmF0ZS5hcHByZWNpYXRpb24udXNkIDwtIHJvdW5kKGV4cCgyNTIqbG9nKDErbG1maXQueWVhcjAkY29lZmZpY2llbnRzWzFdKSktMSwgZGlnaXRzID0gMykKICAgICAgICBjYXQoIlxuIik7Y2F0KHllYXIwKTsKICAgICAgICBjYXQoIlx0IEFubnVhbGl6ZWQgYXBwcmVkaWF0aW9uIHJhdGUgdG8gaW1wbGllZCByZWZlcmVuY2UgYmFza2V0OiIsIHJhdGUuYXBwcmVjaWF0aW9uLnVzZCkKfQpgYGAKCk5vdyB3ZSB3aWxsIGlsbHVzdHJhdGUgc29tZSBhZGRpdGlvbmFsIGZlYXR1cmVzIG9mIGV4Y2hhbmdlIHJhdGUgcmVnaW1lIG1vZGVsbGluZyB1c2luZyB0aGUgcmVmZXJlbmNlIGJhc2tldCBpbXBsaWVkIGJ5IHRoZSBkYXRhIGZvciAyMDEyLiAKCkZpcnN0LCB3ZSBwbG90IHRoZSBjdXJyZW5jeSByZXR1cm5zIGZvciB0aGUgWXVhbiBhbmQgYWxsIGN1cnJlbmNpZXMgaW5jbHVkZWQgaW4gdGhlIGFuYWx5c2lzLiAKCmBgYHtyfQp5ZWFyMSA8LSAiMjAxMiIKCnBhcihtZmNvbD1jKDEsMSkpCnRzLnBsb3QoY3Vtc3VtKGZ4cmF0ZXMuMS5sb2cudHNbIjIwMTIiXSksIAogICAgICAgIGNvbCA9IHJhaW5ib3coTkNPTChmeHJhdGVzLjEubG9nLnRzKSksCiAgICAgICAgbWFpbiA9ICIyMDEyIEN1cnJlbmN5IFJldHVybiIKICAgICAgICApCmxlZ2VuZCh4ID0gMTUwLCB5ID0wLjE1LCBsZWdlbmQgPSBkaW1uYW1lcyhmeHJhdGVzLjEubG9nLnRzKVtbMl1dLCBsdHkgPSByZXAoMSwgdGltZXMgPSBuY29sKGZ4cmF0ZXMuMS5sb2cudHMpKSwgCiAgICAgICAgY29sID0gcmFpbmJvdyhOQ09MKGZ4cmF0ZXMuMS5sb2cudHMpKSwKICAgICAgICBjZXggPSAwLjcpCmBgYAoKVGhlbiB3ZSBwbG90IHRoZSBjdXJyZW5jeSByZXR1cm4gb2YgdGhlIFl1YW4gYW5kIHRoYXQgb2YgdGhlIGltcGxpZWQgcmVmZXJlbmNlIGJhc2tldCBzcGVjaWZpZWQgYnkgdGhlIHJlZ3Jlc3Npb246CgpgYGB7cn0KbG1maXQueWVhcjEgPC0gbG0oIENOWV9TRlIgfiBVU0RfU0ZSICsgWUVOX1NGUiArIEVVUl9TRlIgKyBHQlBfU0ZSICsgCiAgICBXT05fU0ZSICsgTVlSX1NGUiArIFRIQl9TRlIsIGRhdGEgPSBmeHJhdGVzLjEubG9nLnRzW3llYXIxXSkKeTAuYWN0dWFsIDwtIGZ4cmF0ZXMuMS5sb2cudHNbIjIwMTIiXVssICJDTllfU0ZSIl0KeTAuZml0IDwtIHkwLmFjdHVhbCAtIGxtZml0LnllYXIxJHJlc2lkdWFscwoKdHMucGxvdChjdW1zdW0oY2JpbmQoeTAuYWN0dWFsLCB5MC5maXQpKSwKICAgICAgICBjb2wgPSByYWluYm93KE5DT0woZnhyYXRlcy4xLmxvZy50cykpW2MoMSw1KV0sCiAgICAgICAgbWFpbiA9ICIyMDEyIEN1cnJlbmN5IFJldHVybnMgXG5DTllfU0ZSIGFuZCBJbXBsaWVkIEJhc2tldCIpCmBgYAoKTm90ZSBob3cgY2xvc2VseSB0aGUgcmVmZXJlbmNlIGJhc2tldCB0cmFja3MgdGhlIFl1YW4uIFRoaXMgaXMgdG8gYmUgZXhwZWN0ZWQgZ2l2ZW4gdGhlIGhpZ2ggUi1zcXVhcmVkIG9mIHRoZSByZWdyZXNzaW9uLiAKCkZpbmFsbHksIHdlIGFwcGx5IHRoZSBSIGZ1bmN0aW9uIGluZmxlbmNlLm1lYXN1cmVzKCkKCmBgYHtyfQpsYXlvdXQobWF0cml4KGMoMSwyLDMsNCksMiwyKSkKcGxvdChsbWZpdC55ZWFyMSkKYGBgCgpUaGVzZSBkaWFnbm9zdGljcyBpbmRpY2F0ZXM6IHRoZSByZXNpZHVhbHMgYXBwZWFyIHdlbGwtYmVoYXZlZCBhcyB0aGV5IHJlbGF0ZWQgdG8gdGhlIHNpemUgb2YgdGhlIGZpdHRlZCB2YWx1ZXMuIAo=