Data Training and
Testing
Next, we will hold the last ten periods of the data for testing. We
will define four different training data sets. The training set sizes
used in this analysis are 144, 109, 73, and 48. The same test set with
size ten will be used to calculate the prediction error.
ini.data = data.house[,2]
n0 = length(ini.data)
##
train.data01 = data.house[1:(n0-7), 2]
train.data02 = data.house[37:(n0-7), 2]
train.data03 = data.house[73:(n0-7), 2]
train.data04 = data.house[97:(n0-7), 2]
## last 7 observations
test.data = data.house[(n0-6):n0,2]
##
train01.ts = ts(train.data01, frequency = 12, start = c(2012, 1))
train02.ts = ts(train.data02, frequency = 12, start = c(2015, 1))
train03.ts = ts(train.data03, frequency = 12, start = c(2018, 1))
train04.ts = ts(train.data04, frequency = 12, start = c(2020, 1))
##
stl01 = stl(train01.ts, s.window = 12)
stl02 = stl(train02.ts, s.window = 12)
stl03 = stl(train03.ts, s.window = 12)
stl04 = stl(train04.ts, s.window = 12)
## Forecast with decomposing
fcst01 = forecast(stl01,h=10, method="naive")
fcst02 = forecast(stl02,h=10, method="naive")
fcst03 = forecast(stl03,h=10, method="naive")
fcst04 = forecast(stl04,h=10, method="naive")
Next, we perform error analysis.
PE01=(test.data-fcst01$mean)/fcst01$mean
## Warning in `-.default`(test.data, fcst01$mean): longer object length is not a
## multiple of shorter object length
PE02=(test.data-fcst02$mean)/fcst02$mean
## Warning in `-.default`(test.data, fcst02$mean): longer object length is not a
## multiple of shorter object length
PE03=(test.data-fcst03$mean)/fcst03$mean
## Warning in `-.default`(test.data, fcst03$mean): longer object length is not a
## multiple of shorter object length
PE04=(test.data-fcst04$mean)/fcst04$mean
## Warning in `-.default`(test.data, fcst04$mean): longer object length is not a
## multiple of shorter object length
###
MAPE1 = mean(abs(PE01))
MAPE2 = mean(abs(PE02))
MAPE3 = mean(abs(PE03))
MAPE4 = mean(abs(PE04))
###
E1=test.data-fcst01$mean
## Warning in `-.default`(test.data, fcst01$mean): longer object length is not a
## multiple of shorter object length
E2=test.data-fcst02$mean
## Warning in `-.default`(test.data, fcst02$mean): longer object length is not a
## multiple of shorter object length
E3=test.data-fcst03$mean
## Warning in `-.default`(test.data, fcst03$mean): longer object length is not a
## multiple of shorter object length
E4=test.data-fcst04$mean
## Warning in `-.default`(test.data, fcst04$mean): longer object length is not a
## multiple of shorter object length
##
MSE1=mean(E1^2)
MSE2=mean(E2^2)
MSE3=mean(E3^2)
MSE4=mean(E4^2)
###
MSE=c(MSE1, MSE2, MSE3, MSE4)
MAPE=c(MAPE1, MAPE2, MAPE3, MAPE4)
accuracy=cbind(MSE=MSE, MAPE=MAPE)
row.names(accuracy)=c("n.144", "n.109", "n. 73", "n. 48")
kable(accuracy, caption="Error comparison between forecast results with different sample sizes")
Error comparison between forecast results with different sample
sizes
n.144 |
3528.487 |
0.0802875 |
n.109 |
3491.738 |
0.0795013 |
n. 73 |
3965.483 |
0.0852145 |
n. 48 |
5327.657 |
0.1013145 |
We can see from the table above that a training size of 109 performs
the best and has the lowest errors. While the mean square errors look
normal, the mean absolute percentage error is well into the thousands.
Some possible reasons for this are the observations in our time series
ranges from about 300 to a little over one thousand. The time series
also follows several patterns including seasonal trends and being
additive. We will take a closer look at the errors next by making one
graph for the MSE and one for the MAPE.
par(mfrow=c(1,2))
plot(1:4, MSE, type="b", col="darkred", ylab="Error", xlab="",
#ylim=c(0.4,.85),xlim = c(0.5,4.5),
main="MSE", axes=FALSE)
labs=c("n=144", "n=109", "n=73", "n=48")
axis(1, at=1:4, label=labs)
axis(2)
#lines(1:4, MAPE, type="b", col="blue")
text(1:4, MAPE+0.03, as.character(round(MAPE,4)), col="blue", cex=0.7)
text(1:4, MSE-0.03, as.character(round(MSE,4)), col="darkred", cex=0.7)
legend(1.5, 0.63, c("MSE", "MAPE"), col=c("darkred","blue"), lty=1, bty="n", cex=0.7)
###
#```{r fig.align='center', fig.cap= "Comparing forecast errors", fig.width=5, fig.height=3.5}
plot(1:4, MAPE, type="b", col="darkred", ylab="Error", xlab="",
#ylim=c(0.4,.85),xlim = c(0.5,4.5),
main="MAPE", axes=FALSE)
labs=c("n=144", "n=109", "n=73", "n=48")
axis(1, at=1:4, label=labs)
axis(2)
LS0tDQp0aXRsZTogVGltZSBTZXJpZXMgRGVjb21wb3NpdGlvbiBmb3IgSG91c2VzIFNvbGQgaW4gdGhlIFVTDQphdXRob3I6ICJBdmEgRGVTdGVmYW5vIg0KZGF0ZTogIjExLTI0LTI0Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX3dpZHRoOiA2DQogICAgZmlnX2hlaWdodDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICAgIGRmX3ByaW50OiBrYWJsZQ0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogNQ0KICAgIGZpZ19oZWlnaHQ6IDQNCi0tLQ0KDQpgYGB7PWh0bWx9DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpkaXYjVE9DIGxpIHsNCiAgICBsaXN0LXN0eWxlOm5vbmU7DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogMjRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDEgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE1cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDQgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KPC9zdHlsZT4NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0KaWYgKCFyZXF1aXJlKCJJU3dSIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIklTd1IiKQ0KICAgbGlicmFyeShJU3dSKQ0KfQ0KaWYgKCFyZXF1aXJlKCJNQVNTIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIk1BU1MiKQ0KICAgbGlicmFyeShNQVNTKQ0KfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJmb3JlY2FzdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJmb3JlY2FzdCIpDQogICBsaWJyYXJ5KGZvcmVjYXN0KQ0KfQ0KDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmdzID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5hbGlnbj0nY2VudGVyJywgDQogICAgICAgICAgICAgICAgICAgICAgZmlnLnBvcyA9ICdodCcpDQpgYGANCg0KIyBJbnRyb2R1Y3Rpb24NCg0KVGhlIGZvbGxvd2luZyBkYXRhIGlzIGZyb20gaHR0cHM6Ly93d3cuY2Vuc3VzLmdvdi4gVGhlIGRhdGEgc2V0IGNvbnRhaW5zIHRoZSBudW1iZXIgb2YgaG9tZXMgc29sZCAoYnkgdGhlIHRob3VzYW5kcykgaW4gdGhlIFVuaXRlZCBTdGF0ZXMgZnJvbSB0aGUgeWVhcnMgMTk2MyB0byAyMDI0LiBFYWNoIHllYXIgY29udGFpbnMgMTIgb2JzZXJ2YXRpb25zIGZvciBlYWNoIG1vbnRoIG9mIHRoZSB5ZWFyIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiAyMDI0IHRoYXQgb25seSBoYXMgOSBvYnNlcnZhdGlvbnMuIFRoZXJlIGFyZSBhIHRvdGFsIG9mIDc0MSBvYnNlcnZhdGlvbnMuIEZvciB0aGlzIGFuYWx5c2lzLCB3ZSB3aWxsIG9ubHkgdXNlIHRoZSAxNzUgbW9zdCByZWNlbnQgb2JzZXJ2YXRpb25zLg0KDQojIyBWYXJpYWJsZSBEZXNjcmlwdGlvbg0KDQoqIFBlcmlvZCAtIFRoZSB5ZWFyIGFuZCBtb250aCB0aGUgbnVtYmVyIG9mIGhvdXNlcyBzb2xkIHdhcyByZWNvcmRlZC4NCiogVmFsdWUgLSBUaGUgbnVtYmVyIG9mIGhvdXNlcyBib3VnaHQgaW4gdGhlIFVuaXRlZCBzdGF0ZXMgaW4gdGhvdXNhbmRzLiAoRXhhbXBsZTogNDAwID0gNDAwLDAwMCBob3VzZXMgc29sZCkNCg0KIyMgUHJhY3RpY2FsIFF1ZXN0aW9uDQoNCldoYXQgcGF0dGVybnMgY2FuIGJlIGZvdW5kIGluIG91ciB0aW1lIHNlcmllcyBhbmQgd2hhdCBtZXRob2RzIG9mIHNtb290aGluZyBhbmQgZGVjb21wb3NpdGlvbiBzaG91bGQgYmUgdXNlZCBvbiBpdD8gDQoNCiMgRXhwbG9yYXRvcnkgQW5hbHlzaXMNCg0KRmlyc3QsIHRoZSBkYXRhIGlzIGRvd25sb2FkZWQuIE5leHQsIHRoZSBkYXRhIGlzIGN1dCBkb3duIHRvIHRoZSAxNzUgbW9zdCByZWNlbnQgb2JzZXJ2YXRpb25zLiB0aGlzIG1lYW5zIHdlIGFyZSBvbmx5IHVzaW5nIG9ic2VydmF0aW9ucyBmcm9tIHRoZSB5ZWFycyAyMDEwIHRvIDIwMjQuV2UgYWxzbyBtb2RpZnkgdGhlIFZhbGUgdmFyaWFibGUgc28gaXQgZG9lcyBub3QgY29udGFpbiBjb21tYXMuIFRoZXJlIGFwcGVhcnMgdG8gYmUgbm8gbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGRhdGEuIA0KDQpgYGB7cn0NCmhvdXNlIDwtIHJlYWQuY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQXZhRGVTdC9TVEEtMzIxL3JlZnMvaGVhZHMvbWFpbi9Cb29rJTIwMyhTaGVldDEpLmNzdiIsIGhlYWRlciA9IFRSVUUpDQpuLnJvdyA9IGRpbShob3VzZSlbMV0NCmRhdGEuaG91c2UgPSBob3VzZVsobi5yb3ctMTUwKTpuLnJvdywgXQ0KICAgICAgICAgIA0KZGF0YS5ob3VzZSRWYWx1ZSA9IGFzLm51bWVyaWMoZ3N1YigiLCIsICIiLCBkYXRhLmhvdXNlJFZhbHVlKSkNCmBgYA0KDQojIyBEZWZpbmUgVGltZSBTZXJpZXMgT2JqZWN0DQoNCkhlcmUgaXMgYSBncmFwaCBvZiB0aGUgZGF0YSB3aXRoIHRoZSBudW1iZXIgb2YgaG91c2VzIHNvbGQgYnkgdGhlIHRob3VzYW5kcyBvbiB0aGUgeSBheGlzLiBTaW5jZSB0aGUgZGF0YSBpcyByZWNvcmRlZCBieSBtb250aC4gRnJlcXVlbmN5ID0gMTIgd2lsbCBiZSB1c2VkIHRvIGRlZmluZSB0aGUgdGltZSBzZXJpZXMgb2JqZWN0LiANCg0KYGBge3IgIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9IDMsIGZpZy5jYXA9IlVTIEhvdXNlcyBCb3VnaHQgTW9udGhseSJ9DQpob3VzZS50cyA9IHRzKGRhdGEuaG91c2VbLDJdLCBmcmVxdWVuY3kgPSAxMiwgc3RhcnQgPSBjKDIwMTIsIDEpKQ0KcGFyKG1hcj1jKDIsMiwyLDIpKQ0KcGxvdChob3VzZS50cywgbWFpbj0iVVMgSG91c2VzIEJvdWdodCBCZXR3ZWVuIE1hcmNoLCAyMDEyIGFuZCBTZXB0LCAyMDI0IiwgeWxhYj0iSG91c2VzIEJvdWdodCIsIHhsYWI9IiIpDQpgYGANCg0KV2UgY2FuIHNlZSB0aGF0IHRoZSBudW1iZXIgb2YgaG91c2VzIHNvbGQgaW5jcmVhc2VzIGdyYWR1YWxseSB0aHJvdWdob3V0IHRoZSB5ZWFycyB3aXRoIGEgbGFyZ2Ugc3Bpa2UgcmlnaHQgYWZ0ZXIgMjAyMC4gVGhlIHRpbWUgc2VyaWVzIGZvciB0aGUgbW9zdCBwYXJ0IGlzIGFkZGl0aXZlLiANCg0KIyBGb3JlY2FzdGluZyB3aXRoIERlY29tcG9zaW5nIA0KDQpOZXh0LCB3ZSB3aWxsIHRyeSBmb3JlY2FzdGluZyB1c2luZyBib3RoIGNsYXNzaWNhbCBkZWNvbXBvc2luZyBhbmQgU1RMIGRlY29tcG9zaW5nIHRvIHNlZSB3aGljaCBvbmUgcGVyZm9ybXMgYmV0dGVyLiANCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuY2FwPSAiQ2xhc3NpY2FsIGRlY29tcG9zaXRpb24gb2YgYWRkaXRpdmUgdGltZSBzZXJpZXMiLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KY2xzLmRlY29tcCA9IGRlY29tcG9zZShob3VzZS50cykNCnBhcihtYXI9YygyLDIsMiwyKSkNCnBsb3QoY2xzLmRlY29tcCwgeGxhYj0iIikNCmBgYA0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuY2FwPSAiU1RMIGRlY29tcG9zaXRpb24gb2YgYWRkaXRpdmUgdGltZSBzZXJpZXMiLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD00fQ0Kc3RsLmRlY29tcD1zdGwoaG91c2UudHMsIHMud2luZG93ID0gMTIpDQpwYXIobWFyPWMoMiwyLDIsMikpDQpwbG90KHN0bC5kZWNvbXApDQpgYGANCldlIGNhbiBzZWUgdGhhdCBpbiB0aGlzIGNhc2UsIFNUTCBkZWNvbXBvc2l0aW9uIHdvcmtzIGEgbGl0dGxlIGJldHRlciBmb3Igb3VyIGRhdGEuIFdoaWxlIHRoZSB0aW1lIHNlcmllcyBpcyBhZGRpdGl2ZSBhbmQgcmVsYXRpdmVseSBjb25zdGFudCwgdGhlcmUgaXMgYSBsYXJnZSBzcGlrZSBpbiB0aGUgbnVtYmVyIG9mIGhvdXNlcyBzb2xkIHJpZ2h0IGFmdGVyIDIwMjAsIGNyZWF0aW5nIGEgZmV3IG91dGxpZXJzLiBTaW5jZSBTVEwgZGVjb21wb3NpdGlvbiBpcyBtb3JlIHJvYnVzdCwgaXQgd29ya3MgYmV0dGVyIGluIHRoaXMgY2FzZS4gDQoNCiMgRGF0YSBUcmFpbmluZyBhbmQgVGVzdGluZw0KDQpOZXh0LCB3ZSB3aWxsIGhvbGQgdGhlIGxhc3QgdGVuIHBlcmlvZHMgb2YgdGhlIGRhdGEgZm9yIHRlc3RpbmcuIFdlIHdpbGwgZGVmaW5lICBmb3VyIGRpZmZlcmVudCB0cmFpbmluZyBkYXRhIHNldHMuIFRoZSB0cmFpbmluZyBzZXQgc2l6ZXMgdXNlZCBpbiB0aGlzIGFuYWx5c2lzIGFyZSAxNDQsIDEwOSwgNzMsIGFuZCA0OC4gVGhlIHNhbWUgdGVzdCBzZXQgd2l0aCBzaXplIHRlbiB3aWxsIGJlIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBwcmVkaWN0aW9uIGVycm9yLg0KDQpgYGB7cn0NCmluaS5kYXRhID0gZGF0YS5ob3VzZVssMl0NCm4wID0gbGVuZ3RoKGluaS5kYXRhKQ0KIyMNCnRyYWluLmRhdGEwMSA9IGRhdGEuaG91c2VbMToobjAtNyksIDJdDQp0cmFpbi5kYXRhMDIgPSBkYXRhLmhvdXNlWzM3OihuMC03KSwgMl0NCnRyYWluLmRhdGEwMyA9IGRhdGEuaG91c2VbNzM6KG4wLTcpLCAyXQ0KdHJhaW4uZGF0YTA0ID0gZGF0YS5ob3VzZVs5NzoobjAtNyksIDJdDQojIyBsYXN0IDcgb2JzZXJ2YXRpb25zDQp0ZXN0LmRhdGEgPSBkYXRhLmhvdXNlWyhuMC02KTpuMCwyXQ0KIyMNCnRyYWluMDEudHMgPSB0cyh0cmFpbi5kYXRhMDEsIGZyZXF1ZW5jeSA9IDEyLCBzdGFydCA9IGMoMjAxMiwgMSkpDQp0cmFpbjAyLnRzID0gdHModHJhaW4uZGF0YTAyLCBmcmVxdWVuY3kgPSAxMiwgc3RhcnQgPSBjKDIwMTUsIDEpKQ0KdHJhaW4wMy50cyA9IHRzKHRyYWluLmRhdGEwMywgZnJlcXVlbmN5ID0gMTIsIHN0YXJ0ID0gYygyMDE4LCAxKSkNCnRyYWluMDQudHMgPSB0cyh0cmFpbi5kYXRhMDQsIGZyZXF1ZW5jeSA9IDEyLCBzdGFydCA9IGMoMjAyMCwgMSkpDQojIw0Kc3RsMDEgPSBzdGwodHJhaW4wMS50cywgcy53aW5kb3cgPSAxMikNCnN0bDAyID0gc3RsKHRyYWluMDIudHMsIHMud2luZG93ID0gMTIpDQpzdGwwMyA9IHN0bCh0cmFpbjAzLnRzLCBzLndpbmRvdyA9IDEyKQ0Kc3RsMDQgPSBzdGwodHJhaW4wNC50cywgcy53aW5kb3cgPSAxMikNCiMjIEZvcmVjYXN0IHdpdGggZGVjb21wb3NpbmcNCmZjc3QwMSA9IGZvcmVjYXN0KHN0bDAxLGg9MTAsIG1ldGhvZD0ibmFpdmUiKQ0KZmNzdDAyID0gZm9yZWNhc3Qoc3RsMDIsaD0xMCwgbWV0aG9kPSJuYWl2ZSIpDQpmY3N0MDMgPSBmb3JlY2FzdChzdGwwMyxoPTEwLCBtZXRob2Q9Im5haXZlIikNCmZjc3QwNCA9IGZvcmVjYXN0KHN0bDA0LGg9MTAsIG1ldGhvZD0ibmFpdmUiKQ0KDQpgYGANCg0KTmV4dCwgd2UgcGVyZm9ybSBlcnJvciBhbmFseXNpcy4NCg0KYGBge3J9DQpQRTAxPSh0ZXN0LmRhdGEtZmNzdDAxJG1lYW4pL2Zjc3QwMSRtZWFuDQpQRTAyPSh0ZXN0LmRhdGEtZmNzdDAyJG1lYW4pL2Zjc3QwMiRtZWFuDQpQRTAzPSh0ZXN0LmRhdGEtZmNzdDAzJG1lYW4pL2Zjc3QwMyRtZWFuDQpQRTA0PSh0ZXN0LmRhdGEtZmNzdDA0JG1lYW4pL2Zjc3QwNCRtZWFuDQojIyMNCk1BUEUxID0gbWVhbihhYnMoUEUwMSkpDQpNQVBFMiA9IG1lYW4oYWJzKFBFMDIpKQ0KTUFQRTMgPSBtZWFuKGFicyhQRTAzKSkNCk1BUEU0ID0gbWVhbihhYnMoUEUwNCkpDQojIyMNCkUxPXRlc3QuZGF0YS1mY3N0MDEkbWVhbg0KRTI9dGVzdC5kYXRhLWZjc3QwMiRtZWFuDQpFMz10ZXN0LmRhdGEtZmNzdDAzJG1lYW4NCkU0PXRlc3QuZGF0YS1mY3N0MDQkbWVhbg0KIyMNCk1TRTE9bWVhbihFMV4yKQ0KTVNFMj1tZWFuKEUyXjIpDQpNU0UzPW1lYW4oRTNeMikNCk1TRTQ9bWVhbihFNF4yKQ0KIyMjDQpNU0U9YyhNU0UxLCBNU0UyLCBNU0UzLCBNU0U0KQ0KTUFQRT1jKE1BUEUxLCBNQVBFMiwgTUFQRTMsIE1BUEU0KQ0KYWNjdXJhY3k9Y2JpbmQoTVNFPU1TRSwgTUFQRT1NQVBFKQ0Kcm93Lm5hbWVzKGFjY3VyYWN5KT1jKCJuLjE0NCIsICJuLjEwOSIsICJuLiA3MyIsICJuLiA0OCIpDQprYWJsZShhY2N1cmFjeSwgY2FwdGlvbj0iRXJyb3IgY29tcGFyaXNvbiBiZXR3ZWVuIGZvcmVjYXN0IHJlc3VsdHMgd2l0aCBkaWZmZXJlbnQgc2FtcGxlIHNpemVzIikNCmBgYA0KDQpXZSBjYW4gc2VlIGZyb20gdGhlIHRhYmxlIGFib3ZlIHRoYXQgYSB0cmFpbmluZyBzaXplIG9mIDEwOSBwZXJmb3JtcyB0aGUgYmVzdCBhbmQgaGFzIHRoZSBsb3dlc3QgZXJyb3JzLiBXaGlsZSB0aGUgbWVhbiBzcXVhcmUgZXJyb3JzIGxvb2sgbm9ybWFsLCB0aGUgbWVhbiBhYnNvbHV0ZSBwZXJjZW50YWdlIGVycm9yIGlzIHdlbGwgaW50byB0aGUgdGhvdXNhbmRzLiBTb21lIHBvc3NpYmxlIHJlYXNvbnMgZm9yIHRoaXMgYXJlIHRoZSBvYnNlcnZhdGlvbnMgaW4gb3VyIHRpbWUgc2VyaWVzIHJhbmdlcyBmcm9tIGFib3V0IDMwMCB0byBhIGxpdHRsZSBvdmVyIG9uZSB0aG91c2FuZC4gVGhlIHRpbWUgc2VyaWVzIGFsc28gZm9sbG93cyBzZXZlcmFsIHBhdHRlcm5zIGluY2x1ZGluZyBzZWFzb25hbCB0cmVuZHMgYW5kIGJlaW5nIGFkZGl0aXZlLiBXZSB3aWxsIHRha2UgYSBjbG9zZXIgbG9vayBhdCB0aGUgZXJyb3JzIG5leHQgYnkgbWFraW5nIG9uZSBncmFwaCBmb3IgdGhlIE1TRSBhbmQgb25lIGZvciB0aGUgTUFQRS4gDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmNhcD0gIkNvbXBhcmluZyBmb3JlY2FzdCBlcnJvcnMiLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD00fQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QoMTo0LCBNU0UsIHR5cGU9ImIiLCBjb2w9ImRhcmtyZWQiLCB5bGFiPSJFcnJvciIsIHhsYWI9IiIsDQogICAgICN5bGltPWMoMC40LC44NSkseGxpbSA9IGMoMC41LDQuNSksIA0KICAgICBtYWluPSJNU0UiLCBheGVzPUZBTFNFKQ0KbGFicz1jKCJuPTE0NCIsICJuPTEwOSIsICJuPTczIiwgIm49NDgiKQ0KYXhpcygxLCBhdD0xOjQsIGxhYmVsPWxhYnMpDQpheGlzKDIpDQojbGluZXMoMTo0LCBNQVBFLCB0eXBlPSJiIiwgY29sPSJibHVlIikNCnRleHQoMTo0LCBNQVBFKzAuMDMsIGFzLmNoYXJhY3Rlcihyb3VuZChNQVBFLDQpKSwgY29sPSJibHVlIiwgY2V4PTAuNykNCnRleHQoMTo0LCBNU0UtMC4wMywgYXMuY2hhcmFjdGVyKHJvdW5kKE1TRSw0KSksIGNvbD0iZGFya3JlZCIsIGNleD0wLjcpDQpsZWdlbmQoMS41LCAwLjYzLCBjKCJNU0UiLCAiTUFQRSIpLCBjb2w9YygiZGFya3JlZCIsImJsdWUiKSwgbHR5PTEsIGJ0eT0ibiIsIGNleD0wLjcpDQojIyMNCiNgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5jYXA9ICJDb21wYXJpbmcgZm9yZWNhc3QgZXJyb3JzIiwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9My41fQ0KcGxvdCgxOjQsIE1BUEUsIHR5cGU9ImIiLCBjb2w9ImRhcmtyZWQiLCB5bGFiPSJFcnJvciIsIHhsYWI9IiIsDQogICAgICN5bGltPWMoMC40LC44NSkseGxpbSA9IGMoMC41LDQuNSksIA0KICAgICBtYWluPSJNQVBFIiwgYXhlcz1GQUxTRSkNCmxhYnM9Yygibj0xNDQiLCAibj0xMDkiLCAibj03MyIsICJuPTQ4IikNCmF4aXMoMSwgYXQ9MTo0LCBsYWJlbD1sYWJzKQ0KYXhpcygyKQ0KYGBgDQoNCiMgU3VtbWFyeSBhbmQgQ29uY2x1c2lvbg0KDQpUbyBjb25jbHVkZSwgd2UgZXhhbWluZWQgYSB0aW1lIHNlcmllcyBmcm9tIHRoZSB5ZWFycyAyMDEyIHRvIDIwMjQgdG90YWxpbmcgMTUxIG9ic2VydmF0aW9ucy4gVGhlIGRhdGEgbG9va3MgYXQgdGhlIG51bWJlciBvZiBob3VzZXMgc29sZCBpbiB0aGUgVW5pdGVkIFN0YXRlcyBmb3IgZWFjaCBtb250aCBvZiB0aGUgeWVhcnMgcmVjb3JkZWQuIFdlIG5vdGljZWQgdGhhdCB0aGUgdGltZSBzZXJpZXMgZm9sbG93cyBhIG1vc3RseSBzZWFzb25hbCB0cmVuZCB0aGF0IGlzIGFkZGl0aXZlLiBUaGUgb25seSBleGNlcHRpb24gd2FzIGEgc3Bpa2UgaW4gdGhlIG9ic2VydmF0aW9ucyBhZnRlciAyMDIwIHRoYXQgZXZlbnR1YWxseSB3ZW50IGJhY2sgZG93bi4gV2UgZm91bmQgdGhhdCBTVEwgZGVjb21wb3NpdGlvbiB3b3JrcyBiZXR0ZXIgZm9yIHRoaXMgdGltZSBzZXJpZXMgYmVjYXVzZSBpdCBpcyBtb3JlIHJvYnVzdC4gV2VyZSB0aGlzIGFuYWx5c2lzIHRvIGJlIGNvbnRpbnVlZCBpbiB0aGUgZnV0dXJlLCBJIHdvdWxkIGZvY3VzIG9uIHJlZHVjaW5nIHRoZSBNQVBFLiBBIHdheSBJIHdvdWxkIHRyeSB0byBkbyB0aGlzIHdvdWxkIGJlIGJ5IHVzaW5nIGEgZGlmZmVyZW50IG1vZGVsIHRoYXQgYWNjb3VudHMgbW9yZSBmb3Igc2Vhc29uYWwgcGF0dGVybnMgYW5kIHBvc3NpYmx5IG91dGxpZXJzIHRoYXQgZG8gbm90IGZvbGxvdyBhIHBhdHRlcm4gc2luY2UgdGhpcyB0aW1lIHNlcmllcyBjb250YWlucyBhIGZldy4gDQoNCg==