1 Data

The data set used in this analysis count the total passengers on an airline from 1949 to 1960, counted monthly. This data set is built inn to R and does not need to be downloaded.

2 Training/Testing Split

The data is split into training and testing subsets. The last year (12 observations) is withheld and will be used to determine accuracy of the smoothing methods.

train.air <- ts(air[1:132], start = 1949, frequency = 12)
test.air <- ts(air[133:144], start = 1960, frequency = 12)

3 Original Data

The recorded training data is displayed in the graph below. A annual moving average is included to display the positive trend through the seasonality.

trend.air <- ma(train.air, order = 12, centre = TRUE)
par(mar=c(2,2,2,2))
plot(train.air, xlab="", ylab="Total Passengers", col="darkred", lwd =2)
title(main = "Airline Passengers Over Time with Moving Average")
lines(trend.air, lwd =2, col = "blue")
legend("topleft", c("Original Series", "12-Month Moving Average"), lwd=rep(2,2),
       col=c("darkred", "blue"), bty="n")

4 Smoothing Methods

Several candidate smoothing methods will be tested to determine the most accurate. Each method and some accuracy measures are displayed in the table below. By RMSE and MAE metrics, Holt-Winters Multiplicative Damped is the best candidate method.

fit1 = ses(train.air, h=12)
fit2 = holt(train.air, initial="optimal", h = 12)
fit3 = holt(train.air, damped = TRUE, h = 12)
fit4 = holt(train.air, exponential = TRUE, damped = TRUE, h = 12)
fit5 = hw(train.air, h = 12, seasonal = "additive")
fit6 = hw(train.air, h = 12, seasonal = "multiplicative")
fit7 = hw(train.air, h = 12, seasonal = "additive", damped = TRUE)
fit8 = hw(train.air, h = 12, seasonal = "multiplicative", damped = TRUE)

accuracy.table = round(rbind(accuracy(fit1), accuracy(fit2), accuracy(fit3), accuracy(fit4),
                             accuracy(fit5), accuracy(fit6), accuracy(fit7), accuracy(fit8)),4)
row.names(accuracy.table)=c("SES","Holt Linear","Holt Add. Damped", "Holt Exp. Damped",
                            "HW Add.","HW Exp.","HW Add. Damp", "HW Exp. Damp")
pander(accuracy.table, caption = "Accuracy Measures of Various Exponential Smoothing Models")
Accuracy Measures of Various Exponential Smoothing Models
  ME RMSE MAE MPE MAPE MASE ACF1
SES 2.22 31.21 23.9 0.4136 8.912 0.785 0.2863
Holt Linear 0.069 31.15 23.83 -0.5842 8.965 0.7826 0.2861
Holt Add. Damped 1.49 31.19 23.93 -0.0254 8.969 0.7859 0.286
Holt Exp. Damped 1.406 31.21 23.95 -0.0447 8.984 0.7867 0.2858
HW Add. 0.7468 15.41 11.57 0.259 5.002 0.38 0.1636
HW Exp. 1.369 9.95 7.533 0.2993 2.998 0.2474 0.3048
HW Add. Damp 1.638 15.51 11.67 0.6132 5.063 0.3833 0.1705
HW Exp. Damp 1.431 8.482 6.764 0.4725 2.857 0.2221 -0.0371

The different methods are graphed below, separated by linear and seasonal methods. Unsurprisingly with such seasonal data, the seasonal methods appear most appropriate.

par(mfrow=c(2,1), mar=c(3,4,3,1))
pred.id = 133:144
plot(1:132, train.air, lwd=2, type = "o", ylab = "Airline Passengers", xlab = "",
     xlim = c(1,144), ylim = c(80,550), cex=0.3,
     main = "Non-Seasonal Smoothing Methods")
lines(pred.id, fit1$mean, col="red")
lines(pred.id, fit2$mean, col="blue")
lines(pred.id, fit3$mean, col="green")
lines(pred.id, fit4$mean, col="violet")
points(pred.id, fit1$mean, pch=16, col="red", cex = 0.5)
points(pred.id, fit2$mean, pch=17, col="blue", cex = 0.5)
points(pred.id, fit3$mean, pch=19, col="green", cex = 0.5)
points(pred.id, fit4$mean, pch=21, col="violet", cex = 0.5)

legend("bottomright", lty=1, col=c("red","blue","green","violet"), pch=c(16,17,19,21),
       c("SES","Holt Linear", "Holt Linear Damped", "Holt Multiplicitave Damped"),
       cex = 0.7, bty = "n")


plot(1:132, train.air, lwd=2, type = "o", ylab = "Airline Passengers", xlab = "",
     xlim = c(1,144), ylim = c(80,700), cex = 0.3,
     main = "Holt-Winters Trend and Seasonal Smoothing Methods")
lines(pred.id, fit5$mean, col="red")
lines(pred.id, fit6$mean, col="blue")
lines(pred.id, fit7$mean, col="green")
lines(pred.id, fit8$mean, col="violet")
##
points(pred.id, fit5$mean, pch=16, col="red", cex = 0.5)
points(pred.id, fit6$mean, pch=17, col="blue", cex = 0.5)
points(pred.id, fit7$mean, pch=19, col="green", cex = 0.5)
points(pred.id, fit8$mean, pch=21, col="violet", cex = 0.5)
###
legend("bottomright", lty=1, col=c("red","blue","green", "violet"),pch=c(16,17,19,21),
       c("HW Additive","HW Multiplicative","HW Additive Damped", "HW Multiplicative Damped"), 
       cex = 0.7, bty="n")

We select Holt-Winters Multiplicative with Damping based on RMES and MAE. The smoothing parameters are given in the table below.

final.model = hw(air, h =12, seasonal = "multiplicative", damped = TRUE)
smoothing.parameter = final.model$model$par[1:3]
pander(smoothing.parameter, caption = "Est. Values of the smoothing parameters")
alpha beta gamma
0.7194 0.05684 1e-04
LS0tDQp0aXRsZTogIkV4cG9uZW50aWFsIFNtb290aGluZyBNZXRob2RzIg0KYXV0aG9yOiAiTm9haCBCcmVjaGJpbGwiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ193aWR0aDogNg0KICAgIGZpZ19oZWlnaHQ6IDYNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCmVkaXRvcl9vcHRpb25zOiANCiAgbWFya2Rvd246IA0KICAgIHdyYXA6IDcyDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KLyogQ2FzY2FkaW5nIFN0eWxlIFNoZWV0cyAoQ1NTKSBpcyBhIHN0eWxlc2hlZXQgbGFuZ3VhZ2UgdXNlZCB0byBkZXNjcmliZSB0aGUgcHJlc2VudGF0aW9uIG9mIGEgZG9jdW1lbnQgd3JpdHRlbiBpbiBIVE1MIG9yIFhNTC4gaXQgaXMgYSBzaW1wbGUgbWVjaGFuaXNtIGZvciBhZGRpbmcgc3R5bGUgKGUuZy4sIGZvbnRzLCBjb2xvcnMsIHNwYWNpbmcpIHRvIFdlYiBkb2N1bWVudHMuICovDQoNCmgxLnRpdGxlIHsgIC8qIFRpdGxlIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiB0aGUgcmVwb3J0IHRpdGxlICovDQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgYXV0aG9ycyAgKi8NCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBkYXRlICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsgLyogSGVhZGVyIDEgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBsZXZlbCAxIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAyMnB4Ow0KICAgIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQpoMiB7IC8qIEhlYWRlciAyIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgbGV2ZWwgMiBzZWN0aW9uIHRpdGxlICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCAzIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCA0IHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbG9hZF9wYWNrYWdlcyA8LSBmdW5jdGlvbihwa2dfbGlzdCkgew0KICBmb3IgKHBrZyBpbiBwa2dfbGlzdCkgew0KICAgIGlmICghcmVxdWlyZShwa2csIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpIHsNCiAgICAgIGluc3RhbGwucGFja2FnZXMocGtnLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQ0KICAgICAgbGlicmFyeShwa2csIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkNCiAgICB9DQogIH0NCn0NCg0KcGFja2FnZXMgPC0gYygidGlkeXZlcnNlIiwgInBhbmRlciIsICJmb3JlY2FzdCIpDQpsb2FkX3BhY2thZ2VzKHBhY2thZ2VzKQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwgIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQSwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYWxpZ24gPSAiY2VudGVyIg0KICAgICAgICAgICAgICAgICAgICAgICkgICANCmFpciA8LSBBaXJQYXNzZW5nZXJzDQpgYGANCg0KIyMgRGF0YQ0KDQpUaGUgZGF0YSBzZXQgdXNlZCBpbiB0aGlzIGFuYWx5c2lzIGNvdW50IHRoZSB0b3RhbCBwYXNzZW5nZXJzIG9uIGFuDQphaXJsaW5lIGZyb20gMTk0OSB0byAxOTYwLCBjb3VudGVkIG1vbnRobHkuIFRoaXMgZGF0YSBzZXQgaXMgYnVpbHQgaW5uDQp0byBSIGFuZCBkb2VzIG5vdCBuZWVkIHRvIGJlIGRvd25sb2FkZWQuDQoNCiMjIFRyYWluaW5nL1Rlc3RpbmcgU3BsaXQNCg0KVGhlIGRhdGEgaXMgc3BsaXQgaW50byB0cmFpbmluZyBhbmQgdGVzdGluZyBzdWJzZXRzLiBUaGUgbGFzdCB5ZWFyICgxMg0Kb2JzZXJ2YXRpb25zKSBpcyB3aXRoaGVsZCBhbmQgd2lsbCBiZSB1c2VkIHRvIGRldGVybWluZSBhY2N1cmFjeSBvZiB0aGUNCnNtb290aGluZyBtZXRob2RzLg0KDQpgYGB7cn0NCnRyYWluLmFpciA8LSB0cyhhaXJbMToxMzJdLCBzdGFydCA9IDE5NDksIGZyZXF1ZW5jeSA9IDEyKQ0KdGVzdC5haXIgPC0gdHMoYWlyWzEzMzoxNDRdLCBzdGFydCA9IDE5NjAsIGZyZXF1ZW5jeSA9IDEyKQ0KDQpgYGANCg0KIyMgT3JpZ2luYWwgRGF0YQ0KDQpUaGUgcmVjb3JkZWQgdHJhaW5pbmcgZGF0YSBpcyBkaXNwbGF5ZWQgaW4gdGhlIGdyYXBoIGJlbG93LiBBIGFubnVhbA0KbW92aW5nIGF2ZXJhZ2UgaXMgaW5jbHVkZWQgdG8gZGlzcGxheSB0aGUgcG9zaXRpdmUgdHJlbmQgdGhyb3VnaCB0aGUNCnNlYXNvbmFsaXR5Lg0KDQpgYGB7cn0NCnRyZW5kLmFpciA8LSBtYSh0cmFpbi5haXIsIG9yZGVyID0gMTIsIGNlbnRyZSA9IFRSVUUpDQpwYXIobWFyPWMoMiwyLDIsMikpDQpwbG90KHRyYWluLmFpciwgeGxhYj0iIiwgeWxhYj0iVG90YWwgUGFzc2VuZ2VycyIsIGNvbD0iZGFya3JlZCIsIGx3ZCA9MikNCnRpdGxlKG1haW4gPSAiQWlybGluZSBQYXNzZW5nZXJzIE92ZXIgVGltZSB3aXRoIE1vdmluZyBBdmVyYWdlIikNCmxpbmVzKHRyZW5kLmFpciwgbHdkID0yLCBjb2wgPSAiYmx1ZSIpDQpsZWdlbmQoInRvcGxlZnQiLCBjKCJPcmlnaW5hbCBTZXJpZXMiLCAiMTItTW9udGggTW92aW5nIEF2ZXJhZ2UiKSwgbHdkPXJlcCgyLDIpLA0KICAgICAgIGNvbD1jKCJkYXJrcmVkIiwgImJsdWUiKSwgYnR5PSJuIikNCg0KYGBgDQoNCiMjIFNtb290aGluZyBNZXRob2RzDQoNClNldmVyYWwgY2FuZGlkYXRlIHNtb290aGluZyBtZXRob2RzIHdpbGwgYmUgdGVzdGVkIHRvIGRldGVybWluZSB0aGUgbW9zdA0KYWNjdXJhdGUuIEVhY2ggbWV0aG9kIGFuZCBzb21lIGFjY3VyYWN5IG1lYXN1cmVzIGFyZSBkaXNwbGF5ZWQgaW4gdGhlDQp0YWJsZSBiZWxvdy4gQnkgUk1TRSBhbmQgTUFFIG1ldHJpY3MsIEhvbHQtV2ludGVycyBNdWx0aXBsaWNhdGl2ZSBEYW1wZWQNCmlzIHRoZSBiZXN0IGNhbmRpZGF0ZSBtZXRob2QuDQoNCmBgYHtyfQ0KZml0MSA9IHNlcyh0cmFpbi5haXIsIGg9MTIpDQpmaXQyID0gaG9sdCh0cmFpbi5haXIsIGluaXRpYWw9Im9wdGltYWwiLCBoID0gMTIpDQpmaXQzID0gaG9sdCh0cmFpbi5haXIsIGRhbXBlZCA9IFRSVUUsIGggPSAxMikNCmZpdDQgPSBob2x0KHRyYWluLmFpciwgZXhwb25lbnRpYWwgPSBUUlVFLCBkYW1wZWQgPSBUUlVFLCBoID0gMTIpDQpmaXQ1ID0gaHcodHJhaW4uYWlyLCBoID0gMTIsIHNlYXNvbmFsID0gImFkZGl0aXZlIikNCmZpdDYgPSBodyh0cmFpbi5haXIsIGggPSAxMiwgc2Vhc29uYWwgPSAibXVsdGlwbGljYXRpdmUiKQ0KZml0NyA9IGh3KHRyYWluLmFpciwgaCA9IDEyLCBzZWFzb25hbCA9ICJhZGRpdGl2ZSIsIGRhbXBlZCA9IFRSVUUpDQpmaXQ4ID0gaHcodHJhaW4uYWlyLCBoID0gMTIsIHNlYXNvbmFsID0gIm11bHRpcGxpY2F0aXZlIiwgZGFtcGVkID0gVFJVRSkNCg0KYWNjdXJhY3kudGFibGUgPSByb3VuZChyYmluZChhY2N1cmFjeShmaXQxKSwgYWNjdXJhY3koZml0MiksIGFjY3VyYWN5KGZpdDMpLCBhY2N1cmFjeShmaXQ0KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjdXJhY3koZml0NSksIGFjY3VyYWN5KGZpdDYpLCBhY2N1cmFjeShmaXQ3KSwgYWNjdXJhY3koZml0OCkpLDQpDQpyb3cubmFtZXMoYWNjdXJhY3kudGFibGUpPWMoIlNFUyIsIkhvbHQgTGluZWFyIiwiSG9sdCBBZGQuIERhbXBlZCIsICJIb2x0IEV4cC4gRGFtcGVkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSFcgQWRkLiIsIkhXIEV4cC4iLCJIVyBBZGQuIERhbXAiLCAiSFcgRXhwLiBEYW1wIikNCnBhbmRlcihhY2N1cmFjeS50YWJsZSwgY2FwdGlvbiA9ICJBY2N1cmFjeSBNZWFzdXJlcyBvZiBWYXJpb3VzIEV4cG9uZW50aWFsIFNtb290aGluZyBNb2RlbHMiKQ0KDQpgYGANCg0KVGhlIGRpZmZlcmVudCBtZXRob2RzIGFyZSBncmFwaGVkIGJlbG93LCBzZXBhcmF0ZWQgYnkgbGluZWFyIGFuZA0Kc2Vhc29uYWwgbWV0aG9kcy4gVW5zdXJwcmlzaW5nbHkgd2l0aCBzdWNoIHNlYXNvbmFsIGRhdGEsIHRoZSBzZWFzb25hbA0KbWV0aG9kcyBhcHBlYXIgbW9zdCBhcHByb3ByaWF0ZS4NCg0KYGBge3J9DQpwYXIobWZyb3c9YygyLDEpLCBtYXI9YygzLDQsMywxKSkNCnByZWQuaWQgPSAxMzM6MTQ0DQpwbG90KDE6MTMyLCB0cmFpbi5haXIsIGx3ZD0yLCB0eXBlID0gIm8iLCB5bGFiID0gIkFpcmxpbmUgUGFzc2VuZ2VycyIsIHhsYWIgPSAiIiwNCiAgICAgeGxpbSA9IGMoMSwxNDQpLCB5bGltID0gYyg4MCw1NTApLCBjZXg9MC4zLA0KICAgICBtYWluID0gIk5vbi1TZWFzb25hbCBTbW9vdGhpbmcgTWV0aG9kcyIpDQpsaW5lcyhwcmVkLmlkLCBmaXQxJG1lYW4sIGNvbD0icmVkIikNCmxpbmVzKHByZWQuaWQsIGZpdDIkbWVhbiwgY29sPSJibHVlIikNCmxpbmVzKHByZWQuaWQsIGZpdDMkbWVhbiwgY29sPSJncmVlbiIpDQpsaW5lcyhwcmVkLmlkLCBmaXQ0JG1lYW4sIGNvbD0idmlvbGV0IikNCnBvaW50cyhwcmVkLmlkLCBmaXQxJG1lYW4sIHBjaD0xNiwgY29sPSJyZWQiLCBjZXggPSAwLjUpDQpwb2ludHMocHJlZC5pZCwgZml0MiRtZWFuLCBwY2g9MTcsIGNvbD0iYmx1ZSIsIGNleCA9IDAuNSkNCnBvaW50cyhwcmVkLmlkLCBmaXQzJG1lYW4sIHBjaD0xOSwgY29sPSJncmVlbiIsIGNleCA9IDAuNSkNCnBvaW50cyhwcmVkLmlkLCBmaXQ0JG1lYW4sIHBjaD0yMSwgY29sPSJ2aW9sZXQiLCBjZXggPSAwLjUpDQoNCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsdHk9MSwgY29sPWMoInJlZCIsImJsdWUiLCJncmVlbiIsInZpb2xldCIpLCBwY2g9YygxNiwxNywxOSwyMSksDQogICAgICAgYygiU0VTIiwiSG9sdCBMaW5lYXIiLCAiSG9sdCBMaW5lYXIgRGFtcGVkIiwgIkhvbHQgTXVsdGlwbGljaXRhdmUgRGFtcGVkIiksDQogICAgICAgY2V4ID0gMC43LCBidHkgPSAibiIpDQoNCg0KcGxvdCgxOjEzMiwgdHJhaW4uYWlyLCBsd2Q9MiwgdHlwZSA9ICJvIiwgeWxhYiA9ICJBaXJsaW5lIFBhc3NlbmdlcnMiLCB4bGFiID0gIiIsDQogICAgIHhsaW0gPSBjKDEsMTQ0KSwgeWxpbSA9IGMoODAsNzAwKSwgY2V4ID0gMC4zLA0KICAgICBtYWluID0gIkhvbHQtV2ludGVycyBUcmVuZCBhbmQgU2Vhc29uYWwgU21vb3RoaW5nIE1ldGhvZHMiKQ0KbGluZXMocHJlZC5pZCwgZml0NSRtZWFuLCBjb2w9InJlZCIpDQpsaW5lcyhwcmVkLmlkLCBmaXQ2JG1lYW4sIGNvbD0iYmx1ZSIpDQpsaW5lcyhwcmVkLmlkLCBmaXQ3JG1lYW4sIGNvbD0iZ3JlZW4iKQ0KbGluZXMocHJlZC5pZCwgZml0OCRtZWFuLCBjb2w9InZpb2xldCIpDQojIw0KcG9pbnRzKHByZWQuaWQsIGZpdDUkbWVhbiwgcGNoPTE2LCBjb2w9InJlZCIsIGNleCA9IDAuNSkNCnBvaW50cyhwcmVkLmlkLCBmaXQ2JG1lYW4sIHBjaD0xNywgY29sPSJibHVlIiwgY2V4ID0gMC41KQ0KcG9pbnRzKHByZWQuaWQsIGZpdDckbWVhbiwgcGNoPTE5LCBjb2w9ImdyZWVuIiwgY2V4ID0gMC41KQ0KcG9pbnRzKHByZWQuaWQsIGZpdDgkbWVhbiwgcGNoPTIxLCBjb2w9InZpb2xldCIsIGNleCA9IDAuNSkNCiMjIw0KbGVnZW5kKCJib3R0b21yaWdodCIsIGx0eT0xLCBjb2w9YygicmVkIiwiYmx1ZSIsImdyZWVuIiwgInZpb2xldCIpLHBjaD1jKDE2LDE3LDE5LDIxKSwNCiAgICAgICBjKCJIVyBBZGRpdGl2ZSIsIkhXIE11bHRpcGxpY2F0aXZlIiwiSFcgQWRkaXRpdmUgRGFtcGVkIiwgIkhXIE11bHRpcGxpY2F0aXZlIERhbXBlZCIpLCANCiAgICAgICBjZXggPSAwLjcsIGJ0eT0ibiIpDQpgYGANCg0KV2Ugc2VsZWN0IEhvbHQtV2ludGVycyBNdWx0aXBsaWNhdGl2ZSB3aXRoIERhbXBpbmcgYmFzZWQgb24gUk1FUyBhbmQNCk1BRS4gVGhlIHNtb290aGluZyBwYXJhbWV0ZXJzIGFyZSBnaXZlbiBpbiB0aGUgdGFibGUgYmVsb3cuDQoNCmBgYHtyfQ0KZmluYWwubW9kZWwgPSBodyhhaXIsIGggPTEyLCBzZWFzb25hbCA9ICJtdWx0aXBsaWNhdGl2ZSIsIGRhbXBlZCA9IFRSVUUpDQpzbW9vdGhpbmcucGFyYW1ldGVyID0gZmluYWwubW9kZWwkbW9kZWwkcGFyWzE6M10NCnBhbmRlcihzbW9vdGhpbmcucGFyYW1ldGVyLCBjYXB0aW9uID0gIkVzdC4gVmFsdWVzIG9mIHRoZSBzbW9vdGhpbmcgcGFyYW1ldGVycyIpDQpgYGANCg==