From ee15e3377d897fdaec61bafbdf2bf5d3557391e0 Mon Sep 17 00:00:00 2001 From: codingconcepts Date: Tue, 14 Aug 2018 19:59:58 +0100 Subject: [PATCH] Fixed issue whereby empty RawJSON objects would cause MarshalJSON to fail --- main-packr.go | 4 ++-- tmpl/x_helpers.html | 3 +++ tmpl/x_helpers_test.html | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/main-packr.go b/main-packr.go index 236101d..4ccd76c 100644 --- a/main-packr.go +++ b/main-packr.go @@ -12,6 +12,6 @@ func init() { packr.PackJSONBytes("./tmpl", "model.html", "\"e3tkZWZpbmUgIm1vZGVsIn19CnBhY2thZ2Uge3sgLlBhY2thZ2VOYW1lIH19CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBDb2RlIGdlbmVyYXRlZCBieSBtb2RlbGdlbiB8CnwgICAgICAgIERPIE5PVCBFRElULiAgICAgICAgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIElmIHlvdSB3YW50IHRvIGV4dGVuZCBiZWhhdmlvdXI6Ci8vIFBsZWFzZSBjcmVhdGUgYSBjdXN0b20gZmlsZSBpbiB0aGlzIGRpcmVjdG9yeQovLyBhbmQgY3JlYXRlIHRoZSBtZXRob2RzIHRoZXJlIHRvIGF2b2lkIG92ZXJ3cml0aW5nIHlvdXIgY29kZSB3aXRoIHRoZSBnZW5lcmF0ZWQgb25lLgoKaW1wb3J0ICgKImZtdCIKICAgIHt7IHJhbmdlICRrLCAkdjo9IC5Nb2RlbC5JbXBvcnRzIH19CiAgICAie3ska319IgogICAge3stIGVuZCB9fQopCgovLyB7ey5Nb2RlbC5OYW1lfX0gcmVwcmVzZW50cyBhIHJvdyBpbiB0aGUge3suTW9kZWwuVGFibGVOYW1lfX0gdGFibGUKdHlwZSB7ey5Nb2RlbC5OYW1lfX0gc3RydWN0IHsKICAgIHt7IHJhbmdlICRrLCAkdjo9IC5Nb2RlbC5GaWVsZHMgfX0KICAgICAgICB7eyAkdi5OYW1lIH19IHt7ICR2LlR5cGUgfX0gYGpzb246Int7JHYuQ29sdW1uTmFtZX19ImAKICAgIHt7LSBlbmQgfX0Kb2Zmc2V0IGludApsaW1pdCBpbnQKfQoKLy8gSW5zZXJ0IGEgbmV3IHt7Lk1vZGVsLk5hbWV9fSByb3cgaW4gdGhlIHt7Lk1vZGVsLlRhYmxlTmFtZX19IHRhYmxlCmZ1bmMgKHt7LlJlY2VpdmVyfX0gKnt7Lk1vZGVsLk5hbWV9fSkgSW5zZXJ0KHF1IFF1ZXJ5ZXIpIChsYXN0SW5zZXJ0SUQgaW50NjQsIGVyciBlcnJvcikgewogICAgY29uc3Qgc3RtdCA9ICJJTlNFUlQgSU5UTyB7ey5Nb2RlbC5UYWJsZU5hbWV9fSAoe3suTW9kZWwuRmllbGRzIHwgaW5zZXJ0X2ZpZWxkc319KSBWQUxVRVMgKHt7Lk1vZGVsLkZpZWxkcyB8IGluc2VydF92YWx1ZXN9fSkiCiAgICByZXMsIGVyciA6PSBxdS5FeGVjKHN0bXQsIHt7IC4gfCBpbnNlcnRfYXJncyB9fSkKICAgIGlmIGVyciAhPSBuaWwgewogICAgICAgIHJldHVybiAwLCBlcnIKICAgIH0KICAgIHJldHVybiByZXMuTGFzdEluc2VydElkKCkKfQoKLy8gVXBkYXRlIGFuIGV4aXN0aW5nIHt7Lk1vZGVsLk5hbWV9fSByb3cgaW4gdGhlIHt7Lk1vZGVsLlRhYmxlTmFtZX19IHRhYmxlLgpmdW5jICh7ey5SZWNlaXZlcn19ICp7ey5Nb2RlbC5OYW1lfX0pIFVwZGF0ZShxdSBRdWVyeWVyLCBpZCBpbnQ2NCkgKGludDY0LCBlcnJvcikgewogICAgY29uc3Qgc3RtdCA9ICJVUERBVEUge3suTW9kZWwuVGFibGVOYW1lfX0gU0VUIHt7IC4gfCB1cGRhdGVfdmFsdWVzIH19IFdIRVJFIGlkID0gPyIKICAgIHJlc3VsdCwgZXJyIDo9IHF1LkV4ZWMoc3RtdCwge3sgLiB8IHVwZGF0ZV9hcmdzIH19ICwgaWQpCiAgICBpZiBlcnIgIT0gbmlsIHsKICAgICAgICByZXR1cm4gMCwgZXJyCiAgICB9CiAgICByZXR1cm4gcmVzdWx0LlJvd3NBZmZlY3RlZCgpCn0KCi8vIFVwc2VydCBpbnNlcnRzIGEgbmV3IHt7Lk1vZGVsLk5hbWV9fSByb3cgaW4gdGhlIHt7Lk1vZGVsLlRhYmxlTmFtZX19IHRhYmxlCi8vIGlmIHRoZSB1bmlxdWUgY29uc3RyYWludHMgYXJlIG5vdCBmb3VuZCwgb3RoZXJ3aXNlIGl0IHVwZGF0ZXMgaXQuCmZ1bmMgKHt7LlJlY2VpdmVyfX0gKnt7Lk1vZGVsLk5hbWV9fSkgVXBzZXJ0KHF1IFF1ZXJ5ZXIpIChsYXN0SW5zZXJ0SUQgaW50NjQsIGVyciBlcnJvcikgewogICAgY29uc3Qgc3RtdCA9ICJJTlNFUlQgSU5UTyB7ey5Nb2RlbC5UYWJsZU5hbWV9fSAoe3suTW9kZWwuRmllbGRzIHwgdXBzZXJ0X2ZpZWxkc319KSBWQUxVRVMgKHt7Lk1vZGVsLkZpZWxkcyB8IHVwc2VydF92YWx1ZXN9fSkgT04gRFVQTElDQVRFIEtFWSBVUERBVEUge3sgLiB8IHVwc2VydF9vbl9kdXBsaWNhdGUgfX0iCiAgICByZXMsIGVyciA6PSBxdS5FeGVjKHN0bXQsIHt7IC4gfCB1cHNlcnRfYXJncyB9fSkKICAgIGlmIGVyciAhPSBuaWwgewogICAgICAgIHJldHVybiAwLCBlcnIKICAgIH0KICAgIHJldHVybiByZXMuTGFzdEluc2VydElkKCkKfQoKLy8gRmluZCBhbiBleGlzdGluZyB7ey5Nb2RlbC5OYW1lfX0gcm93IGluIHRoZSB7ey5Nb2RlbC5UYWJsZU5hbWV9fSB0YWJsZQpmdW5jICh7ey5SZWNlaXZlcn19ICp7ey5Nb2RlbC5OYW1lfX0pIEZpbmQocXUgUXVlcnllciwgaWQgaW50NjQpIGVycm9yIHsKICAgIGNvbnN0IHN0bXQgPSAiU0VMRUNUICogRlJPTSB7ey5Nb2RlbC5UYWJsZU5hbWV9fSBXSEVSRSBpZCA9ID8iCiAgICByb3cgOj0gcXUuUXVlcnlSb3coc3RtdCwgaWQpCiAgICByZXR1cm4gcm93LlNjYW4oe3sgLiB8IHNjYW5fZmllbGRzfX0pCn0KCi8vIExvYWQgYWxsLCBvciBhIHN1YnNldCBvZiB7ey5Nb2RlbC5OYW1lfX0gcm93cyBmcm9tIHRoZSB7ey5Nb2RlbC5UYWJsZU5hbWV9fSB0YWJsZQpmdW5jICh7ey5SZWNlaXZlcn19ICp7ey5Nb2RlbC5OYW1lfX0pIExvYWQocXUgUXVlcnllcikgKHNldCBbXXt7Lk1vZGVsLk5hbWV9fSwgZXJyIGVycm9yKSB7CiAgICBzdG10IDo9ICJTRUxFQ1QgKiBGUk9NIHt7Lk1vZGVsLlRhYmxlTmFtZX19IgoKICAgIGlmIHt7LlJlY2VpdmVyfX0ubGltaXQgPT0gMCAmJiB7ey5SZWNlaXZlcn19Lm9mZnNldCA+IDAgewogICAgICAgIHJldHVybiBzZXQsIGZtdC5FcnJvcmYoImNhbm5vdCBxdWVyeSB3aXRoIG9mZnNldCBidXQgbm8gbGltaXQiKQogICAgfQoKICAgIGlmIHt7LlJlY2VpdmVyfX0ubGltaXQgPiAwIHsKICAgICAgICBzdG10ICs9IGZtdC5TcHJpbnRmKCIgTElNSVQgJWQiLCB7ey5SZWNlaXZlcn19LmxpbWl0KQogICAgfQogICAgaWYge3suUmVjZWl2ZXJ9fS5vZmZzZXQgPiAwIHsKICAgICAgICBzdG10ICs9IGZtdC5TcHJpbnRmKCIgT0ZGU0VUICVkIiwge3suUmVjZWl2ZXJ9fS5vZmZzZXQpCiAgICB9CiAgICBkZWZlciBmdW5jKCkgewogICAgICAgIHt7LlJlY2VpdmVyfX0ubGltaXQgPSAwCiAgICAgICAge3suUmVjZWl2ZXJ9fS5vZmZzZXQgPSAwCiAgICB9KCkKICAgIHJvd3MsIGVyciA6PSBxdS5RdWVyeShzdG10KQogICAgaWYgZXJyICE9IG5pbCB7CiAgICAgICAgcmV0dXJuCiAgICB9CiAgICBkZWZlciByb3dzLkNsb3NlKCkKICAgICAgICBmb3Igcm93cy5OZXh0KCkgewogICAgICAgICAgICB2YXIge3suUmVjZWl2ZXJ9fSB7ey5Nb2RlbC5OYW1lfX0KICAgICAgICAgICAgaWYgZXJyID0gcm93cy5TY2FuKHt7LiB8IHNjYW5fZmllbGRzfX0pOyBlcnIgIT0gbmlsIHsKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgfQogICAgICAgIHNldCA9IGFwcGVuZChzZXQsIHt7LlJlY2VpdmVyfX0pCiAgICB9CgogICAgcmV0dXJuCn0KCi8vIERlbGV0ZSBhbiBleGlzdGluZyB7ey5Nb2RlbC5OYW1lfX0gcm93IGZyb20gdGhlIHt7Lk1vZGVsLlRhYmxlTmFtZX19IHRhYmxlCmZ1bmMgKHt7LlJlY2VpdmVyfX0gKnt7Lk1vZGVsLk5hbWV9fSkgRGVsZXRlKHF1IFF1ZXJ5ZXIsIGlkIGludDY0KSAocm93c0FmZmVjdGVkIGludDY0LCBlcnIgZXJyb3IpIHsKICAgIGNvbnN0IHN0bXQgPSAiREVMRVRFIEZST00ge3suTW9kZWwuVGFibGVOYW1lfX0gV0hFUkUgaWQgPSA/IgogICAgcmVzdWx0LCBlcnIgOj0gcXUuRXhlYyhzdG10LCBpZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybgoJfQoKCXJldHVybiByZXN1bHQuUm93c0FmZmVjdGVkKCkKfQoKLy8gQ291bnQgdGhlIG51bWJlciBvZiByb3dzIGZyb20gdGhlIHt7Lk1vZGVsLlRhYmxlTmFtZX19IHRhYmxlCmZ1bmMoe3suUmVjZWl2ZXJ9fSAqe3suTW9kZWwuTmFtZX19KSBDb3VudChxdSBRdWVyeWVyKSAoY291bnQgaW50NjQsIGVyciBlcnJvcikgewogICAgY29uc3Qgc3RtdCA9ICJTRUxFQ1QgQ09VTlQoKikgRlJPTSB7ey5Nb2RlbC5UYWJsZU5hbWV9fSIKICAgIHJvdyA6PSBxdS5RdWVyeVJvdyhzdG10KQogICAgaWYgZXJyID0gcm93LlNjYW4oJmNvdW50KTsgZXJyICE9IG5pbCB7CiAgICAgICAgcmV0dXJuCiAgICB9CiAgICByZXR1cm4KfQoKLy8gRXhpc3RzIGNoZWNrcyBmb3IgdGhlIGl0ZW1zIGV4aXN0ZW5jZSBpbiB0aGUgZGF0YWJhc2UsIGJhc2VkIG9uIGl0J3MgaWQuCi8vIEFuIGVycm9yIHdpbGwgb25seSBiZSByZXR1cm5lZCBpZiBhIFNRTCByZWxhdGVkIGZhaWx1cmUgaGFwcGVucy4KLy8gSW4gYWxsIG90aGVyIGNhc2VzLCBhIGJvb2wgYW5kIG5pbCB3aWxsIHJldHVybi4KZnVuYyh7ey5SZWNlaXZlcn19ICp7ey5Nb2RlbC5OYW1lfX0pIEV4aXN0cyhxdSBRdWVyeWVyLCBpZCBpbnQ2NCkgKGV4aXN0cyBib29sLCBlcnIgZXJyb3IpIHsKICAgIGNvbnN0IHN0bXQgPSAiU0VMRUNUIEVYSVNUUyhTRUxFQ1QgMSBGUk9NIHt7Lk1vZGVsLlRhYmxlTmFtZX19IFdIRVJFIGlkID0gPyBMSU1JVCAxKSBBUyBgZXhpc3RzYCIKICAgIHZhciBjb3VudCBpbnQKICAgIHJvdyA6PSBxdS5RdWVyeVJvdyhzdG10LCBpZCkKICAgIGlmIGVyciA9IHJvdy5TY2FuKCZjb3VudCk7IGVyciAhPSBuaWwgewogICAgICAgIHJldHVybgogICAgfQogICAgcmV0dXJuIGNvdW50ID4gMCwgbmlsCn0KCi8vIFRhYmxlTmFtZSByZXR1cm5zIHRoZSB0YWJsZSBuYW1lCmZ1bmMgKHt7LlJlY2VpdmVyfX0gKnt7Lk1vZGVsLk5hbWV9fSkgVGFibGVOYW1lKCkgc3RyaW5nIHsKcmV0dXJuICJ7ey5Nb2RlbC5UYWJsZU5hbWV9fSIKfQoKLy8gU2V0TGltaXQgc2V0cyB0aGUgcXVlcnkgbGltaXQKZnVuYyAoe3suUmVjZWl2ZXJ9fSAqe3suTW9kZWwuTmFtZX19KSBTZXRMaW1pdChsaW1pdCBpbnQpICp7ey5Nb2RlbC5OYW1lfX0gewp7ey5SZWNlaXZlcn19LmxpbWl0ID0gbGltaXQKcmV0dXJuIHt7LlJlY2VpdmVyfX0KfQoKLy8gU2V0T2Zmc2V0IHNldHMgdGhlIHF1ZXJ5IG9mZnNldApmdW5jICh7ey5SZWNlaXZlcn19ICp7ey5Nb2RlbC5OYW1lfX0pIFNldE9mZnNldChvZmZzZXQgaW50KSAqe3suTW9kZWwuTmFtZX19IHsKe3suUmVjZWl2ZXJ9fS5vZmZzZXQgPSBvZmZzZXQKcmV0dXJuIHt7LlJlY2VpdmVyfX0KfQp7e2VuZH19Cgo=\"") packr.PackJSONBytes("./tmpl", "tmpl.go", "\"cGFja2FnZSB0bXBsCgppbXBvcnQgKAoJImZtdCIKCSJodG1sL3RlbXBsYXRlIgoJInN0cmluZ3MiCikKCnZhciBGdW5jTWFwID0gdGVtcGxhdGUuRnVuY01hcHsKCSJpbnNlcnRfZmllbGRzIjogR2V0SW5zZXJ0RmllbGRzLAoJImluc2VydF92YWx1ZXMiOiBHZXRJbnNlcnRWYWx1ZXMsCgkiaW5zZXJ0X2FyZ3MiOiAgIEdldEluc2VydEFyZ3MsCgkic2Nhbl9maWVsZHMiOiAgIEdldFNjYW5GaWVsZHMsCgkidXBkYXRlX2FyZ3MiOiAgIEdldFVwZGF0ZUFyZ3MsCgkidXBkYXRlX3ZhbHVlcyI6IEdldFVwZGF0ZVZhbHVlcywKCSJ1cHNlcnRfZmllbGRzIjogR2V0VXBzZXJ0RmllbGRzLAoJInVwc2VydF92YWx1ZXMiOiBHZXRVcHNlcnRWYWx1ZXMsCgkidXBzZXJ0X29uX2R1cGxpY2F0ZSI6IEdldFVwc2VydE9uRHVwbGljYXRlLAoJInVwc2VydF9hcmdzIjogR2V0VXBzZXJ0QXJncywKfQoKZnVuYyBHZXRJbnNlcnRGaWVsZHMoZmllbGRzIFtdVG1wbEZpZWxkKSBzdHJpbmcgewoJdmFyIHBhcnRzIFtdc3RyaW5nCglmb3IgXywgZmwgOj0gcmFuZ2UgZmllbGRzIHsKCQlpZiBmbC5Db2x1bW5OYW1lID09ICJpZCIgewoJCQljb250aW51ZQoJCX0KCQlwYXJ0cyA9IGFwcGVuZChwYXJ0cywgImAiK2ZsLkNvbHVtbk5hbWUrImAiKQoJfQoJcmV0dXJuIHN0cmluZ3MuSm9pbihwYXJ0cywgIiwgIikKfQoKZnVuYyBHZXRJbnNlcnRWYWx1ZXMoZmllbGRzIFtdVG1wbEZpZWxkKSBzdHJpbmcgewoJdmFyIHBhcnRzIFtdc3RyaW5nCglmb3IgXywgZmwgOj0gcmFuZ2UgZmllbGRzIHsKCQlzd2l0Y2ggZmwuQ29sdW1uTmFtZSB7CgkJY2FzZSAiaWQiOgoJCQljb250aW51ZQoJCWNhc2UgImNyZWF0ZWRfYXQiOgoJCQlwYXJ0cyA9IGFwcGVuZChwYXJ0cywgIk5PVygpIikKCQkJY29udGludWUKCQlkZWZhdWx0OgoJCQlwYXJ0cyA9IGFwcGVuZChwYXJ0cywgIj8iKQoJCX0KCX0KCXJldHVybiBzdHJpbmdzLkpvaW4ocGFydHMsICIsICIpCn0KCmZ1bmMgR2V0SW5zZXJ0QXJncyhtIFN0cnVjdFRtcGxEYXRhKSBzdHJpbmcgewoJdmFyIHBhcnRzIFtdc3RyaW5nCglmb3IgXywgZmwgOj0gcmFuZ2UgbS5Nb2RlbC5GaWVsZHMgewoJCXN3aXRjaCBmbC5OYW1lIHsKCQljYXNlICJJRCIsICJDcmVhdGVkQXQiOgoJCQljb250aW51ZQoJCX0KCQlwYXJ0cyA9IGFwcGVuZChwYXJ0cywgZm10LlNwcmludGYoIiVzLiVzIiwgbS5SZWNlaXZlciwgZmwuTmFtZSkpCgl9CglyZXR1cm4gc3RyaW5ncy5Kb2luKHBhcnRzLCAiLCAiKQp9CgpmdW5jIEdldFNjYW5GaWVsZHMobSBTdHJ1Y3RUbXBsRGF0YSkgdGVtcGxhdGUuSFRNTCB7Cgl2YXIgcGFydHMgW11zdHJpbmcKCWZvciBfLCBmbCA6PSByYW5nZSBtLk1vZGVsLkZpZWxkcyB7CgkJcGFydHMgPSBhcHBlbmQocGFydHMsIGZtdC5TcHJpbnRmKCImJXMuJXMiLCBtLlJlY2VpdmVyLCBmbC5OYW1lKSkKCX0KCXJldHVybiB0ZW1wbGF0ZS5IVE1MKHN0cmluZ3MuSm9pbihwYXJ0cywgIiwgIikpCn0KCmZ1bmMgR2V0VXBkYXRlQXJncyhtIFN0cnVjdFRtcGxEYXRhKSB0ZW1wbGF0ZS5IVE1MIHsKCXZhciBwYXJ0cyBbXXN0cmluZwoJZm9yIF8sIGZsIDo9IHJhbmdlIG0uTW9kZWwuRmllbGRzIHsKCQlzd2l0Y2ggZmwuTmFtZSB7CgkJY2FzZSAiSUQiLCAiQ3JlYXRlZEF0IiwgIlVwZGF0ZWRBdCI6CgkJCWNvbnRpbnVlCgkJfQoJCXBhcnRzID0gYXBwZW5kKHBhcnRzLCBmbXQuU3ByaW50ZigiJXMuJXMiLCBtLlJlY2VpdmVyLCBmbC5OYW1lKSkKCX0KCXJldHVybiB0ZW1wbGF0ZS5IVE1MKHN0cmluZ3MuSm9pbihwYXJ0cywgIiwgIikpCn0KCmZ1bmMgR2V0VXBkYXRlVmFsdWVzKG0gU3RydWN0VG1wbERhdGEpIHN0cmluZyB7Cgl2YXIgcGFydHMgW11zdHJpbmcKCWZvciBfLCBmbCA6PSByYW5nZSBtLk1vZGVsLkZpZWxkcyB7CgkJc3dpdGNoIGZsLk5hbWUgewoJCWNhc2UgIklEIiwgIkNyZWF0ZWRBdCI6CgkJCWNvbnRpbnVlCgkJY2FzZSAiVXBkYXRlZEF0IjoKCQkJcGFydHMgPSBhcHBlbmQocGFydHMsIGZtdC5TcHJpbnRmKCJgJXNgPVVUQ19USU1FU1RBTVAoKSIsIGZsLkNvbHVtbk5hbWUpKQoJCWRlZmF1bHQ6CgkJCXBhcnRzID0gYXBwZW5kKHBhcnRzLCBmbXQuU3ByaW50ZigiYCVzYD0/IiwgZmwuQ29sdW1uTmFtZSkpCgkJfQoJfQoJcmV0dXJuIHN0cmluZ3MuSm9pbihwYXJ0cywgIiwgIikKfQoKZnVuYyBHZXRVcHNlcnRGaWVsZHMoZmllbGRzIFtdVG1wbEZpZWxkKSBzdHJpbmcgewoJdmFyIHBhcnRzIFtdc3RyaW5nCglmb3IgXywgZmwgOj0gcmFuZ2UgZmllbGRzIHsKCQlwYXJ0cyA9IGFwcGVuZChwYXJ0cywgImAiK2ZsLkNvbHVtbk5hbWUrImAiKQoJfQoJcmV0dXJuIHN0cmluZ3MuSm9pbihwYXJ0cywgIiwgIikKfQoKZnVuYyBHZXRVcHNlcnRWYWx1ZXMoZmllbGRzIFtdVG1wbEZpZWxkKSBzdHJpbmcgewoJdmFyIHBhcnRzIFtdc3RyaW5nCglmb3IgXywgZmwgOj0gcmFuZ2UgZmllbGRzIHsKCQlzd2l0Y2ggZmwuQ29sdW1uTmFtZSB7CgkJY2FzZSAiY3JlYXRlZF9hdCI6CgkJCXBhcnRzID0gYXBwZW5kKHBhcnRzLCAiTk9XKCkiKQoJCQljb250aW51ZQoJCWRlZmF1bHQ6CgkJCXBhcnRzID0gYXBwZW5kKHBhcnRzLCAiPyIpCgkJfQoJfQoJcmV0dXJuIHN0cmluZ3MuSm9pbihwYXJ0cywgIiwgIikKfQoKZnVuYyBHZXRVcHNlcnRPbkR1cGxpY2F0ZShtIFN0cnVjdFRtcGxEYXRhKSBzdHJpbmcgewoJdmFyIHBhcnRzIFtdc3RyaW5nCglmb3IgXywgZmwgOj0gcmFuZ2UgbS5Nb2RlbC5GaWVsZHMgewoJCXN3aXRjaCBmbC5OYW1lIHsKCQljYXNlICJDcmVhdGVkQXQiOgoJCQljb250aW51ZQoJCWNhc2UgIklEIjoKCQkJcGFydHMgPSBhcHBlbmQocGFydHMsIGZtdC5TcHJpbnRmKCJgJXNgPUxBU1RfSU5TRVJUX0lEKGAlc2ApIiwgZmwuQ29sdW1uTmFtZSwgZmwuQ29sdW1uTmFtZSkpCgkJY2FzZSAiVXBkYXRlZEF0IjoKCQkJcGFydHMgPSBhcHBlbmQocGFydHMsIGZtdC5TcHJpbnRmKCJgJXNgPVVUQ19USU1FU1RBTVAoKSIsIGZsLkNvbHVtbk5hbWUpKQoJCWRlZmF1bHQ6CgkJCXBhcnRzID0gYXBwZW5kKHBhcnRzLCBmbXQuU3ByaW50ZigiYCVzYD1WQUxVRVMoYCVzYCkiLCBmbC5Db2x1bW5OYW1lLCBmbC5Db2x1bW5OYW1lKSkKCQl9Cgl9CglyZXR1cm4gc3RyaW5ncy5Kb2luKHBhcnRzLCAiLCAiKQp9CgpmdW5jIEdldFVwc2VydEFyZ3MobSBTdHJ1Y3RUbXBsRGF0YSkgc3RyaW5nIHsKCXZhciBwYXJ0cyBbXXN0cmluZwoJZm9yIF8sIGZsIDo9IHJhbmdlIG0uTW9kZWwuRmllbGRzIHsKCQlzd2l0Y2ggZmwuTmFtZSB7CgkJY2FzZSAiQ3JlYXRlZEF0IjoKCQkJY29udGludWUKCQl9CgkJcGFydHMgPSBhcHBlbmQocGFydHMsIGZtdC5TcHJpbnRmKCIlcy4lcyIsIG0uUmVjZWl2ZXIsIGZsLk5hbWUpKQoJfQoJcmV0dXJuIHN0cmluZ3MuSm9pbihwYXJ0cywgIiwgIikKfQ==\"") packr.PackJSONBytes("./tmpl", "types.go", "\"cGFja2FnZSB0bXBsCgovLyBUbXBsU3RydWN0cyBpcyBhIGNvbGxlY3Rpb24gb24gVG1wbFN0cnVjdAp0eXBlIFRtcGxTdHJ1Y3RzIFtdVG1wbFN0cnVjdAoKLy8gVG1wbFN0cnVjdCBkZWZpbmVzIHRoZSB0YWJsZSBkYXRhIHRvIHBhc3MgdG8gdGhlIG1vZGVscwp0eXBlIFRtcGxTdHJ1Y3Qgc3RydWN0IHsKCU5hbWUgICAgICBzdHJpbmcKCVRhYmxlTmFtZSBzdHJpbmcKCUZpZWxkcyAgICBbXVRtcGxGaWVsZAoJSW1wb3J0cyAgIG1hcFtzdHJpbmddc3RydWN0e30KfQoKLy8gVG1wbEZpZWxkIGRlZmluZXMgYSB0YWJsZSBmaWVsZCB0ZW1wbGF0ZQp0eXBlIFRtcGxGaWVsZCBzdHJ1Y3QgewoJTmFtZSAgICAgICBzdHJpbmcKCVR5cGUgICAgICAgc3RyaW5nCglDb2x1bW5OYW1lIHN0cmluZwoJTnVsbGFibGUgICBib29sCn0KCi8vIFN0cnVjdFRtcGxEYXRhIGRlZmluZXMgdGhlIHRvcCBsZXZlbCBzdHJ1Y3QgZGF0YSB0byBwYXNzIHRvIHRoZSBtb2RlbHMKdHlwZSBTdHJ1Y3RUbXBsRGF0YSBzdHJ1Y3QgewoJTW9kZWwgICAgICAgVG1wbFN0cnVjdAoJUmVjZWl2ZXIgICAgc3RyaW5nCglQYWNrYWdlTmFtZSBzdHJpbmcKfQo=\"") - packr.PackJSONBytes("./tmpl", "x_helpers.html", "\"e3tkZWZpbmUgImhlbHBlcnMifX0KCnBhY2thZ2Uge3sgLlBhY2thZ2VOYW1lIH19CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBDb2RlIGdlbmVyYXRlZCBieSBtb2RlbGdlbiB8CnwgICAgICAgIERPIE5PVCBFRElULiAgICAgICAgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCmltcG9ydCAoCgkiYnl0ZXMiCgkiY29udGV4dCIKCSJkYXRhYmFzZS9zcWwiCgkiZGF0YWJhc2Uvc3FsL2RyaXZlciIKCSJlbmNvZGluZy9qc29uIgoJImZtdCIKCSJsb2ciCgkicmVmbGVjdCIKCSJzdHJpbmdzIgoJInRpbWUiCgoJImdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbCIKKQoKLy8gU3RkVGltZSBwcm92aWRlcyBkZWZhdWx0IFNRTCBUSU1FIGZvcm1hdApjb25zdCBTdGRUaW1lID0gIjE1OjA0OjA1IgoKLy8gZW1wdHlUaW1lIGFsbG93cyBkZWZhdWx0IHRpbWVzIHRvIGJlIGNvbnNpZGVyZWQKLy8gbnVsbCBmb3IgaW5zZXJ0aW9uIGludG8gdGhlIGRhdGFiYXNlLgp2YXIgZW1wdHlUaW1lID0gdGltZS5UaW1le30KCi8vIG51bGxMaXRlcmFsIGlzIGhlbHBmdWwgZm9yIGNoZWNraW5nCi8vIGZvciBudWxscywgYXMgdGhleSB3b24ndCBjYXVzZSBlcnJvcnMsCi8vIHlldCB3ZSBuZWVkIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlIHRvIGNoYW5nZSBhbnl3YXkKdmFyIG51bGxMaXRlcmFsID0gW11ieXRlKCJudWxsIikKCi8qKioqKioqKgoqIFR5cGVzICoKKioqKioqKiovCgovLyBRdWVyeWVyIGFsbG93cyBzcWwuREIgYW5kIHNxbC5UeCB0byBiZSB1c2VkIGludGVyY2hhbmdlYWJseSwgYWxsb3dpbmcgeW91Ci8vIHRvIHVzZSBhbnkgb2YgdGhlIG1vZGVsIG1ldGhvZHMgaW5zaWRlIHRyYW5zYWN0aW9ucyBvciBzdGFuZGFsb25lIGNhbGxzLgp0eXBlIFF1ZXJ5ZXIgaW50ZXJmYWNlIHsKCVF1ZXJ5KHF1ZXJ5IHN0cmluZywgYXJncyAuLi5pbnRlcmZhY2V7fSkgKCpzcWwuUm93cywgZXJyb3IpCglRdWVyeVJvdyhxdWVyeSBzdHJpbmcsIGFyZ3MgLi4uaW50ZXJmYWNle30pICpzcWwuUm93CglFeGVjKHF1ZXJ5IHN0cmluZywgYXJncyAuLi5pbnRlcmZhY2V7fSkgKHNxbC5SZXN1bHQsIGVycm9yKQoJQmVnaW5UeChjdHggY29udGV4dC5Db250ZXh0LCBvcHRzICpzcWwuVHhPcHRpb25zKSAoKnNxbC5UeCwgZXJyb3IpCn0KCi8qLS0tLS0tLS0tLS0tLSsKfCBUeXBlIGFsaWFzZXMgfAorLS0tLS0tLS0tLS0tLSovCgovLyBOdWxsRmxvYXQ2NCBhbGlhc2VzIHNxbC5OdWxsRmxvYXQ2NAp0eXBlIE51bGxGbG9hdDY0IHNxbC5OdWxsRmxvYXQ2NAoKLy8gTnVsbFN0cmluZyBhbGlhc2VzIHNxbC5OdWxsU3RyaW5nCnR5cGUgTnVsbFN0cmluZyBzcWwuTnVsbFN0cmluZwoKLy8gTnVsbEJvb2wgYWxpYXNlcyBzcWwuTnVsbEJvb2wKdHlwZSBOdWxsQm9vbCBzcWwuTnVsbEJvb2wKCi8vIE51bGxJbnQ2NCBhbGlhc2VzIHNxbC5OdWxsSW50NjQKdHlwZSBOdWxsSW50NjQgc3FsLk51bGxJbnQ2NAoKLy8gTnVsbFRpbWUgYWxpYXNlcyBzcWwuTnVsbFRpbWUKdHlwZSBOdWxsVGltZSBteXNxbC5OdWxsVGltZQoKLy8gUmF3SlNPTiBhbGlhc2VzIGpzb24uUmF3TWVzc2FnZQp0eXBlIFJhd0pTT04ganNvbi5SYXdNZXNzYWdlCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsU3RyaW5nIGltcGxlbWVudGF0aW9ucyB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLy8gTWFyc2hhbEpTT04gZm9yIE51bGxTdHJpbmcKZnVuYyAobiBOdWxsU3RyaW5nKSBNYXJzaGFsSlNPTigpIChbXWJ5dGUsIGVycm9yKSB7Cgl2YXIgYSAqc3RyaW5nCglpZiBuLlZhbGlkIHsKCQlhID0gJm4uU3RyaW5nCgl9CglyZXR1cm4ganNvbi5NYXJzaGFsKGEpCn0KCi8vIFVubWFyc2hhbEpTT04gZm9yIE51bGxTdHJpbmcKZnVuYyAobiAqTnVsbFN0cmluZykgVW5tYXJzaGFsSlNPTihiIFtdYnl0ZSkgZXJyb3IgewoJaWYgYnl0ZXMuRXF1YWxGb2xkKGIsIG51bGxMaXRlcmFsKSB7CgkJbi5WYWxpZCA9IGZhbHNlCgkJcmV0dXJuIG5pbAoJfQoJZXJyIDo9IGpzb24uVW5tYXJzaGFsKGIsICZuLlN0cmluZykKCW4uVmFsaWQgPSBlcnIgPT0gbmlsCglyZXR1cm4gZXJyCn0KCi8vIFZhbHVlIGZvciBOdWxsU3RyaW5nCmZ1bmMgKG4gTnVsbFN0cmluZykgVmFsdWUoKSAoZHJpdmVyLlZhbHVlLCBlcnJvcikgewoJaWYgIW4uVmFsaWQgewoJCXJldHVybiBuaWwsIG5pbAoJfQoJcmV0dXJuIG4uU3RyaW5nLCBuaWwKfQoKLy8gU2NhbiBmb3IgTnVsbFN0cmluZwpmdW5jIChuICpOdWxsU3RyaW5nKSBTY2FuKHNyYyBpbnRlcmZhY2V7fSkgZXJyb3IgewoJdmFyIGEgc3FsLk51bGxTdHJpbmcKCWlmIGVyciA6PSBhLlNjYW4oc3JjKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJbi5TdHJpbmcgPSBhLlN0cmluZwoJaWYgcmVmbGVjdC5UeXBlT2Yoc3JjKSAhPSBuaWwgewoJCW4uVmFsaWQgPSB0cnVlCgl9CglyZXR1cm4gbmlsCn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsRmxvYXQ2NCBpbXBsZW1lbnRhdGlvbnMgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBNYXJzaGFsSlNPTiBmb3IgTnVsbEZsb2F0NjQKZnVuYyAobiBOdWxsRmxvYXQ2NCkgTWFyc2hhbEpTT04oKSAoW11ieXRlLCBlcnJvcikgewoJdmFyIGEgKmZsb2F0NjQKCWlmIG4uVmFsaWQgewoJCWEgPSAmbi5GbG9hdDY0Cgl9CglyZXR1cm4ganNvbi5NYXJzaGFsKGEpCn0KCi8vIFZhbHVlIGZvciBOdWxsRmxvYXQ2NApmdW5jIChuIE51bGxGbG9hdDY0KSBWYWx1ZSgpIChkcml2ZXIuVmFsdWUsIGVycm9yKSB7CglpZiAhbi5WYWxpZCB7CgkJcmV0dXJuIG5pbCwgbmlsCgl9CglyZXR1cm4gbi5GbG9hdDY0LCBuaWwKfQoKLy8gVW5tYXJzaGFsSlNPTiBmb3IgTnVsbEZsb2F0NjQKZnVuYyAobiAqTnVsbEZsb2F0NjQpIFVubWFyc2hhbEpTT04oYiBbXWJ5dGUpIGVycm9yIHsKCWlmIGJ5dGVzLkVxdWFsRm9sZChiLCBudWxsTGl0ZXJhbCkgewoJCW4uVmFsaWQgPSBmYWxzZQoJCXJldHVybiBuaWwKCX0KCWVyciA6PSBqc29uLlVubWFyc2hhbChiLCAmbi5GbG9hdDY0KQoJbi5WYWxpZCA9IGVyciA9PSBuaWwKCXJldHVybiBlcnIKfQoKLy8gU2NhbiBmb3IgTnVsbEZsb2F0NjQKZnVuYyAobiAqTnVsbEZsb2F0NjQpIFNjYW4oc3JjIGludGVyZmFjZXt9KSBlcnJvciB7Cgl2YXIgYSBzcWwuTnVsbEZsb2F0NjQKCWlmIGVyciA6PSBhLlNjYW4oc3JjKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJbi5GbG9hdDY0ID0gYS5GbG9hdDY0CglpZiByZWZsZWN0LlR5cGVPZihzcmMpICE9IG5pbCB7CgkJbi5WYWxpZCA9IHRydWUKCX0KCXJldHVybiBuaWwKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsSW50NjQgaW1wbGVtZW50YXRpb25zIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIE1hcnNoYWxKU09OIGZvciBOdWxsSW50NjQKZnVuYyAobiBOdWxsSW50NjQpIE1hcnNoYWxKU09OKCkgKFtdYnl0ZSwgZXJyb3IpIHsKCXZhciBhICppbnQ2NAoJaWYgbi5WYWxpZCB7CgkJYSA9ICZuLkludDY0Cgl9CglyZXR1cm4ganNvbi5NYXJzaGFsKGEpCn0KCi8vIFZhbHVlIGZvciBOdWxsSW50NjQKZnVuYyAobiBOdWxsSW50NjQpIFZhbHVlKCkgKGRyaXZlci5WYWx1ZSwgZXJyb3IpIHsKCWlmICFuLlZhbGlkIHsKCQlyZXR1cm4gbmlsLCBuaWwKCX0KCXJldHVybiBuLkludDY0LCBuaWwKfQoKLy8gVW5tYXJzaGFsSlNPTiBmb3IgTnVsbEludDY0CmZ1bmMgKG4gKk51bGxJbnQ2NCkgVW5tYXJzaGFsSlNPTihiIFtdYnl0ZSkgZXJyb3IgewoJaWYgYnl0ZXMuRXF1YWxGb2xkKGIsIG51bGxMaXRlcmFsKSB7CgkJbi5WYWxpZCA9IGZhbHNlCgkJcmV0dXJuIG5pbAoJfQoJZXJyIDo9IGpzb24uVW5tYXJzaGFsKGIsICZuLkludDY0KQoJbi5WYWxpZCA9IGVyciA9PSBuaWwKCXJldHVybiBlcnIKfQoKLy8gU2NhbiBmb3IgTnVsbEludDY0CmZ1bmMgKG4gKk51bGxJbnQ2NCkgU2NhbihzcmMgaW50ZXJmYWNle30pIGVycm9yIHsKCXZhciBhIHNxbC5OdWxsSW50NjQKCWlmIGVyciA6PSBhLlNjYW4oc3JjKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJbi5JbnQ2NCA9IGEuSW50NjQKCWlmIHJlZmxlY3QuVHlwZU9mKHNyYykgIT0gbmlsIHsKCQluLlZhbGlkID0gdHJ1ZQoJfQoJcmV0dXJuIG5pbAp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgTnVsbEJvb2wgaW1wbGVtZW50YXRpb25zIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLy8gTWFyc2hhbEpTT04gZm9yIE51bGxCb29sCmZ1bmMgKG4gTnVsbEJvb2wpIE1hcnNoYWxKU09OKCkgKFtdYnl0ZSwgZXJyb3IpIHsKCXZhciBhICpib29sCglpZiBuLlZhbGlkIHsKCQlhID0gJm4uQm9vbAoJfQoJcmV0dXJuIGpzb24uTWFyc2hhbChhKQp9CgovLyBWYWx1ZSBmb3IgTnVsbEJvb2wKZnVuYyAobiBOdWxsQm9vbCkgVmFsdWUoKSAoZHJpdmVyLlZhbHVlLCBlcnJvcikgewoJaWYgIW4uVmFsaWQgewoJCXJldHVybiBuaWwsIG5pbAoJfQoJcmV0dXJuIG4uQm9vbCwgbmlsCn0KCi8vIFVubWFyc2hhbEpTT04gZm9yIE51bGxCb29sCmZ1bmMgKG4gKk51bGxCb29sKSBVbm1hcnNoYWxKU09OKGIgW11ieXRlKSBlcnJvciB7Cgl2YXIgZmllbGQgKmJvb2wKCWVyciA6PSBqc29uLlVubWFyc2hhbChiLCAmZmllbGQpCglpZiBmaWVsZCAhPSBuaWwgewoJCW4uVmFsaWQgPSB0cnVlCgkJbi5Cb29sID0gKmZpZWxkCgl9CglyZXR1cm4gZXJyCn0KCi8vIFNjYW4gZm9yIE51bGxCb29sCmZ1bmMgKG4gKk51bGxCb29sKSBTY2FuKHNyYyBpbnRlcmZhY2V7fSkgZXJyb3IgewoJdmFyIGEgc3FsLk51bGxCb29sCglpZiBlcnIgOj0gYS5TY2FuKHNyYyk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCW4uQm9vbCA9IGEuQm9vbAoJaWYgcmVmbGVjdC5UeXBlT2Yoc3JjKSAhPSBuaWwgewoJCW4uVmFsaWQgPSB0cnVlCgl9CglyZXR1cm4gbmlsCn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsVGltZSBpbXBsZW1lbnRhdGlvbnMgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBNYXJzaGFsSlNPTiBmb3IgTnVsbFRpbWUKZnVuYyAobiBOdWxsVGltZSkgTWFyc2hhbEpTT04oKSAoW11ieXRlLCBlcnJvcikgewoJdmFyIGEgKnRpbWUuVGltZQoJaWYgbi5WYWxpZCB7CgkJYSA9ICZuLlRpbWUKCX0KCXJldHVybiBqc29uLk1hcnNoYWwoYSkKfQoKLy8gVmFsdWUgZm9yIE51bGxUaW1lCmZ1bmMgKG4gTnVsbFRpbWUpIFZhbHVlKCkgKGRyaXZlci5WYWx1ZSwgZXJyb3IpIHsKCWlmICFuLlZhbGlkIHsKCQlyZXR1cm4gbmlsLCBuaWwKCX0KCXJldHVybiBuLlRpbWUsIG5pbAp9CgovLyBVbm1hcnNoYWxKU09OIGZvciBOdWxsVGltZQpmdW5jIChuICpOdWxsVGltZSkgVW5tYXJzaGFsSlNPTihiIFtdYnl0ZSkgZXJyb3IgewogICAgcyA6PSBzdHJpbmcoYikKICAgIHMgPSBzdHJpbmdzLlRyaW0ocywgYCJgKQoKICAgIHZhciAoCiAgICAgICAgemVyb1RpbWUgdGltZS5UaW1lCiAgICAgICAgdGltICAgICAgdGltZS5UaW1lCiAgICAgICAgZXJyICAgICAgZXJyb3IKICAgICkKCiAgICBpZiBzdHJpbmdzLkVxdWFsRm9sZChzLCAibnVsbCIpIHsKICAgICAgICByZXR1cm4gbmlsCiAgICB9CgogICAgaWYgdGltLCBlcnIgPSB0aW1lLlBhcnNlKHRpbWUuUkZDMzMzOSwgcyk7IGVyciAhPSBuaWwgewogICAgICAgIG4uVmFsaWQgPSBmYWxzZQogICAgICAgIHJldHVybiBlcnIKICAgIH0KCiAgICBpZiB0aW0gPT0gemVyb1RpbWUgewogICAgICAgIHJldHVybiBuaWwKICAgIH0KCiAgICBuLlRpbWUgPSB0aW0KICAgIG4uVmFsaWQgPSB0cnVlCiAgICByZXR1cm4gbmlsCn0KCi8vIFNjYW4gZm9yIE51bGxUaW1lCmZ1bmMgKG4gKk51bGxUaW1lKSBTY2FuKHNyYyBpbnRlcmZhY2V7fSkgZXJyb3IgewoJLy8gU2V0IGluaXRpYWwgc3RhdGUgZm9yIHN1YnNlcXVlbnQgc2NhbnMuCgluLlZhbGlkID0gZmFsc2UKCgl2YXIgYSBteXNxbC5OdWxsVGltZQoJaWYgZXJyIDo9IGEuU2NhbihzcmMpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgluLlRpbWUgPSBhLlRpbWUKCWlmIHJlZmxlY3QuVHlwZU9mKHNyYykgIT0gbmlsIHsKCQluLlZhbGlkID0gdHJ1ZQoJfQoJcmV0dXJuIG5pbAp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBSYXdKU09OIGltcGxlbWVudGF0aW9ucyB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLy8gTWFyc2hhbEpTT04gZm9yIE51bGxTdHJpbmcKZnVuYyAobiBSYXdKU09OKSBNYXJzaGFsSlNPTigpIChbXWJ5dGUsIGVycm9yKSB7CglhIDo9IGpzb24uUmF3TWVzc2FnZShuKQoJcmV0dXJuIGEuTWFyc2hhbEpTT04oKQp9CgovLyBWYWx1ZSBmb3IgTnVsbFN0cmluZwpmdW5jIChuIFJhd0pTT04pIFZhbHVlKCkgKGRyaXZlci5WYWx1ZSwgZXJyb3IpIHsKCXJldHVybiBzdHJpbmcobiksIG5pbAp9CgovLyBVbm1hcnNoYWxKU09OIGZvciBOdWxsU3RyaW5nCmZ1bmMgKG4gKlJhd0pTT04pIFVubWFyc2hhbEpTT04oYiBbXWJ5dGUpIGVycm9yIHsKCXZhciBhIGpzb24uUmF3TWVzc2FnZQoJaWYgZXJyIDo9IGpzb24uVW5tYXJzaGFsKGIsICZhKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJYyA6PSBSYXdKU09OKGEpCgkqbiA9IGMKCXJldHVybiBuaWwKfQoKLy8gU2NhbiBmb3IgTnVsbFN0cmluZwpmdW5jIChuICpSYXdKU09OKSBTY2FuKHNyYyBpbnRlcmZhY2V7fSkgZXJyb3IgewoJdmFyIGEgc3FsLk51bGxTdHJpbmcKCWlmIGVyciA6PSBhLlNjYW4oc3JjKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJanNuIDo9IFJhd0pTT04oW11ieXRlKGEuU3RyaW5nKSkKCSpuID0ganNuCglyZXR1cm4gbmlsCn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0rCnwgSGVscGVyIGZ1bmN0aW9ucyB8CistLS0tLS0tLS0tLS0tLS0tLSovCgovLyBUb051bGxTdHJpbmcgcmV0dXJucyBhIG5ldyBOdWxsU3RyaW5nCmZ1bmMgVG9OdWxsU3RyaW5nKHMgKnN0cmluZykgTnVsbFN0cmluZyB7CglpZiBzID09IG5pbCB7CgkJcmV0dXJuIE51bGxTdHJpbmcoc3FsLk51bGxTdHJpbmd7VmFsaWQ6IGZhbHNlfSkKCX0KCXJldHVybiBOdWxsU3RyaW5nKHNxbC5OdWxsU3RyaW5ne1N0cmluZzogKnMsIFZhbGlkOiB0cnVlfSkKfQoKLy8gVG9OdWxsSW50NjQgcmV0dXJucyBhIG5ldyBOdWxsSW50NjQKZnVuYyBUb051bGxJbnQ2NChpICppbnQ2NCkgTnVsbEludDY0IHsKCWlmIGkgPT0gbmlsIHsKCQlyZXR1cm4gTnVsbEludDY0KHNxbC5OdWxsSW50NjR7VmFsaWQ6IGZhbHNlfSkKCX0KCXJldHVybiBOdWxsSW50NjQoc3FsLk51bGxJbnQ2NHtJbnQ2NDogKmksIFZhbGlkOiB0cnVlfSkKfQoKLy8gVG9OdWxsRmxvYXQ2NCByZXR1cm5zIGEgbmV3IE51bGxGbG9hdDY0CmZ1bmMgVG9OdWxsRmxvYXQ2NChpICpmbG9hdDY0KSBOdWxsRmxvYXQ2NCB7CglpZiBpID09IG5pbCB7CgkJcmV0dXJuIE51bGxGbG9hdDY0KHNxbC5OdWxsRmxvYXQ2NHtWYWxpZDogZmFsc2V9KQoJfQoJcmV0dXJuIE51bGxGbG9hdDY0KHNxbC5OdWxsRmxvYXQ2NHtGbG9hdDY0OiAqaSwgVmFsaWQ6IHRydWV9KQp9CgovLyBUb051bGxCb29sIGNyZWF0ZXMgYSBuZXcgTnVsbEJvb2wKZnVuYyBUb051bGxCb29sKGIgKmJvb2wpIE51bGxCb29sIHsKCWlmIGIgPT0gbmlsIHsKCQlyZXR1cm4gTnVsbEJvb2woc3FsLk51bGxCb29se1ZhbGlkOiBmYWxzZX0pCgl9CglyZXR1cm4gTnVsbEJvb2woc3FsLk51bGxCb29se0Jvb2w6ICpiLCBWYWxpZDogdHJ1ZX0pCn0KCi8vIFRvTnVsbFRpbWUgY3JlYXRlcyBhIG5ldyBOdWxsVGltZQpmdW5jIFRvTnVsbFRpbWUodCB0aW1lLlRpbWUpIE51bGxUaW1lIHsKCWlmIHQgPT0gZW1wdHlUaW1lIHsKCQlyZXR1cm4gTnVsbFRpbWUobXlzcWwuTnVsbFRpbWV7VmFsaWQ6IGZhbHNlfSkKCX0KCXJldHVybiBOdWxsVGltZShteXNxbC5OdWxsVGltZXtUaW1lOiB0LCBWYWxpZDogdHJ1ZX0pCn0KCi8vIFR4T3B0aW9ucyBkZWZpbmVzIGFuIG9wdGlvbiB0eXBlIGZvciBjb25maWd1cmluZwovLyB0cmFuc2F0aW9ucy4gVGhpcyBtYXkgb25seSBiZSB1c2VkIHdpdGggdGhlIEV4ZWN1dGVUcmFuc2FjdGlvbiB3cmFwcGVyLgp0eXBlIFR4T3B0aW9ucyBzdHJ1Y3QgewoJVGltZW91dCAgIHRpbWUuRHVyYXRpb24KCUlzb2xhdGlvbiBzcWwuSXNvbGF0aW9uTGV2ZWwKCVJlYWRPbmx5ICBib29sCn0KCi8vIEV4ZWN1dGVUcmFuc2FjdGlvbiBjbG9zZXMgb3ZlciBhIHRyYW5zYWN0aW9uIGFuZCBhdXRvbWF0aWNhbGx5IGNvbW1pdHMKLy8gb3Igcm9sbGJhY2tzIGRlcGVuZGluZyBvbiB3aGV0aGVyIGVycm9ycyB3ZXJlIGVuY291bnRlcmVkLgovLyBJbiB0aGUgY2FzZSB3aGVyZSBuaWwgaXMgcGFzc2VkIGZvciBvcHQgKCpUeE9wdGlvbiksIHRoZSBmb2xsb3dpbmcgZGVmYXVsdHMgYXJlIHVzZWQ6Ci8vICAmVHhPcHRpb25zewovLyAgCVRpbWVvdXQ6ICAgNSAqIHRpbWUuU2Vjb25kLAovLyAgCUlzb2xhdGlvbjogc3FsLkxldmVsU2VyaWFsaXphYmxlLAovLyAgCVJlYWRPbmx5OiAgZmFsc2UsCi8vICB9CmZ1bmMgRXhlY3V0ZVRyYW5zYWN0aW9uKHF1IFF1ZXJ5ZXIsIG9wdCAqVHhPcHRpb25zLCBhY3Rpb25zIGZ1bmMoKnNxbC5UeCkgZXJyb3IpIChlcnIgZXJyb3IpIHsKCS8vIFByb3ZpZGUgc2FmZSBkZWZhdWx0cyBpbiBjYXNlIG5vbmUgd2VyZSBnaXZlbi4KCWlmIG9wdCA9PSBuaWwgewoJCW9wdCA9ICZUeE9wdGlvbnN7CgkJCVRpbWVvdXQ6ICAgNSAqIHRpbWUuU2Vjb25kLAoJCQlJc29sYXRpb246IHNxbC5MZXZlbFNlcmlhbGl6YWJsZSwKCQkJUmVhZE9ubHk6ICBmYWxzZSwKCQl9Cgl9CgoJLy8gQnVpbGQgdGhlIGNvbnRleHQgd2l0aCB0aGUgcHJvdmlkZWQgdGltZW91dC4KCS8vIFRoaXMgd2lsbCBiZSB1c2VkIHRvIGRlZmluZSB0aGUgdG90YWwgdGltZSB0aGUgdHJhbnNhY3Rpb24gbWF5IHRha2UsCgkvLyBwYXN0IHRoaXMgdGltZSwgaXQgd2lsbCBiZSBjYW5jZWxsZWQsIHJvbGxiYWNrLCB0aGVuIHRocm93IGFuIGVycm9yLgoJY3R4LCBjYW5jZWwgOj0gY29udGV4dC5XaXRoVGltZW91dChjb250ZXh0LkJhY2tncm91bmQoKSwgb3B0LlRpbWVvdXQpCglkZWZlciBjYW5jZWwoKQoKCXZhciB0eCAqc3FsLlR4CglpZiB0eCwgZXJyID0gcXUuQmVnaW5UeChjdHgsICZzcWwuVHhPcHRpb25zewoJCUlzb2xhdGlvbjogb3B0Lklzb2xhdGlvbiwKCQlSZWFkT25seTogIG9wdC5SZWFkT25seSwKCX0pOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJZGVmZXIgZnVuYygpIHsKCQlpZiByIDo9IHJlY292ZXIoKTsgciAhPSBuaWwgewoJCQkvLyBPbmx5IG5lZWQgdG8gbG9nIGhlcmUgYmVjYXVzZSBwYW5pYyB3b24ndCByZXBvcnQgd2hldGhlcgoJCQkvLyB0aGUgcm9sbGJhY2sgd2FzIHN1Y2Nlc3NmdWwgb3Igbm90LgoJCQlpZiB0eGVyciA6PSB0eC5Sb2xsYmFjaygpOyB0eGVyciAhPSBuaWwgewoJCQkJbG9nLlByaW50bG4oImRiIHJvbGxiYWNrIGVycm9yOiIsIHR4ZXJyKQoJCQl9CgoJCQlsb2cuUHJpbnRmKCJyb2xsZWQgYmFjayB0cmFuc2FjdGlvbiIpCgkJCXBhbmljKHIpCgkJfSBlbHNlIGlmIGVyciAhPSBuaWwgewoJCQkvLyBJZiB3ZSBydW4gaW50byBpc3N1ZXMgcm9sbGluZyBiYWNrLCBrZWVwIHRyYWNrIG9mIHRoZSBlcnJvciB0aGF0CgkJCS8vIGNhdXNlZCB0aGUgaXNzdWUgYW5kIHByb3ZpZGUgc29tZSBjb250ZXh0IG9uIHRoZSByb2xsYmFjayBmYWlsdXJlLgoJCQlpZiByZXJyIDo9IHR4LlJvbGxiYWNrKCk7IHJlcnIgIT0gbmlsIHsKCQkJCWVyciA9IGZtdC5FcnJvcmYoImRiIGVycm9yOiAldiByb2xsYmFjayBlcnJvcjogJXYiLCBlcnIsIHJlcnIpCgkJCX0KCQl9IGVsc2UgewoJCQlpZiBjZXJyIDo9IHR4LkNvbW1pdCgpOyBjZXJyICE9IG5pbCB7CgkJCQllcnIgPSBmbXQuRXJyb3JmKCJjb21taXQgZXJyb3I6ICV2IiwgY2VycikKCQkJfQoJCX0KCX0oKQoKCWVyciA9IGFjdGlvbnModHgpCglyZXR1cm4gZXJyCn0Ke3tlbmR9fQo=\"") - packr.PackJSONBytes("./tmpl", "x_helpers_test.html", "\"e3tkZWZpbmUgImhlbHBlcnN0ZXN0In19Ci8vK2J1aWxkICFoZWxwZXJzCgpwYWNrYWdlIHt7IC5QYWNrYWdlTmFtZSB9fQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgQ29kZSBnZW5lcmF0ZWQgYnkgbW9kZWxnZW4gfAp8ICAgICAgICBETyBOT1QgRURJVC4gICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgppbXBvcnQgKAoJImRhdGFiYXNlL3NxbC9kcml2ZXIiCgkiZW5jb2RpbmcvanNvbiIKCSJyZWZsZWN0IgoJInRlc3RpbmciCgkidGltZSIKKQoKZnVuYyBUZXN0U3RydWN0RW1iZWRkaW5nKHQgKnRlc3RpbmcuVCkgewoJdGltIDo9IHRpbWUuRGF0ZSgyMDE3LCAxLCAxLCAwLCAwLCAwLCAwLCB0aW1lLlVUQykKCWV4cGVjdGVkIDo9IFtdYnl0ZShgeyJhIjoxMjMsImIiOnRydWUsImMiOjEyMy4xMjMsImQiOiJzdHJpbmciLCJlIjoiMjAxNy0wMS0wMVQwMDowMDowMFoiLCJmIjpbMSwyLDNdfWApCgl0eXBlIGVtYmVkIHN0cnVjdCB7CgkJQSBOdWxsSW50NjQgICBganNvbjoiYSxvbWl0ZW1wdHkiYAoJCUIgTnVsbEJvb2wgICAgYGpzb246ImIsb21pdGVtcHR5ImAKCQlDIE51bGxGbG9hdDY0IGBqc29uOiJjLG9taXRlbXB0eSJgCgkJRCBOdWxsU3RyaW5nICBganNvbjoiZCxvbWl0ZW1wdHkiYAoJCUUgTnVsbFRpbWUgICAgYGpzb246ImUsb21pdGVtcHR5ImAKCQlGIFJhd0pTT04gICAgIGBqc29uOiJmLG9taXRlbXB0eSJgCgl9CgllbSA6PSBlbWJlZHsKCQlBOiBOdWxsSW50NjR7VmFsaWQ6IHRydWUsIEludDY0OiAxMjN9LAoJCUI6IE51bGxCb29se1ZhbGlkOiB0cnVlLCBCb29sOiB0cnVlfSwKCQlDOiBOdWxsRmxvYXQ2NHtWYWxpZDogdHJ1ZSwgRmxvYXQ2NDogMTIzLjEyM30sCgkJRDogTnVsbFN0cmluZ3tWYWxpZDogdHJ1ZSwgU3RyaW5nOiAic3RyaW5nIn0sCgkJRTogTnVsbFRpbWV7VmFsaWQ6IHRydWUsIFRpbWU6IHRpbX0sCgkJRjogUmF3SlNPTihgWzEsMiwzXWApLAoJfQoJYiwgZXJyIDo9IGpzb24uTWFyc2hhbChlbSkKCWlmIGVyciAhPSBuaWwgewoJCXQuRmF0YWwoZXJyKQoJfQoJaWYgIXJlZmxlY3QuRGVlcEVxdWFsKGV4cGVjdGVkLCBiKSB7CgkJdC5GYXRhbCgibm90IHRoZSBzYW1lIEpTT04hIikKCX0KCWlmICEoc3RyaW5nKGIpID09IHN0cmluZyhleHBlY3RlZCkpIHsKCQl0LkZhdGFsKCJub3QgdGhlIHNhbWUhIikKCX0KCgl2YXIgZW0yIGVtYmVkCglpZiBlcnIgOj0ganNvbi5Vbm1hcnNoYWwoZXhwZWN0ZWQsICZlbTIpOyBlcnIgIT0gbmlsIHsKCQl0LkZhdGFsKGVycikKCX0KCWlmICFyZWZsZWN0LkRlZXBFcXVhbChlbTIsIGVtKSB7CgkJdC5GYXRhbCgibm90IGNvcnJlY3QiKQoJfQp9CgpmdW5jIFRlc3ROdWxsU3RyaW5nX1VubWFyc2hhbEpTT04odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgIE51bGxTdHJpbmcKCQlzb3VyY2UgIFtdYnl0ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICAgICJleHBsaWNpdCBudWxsIiwKCQkJc291cmNlOiAgW11ieXRlKGBudWxsYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAic3RyaW5nIG51bGwiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYCJudWxsImApLAoJCQl3YW50RXJyOiBmYWxzZSwgLy8gdGhpcyBvbmUgU0hPVUxEIGJlIHZhbGlkCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgImhlbGxvImApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogICAgImludmFsaWQiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYHsia2V5IjoidmFsdWUifWApLAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiZW1wdHkiLAoJCQlzb3VyY2U6ICBbXWJ5dGV7fSwKCQkJd2FudEVycjogdHJ1ZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5Vbm1hcnNoYWxKU09OKHR0LnNvdXJjZSk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsU3RyaW5nLlVubWFyc2hhbEpTT04oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbFN0cmluZ19WYWx1ZSh0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgTnVsbFN0cmluZwoJCXdhbnQgICAgZHJpdmVyLlZhbHVlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogTnVsbFN0cmluZ3sKCQkJCVZhbGlkOiAgdHJ1ZSwKCQkJCVN0cmluZzogImhlbGxvIiwKCQkJfSwKCQkJd2FudDogICAgZHJpdmVyLlZhbHVlKCJoZWxsbyIpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiBOdWxsU3RyaW5newoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQl3YW50OiAgICBuaWwsCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uVmFsdWUoKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5WYWx1ZSgpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5WYWx1ZSgpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsU3RyaW5nX1NjYW4odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsU3RyaW5nCgkJd2FudEVyciBib29sCgkJc3JjICAgICBpbnRlcmZhY2V7fQoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46ICZOdWxsU3RyaW5newoJCQkJU3RyaW5nOiAiaGVsbG8iLAoJCQkJVmFsaWQ6ICB0cnVlLAoJCQl9LAoJCQlzcmM6ICAgICAiIiwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbFN0cmluZ3sKCQkJCVN0cmluZzogImhlbGxvIiwKCQkJCVZhbGlkOiAgZmFsc2UsCgkJCX0sCgkJCXNyYzogICAgIG5pbCwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCX0KCWZvciBfLCB0dCA6PSByYW5nZSB0ZXN0cyB7CgkJdC5SdW4odHQubmFtZSwgZnVuYyh0ICp0ZXN0aW5nLlQpIHsKCQkJaWYgZXJyIDo9IHR0Lm4uU2Nhbih0dC5zcmMpOyAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5TY2FuKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCQlpZiAhdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gbmlsIHsKCQkJCXQuRXJyb3JmKCJzaG91bGQgcmV0dXJuIG51bGwiKQoJCQl9CgkJCWlmIHR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IHR0Lm4uU3RyaW5nIHsKCQkJCXQuRXJyb3JmKCJpbnZhbGlkIHZhbHVlIikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxTdHJpbmdfTWFyc2hhbEpTT04odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsU3RyaW5nCgkJd2FudCAgICBbXWJ5dGUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbFN0cmluZ3sKCQkJCVN0cmluZzogImhlbGxvIiwKCQkJCVZhbGlkOiAgdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAiaGVsbG8iYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAidmFsaWQgbnVsbCIsCgkJCW46ICZOdWxsU3RyaW5newoJCQkJU3RyaW5nOiAiIiwKCQkJCVZhbGlkOiAgZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiAmTnVsbFN0cmluZ3sKCQkJCVZhbGlkOiB0cnVlLAoJCQl9LAoJCQl3YW50OiAgICBbXWJ5dGUoYCIiYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uTWFyc2hhbEpTT04oKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5NYXJzaGFsSlNPTigpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5NYXJzaGFsSlNPTigpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsQm9vbF9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgICAgICBzdHJpbmcKCQluICAgICAgICAgICAgTnVsbEJvb2wKCQlzb3VyY2UgICAgICAgW11ieXRlCgkJd2FudEVyciAgICAgIGJvb2wKCQl3YW50VmFsaWRpdHkgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICAgICAgICAgImV4cGxpY2l0IG51bGwiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiAgICAgIGZhbHNlLAoJCQl3YW50VmFsaWRpdHk6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAgICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogICAgICAgW11ieXRlKGBmYWxzZWApLAoJCQl3YW50RXJyOiAgICAgIGZhbHNlLAoJCQl3YW50VmFsaWRpdHk6IHRydWUsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICAgICAgImludmFsaWQiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZShgeyJrZXkiOiJ2YWx1ZSJ9YCksCgkJCXdhbnRFcnI6ICAgICAgdHJ1ZSwKCQkJd2FudFZhbGlkaXR5OiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogICAgICAgICAiZW1wdHkiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZXt9LAoJCQl3YW50RXJyOiAgICAgIHRydWUsCgkJCXdhbnRWYWxpZGl0eTogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICAgICAgImV4cGxpY2l0IG51bGwiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZSgibnVsbCIpLAoJCQl3YW50RXJyOiAgICAgIGZhbHNlLAoJCQl3YW50VmFsaWRpdHk6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWlmIGVyciA6PSB0dC5uLlVubWFyc2hhbEpTT04odHQuc291cmNlKTsgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgJiYgdHQubi5WYWxpZCA9PSB0dC53YW50VmFsaWRpdHkgewoJCQkJdC5FcnJvcmYoIk51bGxCb29sLlVubWFyc2hhbEpTT04oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbEJvb2xfVmFsdWUodCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgIE51bGxCb29sCgkJd2FudCAgICBkcml2ZXIuVmFsdWUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiBOdWxsQm9vbHsKCQkJCVZhbGlkOiB0cnVlLAoJCQkJQm9vbDogIHRydWUsCgkJCX0sCgkJCXdhbnQ6ICAgIGRyaXZlci5WYWx1ZSh0cnVlKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogTnVsbEJvb2x7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIG5pbCwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCX0KCWZvciBfLCB0dCA6PSByYW5nZSB0ZXN0cyB7CgkJdC5SdW4odHQubmFtZSwgZnVuYyh0ICp0ZXN0aW5nLlQpIHsKCQkJZ290LCBlcnIgOj0gdHQubi5WYWx1ZSgpCgkJCWlmIChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5WYWx1ZSgpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbEJvb2wuVmFsdWUoKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbEJvb2xfU2Nhbih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxCb29sCgkJd2FudEVyciBib29sCgkJc3JjICAgICBpbnRlcmZhY2V7fQoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46ICZOdWxsQm9vbHsKCQkJCUJvb2w6ICB0cnVlLAoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXNyYzogICAgIHRydWUsCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAibmlsIHZhbHVlIiwKCQkJbjogJk51bGxCb29sewoJCQkJQm9vbDogIHRydWUsCgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXNyYzogICAgIGZhbHNlLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5TY2FuKHR0LnNyYyk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5TY2FuKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCQlpZiAhdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gbmlsIHsKCQkJCXQuRXJyb3JmKCJzaG91bGQgcmV0dXJuIG51bGwiKQoJCQl9CgkJCWlmIHR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IHR0Lm4uQm9vbCB7CgkJCQl0LkVycm9yZigiaW52YWxpZCB2YWx1ZSIpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsQm9vbF9NYXJzaGFsSlNPTih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxCb29sCgkJd2FudCAgICBbXWJ5dGUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbEJvb2x7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGBmYWxzZWApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogInZhbGlkIG51bGwiLAoJCQluOiAmTnVsbEJvb2x7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiAmTnVsbEJvb2x7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGBmYWxzZWApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlnb3QsIGVyciA6PSB0dC5uLk1hcnNoYWxKU09OKCkKCQkJaWYgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxCb29sLk1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5NYXJzaGFsSlNPTigpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsVGltZV9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsVGltZQoJCXNvdXJjZSAgW11ieXRlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogICAgInZhbGlkIiwKCQkJc291cmNlOiAgW11ieXRlKGAiMjAxNy0xMS0yNFQwMDowMDowMFoiYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiaW52YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgeyJrZXkiOiJ2YWx1ZSJ9YCksCgkJCXdhbnRFcnI6IHRydWUsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJlbXB0eSIsCgkJCXNvdXJjZTogIFtdYnl0ZXt9LAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiZXhwbGljaXQgbnVsbCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5Vbm1hcnNoYWxKU09OKHR0LnNvdXJjZSk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5Vbm1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxUaW1lX1ZhbHVlKHQgKnRlc3RpbmcuVCkgewoJdGltIDo9IHRpbWUuTm93KCkKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgTnVsbFRpbWUKCQl3YW50ICAgIGRyaXZlci5WYWx1ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46IE51bGxUaW1lewoJCQkJVmFsaWQ6IHRydWUsCgkJCQlUaW1lOiAgdGltLAoJCQl9LAoJCQl3YW50OiAgICBkcml2ZXIuVmFsdWUodGltKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogTnVsbFRpbWV7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIG5pbCwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCX0KCWZvciBfLCB0dCA6PSByYW5nZSB0ZXN0cyB7CgkJdC5SdW4odHQubmFtZSwgZnVuYyh0ICp0ZXN0aW5nLlQpIHsKCQkJZ290LCBlcnIgOj0gdHQubi5WYWx1ZSgpCgkJCWlmIChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsVGltZS5WYWx1ZSgpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbFRpbWUuVmFsdWUoKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbFRpbWVfU2Nhbih0ICp0ZXN0aW5nLlQpIHsKCXRpbSA6PSB0aW1lLk5vdygpCgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsVGltZQoJCXdhbnRFcnIgYm9vbAoJCXNyYyAgICAgaW50ZXJmYWNle30KCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlUaW1lOiAgdGltLAoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXNyYzogICAgIHRpbSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlUaW1lOiAgdGltLAoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQlzcmM6ICAgICB0aW1lLk5vdygpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5TY2FuKHR0LnNyYyk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsVGltZS5TY2FuKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCQlpZiAhdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gbmlsIHsKCQkJCXQuRXJyb3JmKCJzaG91bGQgcmV0dXJuIG51bGwiKQoJCQl9CgkJCWlmIHR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IHR0Lm4uVGltZSB7CgkJCQl0LkVycm9yZigiaW52YWxpZCB2YWx1ZSIpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsVGltZV9NYXJzaGFsSlNPTih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxUaW1lCgkJd2FudCAgICBbXWJ5dGUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlUaW1lOiAgdGltZS5EYXRlKDIwMTcsIDExLCAyNCwgMCwgMCwgMCwgMCwgdGltZS5VVEMpLAoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgIjIwMTctMTEtMjRUMDA6MDA6MDBaImApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogInZhbGlkIG51bGwiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAiMDAwMS0wMS0wMVQwMDowMDowMFoiYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uTWFyc2hhbEpTT04oKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFRpbWUuTWFyc2hhbEpTT04oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQkJcmV0dXJuCgkJCX0KCQkJaWYgIXJlZmxlY3QuRGVlcEVxdWFsKGdvdCwgdHQud2FudCkgewoJCQkJdC5FcnJvcmYoIk51bGxUaW1lLk1hcnNoYWxKU09OKCkgPSAldiwgd2FudCAldiIsIGdvdCwgdHQud2FudCkKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxJbnQ2NF9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsSW50NjQKCQlzb3VyY2UgIFtdYnl0ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgMTIzYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiaW52YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgeyJrZXkiOiJ2YWx1ZSJ9YCksCgkJCXdhbnRFcnI6IHRydWUsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJlbXB0eSIsCgkJCXNvdXJjZTogIFtdYnl0ZXt9LAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWlmIGVyciA6PSB0dC5uLlVubWFyc2hhbEpTT04odHQuc291cmNlKTsgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxJbnQ2NC5Vbm1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxJbnQ2NF9WYWx1ZSh0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgTnVsbEludDY0CgkJd2FudCAgICBkcml2ZXIuVmFsdWUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiBOdWxsSW50NjR7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJCUludDY0OiAxMjMsCgkJCX0sCgkJCXdhbnQ6ICAgIGRyaXZlci5WYWx1ZShpbnQ2NCgxMjMpKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogTnVsbEludDY0ewoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQl3YW50OiAgICBuaWwsCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uVmFsdWUoKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbEludDY0LlZhbHVlKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsSW50NjQuVmFsdWUoKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbEludDY0X1NjYW4odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsSW50NjQKCQl3YW50RXJyIGJvb2wKCQlzcmMgICAgIGludGVyZmFjZXt9Cgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogJk51bGxJbnQ2NHsKCQkJCUludDY0OiAxMjMsCgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJc3JjOiAgICAgaW50NjQoMTIzKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbEludDY0ewoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQlzcmM6ICAgICBpbnQ2NCgxMjMpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5TY2FuKHR0LnNyYyk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsSW50NjQuU2NhbigpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCX0KCQkJaWYgIXR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IG5pbCB7CgkJCQl0LkVycm9yZigic2hvdWxkIHJldHVybiBudWxsIikKCQkJfQoJCQlpZiB0dC5uLlZhbGlkICYmIHR0LnNyYyAhPSB0dC5uLkludDY0IHsKCQkJCXQuRXJyb3JmKCJpbnZhbGlkIHZhbHVlIikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxJbnQ2NF9NYXJzaGFsSlNPTih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxJbnQ2NAoJCXdhbnQgICAgW11ieXRlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogJk51bGxJbnQ2NHsKCQkJCUludDY0OiAxMjMsCgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAxMjNgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJ2YWxpZCBudWxsIiwKCQkJbjogJk51bGxJbnQ2NHsKCQkJCVZhbGlkOiBmYWxzZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGBudWxsYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAiaW52YWxpZCIsCgkJCW46ICZOdWxsSW50NjR7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAwYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uTWFyc2hhbEpTT04oKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbEludDY0Lk1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsSW50NjQuTWFyc2hhbEpTT04oKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQpmdW5jIFRlc3ROdWxsRmxvYXQ2NF9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsRmxvYXQ2NAoJCXNvdXJjZSAgW11ieXRlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogICAgImV4cGxpY2l0IG51bGwiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYG51bGxgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgMTIzLjEyM2ApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogICAgImludmFsaWQiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYHsia2V5IjoidmFsdWUifWApLAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiZW1wdHkiLAoJCQlzb3VyY2U6ICBbXWJ5dGV7fSwKCQkJd2FudEVycjogdHJ1ZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5Vbm1hcnNoYWxKU09OKHR0LnNvdXJjZSk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsRmxvYXQ2NC5Vbm1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxGbG9hdDY0X1ZhbHVlKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsRmxvYXQ2NAoJCXdhbnQgICAgZHJpdmVyLlZhbHVlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogTnVsbEZsb2F0NjR7CgkJCQlWYWxpZDogICB0cnVlLAoJCQkJRmxvYXQ2NDogMTIzLjEyMywKCQkJfSwKCQkJd2FudDogICAgZHJpdmVyLlZhbHVlKGZsb2F0NjQoMTIzLjEyMykpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiBOdWxsRmxvYXQ2NHsKCQkJCVZhbGlkOiBmYWxzZSwKCQkJfSwKCQkJd2FudDogICAgbmlsLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlnb3QsIGVyciA6PSB0dC5uLlZhbHVlKCkKCQkJaWYgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxGbG9hdDY0LlZhbHVlKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsRmxvYXQ2NC5WYWx1ZSgpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsRmxvYXQ2NF9TY2FuKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICAqTnVsbEZsb2F0NjQKCQl3YW50RXJyIGJvb2wKCQlzcmMgICAgIGludGVyZmFjZXt9Cgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogJk51bGxGbG9hdDY0ewoJCQkJRmxvYXQ2NDogMTIzLjEyMywKCQkJCVZhbGlkOiAgIHRydWUsCgkJCX0sCgkJCXNyYzogICAgIGZsb2F0NjQoMTIzKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbEZsb2F0NjR7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXNyYzogICAgIGZsb2F0NjQoMTIzLjEyMyksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWlmIGVyciA6PSB0dC5uLlNjYW4odHQuc3JjKTsgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxGbG9hdDY0LlNjYW4oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQl9CgkJCWlmICF0dC5uLlZhbGlkICYmIHR0LnNyYyAhPSBuaWwgewoJCQkJdC5FcnJvcmYoInNob3VsZCByZXR1cm4gbnVsbCIpCgkJCX0KCQkJaWYgdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gdHQubi5GbG9hdDY0IHsKCQkJCXQuRXJyb3JmKCJpbnZhbGlkIHZhbHVlIikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxGbG9hdDY0X01hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICAqTnVsbEZsb2F0NjQKCQl3YW50ICAgIFtdYnl0ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46ICZOdWxsRmxvYXQ2NHsKCQkJCUZsb2F0NjQ6IDEyMy4xMjMsCgkJCQlWYWxpZDogICB0cnVlLAoJCQl9LAoJCQl3YW50OiAgICBbXWJ5dGUoYDEyMy4xMjNgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJ2YWxpZCBudWxsIiwKCQkJbjogJk51bGxGbG9hdDY0ewoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQl3YW50OiAgICBbXWJ5dGUoYG51bGxgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogJk51bGxGbG9hdDY0ewoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgMGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlnb3QsIGVyciA6PSB0dC5uLk1hcnNoYWxKU09OKCkKCQkJaWYgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxGbG9hdDY0Lk1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsRmxvYXQ2NC5NYXJzaGFsSlNPTigpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3RUb051bGxCb29sKHQgKnRlc3RpbmcuVCkgewoJYiA6PSB0cnVlCgliYiA6PSBUb051bGxCb29sKCZiKQoJaWYgIWJiLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgdmFsaWQsIGdvdCAldiIsIGJiLlZhbGlkKQoJfQoJaWYgIWJiLkJvb2wgewoJCXQuRXJyb3JmKCJleHBlY3RlZCB0cnVlLCBnb3QgJXYiLCBiYi5Cb29sKQoJfQoKCXZhciBiMiAqYm9vbAoJYmIyIDo9IFRvTnVsbEJvb2woYjIpCglpZiBiYjIuVmFsaWQgewoJCXQuRXJyb3JmKCJleHBlY3RlZCBub3QgdmFsaWQsIGdvdCAldiIsIGJiMi5WYWxpZCkKCX0KCWlmIGJiMi5Cb29sIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgZmFsc2UsIGdvdCAldiIsIGJiMi5Cb29sKQoJfQp9CmZ1bmMgVGVzdFRvTnVsbEludDY0KHQgKnRlc3RpbmcuVCkgewoJYiA6PSBpbnQ2NCgxMjMpCgliYiA6PSBUb051bGxJbnQ2NCgmYikKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLkludDY0ICE9IDEyMyB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDEyMywgZ290ICV2IiwgYmIuSW50NjQpCgl9CgoJdmFyIGIyICppbnQ2NAoJYmIyIDo9IFRvTnVsbEludDY0KGIyKQoJaWYgYmIyLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgbm90IHZhbGlkLCBnb3QgJXYiLCBiYjIuVmFsaWQpCgl9CglpZiBiYjIuSW50NjQgIT0gMCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDAsIGdvdCAldiIsIGJiMi5JbnQ2NCkKCX0KfQoKZnVuYyBUZXN0VG9OdWxsRmxvYXQ2NCh0ICp0ZXN0aW5nLlQpIHsKCWIgOj0gZmxvYXQ2NCgxMjMuMTIzKQoJYmIgOj0gVG9OdWxsRmxvYXQ2NCgmYikKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLkZsb2F0NjQgIT0gMTIzLjEyMyB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDEyMy4xMjMsIGdvdCAldiIsIGJiLkZsb2F0NjQpCgl9CgoJdmFyIGIyICpmbG9hdDY0CgliYjIgOj0gVG9OdWxsRmxvYXQ2NChiMikKCWlmIGJiMi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIG5vdCB2YWxpZCwgZ290ICV2IiwgYmIyLlZhbGlkKQoJfQoJaWYgYmIyLkZsb2F0NjQgIT0gMCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDAsIGdvdCAldiIsIGJiMi5GbG9hdDY0KQoJfQp9CmZ1bmMgVGVzdFRvTnVsbFN0cmluZyh0ICp0ZXN0aW5nLlQpIHsKCWIgOj0gInF3ZSIKCWJiIDo9IFRvTnVsbFN0cmluZygmYikKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLlN0cmluZyAhPSAicXdlIiB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHF3ZSwgZ290ICV2IiwgYmIuU3RyaW5nKQoJfQoKCXZhciBiMiAqc3RyaW5nCgliYjIgOj0gVG9OdWxsU3RyaW5nKGIyKQoJaWYgYmIyLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgbm90IHZhbGlkLCBnb3QgJXYiLCBiYjIuVmFsaWQpCgl9CglpZiBiYjIuU3RyaW5nICE9ICIiIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgPGVtcHR5IHN0cmluZz4sIGdvdCAldiIsIGJiMi5TdHJpbmcpCgl9Cn0KZnVuYyBUZXN0VG9OdWxsVGltZSh0ICp0ZXN0aW5nLlQpIHsKCXRpbSA6PSB0aW1lLk5vdygpCgliYiA6PSBUb051bGxUaW1lKHRpbSkKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLlRpbWUgIT0gdGltIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgJXYsIGdvdCAldiIsIHRpbSwgYmIuVGltZSkKCX0KCgl0aW0gPSB0aW1lLlRpbWV7fQoJYmIgPSBUb051bGxUaW1lKHRpbSkKCWlmIGJiLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgaW52YWxpZCwgZ290ICV2IiwgYmIuVmFsaWQpCgl9CglpZiBiYi5UaW1lICE9IHRpbSB7CgkJdC5FcnJvcmYoImV4cGVjdGVkICV2LCBnb3QgJXYiLCB0aW0sIGJiLlRpbWUpCgl9Cn0Ke3tlbmR9fQo=\"") + packr.PackJSONBytes("./tmpl", "x_helpers.html", "\"e3tkZWZpbmUgImhlbHBlcnMifX0KCnBhY2thZ2Uge3sgLlBhY2thZ2VOYW1lIH19CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBDb2RlIGdlbmVyYXRlZCBieSBtb2RlbGdlbiB8CnwgICAgICAgIERPIE5PVCBFRElULiAgICAgICAgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCmltcG9ydCAoCgkiYnl0ZXMiCgkiY29udGV4dCIKCSJkYXRhYmFzZS9zcWwiCgkiZGF0YWJhc2Uvc3FsL2RyaXZlciIKCSJlbmNvZGluZy9qc29uIgoJImZtdCIKCSJsb2ciCgkicmVmbGVjdCIKCSJzdHJpbmdzIgoJInRpbWUiCgoJImdpdGh1Yi5jb20vZ28tc3FsLWRyaXZlci9teXNxbCIKKQoKLy8gU3RkVGltZSBwcm92aWRlcyBkZWZhdWx0IFNRTCBUSU1FIGZvcm1hdApjb25zdCBTdGRUaW1lID0gIjE1OjA0OjA1IgoKLy8gZW1wdHlUaW1lIGFsbG93cyBkZWZhdWx0IHRpbWVzIHRvIGJlIGNvbnNpZGVyZWQKLy8gbnVsbCBmb3IgaW5zZXJ0aW9uIGludG8gdGhlIGRhdGFiYXNlLgp2YXIgZW1wdHlUaW1lID0gdGltZS5UaW1le30KCi8vIG51bGxMaXRlcmFsIGlzIGhlbHBmdWwgZm9yIGNoZWNraW5nCi8vIGZvciBudWxscywgYXMgdGhleSB3b24ndCBjYXVzZSBlcnJvcnMsCi8vIHlldCB3ZSBuZWVkIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlIHRvIGNoYW5nZSBhbnl3YXkKdmFyIG51bGxMaXRlcmFsID0gW11ieXRlKCJudWxsIikKCi8qKioqKioqKgoqIFR5cGVzICoKKioqKioqKiovCgovLyBRdWVyeWVyIGFsbG93cyBzcWwuREIgYW5kIHNxbC5UeCB0byBiZSB1c2VkIGludGVyY2hhbmdlYWJseSwgYWxsb3dpbmcgeW91Ci8vIHRvIHVzZSBhbnkgb2YgdGhlIG1vZGVsIG1ldGhvZHMgaW5zaWRlIHRyYW5zYWN0aW9ucyBvciBzdGFuZGFsb25lIGNhbGxzLgp0eXBlIFF1ZXJ5ZXIgaW50ZXJmYWNlIHsKCVF1ZXJ5KHF1ZXJ5IHN0cmluZywgYXJncyAuLi5pbnRlcmZhY2V7fSkgKCpzcWwuUm93cywgZXJyb3IpCglRdWVyeVJvdyhxdWVyeSBzdHJpbmcsIGFyZ3MgLi4uaW50ZXJmYWNle30pICpzcWwuUm93CglFeGVjKHF1ZXJ5IHN0cmluZywgYXJncyAuLi5pbnRlcmZhY2V7fSkgKHNxbC5SZXN1bHQsIGVycm9yKQoJQmVnaW5UeChjdHggY29udGV4dC5Db250ZXh0LCBvcHRzICpzcWwuVHhPcHRpb25zKSAoKnNxbC5UeCwgZXJyb3IpCn0KCi8qLS0tLS0tLS0tLS0tLSsKfCBUeXBlIGFsaWFzZXMgfAorLS0tLS0tLS0tLS0tLSovCgovLyBOdWxsRmxvYXQ2NCBhbGlhc2VzIHNxbC5OdWxsRmxvYXQ2NAp0eXBlIE51bGxGbG9hdDY0IHNxbC5OdWxsRmxvYXQ2NAoKLy8gTnVsbFN0cmluZyBhbGlhc2VzIHNxbC5OdWxsU3RyaW5nCnR5cGUgTnVsbFN0cmluZyBzcWwuTnVsbFN0cmluZwoKLy8gTnVsbEJvb2wgYWxpYXNlcyBzcWwuTnVsbEJvb2wKdHlwZSBOdWxsQm9vbCBzcWwuTnVsbEJvb2wKCi8vIE51bGxJbnQ2NCBhbGlhc2VzIHNxbC5OdWxsSW50NjQKdHlwZSBOdWxsSW50NjQgc3FsLk51bGxJbnQ2NAoKLy8gTnVsbFRpbWUgYWxpYXNlcyBzcWwuTnVsbFRpbWUKdHlwZSBOdWxsVGltZSBteXNxbC5OdWxsVGltZQoKLy8gUmF3SlNPTiBhbGlhc2VzIGpzb24uUmF3TWVzc2FnZQp0eXBlIFJhd0pTT04ganNvbi5SYXdNZXNzYWdlCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsU3RyaW5nIGltcGxlbWVudGF0aW9ucyB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLy8gTWFyc2hhbEpTT04gZm9yIE51bGxTdHJpbmcKZnVuYyAobiBOdWxsU3RyaW5nKSBNYXJzaGFsSlNPTigpIChbXWJ5dGUsIGVycm9yKSB7Cgl2YXIgYSAqc3RyaW5nCglpZiBuLlZhbGlkIHsKCQlhID0gJm4uU3RyaW5nCgl9CglyZXR1cm4ganNvbi5NYXJzaGFsKGEpCn0KCi8vIFVubWFyc2hhbEpTT04gZm9yIE51bGxTdHJpbmcKZnVuYyAobiAqTnVsbFN0cmluZykgVW5tYXJzaGFsSlNPTihiIFtdYnl0ZSkgZXJyb3IgewoJaWYgYnl0ZXMuRXF1YWxGb2xkKGIsIG51bGxMaXRlcmFsKSB7CgkJbi5WYWxpZCA9IGZhbHNlCgkJcmV0dXJuIG5pbAoJfQoJZXJyIDo9IGpzb24uVW5tYXJzaGFsKGIsICZuLlN0cmluZykKCW4uVmFsaWQgPSBlcnIgPT0gbmlsCglyZXR1cm4gZXJyCn0KCi8vIFZhbHVlIGZvciBOdWxsU3RyaW5nCmZ1bmMgKG4gTnVsbFN0cmluZykgVmFsdWUoKSAoZHJpdmVyLlZhbHVlLCBlcnJvcikgewoJaWYgIW4uVmFsaWQgewoJCXJldHVybiBuaWwsIG5pbAoJfQoJcmV0dXJuIG4uU3RyaW5nLCBuaWwKfQoKLy8gU2NhbiBmb3IgTnVsbFN0cmluZwpmdW5jIChuICpOdWxsU3RyaW5nKSBTY2FuKHNyYyBpbnRlcmZhY2V7fSkgZXJyb3IgewoJdmFyIGEgc3FsLk51bGxTdHJpbmcKCWlmIGVyciA6PSBhLlNjYW4oc3JjKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJbi5TdHJpbmcgPSBhLlN0cmluZwoJaWYgcmVmbGVjdC5UeXBlT2Yoc3JjKSAhPSBuaWwgewoJCW4uVmFsaWQgPSB0cnVlCgl9CglyZXR1cm4gbmlsCn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsRmxvYXQ2NCBpbXBsZW1lbnRhdGlvbnMgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBNYXJzaGFsSlNPTiBmb3IgTnVsbEZsb2F0NjQKZnVuYyAobiBOdWxsRmxvYXQ2NCkgTWFyc2hhbEpTT04oKSAoW11ieXRlLCBlcnJvcikgewoJdmFyIGEgKmZsb2F0NjQKCWlmIG4uVmFsaWQgewoJCWEgPSAmbi5GbG9hdDY0Cgl9CglyZXR1cm4ganNvbi5NYXJzaGFsKGEpCn0KCi8vIFZhbHVlIGZvciBOdWxsRmxvYXQ2NApmdW5jIChuIE51bGxGbG9hdDY0KSBWYWx1ZSgpIChkcml2ZXIuVmFsdWUsIGVycm9yKSB7CglpZiAhbi5WYWxpZCB7CgkJcmV0dXJuIG5pbCwgbmlsCgl9CglyZXR1cm4gbi5GbG9hdDY0LCBuaWwKfQoKLy8gVW5tYXJzaGFsSlNPTiBmb3IgTnVsbEZsb2F0NjQKZnVuYyAobiAqTnVsbEZsb2F0NjQpIFVubWFyc2hhbEpTT04oYiBbXWJ5dGUpIGVycm9yIHsKCWlmIGJ5dGVzLkVxdWFsRm9sZChiLCBudWxsTGl0ZXJhbCkgewoJCW4uVmFsaWQgPSBmYWxzZQoJCXJldHVybiBuaWwKCX0KCWVyciA6PSBqc29uLlVubWFyc2hhbChiLCAmbi5GbG9hdDY0KQoJbi5WYWxpZCA9IGVyciA9PSBuaWwKCXJldHVybiBlcnIKfQoKLy8gU2NhbiBmb3IgTnVsbEZsb2F0NjQKZnVuYyAobiAqTnVsbEZsb2F0NjQpIFNjYW4oc3JjIGludGVyZmFjZXt9KSBlcnJvciB7Cgl2YXIgYSBzcWwuTnVsbEZsb2F0NjQKCWlmIGVyciA6PSBhLlNjYW4oc3JjKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJbi5GbG9hdDY0ID0gYS5GbG9hdDY0CglpZiByZWZsZWN0LlR5cGVPZihzcmMpICE9IG5pbCB7CgkJbi5WYWxpZCA9IHRydWUKCX0KCXJldHVybiBuaWwKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsSW50NjQgaW1wbGVtZW50YXRpb25zIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIE1hcnNoYWxKU09OIGZvciBOdWxsSW50NjQKZnVuYyAobiBOdWxsSW50NjQpIE1hcnNoYWxKU09OKCkgKFtdYnl0ZSwgZXJyb3IpIHsKCXZhciBhICppbnQ2NAoJaWYgbi5WYWxpZCB7CgkJYSA9ICZuLkludDY0Cgl9CglyZXR1cm4ganNvbi5NYXJzaGFsKGEpCn0KCi8vIFZhbHVlIGZvciBOdWxsSW50NjQKZnVuYyAobiBOdWxsSW50NjQpIFZhbHVlKCkgKGRyaXZlci5WYWx1ZSwgZXJyb3IpIHsKCWlmICFuLlZhbGlkIHsKCQlyZXR1cm4gbmlsLCBuaWwKCX0KCXJldHVybiBuLkludDY0LCBuaWwKfQoKLy8gVW5tYXJzaGFsSlNPTiBmb3IgTnVsbEludDY0CmZ1bmMgKG4gKk51bGxJbnQ2NCkgVW5tYXJzaGFsSlNPTihiIFtdYnl0ZSkgZXJyb3IgewoJaWYgYnl0ZXMuRXF1YWxGb2xkKGIsIG51bGxMaXRlcmFsKSB7CgkJbi5WYWxpZCA9IGZhbHNlCgkJcmV0dXJuIG5pbAoJfQoJZXJyIDo9IGpzb24uVW5tYXJzaGFsKGIsICZuLkludDY0KQoJbi5WYWxpZCA9IGVyciA9PSBuaWwKCXJldHVybiBlcnIKfQoKLy8gU2NhbiBmb3IgTnVsbEludDY0CmZ1bmMgKG4gKk51bGxJbnQ2NCkgU2NhbihzcmMgaW50ZXJmYWNle30pIGVycm9yIHsKCXZhciBhIHNxbC5OdWxsSW50NjQKCWlmIGVyciA6PSBhLlNjYW4oc3JjKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJbi5JbnQ2NCA9IGEuSW50NjQKCWlmIHJlZmxlY3QuVHlwZU9mKHNyYykgIT0gbmlsIHsKCQluLlZhbGlkID0gdHJ1ZQoJfQoJcmV0dXJuIG5pbAp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgTnVsbEJvb2wgaW1wbGVtZW50YXRpb25zIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLy8gTWFyc2hhbEpTT04gZm9yIE51bGxCb29sCmZ1bmMgKG4gTnVsbEJvb2wpIE1hcnNoYWxKU09OKCkgKFtdYnl0ZSwgZXJyb3IpIHsKCXZhciBhICpib29sCglpZiBuLlZhbGlkIHsKCQlhID0gJm4uQm9vbAoJfQoJcmV0dXJuIGpzb24uTWFyc2hhbChhKQp9CgovLyBWYWx1ZSBmb3IgTnVsbEJvb2wKZnVuYyAobiBOdWxsQm9vbCkgVmFsdWUoKSAoZHJpdmVyLlZhbHVlLCBlcnJvcikgewoJaWYgIW4uVmFsaWQgewoJCXJldHVybiBuaWwsIG5pbAoJfQoJcmV0dXJuIG4uQm9vbCwgbmlsCn0KCi8vIFVubWFyc2hhbEpTT04gZm9yIE51bGxCb29sCmZ1bmMgKG4gKk51bGxCb29sKSBVbm1hcnNoYWxKU09OKGIgW11ieXRlKSBlcnJvciB7Cgl2YXIgZmllbGQgKmJvb2wKCWVyciA6PSBqc29uLlVubWFyc2hhbChiLCAmZmllbGQpCglpZiBmaWVsZCAhPSBuaWwgewoJCW4uVmFsaWQgPSB0cnVlCgkJbi5Cb29sID0gKmZpZWxkCgl9CglyZXR1cm4gZXJyCn0KCi8vIFNjYW4gZm9yIE51bGxCb29sCmZ1bmMgKG4gKk51bGxCb29sKSBTY2FuKHNyYyBpbnRlcmZhY2V7fSkgZXJyb3IgewoJdmFyIGEgc3FsLk51bGxCb29sCglpZiBlcnIgOj0gYS5TY2FuKHNyYyk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCW4uQm9vbCA9IGEuQm9vbAoJaWYgcmVmbGVjdC5UeXBlT2Yoc3JjKSAhPSBuaWwgewoJCW4uVmFsaWQgPSB0cnVlCgl9CglyZXR1cm4gbmlsCn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBOdWxsVGltZSBpbXBsZW1lbnRhdGlvbnMgfAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBNYXJzaGFsSlNPTiBmb3IgTnVsbFRpbWUKZnVuYyAobiBOdWxsVGltZSkgTWFyc2hhbEpTT04oKSAoW11ieXRlLCBlcnJvcikgewoJdmFyIGEgKnRpbWUuVGltZQoJaWYgbi5WYWxpZCB7CgkJYSA9ICZuLlRpbWUKCX0KCXJldHVybiBqc29uLk1hcnNoYWwoYSkKfQoKLy8gVmFsdWUgZm9yIE51bGxUaW1lCmZ1bmMgKG4gTnVsbFRpbWUpIFZhbHVlKCkgKGRyaXZlci5WYWx1ZSwgZXJyb3IpIHsKCWlmICFuLlZhbGlkIHsKCQlyZXR1cm4gbmlsLCBuaWwKCX0KCXJldHVybiBuLlRpbWUsIG5pbAp9CgovLyBVbm1hcnNoYWxKU09OIGZvciBOdWxsVGltZQpmdW5jIChuICpOdWxsVGltZSkgVW5tYXJzaGFsSlNPTihiIFtdYnl0ZSkgZXJyb3IgewogICAgcyA6PSBzdHJpbmcoYikKICAgIHMgPSBzdHJpbmdzLlRyaW0ocywgYCJgKQoKICAgIHZhciAoCiAgICAgICAgemVyb1RpbWUgdGltZS5UaW1lCiAgICAgICAgdGltICAgICAgdGltZS5UaW1lCiAgICAgICAgZXJyICAgICAgZXJyb3IKICAgICkKCiAgICBpZiBzdHJpbmdzLkVxdWFsRm9sZChzLCAibnVsbCIpIHsKICAgICAgICByZXR1cm4gbmlsCiAgICB9CgogICAgaWYgdGltLCBlcnIgPSB0aW1lLlBhcnNlKHRpbWUuUkZDMzMzOSwgcyk7IGVyciAhPSBuaWwgewogICAgICAgIG4uVmFsaWQgPSBmYWxzZQogICAgICAgIHJldHVybiBlcnIKICAgIH0KCiAgICBpZiB0aW0gPT0gemVyb1RpbWUgewogICAgICAgIHJldHVybiBuaWwKICAgIH0KCiAgICBuLlRpbWUgPSB0aW0KICAgIG4uVmFsaWQgPSB0cnVlCiAgICByZXR1cm4gbmlsCn0KCi8vIFNjYW4gZm9yIE51bGxUaW1lCmZ1bmMgKG4gKk51bGxUaW1lKSBTY2FuKHNyYyBpbnRlcmZhY2V7fSkgZXJyb3IgewoJLy8gU2V0IGluaXRpYWwgc3RhdGUgZm9yIHN1YnNlcXVlbnQgc2NhbnMuCgluLlZhbGlkID0gZmFsc2UKCgl2YXIgYSBteXNxbC5OdWxsVGltZQoJaWYgZXJyIDo9IGEuU2NhbihzcmMpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgluLlRpbWUgPSBhLlRpbWUKCWlmIHJlZmxlY3QuVHlwZU9mKHNyYykgIT0gbmlsIHsKCQluLlZhbGlkID0gdHJ1ZQoJfQoJcmV0dXJuIG5pbAp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBSYXdKU09OIGltcGxlbWVudGF0aW9ucyB8CistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLy8gTWFyc2hhbEpTT04gZm9yIE51bGxTdHJpbmcKZnVuYyAobiBSYXdKU09OKSBNYXJzaGFsSlNPTigpIChbXWJ5dGUsIGVycm9yKSB7CglpZiBsZW4obikgPT0gMCB7CgkJcmV0dXJuIFtdYnl0ZSgibnVsbCIpLCBuaWwKCX0KCWEgOj0ganNvbi5SYXdNZXNzYWdlKG4pCglyZXR1cm4gYS5NYXJzaGFsSlNPTigpCn0KCi8vIFZhbHVlIGZvciBOdWxsU3RyaW5nCmZ1bmMgKG4gUmF3SlNPTikgVmFsdWUoKSAoZHJpdmVyLlZhbHVlLCBlcnJvcikgewoJcmV0dXJuIHN0cmluZyhuKSwgbmlsCn0KCi8vIFVubWFyc2hhbEpTT04gZm9yIE51bGxTdHJpbmcKZnVuYyAobiAqUmF3SlNPTikgVW5tYXJzaGFsSlNPTihiIFtdYnl0ZSkgZXJyb3IgewoJdmFyIGEganNvbi5SYXdNZXNzYWdlCglpZiBlcnIgOj0ganNvbi5Vbm1hcnNoYWwoYiwgJmEpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgljIDo9IFJhd0pTT04oYSkKCSpuID0gYwoJcmV0dXJuIG5pbAp9CgovLyBTY2FuIGZvciBOdWxsU3RyaW5nCmZ1bmMgKG4gKlJhd0pTT04pIFNjYW4oc3JjIGludGVyZmFjZXt9KSBlcnJvciB7Cgl2YXIgYSBzcWwuTnVsbFN0cmluZwoJaWYgZXJyIDo9IGEuU2NhbihzcmMpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9Cglqc24gOj0gUmF3SlNPTihbXWJ5dGUoYS5TdHJpbmcpKQoJKm4gPSBqc24KCXJldHVybiBuaWwKfQoKLyotLS0tLS0tLS0tLS0tLS0tLSsKfCBIZWxwZXIgZnVuY3Rpb25zIHwKKy0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIFRvTnVsbFN0cmluZyByZXR1cm5zIGEgbmV3IE51bGxTdHJpbmcKZnVuYyBUb051bGxTdHJpbmcocyAqc3RyaW5nKSBOdWxsU3RyaW5nIHsKCWlmIHMgPT0gbmlsIHsKCQlyZXR1cm4gTnVsbFN0cmluZyhzcWwuTnVsbFN0cmluZ3tWYWxpZDogZmFsc2V9KQoJfQoJcmV0dXJuIE51bGxTdHJpbmcoc3FsLk51bGxTdHJpbmd7U3RyaW5nOiAqcywgVmFsaWQ6IHRydWV9KQp9CgovLyBUb051bGxJbnQ2NCByZXR1cm5zIGEgbmV3IE51bGxJbnQ2NApmdW5jIFRvTnVsbEludDY0KGkgKmludDY0KSBOdWxsSW50NjQgewoJaWYgaSA9PSBuaWwgewoJCXJldHVybiBOdWxsSW50NjQoc3FsLk51bGxJbnQ2NHtWYWxpZDogZmFsc2V9KQoJfQoJcmV0dXJuIE51bGxJbnQ2NChzcWwuTnVsbEludDY0e0ludDY0OiAqaSwgVmFsaWQ6IHRydWV9KQp9CgovLyBUb051bGxGbG9hdDY0IHJldHVybnMgYSBuZXcgTnVsbEZsb2F0NjQKZnVuYyBUb051bGxGbG9hdDY0KGkgKmZsb2F0NjQpIE51bGxGbG9hdDY0IHsKCWlmIGkgPT0gbmlsIHsKCQlyZXR1cm4gTnVsbEZsb2F0NjQoc3FsLk51bGxGbG9hdDY0e1ZhbGlkOiBmYWxzZX0pCgl9CglyZXR1cm4gTnVsbEZsb2F0NjQoc3FsLk51bGxGbG9hdDY0e0Zsb2F0NjQ6ICppLCBWYWxpZDogdHJ1ZX0pCn0KCi8vIFRvTnVsbEJvb2wgY3JlYXRlcyBhIG5ldyBOdWxsQm9vbApmdW5jIFRvTnVsbEJvb2woYiAqYm9vbCkgTnVsbEJvb2wgewoJaWYgYiA9PSBuaWwgewoJCXJldHVybiBOdWxsQm9vbChzcWwuTnVsbEJvb2x7VmFsaWQ6IGZhbHNlfSkKCX0KCXJldHVybiBOdWxsQm9vbChzcWwuTnVsbEJvb2x7Qm9vbDogKmIsIFZhbGlkOiB0cnVlfSkKfQoKLy8gVG9OdWxsVGltZSBjcmVhdGVzIGEgbmV3IE51bGxUaW1lCmZ1bmMgVG9OdWxsVGltZSh0IHRpbWUuVGltZSkgTnVsbFRpbWUgewoJaWYgdCA9PSBlbXB0eVRpbWUgewoJCXJldHVybiBOdWxsVGltZShteXNxbC5OdWxsVGltZXtWYWxpZDogZmFsc2V9KQoJfQoJcmV0dXJuIE51bGxUaW1lKG15c3FsLk51bGxUaW1le1RpbWU6IHQsIFZhbGlkOiB0cnVlfSkKfQoKLy8gVHhPcHRpb25zIGRlZmluZXMgYW4gb3B0aW9uIHR5cGUgZm9yIGNvbmZpZ3VyaW5nCi8vIHRyYW5zYXRpb25zLiBUaGlzIG1heSBvbmx5IGJlIHVzZWQgd2l0aCB0aGUgRXhlY3V0ZVRyYW5zYWN0aW9uIHdyYXBwZXIuCnR5cGUgVHhPcHRpb25zIHN0cnVjdCB7CglUaW1lb3V0ICAgdGltZS5EdXJhdGlvbgoJSXNvbGF0aW9uIHNxbC5Jc29sYXRpb25MZXZlbAoJUmVhZE9ubHkgIGJvb2wKfQoKLy8gRXhlY3V0ZVRyYW5zYWN0aW9uIGNsb3NlcyBvdmVyIGEgdHJhbnNhY3Rpb24gYW5kIGF1dG9tYXRpY2FsbHkgY29tbWl0cwovLyBvciByb2xsYmFja3MgZGVwZW5kaW5nIG9uIHdoZXRoZXIgZXJyb3JzIHdlcmUgZW5jb3VudGVyZWQuCi8vIEluIHRoZSBjYXNlIHdoZXJlIG5pbCBpcyBwYXNzZWQgZm9yIG9wdCAoKlR4T3B0aW9uKSwgdGhlIGZvbGxvd2luZyBkZWZhdWx0cyBhcmUgdXNlZDoKLy8gICZUeE9wdGlvbnN7Ci8vICAJVGltZW91dDogICA1ICogdGltZS5TZWNvbmQsCi8vICAJSXNvbGF0aW9uOiBzcWwuTGV2ZWxTZXJpYWxpemFibGUsCi8vICAJUmVhZE9ubHk6ICBmYWxzZSwKLy8gIH0KZnVuYyBFeGVjdXRlVHJhbnNhY3Rpb24ocXUgUXVlcnllciwgb3B0ICpUeE9wdGlvbnMsIGFjdGlvbnMgZnVuYygqc3FsLlR4KSBlcnJvcikgKGVyciBlcnJvcikgewoJLy8gUHJvdmlkZSBzYWZlIGRlZmF1bHRzIGluIGNhc2Ugbm9uZSB3ZXJlIGdpdmVuLgoJaWYgb3B0ID09IG5pbCB7CgkJb3B0ID0gJlR4T3B0aW9uc3sKCQkJVGltZW91dDogICA1ICogdGltZS5TZWNvbmQsCgkJCUlzb2xhdGlvbjogc3FsLkxldmVsU2VyaWFsaXphYmxlLAoJCQlSZWFkT25seTogIGZhbHNlLAoJCX0KCX0KCgkvLyBCdWlsZCB0aGUgY29udGV4dCB3aXRoIHRoZSBwcm92aWRlZCB0aW1lb3V0LgoJLy8gVGhpcyB3aWxsIGJlIHVzZWQgdG8gZGVmaW5lIHRoZSB0b3RhbCB0aW1lIHRoZSB0cmFuc2FjdGlvbiBtYXkgdGFrZSwKCS8vIHBhc3QgdGhpcyB0aW1lLCBpdCB3aWxsIGJlIGNhbmNlbGxlZCwgcm9sbGJhY2ssIHRoZW4gdGhyb3cgYW4gZXJyb3IuCgljdHgsIGNhbmNlbCA6PSBjb250ZXh0LldpdGhUaW1lb3V0KGNvbnRleHQuQmFja2dyb3VuZCgpLCBvcHQuVGltZW91dCkKCWRlZmVyIGNhbmNlbCgpCgoJdmFyIHR4ICpzcWwuVHgKCWlmIHR4LCBlcnIgPSBxdS5CZWdpblR4KGN0eCwgJnNxbC5UeE9wdGlvbnN7CgkJSXNvbGF0aW9uOiBvcHQuSXNvbGF0aW9uLAoJCVJlYWRPbmx5OiAgb3B0LlJlYWRPbmx5LAoJfSk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglkZWZlciBmdW5jKCkgewoJCWlmIHIgOj0gcmVjb3ZlcigpOyByICE9IG5pbCB7CgkJCS8vIE9ubHkgbmVlZCB0byBsb2cgaGVyZSBiZWNhdXNlIHBhbmljIHdvbid0IHJlcG9ydCB3aGV0aGVyCgkJCS8vIHRoZSByb2xsYmFjayB3YXMgc3VjY2Vzc2Z1bCBvciBub3QuCgkJCWlmIHR4ZXJyIDo9IHR4LlJvbGxiYWNrKCk7IHR4ZXJyICE9IG5pbCB7CgkJCQlsb2cuUHJpbnRsbigiZGIgcm9sbGJhY2sgZXJyb3I6IiwgdHhlcnIpCgkJCX0KCgkJCWxvZy5QcmludGYoInJvbGxlZCBiYWNrIHRyYW5zYWN0aW9uIikKCQkJcGFuaWMocikKCQl9IGVsc2UgaWYgZXJyICE9IG5pbCB7CgkJCS8vIElmIHdlIHJ1biBpbnRvIGlzc3VlcyByb2xsaW5nIGJhY2ssIGtlZXAgdHJhY2sgb2YgdGhlIGVycm9yIHRoYXQKCQkJLy8gY2F1c2VkIHRoZSBpc3N1ZSBhbmQgcHJvdmlkZSBzb21lIGNvbnRleHQgb24gdGhlIHJvbGxiYWNrIGZhaWx1cmUuCgkJCWlmIHJlcnIgOj0gdHguUm9sbGJhY2soKTsgcmVyciAhPSBuaWwgewoJCQkJZXJyID0gZm10LkVycm9yZigiZGIgZXJyb3I6ICV2IHJvbGxiYWNrIGVycm9yOiAldiIsIGVyciwgcmVycikKCQkJfQoJCX0gZWxzZSB7CgkJCWlmIGNlcnIgOj0gdHguQ29tbWl0KCk7IGNlcnIgIT0gbmlsIHsKCQkJCWVyciA9IGZtdC5FcnJvcmYoImNvbW1pdCBlcnJvcjogJXYiLCBjZXJyKQoJCQl9CgkJfQoJfSgpCgoJZXJyID0gYWN0aW9ucyh0eCkKCXJldHVybiBlcnIKfQp7e2VuZH19Cg==\"") + packr.PackJSONBytes("./tmpl", "x_helpers_test.html", "\"e3tkZWZpbmUgImhlbHBlcnN0ZXN0In19Ci8vK2J1aWxkICFoZWxwZXJzCgpwYWNrYWdlIHt7IC5QYWNrYWdlTmFtZSB9fQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgQ29kZSBnZW5lcmF0ZWQgYnkgbW9kZWxnZW4gfAp8ICAgICAgICBETyBOT1QgRURJVC4gICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgppbXBvcnQgKAoJImRhdGFiYXNlL3NxbC9kcml2ZXIiCgkiZW5jb2RpbmcvanNvbiIKCSJyZWZsZWN0IgoJInRlc3RpbmciCgkidGltZSIKKQoKZnVuYyBUZXN0U3RydWN0RW1iZWRkaW5nKHQgKnRlc3RpbmcuVCkgewoJdGltIDo9IHRpbWUuRGF0ZSgyMDE3LCAxLCAxLCAwLCAwLCAwLCAwLCB0aW1lLlVUQykKCWV4cGVjdGVkIDo9IFtdYnl0ZShgeyJhIjoxMjMsImIiOnRydWUsImMiOjEyMy4xMjMsImQiOiJzdHJpbmciLCJlIjoiMjAxNy0wMS0wMVQwMDowMDowMFoiLCJmIjpbMSwyLDNdfWApCgl0eXBlIGVtYmVkIHN0cnVjdCB7CgkJQSBOdWxsSW50NjQgICBganNvbjoiYSxvbWl0ZW1wdHkiYAoJCUIgTnVsbEJvb2wgICAgYGpzb246ImIsb21pdGVtcHR5ImAKCQlDIE51bGxGbG9hdDY0IGBqc29uOiJjLG9taXRlbXB0eSJgCgkJRCBOdWxsU3RyaW5nICBganNvbjoiZCxvbWl0ZW1wdHkiYAoJCUUgTnVsbFRpbWUgICAgYGpzb246ImUsb21pdGVtcHR5ImAKCQlGIFJhd0pTT04gICAgIGBqc29uOiJmLG9taXRlbXB0eSJgCgl9CgllbSA6PSBlbWJlZHsKCQlBOiBOdWxsSW50NjR7VmFsaWQ6IHRydWUsIEludDY0OiAxMjN9LAoJCUI6IE51bGxCb29se1ZhbGlkOiB0cnVlLCBCb29sOiB0cnVlfSwKCQlDOiBOdWxsRmxvYXQ2NHtWYWxpZDogdHJ1ZSwgRmxvYXQ2NDogMTIzLjEyM30sCgkJRDogTnVsbFN0cmluZ3tWYWxpZDogdHJ1ZSwgU3RyaW5nOiAic3RyaW5nIn0sCgkJRTogTnVsbFRpbWV7VmFsaWQ6IHRydWUsIFRpbWU6IHRpbX0sCgkJRjogUmF3SlNPTihgWzEsMiwzXWApLAoJfQoJYiwgZXJyIDo9IGpzb24uTWFyc2hhbChlbSkKCWlmIGVyciAhPSBuaWwgewoJCXQuRmF0YWwoZXJyKQoJfQoJaWYgIXJlZmxlY3QuRGVlcEVxdWFsKGV4cGVjdGVkLCBiKSB7CgkJdC5GYXRhbCgibm90IHRoZSBzYW1lIEpTT04hIikKCX0KCWlmICEoc3RyaW5nKGIpID09IHN0cmluZyhleHBlY3RlZCkpIHsKCQl0LkZhdGFsKCJub3QgdGhlIHNhbWUhIikKCX0KCgl2YXIgZW0yIGVtYmVkCglpZiBlcnIgOj0ganNvbi5Vbm1hcnNoYWwoZXhwZWN0ZWQsICZlbTIpOyBlcnIgIT0gbmlsIHsKCQl0LkZhdGFsKGVycikKCX0KCWlmICFyZWZsZWN0LkRlZXBFcXVhbChlbTIsIGVtKSB7CgkJdC5GYXRhbCgibm90IGNvcnJlY3QiKQoJfQp9CgpmdW5jIFRlc3ROdWxsU3RyaW5nX1VubWFyc2hhbEpTT04odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgIE51bGxTdHJpbmcKCQlzb3VyY2UgIFtdYnl0ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICAgICJleHBsaWNpdCBudWxsIiwKCQkJc291cmNlOiAgW11ieXRlKGBudWxsYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAic3RyaW5nIG51bGwiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYCJudWxsImApLAoJCQl3YW50RXJyOiBmYWxzZSwgLy8gdGhpcyBvbmUgU0hPVUxEIGJlIHZhbGlkCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgImhlbGxvImApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogICAgImludmFsaWQiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYHsia2V5IjoidmFsdWUifWApLAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiZW1wdHkiLAoJCQlzb3VyY2U6ICBbXWJ5dGV7fSwKCQkJd2FudEVycjogdHJ1ZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5Vbm1hcnNoYWxKU09OKHR0LnNvdXJjZSk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsU3RyaW5nLlVubWFyc2hhbEpTT04oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbFN0cmluZ19WYWx1ZSh0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgTnVsbFN0cmluZwoJCXdhbnQgICAgZHJpdmVyLlZhbHVlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogTnVsbFN0cmluZ3sKCQkJCVZhbGlkOiAgdHJ1ZSwKCQkJCVN0cmluZzogImhlbGxvIiwKCQkJfSwKCQkJd2FudDogICAgZHJpdmVyLlZhbHVlKCJoZWxsbyIpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiBOdWxsU3RyaW5newoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQl3YW50OiAgICBuaWwsCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uVmFsdWUoKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5WYWx1ZSgpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5WYWx1ZSgpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsU3RyaW5nX1NjYW4odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsU3RyaW5nCgkJd2FudEVyciBib29sCgkJc3JjICAgICBpbnRlcmZhY2V7fQoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46ICZOdWxsU3RyaW5newoJCQkJU3RyaW5nOiAiaGVsbG8iLAoJCQkJVmFsaWQ6ICB0cnVlLAoJCQl9LAoJCQlzcmM6ICAgICAiIiwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbFN0cmluZ3sKCQkJCVN0cmluZzogImhlbGxvIiwKCQkJCVZhbGlkOiAgZmFsc2UsCgkJCX0sCgkJCXNyYzogICAgIG5pbCwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCX0KCWZvciBfLCB0dCA6PSByYW5nZSB0ZXN0cyB7CgkJdC5SdW4odHQubmFtZSwgZnVuYyh0ICp0ZXN0aW5nLlQpIHsKCQkJaWYgZXJyIDo9IHR0Lm4uU2Nhbih0dC5zcmMpOyAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5TY2FuKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCQlpZiAhdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gbmlsIHsKCQkJCXQuRXJyb3JmKCJzaG91bGQgcmV0dXJuIG51bGwiKQoJCQl9CgkJCWlmIHR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IHR0Lm4uU3RyaW5nIHsKCQkJCXQuRXJyb3JmKCJpbnZhbGlkIHZhbHVlIikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxTdHJpbmdfTWFyc2hhbEpTT04odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsU3RyaW5nCgkJd2FudCAgICBbXWJ5dGUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbFN0cmluZ3sKCQkJCVN0cmluZzogImhlbGxvIiwKCQkJCVZhbGlkOiAgdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAiaGVsbG8iYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAidmFsaWQgbnVsbCIsCgkJCW46ICZOdWxsU3RyaW5newoJCQkJU3RyaW5nOiAiIiwKCQkJCVZhbGlkOiAgZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiAmTnVsbFN0cmluZ3sKCQkJCVZhbGlkOiB0cnVlLAoJCQl9LAoJCQl3YW50OiAgICBbXWJ5dGUoYCIiYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uTWFyc2hhbEpTT04oKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5NYXJzaGFsSlNPTigpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbFN0cmluZy5NYXJzaGFsSlNPTigpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsQm9vbF9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgICAgICBzdHJpbmcKCQluICAgICAgICAgICAgTnVsbEJvb2wKCQlzb3VyY2UgICAgICAgW11ieXRlCgkJd2FudEVyciAgICAgIGJvb2wKCQl3YW50VmFsaWRpdHkgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICAgICAgICAgImV4cGxpY2l0IG51bGwiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiAgICAgIGZhbHNlLAoJCQl3YW50VmFsaWRpdHk6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAgICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogICAgICAgW11ieXRlKGBmYWxzZWApLAoJCQl3YW50RXJyOiAgICAgIGZhbHNlLAoJCQl3YW50VmFsaWRpdHk6IHRydWUsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICAgICAgImludmFsaWQiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZShgeyJrZXkiOiJ2YWx1ZSJ9YCksCgkJCXdhbnRFcnI6ICAgICAgdHJ1ZSwKCQkJd2FudFZhbGlkaXR5OiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogICAgICAgICAiZW1wdHkiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZXt9LAoJCQl3YW50RXJyOiAgICAgIHRydWUsCgkJCXdhbnRWYWxpZGl0eTogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICAgICAgImV4cGxpY2l0IG51bGwiLAoJCQlzb3VyY2U6ICAgICAgIFtdYnl0ZSgibnVsbCIpLAoJCQl3YW50RXJyOiAgICAgIGZhbHNlLAoJCQl3YW50VmFsaWRpdHk6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWlmIGVyciA6PSB0dC5uLlVubWFyc2hhbEpTT04odHQuc291cmNlKTsgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgJiYgdHQubi5WYWxpZCA9PSB0dC53YW50VmFsaWRpdHkgewoJCQkJdC5FcnJvcmYoIk51bGxCb29sLlVubWFyc2hhbEpTT04oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbEJvb2xfVmFsdWUodCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgIE51bGxCb29sCgkJd2FudCAgICBkcml2ZXIuVmFsdWUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiBOdWxsQm9vbHsKCQkJCVZhbGlkOiB0cnVlLAoJCQkJQm9vbDogIHRydWUsCgkJCX0sCgkJCXdhbnQ6ICAgIGRyaXZlci5WYWx1ZSh0cnVlKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogTnVsbEJvb2x7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIG5pbCwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCX0KCWZvciBfLCB0dCA6PSByYW5nZSB0ZXN0cyB7CgkJdC5SdW4odHQubmFtZSwgZnVuYyh0ICp0ZXN0aW5nLlQpIHsKCQkJZ290LCBlcnIgOj0gdHQubi5WYWx1ZSgpCgkJCWlmIChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5WYWx1ZSgpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbEJvb2wuVmFsdWUoKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbEJvb2xfU2Nhbih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxCb29sCgkJd2FudEVyciBib29sCgkJc3JjICAgICBpbnRlcmZhY2V7fQoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46ICZOdWxsQm9vbHsKCQkJCUJvb2w6ICB0cnVlLAoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXNyYzogICAgIHRydWUsCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAibmlsIHZhbHVlIiwKCQkJbjogJk51bGxCb29sewoJCQkJQm9vbDogIHRydWUsCgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXNyYzogICAgIGZhbHNlLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5TY2FuKHR0LnNyYyk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5TY2FuKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCQlpZiAhdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gbmlsIHsKCQkJCXQuRXJyb3JmKCJzaG91bGQgcmV0dXJuIG51bGwiKQoJCQl9CgkJCWlmIHR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IHR0Lm4uQm9vbCB7CgkJCQl0LkVycm9yZigiaW52YWxpZCB2YWx1ZSIpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsQm9vbF9NYXJzaGFsSlNPTih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxCb29sCgkJd2FudCAgICBbXWJ5dGUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbEJvb2x7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGBmYWxzZWApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogInZhbGlkIG51bGwiLAoJCQluOiAmTnVsbEJvb2x7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiAmTnVsbEJvb2x7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGBmYWxzZWApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlnb3QsIGVyciA6PSB0dC5uLk1hcnNoYWxKU09OKCkKCQkJaWYgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxCb29sLk1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5NYXJzaGFsSlNPTigpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsVGltZV9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsVGltZQoJCXNvdXJjZSAgW11ieXRlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogICAgInZhbGlkIiwKCQkJc291cmNlOiAgW11ieXRlKGAiMjAxNy0xMS0yNFQwMDowMDowMFoiYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiaW52YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgeyJrZXkiOiJ2YWx1ZSJ9YCksCgkJCXdhbnRFcnI6IHRydWUsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJlbXB0eSIsCgkJCXNvdXJjZTogIFtdYnl0ZXt9LAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiZXhwbGljaXQgbnVsbCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5Vbm1hcnNoYWxKU09OKHR0LnNvdXJjZSk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsQm9vbC5Vbm1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxUaW1lX1ZhbHVlKHQgKnRlc3RpbmcuVCkgewoJdGltIDo9IHRpbWUuTm93KCkKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgTnVsbFRpbWUKCQl3YW50ICAgIGRyaXZlci5WYWx1ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46IE51bGxUaW1lewoJCQkJVmFsaWQ6IHRydWUsCgkJCQlUaW1lOiAgdGltLAoJCQl9LAoJCQl3YW50OiAgICBkcml2ZXIuVmFsdWUodGltKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogTnVsbFRpbWV7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIG5pbCwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCX0KCWZvciBfLCB0dCA6PSByYW5nZSB0ZXN0cyB7CgkJdC5SdW4odHQubmFtZSwgZnVuYyh0ICp0ZXN0aW5nLlQpIHsKCQkJZ290LCBlcnIgOj0gdHQubi5WYWx1ZSgpCgkJCWlmIChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsVGltZS5WYWx1ZSgpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCQlyZXR1cm4KCQkJfQoJCQlpZiAhcmVmbGVjdC5EZWVwRXF1YWwoZ290LCB0dC53YW50KSB7CgkJCQl0LkVycm9yZigiTnVsbFRpbWUuVmFsdWUoKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbFRpbWVfU2Nhbih0ICp0ZXN0aW5nLlQpIHsKCXRpbSA6PSB0aW1lLk5vdygpCgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsVGltZQoJCXdhbnRFcnIgYm9vbAoJCXNyYyAgICAgaW50ZXJmYWNle30KCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlUaW1lOiAgdGltLAoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXNyYzogICAgIHRpbSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlUaW1lOiAgdGltLAoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQlzcmM6ICAgICB0aW1lLk5vdygpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5TY2FuKHR0LnNyYyk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsVGltZS5TY2FuKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCQlpZiAhdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gbmlsIHsKCQkJCXQuRXJyb3JmKCJzaG91bGQgcmV0dXJuIG51bGwiKQoJCQl9CgkJCWlmIHR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IHR0Lm4uVGltZSB7CgkJCQl0LkVycm9yZigiaW52YWxpZCB2YWx1ZSIpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsVGltZV9NYXJzaGFsSlNPTih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxUaW1lCgkJd2FudCAgICBbXWJ5dGUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlUaW1lOiAgdGltZS5EYXRlKDIwMTcsIDExLCAyNCwgMCwgMCwgMCwgMCwgdGltZS5VVEMpLAoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgIjIwMTctMTEtMjRUMDA6MDA6MDBaImApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogInZhbGlkIG51bGwiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgbnVsbGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiAmTnVsbFRpbWV7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAiMDAwMS0wMS0wMVQwMDowMDowMFoiYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uTWFyc2hhbEpTT04oKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbFRpbWUuTWFyc2hhbEpTT04oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQkJcmV0dXJuCgkJCX0KCQkJaWYgIXJlZmxlY3QuRGVlcEVxdWFsKGdvdCwgdHQud2FudCkgewoJCQkJdC5FcnJvcmYoIk51bGxUaW1lLk1hcnNoYWxKU09OKCkgPSAldiwgd2FudCAldiIsIGdvdCwgdHQud2FudCkKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxJbnQ2NF9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsSW50NjQKCQlzb3VyY2UgIFtdYnl0ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgMTIzYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiaW52YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgeyJrZXkiOiJ2YWx1ZSJ9YCksCgkJCXdhbnRFcnI6IHRydWUsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJlbXB0eSIsCgkJCXNvdXJjZTogIFtdYnl0ZXt9LAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWlmIGVyciA6PSB0dC5uLlVubWFyc2hhbEpTT04odHQuc291cmNlKTsgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxJbnQ2NC5Vbm1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxJbnQ2NF9WYWx1ZSh0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgTnVsbEludDY0CgkJd2FudCAgICBkcml2ZXIuVmFsdWUKCQl3YW50RXJyIGJvb2wKCX17CgkJewoJCQluYW1lOiAidmFsaWQiLAoJCQluOiBOdWxsSW50NjR7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJCUludDY0OiAxMjMsCgkJCX0sCgkJCXdhbnQ6ICAgIGRyaXZlci5WYWx1ZShpbnQ2NCgxMjMpKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogTnVsbEludDY0ewoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQl3YW50OiAgICBuaWwsCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uVmFsdWUoKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbEludDY0LlZhbHVlKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsSW50NjQuVmFsdWUoKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQoKZnVuYyBUZXN0TnVsbEludDY0X1NjYW4odCAqdGVzdGluZy5UKSB7Cgl0ZXN0cyA6PSBbXXN0cnVjdCB7CgkJbmFtZSAgICBzdHJpbmcKCQluICAgICAgICpOdWxsSW50NjQKCQl3YW50RXJyIGJvb2wKCQlzcmMgICAgIGludGVyZmFjZXt9Cgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogJk51bGxJbnQ2NHsKCQkJCUludDY0OiAxMjMsCgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJc3JjOiAgICAgaW50NjQoMTIzKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbEludDY0ewoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQlzcmM6ICAgICBpbnQ2NCgxMjMpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5TY2FuKHR0LnNyYyk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsSW50NjQuU2NhbigpIGVycm9yID0gJXYsIHdhbnRFcnIgJXYiLCBlcnIsIHR0LndhbnRFcnIpCgkJCX0KCQkJaWYgIXR0Lm4uVmFsaWQgJiYgdHQuc3JjICE9IG5pbCB7CgkJCQl0LkVycm9yZigic2hvdWxkIHJldHVybiBudWxsIikKCQkJfQoJCQlpZiB0dC5uLlZhbGlkICYmIHR0LnNyYyAhPSB0dC5uLkludDY0IHsKCQkJCXQuRXJyb3JmKCJpbnZhbGlkIHZhbHVlIikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxJbnQ2NF9NYXJzaGFsSlNPTih0ICp0ZXN0aW5nLlQpIHsKCXRlc3RzIDo9IFtdc3RydWN0IHsKCQluYW1lICAgIHN0cmluZwoJCW4gICAgICAgKk51bGxJbnQ2NAoJCXdhbnQgICAgW11ieXRlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogJk51bGxJbnQ2NHsKCQkJCUludDY0OiAxMjMsCgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAxMjNgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJ2YWxpZCBudWxsIiwKCQkJbjogJk51bGxJbnQ2NHsKCQkJCVZhbGlkOiBmYWxzZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGBudWxsYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgkJewoJCQluYW1lOiAiaW52YWxpZCIsCgkJCW46ICZOdWxsSW50NjR7CgkJCQlWYWxpZDogdHJ1ZSwKCQkJfSwKCQkJd2FudDogICAgW11ieXRlKGAwYCksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWdvdCwgZXJyIDo9IHR0Lm4uTWFyc2hhbEpTT04oKQoJCQlpZiAoZXJyICE9IG5pbCkgIT0gdHQud2FudEVyciB7CgkJCQl0LkVycm9yZigiTnVsbEludDY0Lk1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsSW50NjQuTWFyc2hhbEpTT04oKSA9ICV2LCB3YW50ICV2IiwgZ290LCB0dC53YW50KQoJCQl9CgkJfSkKCX0KfQpmdW5jIFRlc3ROdWxsRmxvYXQ2NF9Vbm1hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsRmxvYXQ2NAoJCXNvdXJjZSAgW11ieXRlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogICAgImV4cGxpY2l0IG51bGwiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYG51bGxgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICAgICJ2YWxpZCIsCgkJCXNvdXJjZTogIFtdYnl0ZShgMTIzLjEyM2ApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogICAgImludmFsaWQiLAoJCQlzb3VyY2U6ICBbXWJ5dGUoYHsia2V5IjoidmFsdWUifWApLAoJCQl3YW50RXJyOiB0cnVlLAoJCX0sCgkJewoJCQluYW1lOiAgICAiZW1wdHkiLAoJCQlzb3VyY2U6ICBbXWJ5dGV7fSwKCQkJd2FudEVycjogdHJ1ZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlpZiBlcnIgOj0gdHQubi5Vbm1hcnNoYWxKU09OKHR0LnNvdXJjZSk7IChlcnIgIT0gbmlsKSAhPSB0dC53YW50RXJyIHsKCQkJCXQuRXJyb3JmKCJOdWxsRmxvYXQ2NC5Vbm1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxGbG9hdDY0X1ZhbHVlKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICBOdWxsRmxvYXQ2NAoJCXdhbnQgICAgZHJpdmVyLlZhbHVlCgkJd2FudEVyciBib29sCgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogTnVsbEZsb2F0NjR7CgkJCQlWYWxpZDogICB0cnVlLAoJCQkJRmxvYXQ2NDogMTIzLjEyMywKCQkJfSwKCQkJd2FudDogICAgZHJpdmVyLlZhbHVlKGZsb2F0NjQoMTIzLjEyMykpLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJCXsKCQkJbmFtZTogImludmFsaWQiLAoJCQluOiBOdWxsRmxvYXQ2NHsKCQkJCVZhbGlkOiBmYWxzZSwKCQkJfSwKCQkJd2FudDogICAgbmlsLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlnb3QsIGVyciA6PSB0dC5uLlZhbHVlKCkKCQkJaWYgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxGbG9hdDY0LlZhbHVlKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsRmxvYXQ2NC5WYWx1ZSgpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3ROdWxsRmxvYXQ2NF9TY2FuKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICAqTnVsbEZsb2F0NjQKCQl3YW50RXJyIGJvb2wKCQlzcmMgICAgIGludGVyZmFjZXt9Cgl9ewoJCXsKCQkJbmFtZTogInZhbGlkIiwKCQkJbjogJk51bGxGbG9hdDY0ewoJCQkJRmxvYXQ2NDogMTIzLjEyMywKCQkJCVZhbGlkOiAgIHRydWUsCgkJCX0sCgkJCXNyYzogICAgIGZsb2F0NjQoMTIzKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJuaWwgdmFsdWUiLAoJCQluOiAmTnVsbEZsb2F0NjR7CgkJCQlWYWxpZDogZmFsc2UsCgkJCX0sCgkJCXNyYzogICAgIGZsb2F0NjQoMTIzLjEyMyksCgkJCXdhbnRFcnI6IGZhbHNlLAoJCX0sCgl9Cglmb3IgXywgdHQgOj0gcmFuZ2UgdGVzdHMgewoJCXQuUnVuKHR0Lm5hbWUsIGZ1bmModCAqdGVzdGluZy5UKSB7CgkJCWlmIGVyciA6PSB0dC5uLlNjYW4odHQuc3JjKTsgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxGbG9hdDY0LlNjYW4oKSBlcnJvciA9ICV2LCB3YW50RXJyICV2IiwgZXJyLCB0dC53YW50RXJyKQoJCQl9CgkJCWlmICF0dC5uLlZhbGlkICYmIHR0LnNyYyAhPSBuaWwgewoJCQkJdC5FcnJvcmYoInNob3VsZCByZXR1cm4gbnVsbCIpCgkJCX0KCQkJaWYgdHQubi5WYWxpZCAmJiB0dC5zcmMgIT0gdHQubi5GbG9hdDY0IHsKCQkJCXQuRXJyb3JmKCJpbnZhbGlkIHZhbHVlIikKCQkJfQoJCX0pCgl9Cn0KCmZ1bmMgVGVzdE51bGxGbG9hdDY0X01hcnNoYWxKU09OKHQgKnRlc3RpbmcuVCkgewoJdGVzdHMgOj0gW11zdHJ1Y3QgewoJCW5hbWUgICAgc3RyaW5nCgkJbiAgICAgICAqTnVsbEZsb2F0NjQKCQl3YW50ICAgIFtdYnl0ZQoJCXdhbnRFcnIgYm9vbAoJfXsKCQl7CgkJCW5hbWU6ICJ2YWxpZCIsCgkJCW46ICZOdWxsRmxvYXQ2NHsKCQkJCUZsb2F0NjQ6IDEyMy4xMjMsCgkJCQlWYWxpZDogICB0cnVlLAoJCQl9LAoJCQl3YW50OiAgICBbXWJ5dGUoYDEyMy4xMjNgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJ2YWxpZCBudWxsIiwKCQkJbjogJk51bGxGbG9hdDY0ewoJCQkJVmFsaWQ6IGZhbHNlLAoJCQl9LAoJCQl3YW50OiAgICBbXWJ5dGUoYG51bGxgKSwKCQkJd2FudEVycjogZmFsc2UsCgkJfSwKCQl7CgkJCW5hbWU6ICJpbnZhbGlkIiwKCQkJbjogJk51bGxGbG9hdDY0ewoJCQkJVmFsaWQ6IHRydWUsCgkJCX0sCgkJCXdhbnQ6ICAgIFtdYnl0ZShgMGApLAoJCQl3YW50RXJyOiBmYWxzZSwKCQl9LAoJfQoJZm9yIF8sIHR0IDo9IHJhbmdlIHRlc3RzIHsKCQl0LlJ1bih0dC5uYW1lLCBmdW5jKHQgKnRlc3RpbmcuVCkgewoJCQlnb3QsIGVyciA6PSB0dC5uLk1hcnNoYWxKU09OKCkKCQkJaWYgKGVyciAhPSBuaWwpICE9IHR0LndhbnRFcnIgewoJCQkJdC5FcnJvcmYoIk51bGxGbG9hdDY0Lk1hcnNoYWxKU09OKCkgZXJyb3IgPSAldiwgd2FudEVyciAldiIsIGVyciwgdHQud2FudEVycikKCQkJCXJldHVybgoJCQl9CgkJCWlmICFyZWZsZWN0LkRlZXBFcXVhbChnb3QsIHR0LndhbnQpIHsKCQkJCXQuRXJyb3JmKCJOdWxsRmxvYXQ2NC5NYXJzaGFsSlNPTigpID0gJXYsIHdhbnQgJXYiLCBnb3QsIHR0LndhbnQpCgkJCX0KCQl9KQoJfQp9CgpmdW5jIFRlc3RUb051bGxCb29sKHQgKnRlc3RpbmcuVCkgewoJYiA6PSB0cnVlCgliYiA6PSBUb051bGxCb29sKCZiKQoJaWYgIWJiLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgdmFsaWQsIGdvdCAldiIsIGJiLlZhbGlkKQoJfQoJaWYgIWJiLkJvb2wgewoJCXQuRXJyb3JmKCJleHBlY3RlZCB0cnVlLCBnb3QgJXYiLCBiYi5Cb29sKQoJfQoKCXZhciBiMiAqYm9vbAoJYmIyIDo9IFRvTnVsbEJvb2woYjIpCglpZiBiYjIuVmFsaWQgewoJCXQuRXJyb3JmKCJleHBlY3RlZCBub3QgdmFsaWQsIGdvdCAldiIsIGJiMi5WYWxpZCkKCX0KCWlmIGJiMi5Cb29sIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgZmFsc2UsIGdvdCAldiIsIGJiMi5Cb29sKQoJfQp9CmZ1bmMgVGVzdFRvTnVsbEludDY0KHQgKnRlc3RpbmcuVCkgewoJYiA6PSBpbnQ2NCgxMjMpCgliYiA6PSBUb051bGxJbnQ2NCgmYikKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLkludDY0ICE9IDEyMyB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDEyMywgZ290ICV2IiwgYmIuSW50NjQpCgl9CgoJdmFyIGIyICppbnQ2NAoJYmIyIDo9IFRvTnVsbEludDY0KGIyKQoJaWYgYmIyLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgbm90IHZhbGlkLCBnb3QgJXYiLCBiYjIuVmFsaWQpCgl9CglpZiBiYjIuSW50NjQgIT0gMCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDAsIGdvdCAldiIsIGJiMi5JbnQ2NCkKCX0KfQoKZnVuYyBUZXN0VG9OdWxsRmxvYXQ2NCh0ICp0ZXN0aW5nLlQpIHsKCWIgOj0gZmxvYXQ2NCgxMjMuMTIzKQoJYmIgOj0gVG9OdWxsRmxvYXQ2NCgmYikKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLkZsb2F0NjQgIT0gMTIzLjEyMyB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDEyMy4xMjMsIGdvdCAldiIsIGJiLkZsb2F0NjQpCgl9CgoJdmFyIGIyICpmbG9hdDY0CgliYjIgOj0gVG9OdWxsRmxvYXQ2NChiMikKCWlmIGJiMi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIG5vdCB2YWxpZCwgZ290ICV2IiwgYmIyLlZhbGlkKQoJfQoJaWYgYmIyLkZsb2F0NjQgIT0gMCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIDAsIGdvdCAldiIsIGJiMi5GbG9hdDY0KQoJfQp9CmZ1bmMgVGVzdFRvTnVsbFN0cmluZyh0ICp0ZXN0aW5nLlQpIHsKCWIgOj0gInF3ZSIKCWJiIDo9IFRvTnVsbFN0cmluZygmYikKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLlN0cmluZyAhPSAicXdlIiB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHF3ZSwgZ290ICV2IiwgYmIuU3RyaW5nKQoJfQoKCXZhciBiMiAqc3RyaW5nCgliYjIgOj0gVG9OdWxsU3RyaW5nKGIyKQoJaWYgYmIyLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgbm90IHZhbGlkLCBnb3QgJXYiLCBiYjIuVmFsaWQpCgl9CglpZiBiYjIuU3RyaW5nICE9ICIiIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgPGVtcHR5IHN0cmluZz4sIGdvdCAldiIsIGJiMi5TdHJpbmcpCgl9Cn0KZnVuYyBUZXN0VG9OdWxsVGltZSh0ICp0ZXN0aW5nLlQpIHsKCXRpbSA6PSB0aW1lLk5vdygpCgliYiA6PSBUb051bGxUaW1lKHRpbSkKCWlmICFiYi5WYWxpZCB7CgkJdC5FcnJvcmYoImV4cGVjdGVkIHZhbGlkLCBnb3QgJXYiLCBiYi5WYWxpZCkKCX0KCWlmIGJiLlRpbWUgIT0gdGltIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgJXYsIGdvdCAldiIsIHRpbSwgYmIuVGltZSkKCX0KCgl0aW0gPSB0aW1lLlRpbWV7fQoJYmIgPSBUb051bGxUaW1lKHRpbSkKCWlmIGJiLlZhbGlkIHsKCQl0LkVycm9yZigiZXhwZWN0ZWQgaW52YWxpZCwgZ290ICV2IiwgYmIuVmFsaWQpCgl9CglpZiBiYi5UaW1lICE9IHRpbSB7CgkJdC5FcnJvcmYoImV4cGVjdGVkICV2LCBnb3QgJXYiLCB0aW0sIGJiLlRpbWUpCgl9Cn0KCmZ1bmMgVGVzdFJhd0pTT05fTWFyc2hhbEpTT04odCAqdGVzdGluZy5UKSB7CgljYXNlcyA6PSBbXXN0cnVjdCB7CgkJbmFtZSBzdHJpbmcKCQlkYXRhIFtdYnl0ZQoJCWV4cCAgc3RyaW5nCgl9ewoJCXsKCQkJbmFtZTogImVtcHR5IGRhdGEiLAoJCQlkYXRhOiBbXWJ5dGV7fSwKCQkJZXhwOiAgIm51bGwiLAoJCX0sCgl9CgoJZm9yIF8sIGMgOj0gcmFuZ2UgY2FzZXMgewoJCXQuUnVuKGMubmFtZSwgZnVuYyh0ICp0ZXN0aW5nLlQpIHsKCQkJcmogOj0gUmF3SlNPTihjLmRhdGEpCgkJCWIsIGVyciA6PSByai5NYXJzaGFsSlNPTigpCgkJCWlmIGVyciAhPSBuaWwgewoJCQkJdC5GYXRhbGYoInVuZXhwZWN0ZWQgZXJyb3I6ICV2IiwgZXJyKQoJCQl9CgkJCWlmIHN0cmluZyhiKSAhPSBjLmV4cCB7CgkJCQl0LkZhdGFsZigiXG5leHA6ICVxXG5nb3Q6ICVxIiwgYy5leHAsIHN0cmluZyhiKSkKCQkJfQoJCX0pCgl9Cn0Ke3tlbmR9fQo=\"") } diff --git a/tmpl/x_helpers.html b/tmpl/x_helpers.html index f83ee14..9274792 100644 --- a/tmpl/x_helpers.html +++ b/tmpl/x_helpers.html @@ -321,6 +321,9 @@ // MarshalJSON for NullString func (n RawJSON) MarshalJSON() ([]byte, error) { + if len(n) == 0 { + return []byte("null"), nil + } a := json.RawMessage(n) return a.MarshalJSON() } diff --git a/tmpl/x_helpers_test.html b/tmpl/x_helpers_test.html index 9eece5b..687060a 100644 --- a/tmpl/x_helpers_test.html +++ b/tmpl/x_helpers_test.html @@ -981,4 +981,31 @@ t.Errorf("expected %v, got %v", tim, bb.Time) } } + +func TestRawJSON_MarshalJSON(t *testing.T) { + cases := []struct { + name string + data []byte + exp string + }{ + { + name: "empty data", + data: []byte{}, + exp: "null", + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + rj := RawJSON(c.data) + b, err := rj.MarshalJSON() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if string(b) != c.exp { + t.Fatalf("\nexp: %q\ngot: %q", c.exp, string(b)) + } + }) + } +} {{end}}