OneTimeAuthentificationLink
10.0.2
Rother OSS GmbH
https://rother-oss.com/
GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
Do not automatically activate CustomerUser creation.
Initial Release.
Automatically creates customer users and gives them access via one time authentification tokens.
10.0.x
2021-03-01 16:33:00
opms
IyAtLQojIE9UT0JPIGlzIGEgd2ViLWJhc2VkIHRpY2tldGluZyBzeXN0ZW0gZm9yIHNlcnZpY2Ugb3JnYW5pc2F0aW9ucy4KIyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIwIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDE5LTIwMjEgUm90aGVyIE9TUyBHbWJILCBodHRwczovL290b2JvLmRlLwojIC0tCiMgJG9yaWdpbjogb3RvYm8gLSBlYWFmYmNmMTRhNDVkOTY3Y2UxMDk0OGNhNzNiZjRjOGRjNDY0NTc1IC0gS2VybmVsL1N5c3RlbS9DdXN0b21lckF1dGgucG0KIyAtLQojIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyCiMgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKIyBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgojIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCiMgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gSWYgbm90LCBzZWUgPGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJBdXRoOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6TGFuZ3VhZ2UgcXcoVHJhbnNsYXRhYmxlKTsKCm91ciBAT2JqZWN0RGVwZW5kZW5jaWVzID0gKAogICAgJ0tlcm5lbDo6Q29uZmlnJywKICAgICdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpMb2cnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpNYWluJywKICAgICdLZXJuZWw6OlN5c3RlbTo6U3lzdGVtTWFpbnRlbmFuY2UnLAopOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpDdXN0b21lckF1dGggLSBjdXN0b21lciBhdXRoZW50aWNhdGlvbiBtb2R1bGUuCgo9aGVhZDEgREVTQ1JJUFRJT04KClRoZSBhdXRoZW50aWNhdGlvbiBtb2R1bGUgZm9yIHRoZSBjdXN0b21lciBpbnRlcmZhY2UuCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPWhlYWQyIG5ldygpCgpEb24ndCB1c2UgdGhlIGNvbnN0cnVjdG9yIGRpcmVjdGx5LCB1c2UgdGhlIE9iamVjdE1hbmFnZXIgaW5zdGVhZDoKCiAgICBteSAkQ3VzdG9tZXJBdXRoT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQXV0aCcpOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgbXkgJENvbmZpZ09iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyk7CiAgICBteSAkTWFpbk9iamVjdCAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Ok1haW4nKTsKCiAgICAjIGxvYWQgYXV0aCBtb2R1bGVzCiAgICBTT1VSQ0U6CiAgICBmb3IgbXkgJENvdW50ICggJycsIDEgLi4gMTAgKSB7CiAgICAgICAgbXkgJEdlbmVyaWNNb2R1bGUgPSAkQ29uZmlnT2JqZWN0LT5HZXQoIkN1c3RvbWVyOjpBdXRoTW9kdWxlJENvdW50Iik7CiAgICAgICAgbmV4dCBTT1VSQ0UgaWYgISRHZW5lcmljTW9kdWxlOwoKICAgICAgICBpZiAoICEkTWFpbk9iamVjdC0+UmVxdWlyZSgkR2VuZXJpY01vZHVsZSkgKSB7CiAgICAgICAgICAgICRNYWluT2JqZWN0LT5EaWUoIkNhbid0IGxvYWQgYmFja2VuZCBtb2R1bGUgJEdlbmVyaWNNb2R1bGUhICRAIik7CiAgICAgICAgfQogICAgICAgICRTZWxmLT57IkJhY2tlbmQkQ291bnQifSA9ICRHZW5lcmljTW9kdWxlLT5uZXcoICV7JFNlbGZ9LCBDb3VudCA9PiAkQ291bnQgKTsKICAgIH0KCiAgICAjIGxvYWQgMmZhY3RvciBhdXRoIG1vZHVsZXMKICAgIFNPVVJDRToKICAgIGZvciBteSAkQ291bnQgKCAnJywgMSAuLiAxMCApIHsKICAgICAgICBteSAkR2VuZXJpY01vZHVsZSA9ICRDb25maWdPYmplY3QtPkdldCgiQ3VzdG9tZXI6OkF1dGhUd29GYWN0b3JNb2R1bGUkQ291bnQiKTsKICAgICAgICBuZXh0IFNPVVJDRSBpZiAhJEdlbmVyaWNNb2R1bGU7CgogICAgICAgIGlmICggISRNYWluT2JqZWN0LT5SZXF1aXJlKCRHZW5lcmljTW9kdWxlKSApIHsKICAgICAgICAgICAgJE1haW5PYmplY3QtPkRpZSgiQ2FuJ3QgbG9hZCBiYWNrZW5kIG1vZHVsZSAkR2VuZXJpY01vZHVsZSEgJEAiKTsKICAgICAgICB9CiAgICAgICAgJFNlbGYtPnsiQXV0aFR3b0ZhY3RvckJhY2tlbmQkQ291bnQifSA9ICRHZW5lcmljTW9kdWxlLT5uZXcoICV7JFNlbGZ9LCBDb3VudCA9PiAkQ291bnQgKTsKICAgIH0KCiAgICAjIEluaXRpYWxpemUgbGFzdCBlcnJvciBtZXNzYWdlCiAgICAkU2VsZi0+e0xhc3RFcnJvck1lc3NhZ2V9ID0gJyc7CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aGVhZDIgR2V0T3B0aW9uKCkKCkdldCBtb2R1bGUgb3B0aW9ucy4gQ3VycmVudGx5IHRoZXJlIGlzIGp1c3Qgb25lIG9wdGlvbiwgIlByZUF1dGgiLgoKICAgIGlmICgkQXV0aE9iamVjdC0+R2V0T3B0aW9uKFdoYXQgPT4gJ1ByZUF1dGgnKSkgewogICAgICAgIHByaW50ICJObyBsb2dpbiBzY3JlZW4gaXMgbmVlZGVkLiBBdXRoZW50aWNhdGlvbiBpcyBiYXNlZCBvbiBvdGhlciBvcHRpb25zLiBFLiBnLiAkRU5We1JFTU9URV9VU0VSfVxuIjsKICAgIH0KCj1jdXQKCnN1YiBHZXRPcHRpb24gewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICByZXR1cm4gJFNlbGYtPntCYWNrZW5kfS0+R2V0T3B0aW9uKCVQYXJhbSk7Cn0KCiMgUm90aGVyIE9TUyAvIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKPWhlYWQyIEV4dGVuZGVkUGFyYW1OYW1lcygpCgpHZXQgbmFtZXMgb2YgZXh0ZW5kZWQgcGFyYW1zIHdoaWNoIHByb3ZpZGUgYXV0aGVudGlmaWNhdGlvbiBpbmZvcm1hdGlvbgoKICAgIG15IEBQYXJhbU5hbWVzID0gJEF1dGhPYmplY3QtPkV4dGVuZGVkUGFyYW1OYW1lcygpOwoKPWN1dAoKc3ViIEV4dGVuZGVkUGFyYW1OYW1lcyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICVOYW1lczsKICAgIENPVU5UOgogICAgZm9yICggJycsIDEgLi4gMTAgKSB7CiAgICAgICAgbmV4dCBDT1VOVCBpZiAhJFNlbGYtPnsiQmFja2VuZCRfIn07CiAgICAgICAgbmV4dCBDT1VOVCBpZiAhJFNlbGYtPnsiQmFja2VuZCRfIn0tPmNhbignRXh0ZW5kZWRQYXJhbU5hbWVzJyk7CgogICAgICAgIGZvciBteSAkRXh0TmFtZSAoICRTZWxmLT57IkJhY2tlbmQkXyJ9LT5FeHRlbmRlZFBhcmFtTmFtZXMoKSApIHsKICAgICAgICAgICAgJE5hbWVzeyRFeHROYW1lfSA9IDE7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAoIGtleXMgJU5hbWVzICk7Cn0KIyBFTyBPbmVUaW1lQXV0aGVudGljYXRpb25MaW5rCgo9aGVhZDIgQXV0aCgpCgpUaGUgYXV0aGVudGljYXRpb24gZnVuY3Rpb24uCgogICAgaWYgKCRBdXRoT2JqZWN0LT5BdXRoKFVzZXIgPT4gJFVzZXIsIFB3ID0+ICRQdykpIHsKICAgICAgICBwcmludCAiQXV0aCBvayFcbiI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBwcmludCAiQXV0aCBpbnZhbGlkIVxuIjsKICAgIH0KCj1jdXQKCnN1YiBBdXRoIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBnZXQgY3VzdG9tZXIgdXNlciBvYmplY3QKICAgIG15ICRDb25maWdPYmplY3QgICAgICAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwogICAgbXkgJEN1c3RvbWVyVXNlck9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXInKTsKCiAgICAjIHVzZSBhbGwgMTEgYmFja2VuZHMgYW5kIHJldHVybiBvbiBmaXJzdCBhdXRoCiAgICBteSAkVXNlcjsKICAgIENPVU5UOgogICAgZm9yICggJycsIDEgLi4gMTAgKSB7CgogICAgICAgICMgbmV4dCBvbiBubyBjb25maWcgc2V0dGluZwogICAgICAgIG5leHQgQ09VTlQgaWYgISRTZWxmLT57IkJhY2tlbmQkXyJ9OwoKICAgICAgICAjIGNoZWNrIGF1dGggYmFja2VuZAogICAgICAgICRVc2VyID0gJFNlbGYtPnsiQmFja2VuZCRfIn0tPkF1dGgoJVBhcmFtKTsKCiMgUm90aGVyIE9TUyAvIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKICAgICAgICBpZiAoIHJlZiAkVXNlciAmJiByZWYgJFVzZXIgZXEgJ0hBU0gnICYmICRVc2VyLT57RXJyb3J9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xhc3RFcnJvck1lc3NhZ2V9ID0gJFVzZXItPntFcnJvcn07CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiMgRU8gT25lVGltZUF1dGhlbnRpY2F0aW9uTGluawoKICAgICAgICAjIG5leHQgb24gbm8gc3VjY2VzcwogICAgICAgIG5leHQgQ09VTlQgaWYgISRVc2VyOwoKICAgICAgICAjIGNoZWNrIDJmYWN0b3IgYXV0aCBiYWNrZW5kcwogICAgICAgIG15ICRUd29GYWN0b3JBdXRoOwogICAgICAgIFRXT0ZBQ1RPUlNPVVJDRToKICAgICAgICBmb3IgbXkgJENvdW50ICggJycsIDEgLi4gMTAgKSB7CgogICAgICAgICAgICAjIHJldHVybiBvbiBubyBjb25maWcgc2V0dGluZwogICAgICAgICAgICBuZXh0IFRXT0ZBQ1RPUlNPVVJDRSBpZiAhJFNlbGYtPnsiQXV0aFR3b0ZhY3RvckJhY2tlbmQkQ291bnQifTsKCiAgICAgICAgICAgICMgMmZhY3RvciBiYWNrZW5kCiAgICAgICAgICAgIG15ICRBdXRoT2sgPSAkU2VsZi0+eyJBdXRoVHdvRmFjdG9yQmFja2VuZCRDb3VudCJ9LT5BdXRoKAogICAgICAgICAgICAgICAgVHdvRmFjdG9yVG9rZW4gPT4gJFBhcmFte1R3b0ZhY3RvclRva2VufSwKICAgICAgICAgICAgICAgIFVzZXIgICAgICAgICAgID0+ICRVc2VyLAogICAgICAgICAgICApOwogICAgICAgICAgICAkVHdvRmFjdG9yQXV0aCA9ICRBdXRoT2sgPyAncGFzc2VkJyA6ICdmYWlsZWQnOwoKICAgICAgICAgICAgbGFzdCBUV09GQUNUT1JTT1VSQ0UgaWYgJEF1dGhPazsKICAgICAgICB9CgogICAgICAgICMgaWYgYXQgbGVhc3Qgb25lIDJmYWN0b3IgYXV0aCBiYWNrZW5kIHdhcyBjaGVja2VkIGJ1dCBub25lIHdhcyBzdWNjZXNzZnVsLAogICAgICAgICMgaXQgY291bnRzIGFzIGEgZmFpbGVkIGxvZ2luCiAgICAgICAgaWYgKCAkVHdvRmFjdG9yQXV0aCAmJiAkVHdvRmFjdG9yQXV0aCBuZSAncGFzc2VkJyApIHsKICAgICAgICAgICAgJFVzZXIgPSB1bmRlZjsKICAgICAgICAgICAgbGFzdCBDT1VOVDsKICAgICAgICB9CgogICAgICAgICMgcmVtZW1iZXIgYXV0aCBiYWNrZW5kCiAgICAgICAgaWYgKCRVc2VyKSB7CiAgICAgICAgICAgICRDdXN0b21lclVzZXJPYmplY3QtPlNldFByZWZlcmVuY2VzKAogICAgICAgICAgICAgICAgS2V5ICAgID0+ICdVc2VyQXV0aEJhY2tlbmQnLAogICAgICAgICAgICAgICAgVmFsdWUgID0+ICRfLAogICAgICAgICAgICAgICAgVXNlcklEID0+ICRVc2VyLAogICAgICAgICAgICApOwogICAgICAgICAgICBsYXN0IENPVU5UOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNoZWNrIGlmIHJlY29yZCBleGlzdHMKICAgIGlmICggISRVc2VyICkgewogICAgICAgIG15ICVDdXN0b21lckRhdGEgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRQYXJhbXtVc2VyfSApOwogICAgICAgIGlmICglQ3VzdG9tZXJEYXRhKSB7CiAgICAgICAgICAgIG15ICRDb3VudCA9ICRDdXN0b21lckRhdGF7VXNlckxvZ2luRmFpbGVkfSB8fCAwOwogICAgICAgICAgICAkQ291bnQrKzsKICAgICAgICAgICAgJEN1c3RvbWVyVXNlck9iamVjdC0+U2V0UHJlZmVyZW5jZXMoCiAgICAgICAgICAgICAgICBLZXkgICAgPT4gJ1VzZXJMb2dpbkZhaWxlZCcsCiAgICAgICAgICAgICAgICBWYWx1ZSAgPT4gJENvdW50LAogICAgICAgICAgICAgICAgVXNlcklEID0+ICRDdXN0b21lckRhdGF7VXNlckxvZ2lufSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY2hlY2sgaWYgdXNlciBpcyB2YWxpZAogICAgbXkgJUN1c3RvbWVyRGF0YSA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckRhdGFHZXQoIFVzZXIgPT4gJFVzZXIgKTsKICAgIGlmICggZGVmaW5lZCAkQ3VzdG9tZXJEYXRhe1ZhbGlkSUR9ICYmICRDdXN0b21lckRhdGF7VmFsaWRJRH0gbmUgMSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ25vdGljZScsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDdXN0b21lclVzZXI6ICckVXNlcicgaXMgc2V0IHRvIGludmFsaWQsIGNhbid0IGxvZ2luISIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuICRVc2VyIGlmICElQ3VzdG9tZXJEYXRhOwoKICAgICMgcmVzZXQgZmFpbGVkIGxvZ2lucwogICAgJEN1c3RvbWVyVXNlck9iamVjdC0+U2V0UHJlZmVyZW5jZXMoCiAgICAgICAgS2V5ICAgID0+ICdVc2VyTG9naW5GYWlsZWQnLAogICAgICAgIFZhbHVlICA9PiAwLAogICAgICAgIFVzZXJJRCA9PiAkQ3VzdG9tZXJEYXRhe1VzZXJMb2dpbn0sCiAgICApOwoKICAgICMgb24gc3lzdGVtIG1haW50ZW5hbmNlIGN1c3RvbWVycwogICAgIyBzaG91bGRuJ3QgYmUgYWxsb3dlZCBnZXQgaW50byB0aGUgc3lzdGVtCiAgICBteSAkQWN0aXZlTWFpbnRlbmFuY2UgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6U3lzdGVtTWFpbnRlbmFuY2UnKS0+U3lzdGVtTWFpbnRlbmFuY2VJc0FjdGl2ZSgpOwoKICAgICMgY2hlY2sgaWYgc3lzdGVtIG1haW50ZW5hbmNlIGlzIGFjdGl2ZQogICAgaWYgKCRBY3RpdmVNYWludGVuYW5jZSkgewoKICAgICAgICAkU2VsZi0+e0xhc3RFcnJvck1lc3NhZ2V9ID0KICAgICAgICAgICAgJENvbmZpZ09iamVjdC0+R2V0KCdTeXN0ZW1NYWludGVuYW5jZTo6SXNBY3RpdmVEZWZhdWx0TG9naW5FcnJvck1lc3NhZ2UnKQogICAgICAgICAgICB8fCBUcmFuc2xhdGFibGUoIkl0IGlzIGN1cnJlbnRseSBub3QgcG9zc2libGUgdG8gbG9naW4gZHVlIHRvIGEgc2NoZWR1bGVkIHN5c3RlbSBtYWludGVuYW5jZS4iKTsKCiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgbGFzdCBsb2dpbiBwcmVmZXJlbmNlcyB1cGRhdGUKICAgIG15ICREYXRlVGltZU9iamVjdCA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpOwoKICAgICRDdXN0b21lclVzZXJPYmplY3QtPlNldFByZWZlcmVuY2VzKAogICAgICAgIEtleSAgICA9PiAnVXNlckxhc3RMb2dpbicsCiAgICAgICAgVmFsdWUgID0+ICREYXRlVGltZU9iamVjdC0+VG9FcG9jaCgpLAogICAgICAgIFVzZXJJRCA9PiAkQ3VzdG9tZXJEYXRhe1VzZXJMb2dpbn0sCiAgICApOwoKICAgIHJldHVybiAkVXNlcjsKfQoKPWhlYWQyIEdldExhc3RFcnJvck1lc3NhZ2UoKQoKUmV0cmlldmUgJFNlbGYtPntMYXN0RXJyb3JNZXNzYWdlfSBjb250ZW50LgoKICAgIG15ICRBdXRoRXJyb3JNZXNzYWdlID0gJEF1dGhPYmplY3QtPkdldExhc3RFcnJvck1lc3NhZ2UoKTsKCiAgICBSZXN1bHQ6CgogICAgICAgICRBdXRoRXJyb3JNZXNzYWdlID0gIkFuIGVycm9yIHN0cmluZyBtZXNzYWdlLiI7Cgo9Y3V0CgpzdWIgR2V0TGFzdEVycm9yTWVzc2FnZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIHJldHVybiAkU2VsZi0+e0xhc3RFcnJvck1lc3NhZ2V9Owp9CgoxOwo=
IyAtLQojIE9UT0JPIGlzIGEgd2ViLWJhc2VkIHRpY2tldGluZyBzeXN0ZW0gZm9yIHNlcnZpY2Ugb3JnYW5pc2F0aW9ucy4KIyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIwIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDE5LTIwMjEgUm90aGVyIE9TUyBHbWJILCBodHRwczovL290b2JvLmRlLwojIC0tCiMgJG9yaWdpbjogb3RvYm8gLSBkMmQ2YmU5MmMxNjY1NDczMDkxMzAzZGJmMzAwZTBjODMwZDZkOWJlIC0gS2VybmVsL1N5c3RlbS9UZW1wbGF0ZUdlbmVyYXRvci5wbQojIC0tCiMgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIKIyB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQojIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiMgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKIyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiBJZiBub3QsIHNlZSA8aHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpUZW1wbGF0ZUdlbmVyYXRvcjsKIyMgbm9maWx0ZXIoVGlkeUFsbDo6UGx1Z2luOjpPVE9CTzo6UGVybDo6TGF5b3V0T2JqZWN0KQoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6TGFuZ3VhZ2U7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OlZhcmlhYmxlQ2hlY2sgcXcoOmFsbCk7CgpvdXIgQE9iamVjdERlcGVuZGVuY2llcyA9ICgKICAgICdLZXJuZWw6OkNvbmZpZycsCiAgICAnS2VybmVsOjpTeXN0ZW06OkF1dG9SZXNwb25zZScsCiAgICAnS2VybmVsOjpTeXN0ZW06OkNvbW11bmljYXRpb25DaGFubmVsJywKICAgICdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkOjpCYWNrZW5kJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RW5jb2RlJywKICAgICdLZXJuZWw6OlN5c3RlbTo6SFRNTFV0aWxzJywKICAgICdLZXJuZWw6OlN5c3RlbTo6TG9nJywKICAgICdLZXJuZWw6OlN5c3RlbTo6UXVldWUnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpTYWx1dGF0aW9uJywKICAgICdLZXJuZWw6OlN5c3RlbTo6U2lnbmF0dXJlJywKICAgICdLZXJuZWw6OlN5c3RlbTo6U3RhbmRhcmRUZW1wbGF0ZScsCiAgICAnS2VybmVsOjpTeXN0ZW06OlN5c3RlbUFkZHJlc3MnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpUaWNrZXQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkFydGljbGUnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpVc2VyJywKICAgICdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0JywKICAgICdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnLAopOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpUZW1wbGF0ZUdlbmVyYXRvciAtIHNpZ25hdHVyZSBsaWIKCj1oZWFkMSBERVNDUklQVElPTgoKQWxsIHNpZ25hdHVyZSBmdW5jdGlvbnMuCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPWhlYWQyIG5ldygpCgpEb24ndCB1c2UgdGhlIGNvbnN0cnVjdG9yIGRpcmVjdGx5LCB1c2UgdGhlIE9iamVjdE1hbmFnZXIgaW5zdGVhZDoKCiAgICBteSAkVGVtcGxhdGVHZW5lcmF0b3JPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VGVtcGxhdGVHZW5lcmF0b3InKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgJFNlbGYtPntSaWNoVGV4dH0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpLT5HZXQoJ0Zyb250ZW5kOjpSaWNoVGV4dCcpOwoKICAgIHJldHVybiAkU2VsZjsKfQoKPWhlYWQyIFNhbHV0YXRpb24oKQoKZ2VuZXJhdGUgc2FsdXRhdGlvbgoKICAgIG15ICRTYWx1dGF0aW9uID0gJFRlbXBsYXRlR2VuZXJhdG9yT2JqZWN0LT5TYWx1dGF0aW9uKAogICAgICAgIFRpY2tldElEID0+IDEyMywKICAgICAgICBVc2VySUQgICA9PiAxMjMsCiAgICAgICAgRGF0YSAgICAgPT4gJEFydGljbGVIYXNoUmVmLAogICAgKTsKCnJldHVybnMKICAgIFRleHQKICAgIENvbnRlbnRUeXBlCgo9Y3V0CgpzdWIgU2FsdXRhdGlvbiB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KFRpY2tldElEIERhdGEgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRfISIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIEdldCB0aWNrZXQuCiAgICBteSAlVGlja2V0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlRpY2tldCcpLT5UaWNrZXRHZXQoCiAgICAgICAgVGlja2V0SUQgICAgICA9PiAkUGFyYW17VGlja2V0SUR9LAogICAgICAgIER5bmFtaWNGaWVsZHMgPT4gMSwKICAgICk7CgogICAgIyBHZXQgcXVldWUuCiAgICBteSAlUXVldWUgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6UXVldWUnKS0+UXVldWVHZXQoCiAgICAgICAgSUQgPT4gJFRpY2tldHtRdWV1ZUlEfSwKICAgICk7CgogICAgIyBHZXQgc2FsdXRhdGlvbi4KICAgIG15ICVTYWx1dGF0aW9uID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlNhbHV0YXRpb24nKS0+U2FsdXRhdGlvbkdldCgKICAgICAgICBJRCA9PiAkUXVldWV7U2FsdXRhdGlvbklEfSwKICAgICk7CgogICAgIyBkbyB0ZXh0L3BsYWluIHRvIHRleHQvaHRtbCBjb252ZXJ0CiAgICBpZiAoICRTZWxmLT57UmljaFRleHR9ICYmICRTYWx1dGF0aW9ue0NvbnRlbnRUeXBlfSA9fiAvdGV4dFwvcGxhaW4vaSApIHsKICAgICAgICAkU2FsdXRhdGlvbntDb250ZW50VHlwZX0gPSAndGV4dC9odG1sJzsKICAgICAgICAkU2FsdXRhdGlvbntUZXh0fSAgICAgICAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6SFRNTFV0aWxzJyktPlRvSFRNTCgKICAgICAgICAgICAgU3RyaW5nID0+ICRTYWx1dGF0aW9ue1RleHR9LAogICAgICAgICk7CiAgICB9CgogICAgIyBkbyB0ZXh0L2h0bWwgdG8gdGV4dC9wbGFpbiBjb252ZXJ0CiAgICBpZiAoICEkU2VsZi0+e1JpY2hUZXh0fSAmJiAkU2FsdXRhdGlvbntDb250ZW50VHlwZX0gPX4gL3RleHRcL2h0bWwvaSApIHsKICAgICAgICAkU2FsdXRhdGlvbntDb250ZW50VHlwZX0gPSAndGV4dC9wbGFpbic7CiAgICAgICAgJFNhbHV0YXRpb257VGV4dH0gICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0FzY2lpKAogICAgICAgICAgICBTdHJpbmcgPT4gJFNhbHV0YXRpb257VGV4dH0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjIGdldCBsaXN0IHVuc3VwcG9ydGVkIHRhZ3MgZm9yIHN0YW5kYXJkIHRlbXBsYXRlCiAgICBteSBATGlzdE9mVW5TdXBwb3J0ZWRUYWcgPSBxdyhPVE9CT19BR0VOVF9TVUJKRUNUIE9UT0JPX0FHRU5UX0JPRFkgT1RPQk9fQ1VTVE9NRVJfQk9EWSBPVE9CT19DVVNUT01FUl9TVUJKRUNUKTsKCiAgICBteSAkU2FsdXRhdGlvblRleHQgPSAkU2VsZi0+X1JlbW92ZVVuU3VwcG9ydGVkVGFnKAogICAgICAgIFRleHQgICAgICAgICAgICAgICAgID0+ICRTYWx1dGF0aW9ue1RleHR9IHx8ICcnLAogICAgICAgIExpc3RPZlVuU3VwcG9ydGVkVGFnID0+IFxATGlzdE9mVW5TdXBwb3J0ZWRUYWcsCiAgICApOwoKICAgICMgcmVwbGFjZSBwbGFjZSBob2xkZXIgc3R1ZmYKICAgICRTYWx1dGF0aW9uVGV4dCA9ICRTZWxmLT5fUmVwbGFjZSgKICAgICAgICBSaWNoVGV4dCAgID0+ICRTZWxmLT57UmljaFRleHR9LAogICAgICAgIFRleHQgICAgICAgPT4gJFNhbHV0YXRpb25UZXh0LAogICAgICAgIFRpY2tldERhdGEgPT4gXCVUaWNrZXQsCiAgICAgICAgRGF0YSAgICAgICA9PiAkUGFyYW17RGF0YX0sCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgIyBhZGQgdXJscwogICAgaWYgKCAkU2VsZi0+e1JpY2hUZXh0fSApIHsKICAgICAgICAkU2FsdXRhdGlvblRleHQgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6SFRNTFV0aWxzJyktPkxpbmtRdW90ZSgKICAgICAgICAgICAgU3RyaW5nID0+ICRTYWx1dGF0aW9uVGV4dCwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAkU2FsdXRhdGlvblRleHQ7Cn0KCj1oZWFkMiBTaWduYXR1cmUoKQoKZ2VuZXJhdGUgc2FsdXRhdGlvbgoKICAgIG15ICRTaWduYXR1cmUgPSAkVGVtcGxhdGVHZW5lcmF0b3JPYmplY3QtPlNpZ25hdHVyZSgKICAgICAgICBUaWNrZXRJRCA9PiAxMjMsCiAgICAgICAgVXNlcklEICAgPT4gMTIzLAogICAgICAgIERhdGEgICAgID0+ICRBcnRpY2xlSGFzaFJlZiwKICAgICk7CgpvcgoKICAgIG15ICRTaWduYXR1cmUgPSAkVGVtcGxhdGVHZW5lcmF0b3JPYmplY3QtPlNpZ25hdHVyZSgKICAgICAgICBRdWV1ZUlEID0+IDEyMywKICAgICAgICBVc2VySUQgID0+IDEyMywKICAgICAgICBEYXRhICAgID0+ICRBcnRpY2xlSGFzaFJlZiwKICAgICk7CgpyZXR1cm5zCiAgICBUZXh0CiAgICBDb250ZW50VHlwZQoKPWN1dAoKc3ViIFNpZ25hdHVyZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KERhdGEgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRfISIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIG5lZWQgdGlja2V0IGlkIG9yIHF1ZXVlIGlkCiAgICBpZiAoICEkUGFyYW17VGlja2V0SUR9ICYmICEkUGFyYW17UXVldWVJRH0gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFRpY2tldElEIG9yIFF1ZXVlSUQhJwogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgR2V0IHRpY2tldCBkYXRhLgogICAgbXkgJVRpY2tldDsKICAgIGlmICggJFBhcmFte1RpY2tldElEfSApIHsKICAgICAgICAlVGlja2V0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlRpY2tldCcpLT5UaWNrZXRHZXQoCiAgICAgICAgICAgIFRpY2tldElEICAgICAgPT4gJFBhcmFte1RpY2tldElEfSwKICAgICAgICAgICAgRHluYW1pY0ZpZWxkcyA9PiAxLAogICAgICAgICk7CiAgICB9CgogICAgIyBHZXQgcXVldWUuCiAgICBteSAlUXVldWUgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6UXVldWUnKS0+UXVldWVHZXQoCiAgICAgICAgSUQgPT4gJFRpY2tldHtRdWV1ZUlEfSB8fCAkUGFyYW17UXVldWVJRH0sCiAgICApOwoKICAgICMgR2V0IHNpZ25hdHVyZS4KICAgIG15ICVTaWduYXR1cmUgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6U2lnbmF0dXJlJyktPlNpZ25hdHVyZUdldCgKICAgICAgICBJRCA9PiAkUXVldWV7U2lnbmF0dXJlSUR9LAogICAgKTsKCiAgICAjIGRvIHRleHQvcGxhaW4gdG8gdGV4dC9odG1sIGNvbnZlcnQKICAgIGlmICggJFNlbGYtPntSaWNoVGV4dH0gJiYgJFNpZ25hdHVyZXtDb250ZW50VHlwZX0gPX4gL3RleHRcL3BsYWluL2kgKSB7CiAgICAgICAgJFNpZ25hdHVyZXtDb250ZW50VHlwZX0gPSAndGV4dC9odG1sJzsKICAgICAgICAkU2lnbmF0dXJle1RleHR9ICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+VG9IVE1MKAogICAgICAgICAgICBTdHJpbmcgPT4gJFNpZ25hdHVyZXtUZXh0fSwKICAgICAgICApOwogICAgfQoKICAgICMgZG8gdGV4dC9odG1sIHRvIHRleHQvcGxhaW4gY29udmVydAogICAgaWYgKCAhJFNlbGYtPntSaWNoVGV4dH0gJiYgJFNpZ25hdHVyZXtDb250ZW50VHlwZX0gPX4gL3RleHRcL2h0bWwvaSApIHsKICAgICAgICAkU2lnbmF0dXJle0NvbnRlbnRUeXBlfSA9ICd0ZXh0L3BsYWluJzsKICAgICAgICAkU2lnbmF0dXJle1RleHR9ICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+VG9Bc2NpaSgKICAgICAgICAgICAgU3RyaW5nID0+ICRTaWduYXR1cmV7VGV4dH0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjIGdldCBsaXN0IHVuc3VwcG9ydGVkIHRhZ3MgZm9yIHN0YW5kYXJkIHRlbXBsYXRlCiAgICBteSBATGlzdE9mVW5TdXBwb3J0ZWRUYWcgPSBxdyhPVE9CT19BR0VOVF9TVUJKRUNUIE9UT0JPX0FHRU5UX0JPRFkgT1RPQk9fQ1VTVE9NRVJfQk9EWSBPVE9CT19DVVNUT01FUl9TVUJKRUNUKTsKCiAgICBteSAkU2lnbmF0dXJlVGV4dCA9ICRTZWxmLT5fUmVtb3ZlVW5TdXBwb3J0ZWRUYWcoCiAgICAgICAgVGV4dCAgICAgICAgICAgICAgICAgPT4gJFNpZ25hdHVyZXtUZXh0fSB8fCAnJywKICAgICAgICBMaXN0T2ZVblN1cHBvcnRlZFRhZyA9PiBcQExpc3RPZlVuU3VwcG9ydGVkVGFnLAogICAgKTsKCiAgICAjIHJlcGxhY2UgcGxhY2UgaG9sZGVyIHN0dWZmCiAgICAkU2lnbmF0dXJlVGV4dCA9ICRTZWxmLT5fUmVwbGFjZSgKICAgICAgICBSaWNoVGV4dCAgID0+ICRTZWxmLT57UmljaFRleHR9LAogICAgICAgIFRleHQgICAgICAgPT4gJFNpZ25hdHVyZVRleHQsCiAgICAgICAgVGlja2V0RGF0YSA9PiBcJVRpY2tldCwKICAgICAgICBEYXRhICAgICAgID0+ICRQYXJhbXtEYXRhfSwKICAgICAgICBRdWV1ZUlEICAgID0+ICRQYXJhbXtRdWV1ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICAjIGFkZCB1cmxzCiAgICBpZiAoICRTZWxmLT57UmljaFRleHR9ICkgewogICAgICAgICRTaWduYXR1cmVUZXh0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5MaW5rUXVvdGUoCiAgICAgICAgICAgIFN0cmluZyA9PiAkU2lnbmF0dXJlVGV4dCwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAkU2lnbmF0dXJlVGV4dDsKfQoKPWhlYWQyIFNlbmRlcigpCgpnZW5lcmF0ZSBzZW5kZXIgYWRkcmVzcyAoRlJPTSBzdHJpbmcpIGZvciBlbWFpbHMKCiAgICBteSAkU2VuZGVyID0gJFRlbXBsYXRlR2VuZXJhdG9yT2JqZWN0LT5TZW5kZXIoCiAgICAgICAgUXVldWVJRCAgICA9PiAxMjMsCiAgICAgICAgVXNlcklEICAgICA9PiAxMjMsCiAgICApOwoKcmV0dXJuczoKCiAgICBKb2huIERvZSBhdCBTdXBlciBTdXBwb3J0IDxzZXJ2aWNlQGV4YW1wbGUuY29tPgoKYW5kIGl0IHJldHVybnMgdGhlIHF1b3RlZCByZWFsIG5hbWUgaWYgbmVjZXNzYXJ5CgogICAgIkpvaG4gRG9lLCBTdXBwb3J0IiA8c2VydmljZUBleGFtcGxlLnRsZD4KCj1jdXQKCnN1YiBTZW5kZXIgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyggVXNlcklEIFF1ZXVlSUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJF8hIgogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZ2V0IHNlbmRlciBhdHRyaWJ1dGVzCiAgICBteSAlQWRkcmVzcyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpRdWV1ZScpLT5HZXRTeXN0ZW1BZGRyZXNzKAogICAgICAgIFF1ZXVlSUQgPT4gJFBhcmFte1F1ZXVlSUR9LAogICAgKTsKCiAgICAjIGdldCBjb25maWcgb2JqZWN0CiAgICBteSAkQ29uZmlnT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKCiAgICAjIGNoZWNrIGNvbmZpZyBmb3IgYWdlbnQgcmVhbCBuYW1lCiAgICBteSAkVXNlQWdlbnRSZWFsTmFtZSA9ICRDb25maWdPYmplY3QtPkdldCgnVGlja2V0OjpEZWZpbmVFbWFpbEZyb20nKTsKICAgIGlmICggJFVzZUFnZW50UmVhbE5hbWUgJiYgJFVzZUFnZW50UmVhbE5hbWUgPX4gL14oQWdlbnROYW1lfEFnZW50TmFtZVN5c3RlbUFkZHJlc3NOYW1lKSQvICkgewoKICAgICAgICAjIGdldCBkYXRhIGZyb20gY3VycmVudCBhZ2VudAogICAgICAgIG15ICVVc2VyRGF0YSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpVc2VyJyktPkdldFVzZXJEYXRhKAogICAgICAgICAgICBVc2VySUQgICAgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICAgICBOb091dE9mT2ZmaWNlID0+IDEsCiAgICAgICAgKTsKCiAgICAgICAgIyBzZXQgcmVhbCBuYW1lIHdpdGggdXNlciBuYW1lCiAgICAgICAgaWYgKCAkVXNlQWdlbnRSZWFsTmFtZSBlcSAnQWdlbnROYW1lJyApIHsKCiAgICAgICAgICAgICMgY2hlY2sgZm9yIHVzZXIgZGF0YQogICAgICAgICAgICBpZiAoICRVc2VyRGF0YXtVc2VyRnVsbG5hbWV9ICkgewoKICAgICAgICAgICAgICAgICMgcmV3cml0ZSBSZWFsTmFtZQogICAgICAgICAgICAgICAgJEFkZHJlc3N7UmVhbE5hbWV9ID0gIiRVc2VyRGF0YXtVc2VyRnVsbG5hbWV9IjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBzZXQgcmVhbCBuYW1lIHdpdGggdXNlciBuYW1lCiAgICAgICAgaWYgKCAkVXNlQWdlbnRSZWFsTmFtZSBlcSAnQWdlbnROYW1lU3lzdGVtQWRkcmVzc05hbWUnICkgewoKICAgICAgICAgICAgIyBjaGVjayBmb3IgdXNlciBkYXRhCiAgICAgICAgICAgIGlmICggJFVzZXJEYXRhe1VzZXJGdWxsbmFtZX0gKSB7CgogICAgICAgICAgICAgICAgIyByZXdyaXRlIFJlYWxOYW1lCiAgICAgICAgICAgICAgICBteSAkU2VwYXJhdG9yID0gJyAnIC4gJENvbmZpZ09iamVjdC0+R2V0KCdUaWNrZXQ6OkRlZmluZUVtYWlsRnJvbVNlcGFyYXRvcicpCiAgICAgICAgICAgICAgICAgICAgfHwgJyc7CiAgICAgICAgICAgICAgICAkQWRkcmVzc3tSZWFsTmFtZX0gPSAkVXNlckRhdGF7VXNlckZ1bGxuYW1lfSAuICRTZXBhcmF0b3IgLiAnICcgLiAkQWRkcmVzc3tSZWFsTmFtZX07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgIyBwcmVwYXJlIHJlYWxuYW1lIHF1b3RlCiAgICBpZiAoICRBZGRyZXNze1JlYWxOYW1lfSA9fiAvKFsuXXwsfEB8XCh8XCl8OikvICYmICRBZGRyZXNze1JlYWxOYW1lfSAhfiAvXigifCcpLyApIHsKICAgICAgICAkQWRkcmVzc3tSZWFsTmFtZX0gPX4gcy8iLy9nOyAgICAjIHJlbW92ZSBhbnkgcXVvdGVzIHRoYXQgYXJlIGFscmVhZHkgcHJlc2VudAogICAgICAgICRBZGRyZXNze1JlYWxOYW1lfSA9ICciJyAuICRBZGRyZXNze1JlYWxOYW1lfSAuICciJzsKICAgIH0KICAgIG15ICRTZW5kZXIgPSAiJEFkZHJlc3N7UmVhbE5hbWV9IDwkQWRkcmVzc3tFbWFpbH0+IjsKCiAgICByZXR1cm4gJFNlbmRlcjsKfQoKPWhlYWQyIFRlbXBsYXRlKCkKCmdlbmVyYXRlIHRlbXBsYXRlCgogICAgbXkgJFRlbXBsYXRlID0gJFRlbXBsYXRlR2VuZXJhdG9yT2JqZWN0LT5UZW1wbGF0ZSgKICAgICAgICBUZW1wbGF0ZUlEID0+IDEyMwogICAgICAgIFRpY2tldElEICAgPT4gMTIzLCAgICAgICAgICAgICAgICAgICMgT3B0aW9uYWwKICAgICAgICBEYXRhICAgICAgID0+ICRBcnRpY2xlSGFzaFJlZiwgICAgICAjIE9wdGlvbmFsCiAgICAgICAgVXNlcklEICAgICA9PiAxMjMsCiAgICApOwoKUmV0dXJuczoKCiAgICAkVGVtcGxhdGUgPT4gICdTb21lIHRleHQnOwoKPWN1dAoKc3ViIFRlbXBsYXRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoVGVtcGxhdGVJRCBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJF8hIgogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIG15ICVUZW1wbGF0ZSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpTdGFuZGFyZFRlbXBsYXRlJyktPlN0YW5kYXJkVGVtcGxhdGVHZXQoCiAgICAgICAgSUQgPT4gJFBhcmFte1RlbXBsYXRlSUR9LAogICAgKTsKCiAgICAjIGRvIHRleHQvcGxhaW4gdG8gdGV4dC9odG1sIGNvbnZlcnQKICAgIGlmICgKICAgICAgICAkU2VsZi0+e1JpY2hUZXh0fQogICAgICAgICYmICRUZW1wbGF0ZXtDb250ZW50VHlwZX0gPX4gL3RleHRcL3BsYWluL2kKICAgICAgICAmJiAkVGVtcGxhdGV7VGVtcGxhdGV9CiAgICAgICAgKQogICAgewogICAgICAgICRUZW1wbGF0ZXtDb250ZW50VHlwZX0gPSAndGV4dC9odG1sJzsKICAgICAgICAkVGVtcGxhdGV7VGVtcGxhdGV9ICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0hUTUwoCiAgICAgICAgICAgIFN0cmluZyA9PiAkVGVtcGxhdGV7VGVtcGxhdGV9LAogICAgICAgICk7CiAgICB9CgogICAgIyBkbyB0ZXh0L2h0bWwgdG8gdGV4dC9wbGFpbiBjb252ZXJ0CiAgICBpZiAoCiAgICAgICAgISRTZWxmLT57UmljaFRleHR9CiAgICAgICAgJiYgJFRlbXBsYXRle0NvbnRlbnRUeXBlfSA9fiAvdGV4dFwvaHRtbC9pCiAgICAgICAgJiYgJFRlbXBsYXRle1RlbXBsYXRlfQogICAgICAgICkKICAgIHsKICAgICAgICAkVGVtcGxhdGV7Q29udGVudFR5cGV9ID0gJ3RleHQvcGxhaW4nOwogICAgICAgICRUZW1wbGF0ZXtUZW1wbGF0ZX0gICAgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6SFRNTFV0aWxzJyktPlRvQXNjaWkoCiAgICAgICAgICAgIFN0cmluZyA9PiAkVGVtcGxhdGV7VGVtcGxhdGV9LAogICAgICAgICk7CiAgICB9CgogICAgIyBHZXQgdXNlciBsYW5ndWFnZS4KICAgIG15ICRMYW5ndWFnZTsKICAgIG15ICVUaWNrZXQ7CiAgICBpZiAoIGRlZmluZWQgJFBhcmFte1RpY2tldElEfSApIHsKCiAgICAgICAgIyBHZXQgdGlja2V0IGRhdGEuCiAgICAgICAgJVRpY2tldCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpUaWNrZXQnKS0+VGlja2V0R2V0KAogICAgICAgICAgICBUaWNrZXRJRCAgICAgID0+ICRQYXJhbXtUaWNrZXRJRH0sCiAgICAgICAgICAgIER5bmFtaWNGaWVsZHMgPT4gMSwKICAgICAgICApOwoKICAgICAgICAjIEdldCByZWNpcGllbnQuCiAgICAgICAgbXkgJVVzZXIgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyJyktPkN1c3RvbWVyVXNlckRhdGFHZXQoCiAgICAgICAgICAgIFVzZXIgPT4gJFRpY2tldHtDdXN0b21lclVzZXJJRH0sCiAgICAgICAgKTsKICAgICAgICAkTGFuZ3VhZ2UgPSAkVXNlcntVc2VyTGFuZ3VhZ2V9OwogICAgfQoKICAgICMgSWYgdGVtcGxhdGUgdHlwZSBpcyAnQ3JlYXRlJyBhbmQgdGhlcmUgaXMgY3VzdG9tZXIgdXNlciBpbmZvcm1hdGlvbiwgdHJlYXQgaXQgYXMgYSB0aWNrZXQgcGFyYW0gaW4gb3JkZXIgdG8KICAgICMgY29ycmVjdGx5IHJlcGxhY2UgY3VzdG9tZXIgdXNlciB0YWdzLiBTZWUgYnVnIzE0NDU1LgogICAgaWYgKCAkVGVtcGxhdGV7VGVtcGxhdGVUeXBlfSBlcSAnQ3JlYXRlJyAmJiAkUGFyYW17Q3VzdG9tZXJVc2VySUR9ICkgewogICAgICAgICRUaWNrZXR7Q3VzdG9tZXJVc2VySUR9ID0gJFBhcmFte0N1c3RvbWVyVXNlcklEfTsKICAgIH0KCiAgICAjIGlmIGN1c3RvbWVyIGxhbmd1YWdlIGlzIG5vdCBkZWZpbmVkLCBzZXQgZGVmYXVsdCBsYW5ndWFnZQogICAgJExhbmd1YWdlIC8vPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpLT5HZXQoJ0RlZmF1bHRMYW5ndWFnZScpIHx8ICdlbic7CgogICAgIyBnZXQgbGlzdCB1bnN1cHBvcnRlZCB0YWdzIGZvciBzdGFuZGFyZCB0ZW1wbGF0ZQogICAgbXkgQExpc3RPZlVuU3VwcG9ydGVkVGFnID0gcXcoT1RPQk9fQUdFTlRfU1VCSkVDVCBPVE9CT19BR0VOVF9CT0RZIE9UT0JPX0NVU1RPTUVSX0JPRFkgT1RPQk9fQ1VTVE9NRVJfU1VCSkVDVCk7CgogICAgbXkgJVN1cHBvcnRlZFR5cGVzID0gKAogICAgICAgIEFuc3dlciAgPT4gMSwKICAgICAgICBGb3J3YXJkID0+IDEsCiAgICAgICAgTm90ZSAgICA9PiAxLAogICAgKTsKCiAgICBteSAkVGVtcGxhdGVUZXh0ID0gJFRlbXBsYXRle1RlbXBsYXRlfSB8fCAnJzsKICAgIG15ICRUZW1wbGF0ZVR5cGUgPSAkVGVtcGxhdGV7VGVtcGxhdGVUeXBlfTsKCiAgICAjIFJlbW92ZSB1bnN1cHBvcnRlZCB0YWdzIG9ubHkgZm9yIHNvbWUgdGVtcGxhdGUgdHlwZXMuCiAgICBpZiAoICEkU3VwcG9ydGVkVHlwZXN7ICRUZW1wbGF0ZXtUZW1wbGF0ZVR5cGV9IH0gKSB7CiAgICAgICAgJFRlbXBsYXRlVGV4dCA9ICRTZWxmLT5fUmVtb3ZlVW5TdXBwb3J0ZWRUYWcoCiAgICAgICAgICAgIFRleHQgICAgICAgICAgICAgICAgID0+ICRUZW1wbGF0ZXtUZW1wbGF0ZX0gfHwgJycsCiAgICAgICAgICAgIExpc3RPZlVuU3VwcG9ydGVkVGFnID0+IFxATGlzdE9mVW5TdXBwb3J0ZWRUYWcsCiAgICAgICAgKTsKCiAgICAgICAgIyBSZXNldCB0ZW1wbGF0ZSB0eXBlIGZvciB1bnN1cHBvcnRlZCB0YWcuCiAgICAgICAgJFRlbXBsYXRlVHlwZSA9ICcnOwogICAgfQoKICAgICMgcmVwbGFjZSBwbGFjZSBob2xkZXIgc3R1ZmYKICAgICRUZW1wbGF0ZVRleHQgPSAkU2VsZi0+X1JlcGxhY2UoCiAgICAgICAgUmljaFRleHQgICA9PiAkU2VsZi0+e1JpY2hUZXh0fSwKICAgICAgICBUZXh0ICAgICAgID0+ICRUZW1wbGF0ZVRleHQgfHwgJycsCiAgICAgICAgVGlja2V0RGF0YSA9PiBcJVRpY2tldCwKICAgICAgICBEYXRhICAgICAgID0+ICRQYXJhbXtEYXRhfSB8fCB7fSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgIExhbmd1YWdlICAgPT4gJExhbmd1YWdlLAogICAgICAgIFRlbXBsYXRlICAgPT4gJFRlbXBsYXRlVHlwZSwKICAgICk7CgogICAgaWYgKCAkU2VsZi0+e1JpY2hUZXh0fSApIHsKICAgICAgICAkVGVtcGxhdGVUZXh0ID1+IHMvJmx0Oy88L2c7CiAgICAgICAgJFRlbXBsYXRlVGV4dCA9fiBzLyZndDsvPi9nOwogICAgICAgICRUZW1wbGF0ZVRleHQgPX4gcy8mcXVvdDsvIi9nOwogICAgICAgICRUZW1wbGF0ZVRleHQgPX4gcy8mYXBvczsvJy9nOwogICAgICAgICRUZW1wbGF0ZVRleHQgPX4gcy8mbmJzcDsvIC9nOwogICAgfQoKICAgIHJldHVybiAkVGVtcGxhdGVUZXh0Owp9Cgo9aGVhZDIgR2VuZXJpY0FnZW50QXJ0aWNsZSgpCgpnZW5lcmF0ZSBpbnRlcm5hbCBvciBleHRlcm5hbCBub3RlcwoKICAgIG15ICRHZW5lcmljQWdlbnRBcnRpY2xlID0gJFRlbXBsYXRlR2VuZXJhdG9yT2JqZWN0LT5HZW5lcmljQWdlbnRBcnRpY2xlKAogICAgICAgIE5vdGlmaWNhdGlvbiAgICA9PiAkTm90aWZpY2F0aW9uRGF0YUhhc2hSZWYsCiAgICAgICAgVGlja2V0SUQgICAgICAgID0+IDEyMywKICAgICAgICBVc2VySUQgICAgICAgICAgPT4gMTIzLAogICAgICAgIERhdGEgICAgICAgICAgICA9PiAkQXJ0aWNsZUhhc2hSZWYsICAgICAgICAgICAgICMgT3B0aW9uYWwKICAgICk7Cgo9Y3V0CgpzdWIgR2VuZXJpY0FnZW50QXJ0aWNsZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KFRpY2tldElEIE5vdGlmaWNhdGlvbiBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJF8hIgogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIG15ICVUZW1wbGF0ZSA9ICV7ICRQYXJhbXtOb3RpZmljYXRpb259IH07CgogICAgIyBnZXQgdGlja2V0IG9iamVjdAogICAgbXkgJFRpY2tldE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpUaWNrZXQnKTsKCiAgICAjIEdldCB0aWNrZXQgZGF0YS4KICAgIG15ICVUaWNrZXQgPSAkVGlja2V0T2JqZWN0LT5UaWNrZXRHZXQoCiAgICAgICAgVGlja2V0SUQgICAgICA9PiAkUGFyYW17VGlja2V0SUR9LAogICAgICAgIER5bmFtaWNGaWVsZHMgPT4gMSwKICAgICk7CgogICAgIyBkbyB0ZXh0L3BsYWluIHRvIHRleHQvaHRtbCBjb252ZXJ0CiAgICBpZiAoCiAgICAgICAgJFNlbGYtPntSaWNoVGV4dH0KICAgICAgICAmJiAkVGVtcGxhdGV7Q29udGVudFR5cGV9ID1+IC90ZXh0XC9wbGFpbi9pCiAgICAgICAgJiYgJFRlbXBsYXRle0JvZHl9CiAgICAgICAgKQogICAgewogICAgICAgICRUZW1wbGF0ZXtDb250ZW50VHlwZX0gPSAndGV4dC9odG1sJzsKICAgICAgICAkVGVtcGxhdGV7Qm9keX0gICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0hUTUwoCiAgICAgICAgICAgIFN0cmluZyA9PiAkVGVtcGxhdGV7Qm9keX0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjIGRvIHRleHQvaHRtbCB0byB0ZXh0L3BsYWluIGNvbnZlcnQKICAgIGlmICgKICAgICAgICAhJFNlbGYtPntSaWNoVGV4dH0KICAgICAgICAmJiAkVGVtcGxhdGV7Q29udGVudFR5cGV9ID1+IC90ZXh0XC9odG1sL2kKICAgICAgICAmJiAkVGVtcGxhdGV7Qm9keX0KICAgICAgICApCiAgICB7CiAgICAgICAgJFRlbXBsYXRle0NvbnRlbnRUeXBlfSA9ICd0ZXh0L3BsYWluJzsKICAgICAgICAkVGVtcGxhdGV7Qm9keX0gICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0FzY2lpKAogICAgICAgICAgICBTdHJpbmcgPT4gJFRlbXBsYXRle0JvZHl9LAogICAgICAgICk7CiAgICB9CgogICAgIyByZXBsYWNlIHBsYWNlIGhvbGRlciBzdHVmZgogICAgJFRlbXBsYXRle0JvZHl9ID0gJFNlbGYtPl9SZXBsYWNlKAogICAgICAgIFJpY2hUZXh0ICAgPT4gJFNlbGYtPntSaWNoVGV4dH0sCiAgICAgICAgVGV4dCAgICAgICA9PiAkVGVtcGxhdGV7Qm9keX0sCiAgICAgICAgUmVjaXBpZW50ICA9PiAkUGFyYW17UmVjaXBpZW50fSwKICAgICAgICBEYXRhICAgICAgID0+ICRQYXJhbXtEYXRhfSB8fCB7fSwKICAgICAgICBUaWNrZXREYXRhID0+IFwlVGlja2V0LAogICAgICAgIFVzZXJJRCAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwogICAgJFRlbXBsYXRle1N1YmplY3R9ID0gJFNlbGYtPl9SZXBsYWNlKAogICAgICAgIFJpY2hUZXh0ICAgPT4gMCwKICAgICAgICBUZXh0ICAgICAgID0+ICRUZW1wbGF0ZXtTdWJqZWN0fSwKICAgICAgICBSZWNpcGllbnQgID0+ICRQYXJhbXtSZWNpcGllbnR9LAogICAgICAgIERhdGEgICAgICAgPT4gJFBhcmFte0RhdGF9IHx8IHt9LAogICAgICAgIFRpY2tldERhdGEgPT4gXCVUaWNrZXQsCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgJFRlbXBsYXRle1N1YmplY3R9ID0gJFRpY2tldE9iamVjdC0+VGlja2V0U3ViamVjdEJ1aWxkKAogICAgICAgIFRpY2tldE51bWJlciA9PiAkVGlja2V0e1RpY2tldE51bWJlcn0sCiAgICAgICAgU3ViamVjdCAgICAgID0+ICRUZW1wbGF0ZXtTdWJqZWN0fSB8fCAnJywKICAgICAgICBUeXBlICAgICAgICAgPT4gJ05ldycsCiAgICApOwoKICAgICMgYWRkIFVSTHMgYW5kIHZlcmlmeSB0byBiZSBmdWxsIEhUTUwgZG9jdW1lbnQKICAgIGlmICggJFNlbGYtPntSaWNoVGV4dH0gKSB7CgogICAgICAgICRUZW1wbGF0ZXtCb2R5fSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+TGlua1F1b3RlKAogICAgICAgICAgICBTdHJpbmcgPT4gJFRlbXBsYXRle0JvZHl9LAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuICVUZW1wbGF0ZTsKfQoKPWhlYWQyIEF0dHJpYnV0ZXMoKQoKZ2VuZXJhdGUgYXR0cmlidXRlcwoKICAgIG15ICVBdHRyaWJ1dGVzID0gJFRlbXBsYXRlR2VuZXJhdG9yT2JqZWN0LT5BdHRyaWJ1dGVzKAogICAgICAgIFRpY2tldElEICAgPT4gMTIzLAogICAgICAgIEFydGljbGVJRCAgPT4gMTIzLAogICAgICAgIFJlc3BvbnNlSUQgPT4gMTIzCiAgICAgICAgVXNlcklEICAgICA9PiAxMjMsCiAgICAgICAgQWN0aW9uICAgICA9PiAnRm9yd2FyZCcsICMgUG9zc2libGUgdmFsdWVzIGFyZSBSZXBseSBhbmQgRm9yd2FyZCwgUmVwbHkgaXMgZGVmYXVsdC4KICAgICk7CgpyZXR1cm5zCiAgICBTdGFuZGFyZFJlc3BvbnNlCiAgICBTYWx1dGF0aW9uCiAgICBTaWduYXR1cmUKCj1jdXQKCnN1YiBBdHRyaWJ1dGVzIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoVGlja2V0SUQgRGF0YSBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJF8hIgogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZ2V0IHRpY2tldCBvYmplY3QKICAgIG15ICRUaWNrZXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VGlja2V0Jyk7CgogICAgIyBnZXQgcXVldWUKICAgIG15ICVUaWNrZXQgPSAkVGlja2V0T2JqZWN0LT5UaWNrZXRHZXQoCiAgICAgICAgVGlja2V0SUQgICAgICA9PiAkUGFyYW17VGlja2V0SUR9LAogICAgICAgIER5bmFtaWNGaWVsZHMgPT4gMCwKICAgICk7CgogICAgIyBwcmVwYXJlIHN1YmplY3QgLi4uCiAgICAkUGFyYW17RGF0YX0tPntTdWJqZWN0fSA9ICRUaWNrZXRPYmplY3QtPlRpY2tldFN1YmplY3RCdWlsZCgKICAgICAgICBUaWNrZXROdW1iZXIgPT4gJFRpY2tldHtUaWNrZXROdW1iZXJ9LAogICAgICAgIFN1YmplY3QgICAgICA9PiAkUGFyYW17RGF0YX0tPntTdWJqZWN0fSB8fCAnJywKICAgICAgICBBY3Rpb24gICAgICAgPT4gJFBhcmFte0FjdGlvbn0gfHwgJycsCiAgICApOwoKICAgICMgZ2V0IHNlbmRlciBhZGRyZXNzCiAgICAkUGFyYW17RGF0YX0tPntGcm9tfSA9ICRTZWxmLT5TZW5kZXIoCiAgICAgICAgUXVldWVJRCA9PiAkVGlja2V0e1F1ZXVlSUR9LAogICAgICAgIFVzZXJJRCAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgIHJldHVybiAleyAkUGFyYW17RGF0YX0gfTsKfQoKPWhlYWQyIEF1dG9SZXNwb25zZSgpCgpnZW5lcmF0ZSByZXNwb25zZQoKQXV0b1Jlc3BvbnNlCiAgICBUaWNrZXRJRAogICAgICAgIE93bmVyCiAgICAgICAgUmVzcG9uc2libGUKICAgICAgICBDVVNUT01FUl9EQVRBCiAgICBBcnRpY2xlSUQKICAgICAgICBDVVNUT01FUl9TVUJKRUNUCiAgICAgICAgQ1VTVE9NRVJfRU1BSUwKICAgIFVzZXJJRAoKICAgIFRvCiAgICBDYwogICAgQmNjCiAgICBTdWJqZWN0CiAgICBCb2R5CiAgICBDb250ZW50VHlwZQoKICAgIG15ICVBdXRvUmVzcG9uc2UgPSAkVGVtcGxhdGVHZW5lcmF0b3JPYmplY3QtPkF1dG9SZXNwb25zZSgKICAgICAgICBUaWNrZXRJRCAgICAgICAgID0+IDEyMywKICAgICAgICBPcmlnSGVhZGVyICAgICAgID0+IHt9LAogICAgICAgIEF1dG9SZXNwb25zZVR5cGUgPT4gJ2F1dG8gcmVwbHknLAogICAgICAgIFVzZXJJRCAgICAgICAgICAgPT4gMTIzLAogICAgKTsKCj1jdXQKCnN1YiBBdXRvUmVzcG9uc2UgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyhUaWNrZXRJRCBBdXRvUmVzcG9uc2VUeXBlIE9yaWdIZWFkZXIgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRfISIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCB0aWNrZXQgb2JqZWN0CiAgICBteSAkVGlja2V0T2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlRpY2tldCcpOwoKICAgICMgR2V0IHRpY2tldCBkYXRhLgogICAgbXkgJVRpY2tldCA9ICRUaWNrZXRPYmplY3QtPlRpY2tldEdldCgKICAgICAgICBUaWNrZXRJRCAgICAgID0+ICRQYXJhbXtUaWNrZXRJRH0sCiAgICAgICAgRHluYW1pY0ZpZWxkcyA9PiAxLAogICAgKTsKCiAgICAjIGdldCBhdXRvIGRlZmF1bHQgcmVzcG9uc2VzCiAgICBteSAlQXV0b1Jlc3BvbnNlID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkF1dG9SZXNwb25zZScpLT5BdXRvUmVzcG9uc2VHZXRCeVR5cGVRdWV1ZUlEKAogICAgICAgIFF1ZXVlSUQgPT4gJFRpY2tldHtRdWV1ZUlEfSwKICAgICAgICBUeXBlICAgID0+ICRQYXJhbXtBdXRvUmVzcG9uc2VUeXBlfSwKICAgICk7CgogICAgcmV0dXJuIGlmICElQXV0b1Jlc3BvbnNlOwoKICAgICMgZ2V0IG9sZCBhcnRpY2xlIGZvciBxdW90aW5nCiAgICBteSAkQXJ0aWNsZU9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkFydGljbGUnKTsKICAgIG15IEBBcnRpY2xlTGlzdCAgID0gJEFydGljbGVPYmplY3QtPkFydGljbGVMaXN0KAogICAgICAgIFRpY2tldElEICAgPT4gJFBhcmFte1RpY2tldElEfSwKICAgICAgICBTZW5kZXJUeXBlID0+ICdjdXN0b21lcicsCiAgICAgICAgT25seUxhc3QgICA9PiAxLAogICAgKTsKCiAgICBpZiAoICFAQXJ0aWNsZUxpc3QgKSB7CiAgICAgICAgQEFydGljbGVMaXN0ID0gJEFydGljbGVPYmplY3QtPkFydGljbGVMaXN0KAogICAgICAgICAgICBUaWNrZXRJRCAgICAgICAgICAgICA9PiAkUGFyYW17VGlja2V0SUR9LAogICAgICAgICAgICBJc1Zpc2libGVGb3JDdXN0b21lciA9PiAxLAogICAgICAgICAgICBPbmx5TGFzdCAgICAgICAgICAgICA9PiAxLAogICAgICAgICk7CiAgICB9CgogICAgaWYgKEBBcnRpY2xlTGlzdCkgewogICAgICAgIG15ICVBcnRpY2xlID0gJEFydGljbGVPYmplY3QtPkJhY2tlbmRGb3JBcnRpY2xlKCAleyAkQXJ0aWNsZUxpc3RbMF0gfSApLT5BcnRpY2xlR2V0KCAleyAkQXJ0aWNsZUxpc3RbMF0gfSApOwoKICAgICAgICBmb3IgKHF3KEZyb20gVG8gQ2MgU3ViamVjdCBCb2R5KSkgewogICAgICAgICAgICBpZiAoICEkUGFyYW17T3JpZ0hlYWRlcn0tPnskX30gKSB7CiAgICAgICAgICAgICAgICAkUGFyYW17T3JpZ0hlYWRlcn0tPnskX30gPSAkQXJ0aWNsZXskX30gfHwgJyc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hvbXAgJFBhcmFte09yaWdIZWFkZXJ9LT57JF99OwogICAgICAgIH0KICAgIH0KCiAgICAjIGZvcm1hdCBib2R5IChvbmx5IGlmIGxvbmdlciB0aGFuIDg2IGNoYXJzKQogICAgaWYgKCAkUGFyYW17T3JpZ0hlYWRlcn0tPntCb2R5fSApIHsKICAgICAgICBpZiAoIGxlbmd0aCAkUGFyYW17T3JpZ0hlYWRlcn0tPntCb2R5fSA+IDg2ICkgewogICAgICAgICAgICBteSBATGluZXMgPSBzcGxpdCAvXG4vLCAkUGFyYW17T3JpZ0hlYWRlcn0tPntCb2R5fTsKICAgICAgICAgICAgTElORToKICAgICAgICAgICAgZm9yIG15ICRMaW5lIChATGluZXMpIHsKICAgICAgICAgICAgICAgIG15ICRMaW5lV3JhcHBlZCA9ICRMaW5lID1+IHMvKF4+Lit8Lns0LDg2fSkoPzpcc3xceikvJDFcbi9nbTsKCiAgICAgICAgICAgICAgICBuZXh0IExJTkUgaWYgJExpbmVXcmFwcGVkOwoKICAgICAgICAgICAgICAgICMgaWYgdGhlIHJlZ2V4IGRvZXMgbm90IG1hdGNoIHRoZW4gd2UgbmVlZAogICAgICAgICAgICAgICAgIyB0byBhZGQgdGhlIG1pc3NpbmcgbmV3IGxpbmUgb2YgdGhlIHNwbGl0CiAgICAgICAgICAgICAgICAjIGVsc2Ugd2Ugd2lsbCBsb3NlIGUuZy4gZW1wdHkgbGluZXMgb2YgdGhlIGJvZHkuCiAgICAgICAgICAgICAgICAjIChidWcjMTA2NzkpCiAgICAgICAgICAgICAgICAkTGluZSAuPSAiXG4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRQYXJhbXtPcmlnSGVhZGVyfS0+e0JvZHl9ID0gam9pbiAnJywgQExpbmVzOwogICAgICAgIH0KICAgIH0KCiAgICAjIGZpbGwgdXAgcmVxdWlyZWQgYXR0cmlidXRlcwogICAgZm9yIChxdyhTdWJqZWN0IEJvZHkpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFte09yaWdIZWFkZXJ9LT57JF99ICkgewogICAgICAgICAgICAkUGFyYW17T3JpZ0hlYWRlcn0tPnskX30gPSAiTm8gJF8iOwogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCByZWNpcGllbnQKICAgIG15ICVVc2VyID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicpLT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgIFVzZXIgPT4gJFRpY2tldHtDdXN0b21lclVzZXJJRH0sCiAgICApOwoKICAgICMgZ2V0IHVzZXIgbGFuZ3VhZ2UKICAgIG15ICRMYW5ndWFnZSA9ICRVc2Vye1VzZXJMYW5ndWFnZX0gfHwgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKS0+R2V0KCdEZWZhdWx0TGFuZ3VhZ2UnKSB8fCAnZW4nOwoKICAgICMgZG8gdGV4dC9wbGFpbiB0byB0ZXh0L2h0bWwgY29udmVydAogICAgaWYgKCAkU2VsZi0+e1JpY2hUZXh0fSAmJiAkQXV0b1Jlc3BvbnNle0NvbnRlbnRUeXBlfSA9fiAvdGV4dFwvcGxhaW4vaSApIHsKICAgICAgICAkQXV0b1Jlc3BvbnNle0NvbnRlbnRUeXBlfSA9ICd0ZXh0L2h0bWwnOwogICAgICAgICRBdXRvUmVzcG9uc2V7VGV4dH0gICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0hUTUwoCiAgICAgICAgICAgIFN0cmluZyA9PiAkQXV0b1Jlc3BvbnNle1RleHR9LAogICAgICAgICk7CiAgICB9CgogICAgIyBkbyB0ZXh0L2h0bWwgdG8gdGV4dC9wbGFpbiBjb252ZXJ0CiAgICBpZiAoICEkU2VsZi0+e1JpY2hUZXh0fSAmJiAkQXV0b1Jlc3BvbnNle0NvbnRlbnRUeXBlfSA9fiAvdGV4dFwvaHRtbC9pICkgewogICAgICAgICRBdXRvUmVzcG9uc2V7Q29udGVudFR5cGV9ID0gJ3RleHQvcGxhaW4nOwogICAgICAgICRBdXRvUmVzcG9uc2V7VGV4dH0gICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0FzY2lpKAogICAgICAgICAgICBTdHJpbmcgPT4gJEF1dG9SZXNwb25zZXtUZXh0fSwKICAgICAgICApOwogICAgfQoKICAgICMgcmVwbGFjZSBwbGFjZSBob2xkZXIgc3R1ZmYKICAgICRBdXRvUmVzcG9uc2V7VGV4dH0gPSAkU2VsZi0+X1JlcGxhY2UoCiAgICAgICAgUmljaFRleHQgPT4gJFNlbGYtPntSaWNoVGV4dH0sCiAgICAgICAgVGV4dCAgICAgPT4gJEF1dG9SZXNwb25zZXtUZXh0fSwKICAgICAgICBEYXRhICAgICA9PiB7CiAgICAgICAgICAgICV7ICRQYXJhbXtPcmlnSGVhZGVyfSB9LAogICAgICAgICAgICBGcm9tID0+ICRQYXJhbXtPcmlnSGVhZGVyfS0+e1RvfSwKICAgICAgICAgICAgVG8gICA9PiAkUGFyYW17T3JpZ0hlYWRlcn0tPntGcm9tfSwKICAgICAgICB9LAogICAgICAgIFRpY2tldERhdGEgICAgICA9PiBcJVRpY2tldCwKICAgICAgICBVc2VySUQgICAgICAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICAgICAgTGFuZ3VhZ2UgICAgICAgID0+ICRMYW5ndWFnZSwKICAgICAgICBBZGRUaW1lem9uZUluZm8gPT4gewogICAgICAgICAgICBBdXRvUmVzcG9uc2UgPT4gMSwKICAgICAgICB9LAogICAgKTsKICAgICRBdXRvUmVzcG9uc2V7U3ViamVjdH0gPSAkU2VsZi0+X1JlcGxhY2UoCiAgICAgICAgUmljaFRleHQgPT4gMCwKICAgICAgICBUZXh0ICAgICA9PiAkQXV0b1Jlc3BvbnNle1N1YmplY3R9LAogICAgICAgIERhdGEgICAgID0+IHsKICAgICAgICAgICAgJXsgJFBhcmFte09yaWdIZWFkZXJ9IH0sCiAgICAgICAgICAgIEZyb20gPT4gJFBhcmFte09yaWdIZWFkZXJ9LT57VG99LAogICAgICAgICAgICBUbyAgID0+ICRQYXJhbXtPcmlnSGVhZGVyfS0+e0Zyb219LAogICAgICAgIH0sCiAgICAgICAgVGlja2V0RGF0YSAgICAgID0+IFwlVGlja2V0LAogICAgICAgIFVzZXJJRCAgICAgICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICAgICBMYW5ndWFnZSAgICAgICAgPT4gJExhbmd1YWdlLAogICAgICAgIEFkZFRpbWV6b25lSW5mbyA9PiB7CiAgICAgICAgICAgIEF1dG9SZXNwb25zZSA9PiAxLAogICAgICAgIH0sCiAgICApOwoKICAgICRBdXRvUmVzcG9uc2V7U3ViamVjdH0gPSAkVGlja2V0T2JqZWN0LT5UaWNrZXRTdWJqZWN0QnVpbGQoCiAgICAgICAgVGlja2V0TnVtYmVyID0+ICRUaWNrZXR7VGlja2V0TnVtYmVyfSwKICAgICAgICBTdWJqZWN0ICAgICAgPT4gJEF1dG9SZXNwb25zZXtTdWJqZWN0fSwKICAgICAgICBUeXBlICAgICAgICAgPT4gJ05ldycsCiAgICAgICAgTm9DbGVhbnVwICAgID0+IDEsCiAgICApOwoKICAgICMgZ2V0IHNlbmRlciBhdHRyaWJ1dGVzIGJhc2VkIG9uIGF1dG8gcmVzcG9uc2UgdHlwZQogICAgaWYgKCAkQXV0b1Jlc3BvbnNle1N5c3RlbUFkZHJlc3NJRH0gKSB7CgogICAgICAgIG15ICVBZGRyZXNzID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlN5c3RlbUFkZHJlc3MnKS0+U3lzdGVtQWRkcmVzc0dldCgKICAgICAgICAgICAgSUQgPT4gJEF1dG9SZXNwb25zZXtTeXN0ZW1BZGRyZXNzSUR9LAogICAgICAgICk7CgogICAgICAgICRBdXRvUmVzcG9uc2V7U2VuZGVyQWRkcmVzc30gID0gJEFkZHJlc3N7TmFtZX07CiAgICAgICAgJEF1dG9SZXNwb25zZXtTZW5kZXJSZWFsbmFtZX0gPSAkQWRkcmVzc3tSZWFsbmFtZX07CiAgICB9CgogICAgIyBnZXQgc2VuZGVyIGF0dHJpYnV0ZXMgYmFzZWQgb24gcXVldWUKICAgIGVsc2UgewoKICAgICAgICBteSAlQWRkcmVzcyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpRdWV1ZScpLT5HZXRTeXN0ZW1BZGRyZXNzKAogICAgICAgICAgICBRdWV1ZUlEID0+ICRUaWNrZXR7UXVldWVJRH0sCiAgICAgICAgKTsKCiAgICAgICAgJEF1dG9SZXNwb25zZXtTZW5kZXJBZGRyZXNzfSAgPSAkQWRkcmVzc3tFbWFpbH07CiAgICAgICAgJEF1dG9SZXNwb25zZXtTZW5kZXJSZWFsbmFtZX0gPSAkQWRkcmVzc3tSZWFsTmFtZX07CiAgICB9CgogICAgIyBhZGQgdXJscyBhbmQgdmVyaWZ5IHRvIGJlIGZ1bGwgaHRtbCBkb2N1bWVudAogICAgaWYgKCAkU2VsZi0+e1JpY2hUZXh0fSApIHsKCiAgICAgICAgJEF1dG9SZXNwb25zZXtUZXh0fSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+TGlua1F1b3RlKAogICAgICAgICAgICBTdHJpbmcgPT4gJEF1dG9SZXNwb25zZXtUZXh0fSwKICAgICAgICApOwoKICAgICAgICAkQXV0b1Jlc3BvbnNle1RleHR9ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Eb2N1bWVudENvbXBsZXRlKAogICAgICAgICAgICBDaGFyc2V0ID0+ICd1dGYtOCcsCiAgICAgICAgICAgIFN0cmluZyAgPT4gJEF1dG9SZXNwb25zZXtUZXh0fSwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAlQXV0b1Jlc3BvbnNlOwp9Cgo9aGVhZDIgTm90aWZpY2F0aW9uRXZlbnQoKQoKcmVwbGFjZSBhbGwgT1RPQk8gc21hcnQgdGFncyBpbiB0aGUgbm90aWZpY2F0aW9uIGJvZHkgYW5kIHN1YmplY3QKCiAgICBteSAlTm90aWZpY2F0aW9uRXZlbnQgPSAkVGVtcGxhdGVHZW5lcmF0b3JPYmplY3QtPk5vdGlmaWNhdGlvbkV2ZW50KAogICAgICAgIFRpY2tldERhdGEgICAgICAgICAgICA9PiAkVGlja2V0RGF0YUhhc2hSZWYsCiAgICAgICAgUmVjaXBpZW50ICAgICAgICAgICAgID0+ICRVc2VyRGF0YUhhc2hSZWYsICAgICAgICAgICMgQWdlbnQgb3IgQ3VzdG9tZXIgZGF0YSBnZXQgcmVzdWx0CiAgICAgICAgTm90aWZpY2F0aW9uICAgICAgICAgID0+ICROb3RpZmljYXRpb25EYXRhSGFzaFJlZiwKICAgICAgICBDdXN0b21lck1lc3NhZ2VQYXJhbXMgPT4gJEFydGljbGVIYXNoUmVmLCAgICAgICAgICAgIyBvcHRpb25hbAogICAgICAgIFVzZXJJRCAgICAgICAgICAgICAgICA9PiAxMjMsCiAgICApOwoKPWN1dAoKc3ViIE5vdGlmaWNhdGlvbkV2ZW50IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkTmVlZGVkIChxdyhUaWNrZXREYXRhIE5vdGlmaWNhdGlvbiBSZWNpcGllbnQgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskTmVlZGVkfSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJE5lZWRlZCEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIGlmICggIUlzSGFzaFJlZldpdGhEYXRhKCAkUGFyYW17Tm90aWZpY2F0aW9ufSApICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTm90aWZpY2F0aW9uIGlzIGludmFsaWQhIiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBteSAlTm90aWZpY2F0aW9uID0gJXsgJFBhcmFte05vdGlmaWNhdGlvbn0gfTsKCiAgICAjIGV4Y2hhbmdpbmcgb3JpZ2luYWwgcmVmZXJlbmNlIHByZXZlbnQgaXQgdG8gZ3JvdyB1cAogICAgaWYgKCByZWYgJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30gJiYgcmVmICRQYXJhbXtDdXN0b21lck1lc3NhZ2VQYXJhbXN9IGVxICdIQVNIJyApIHsKICAgICAgICBteSAlTG9jYWxDdXN0b21lck1lc3NhZ2VQYXJhbXMgPSAleyAkUGFyYW17Q3VzdG9tZXJNZXNzYWdlUGFyYW1zfSB9OwogICAgICAgICRQYXJhbXtDdXN0b21lck1lc3NhZ2VQYXJhbXN9ID0gXCVMb2NhbEN1c3RvbWVyTWVzc2FnZVBhcmFtczsKICAgIH0KCiAgICBteSAkQXJ0aWNsZU9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkFydGljbGUnKTsKCiAgICAjIEdldCBsYXN0IGFydGljbGUgZnJvbSBjdXN0b21lci4KICAgIG15IEBDdXN0b21lckFydGljbGVzID0gJEFydGljbGVPYmplY3QtPkFydGljbGVMaXN0KAogICAgICAgIFRpY2tldElEICAgPT4gJFBhcmFte1RpY2tldERhdGF9LT57VGlja2V0SUR9LAogICAgICAgIFNlbmRlclR5cGUgPT4gJ2N1c3RvbWVyJywKICAgICAgICBPbmx5TGFzdCAgID0+IDEsCiAgICApOwoKICAgIG15ICVDdXN0b21lckFydGljbGU7CgogICAgQVJUSUNMRToKICAgIGZvciBteSAkQXJ0aWNsZSAoQEN1c3RvbWVyQXJ0aWNsZXMpIHsKICAgICAgICBuZXh0IEFSVElDTEUgaWYgISRBcnRpY2xlLT57QXJ0aWNsZUlEfTsKCiAgICAgICAgJUN1c3RvbWVyQXJ0aWNsZSA9ICRBcnRpY2xlT2JqZWN0LT5CYWNrZW5kRm9yQXJ0aWNsZSggJXskQXJ0aWNsZX0gKS0+QXJ0aWNsZUdldCgKICAgICAgICAgICAgJXskQXJ0aWNsZX0sCiAgICAgICAgICAgIER5bmFtaWNGaWVsZHMgPT4gMCwKICAgICAgICApOwogICAgfQoKICAgICMgR2V0IGxhc3QgYXJ0aWNsZSBmcm9tIGFnZW50LgogICAgbXkgQEFnZW50QXJ0aWNsZXMgPSAkQXJ0aWNsZU9iamVjdC0+QXJ0aWNsZUxpc3QoCiAgICAgICAgVGlja2V0SUQgICA9PiAkUGFyYW17VGlja2V0RGF0YX0tPntUaWNrZXRJRH0sCiAgICAgICAgU2VuZGVyVHlwZSA9PiAnYWdlbnQnLAogICAgICAgIE9ubHlMYXN0ICAgPT4gMSwKICAgICk7CgogICAgbXkgJUFnZW50QXJ0aWNsZTsKCiAgICBBR0VOVEFSVElDTEU6CiAgICBmb3IgbXkgJEFydGljbGUgKEBBZ2VudEFydGljbGVzKSB7CiAgICAgICAgbmV4dCBBR0VOVEFSVElDTEUgaWYgISRBcnRpY2xlLT57QXJ0aWNsZUlEfTsKCiAgICAgICAgJUFnZW50QXJ0aWNsZSA9ICRBcnRpY2xlT2JqZWN0LT5CYWNrZW5kRm9yQXJ0aWNsZSggJXskQXJ0aWNsZX0gKS0+QXJ0aWNsZUdldCgKICAgICAgICAgICAgJXskQXJ0aWNsZX0sCiAgICAgICAgICAgIER5bmFtaWNGaWVsZHMgPT4gMCwKICAgICAgICApOwoKICAgICAgICAjIEluY2x1ZGUgdGhlIHRyYW5zbWlzc2lvbiBzdGF0dXMsIGlmIGFydGljbGUgaXMgYW4gZW1haWwuCiAgICAgICAgbXkgJUNvbW11bmljYXRpb25DaGFubmVsID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNvbW11bmljYXRpb25DaGFubmVsJyktPkNoYW5uZWxHZXQoCiAgICAgICAgICAgIENoYW5uZWxJRCA9PiAkQXJ0aWNsZS0+e0NvbW11bmljYXRpb25DaGFubmVsSUR9LAogICAgICAgICk7CiAgICAgICAgaWYgKCAkQ29tbXVuaWNhdGlvbkNoYW5uZWx7Q2hhbm5lbE5hbWV9IGVxICdFbWFpbCcgKSB7CiAgICAgICAgICAgIG15ICRUcmFuc21pc3Npb25TdGF0dXMgPSAkQXJ0aWNsZU9iamVjdC0+QmFja2VuZEZvckFydGljbGUoICV7JEFydGljbGV9ICktPkFydGljbGVUcmFuc21pc3Npb25TdGF0dXMoCiAgICAgICAgICAgICAgICBBcnRpY2xlSUQgPT4gJEFydGljbGUtPntBcnRpY2xlSUR9LAogICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoICRUcmFuc21pc3Npb25TdGF0dXMgJiYgJFRyYW5zbWlzc2lvblN0YXR1cy0+e01lc3NhZ2V9ICkgewogICAgICAgICAgICAgICAgJEFnZW50QXJ0aWNsZXtUcmFuc21pc3Npb25TdGF0dXNNZXNzYWdlfSA9ICRUcmFuc21pc3Npb25TdGF0dXMtPntNZXNzYWdlfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBteSAkTGF5b3V0T2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcpOwoKICAgIEFSVElDTEU6CiAgICBmb3IgbXkgJEFydGljbGVEYXRhICggXCVDdXN0b21lckFydGljbGUsIFwlQWdlbnRBcnRpY2xlICkgewogICAgICAgIG5leHQgQVJUSUNMRSBpZiAhJEFydGljbGVEYXRhLT57VGlja2V0SUR9OwogICAgICAgIG5leHQgQVJUSUNMRSBpZiAhJEFydGljbGVEYXRhLT57QXJ0aWNsZUlEfTsKCiAgICAgICAgIyBHZXQgYXJ0aWNsZSBwcmV2aWV3IGluIHBsYWluIHRleHQgYW5kIHN0b3JlIGl0IGFzIEJvZHkga2V5LgogICAgICAgICRBcnRpY2xlRGF0YS0+e0JvZHl9ID0gJExheW91dE9iamVjdC0+QXJ0aWNsZVByZXZpZXcoCiAgICAgICAgICAgIFRpY2tldElEICAgPT4gJEFydGljbGVEYXRhLT57VGlja2V0SUR9LAogICAgICAgICAgICBBcnRpY2xlSUQgID0+ICRBcnRpY2xlRGF0YS0+e0FydGljbGVJRH0sCiAgICAgICAgICAgIFJlc3VsdFR5cGUgPT4gJ3BsYWluJywKICAgICAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICAgICApOwoKICAgICAgICAjIGdldCBhY2NvdW50ZWQgdGltZQogICAgICAgIG15ICRBY2NvdW50ZWRUaW1lID0gJEFydGljbGVPYmplY3QtPkFydGljbGVBY2NvdW50ZWRUaW1lR2V0KAogICAgICAgICAgICBBcnRpY2xlSUQgPT4gJEFydGljbGVEYXRhLT57QXJ0aWNsZUlEfSwKICAgICAgICApOwoKICAgICAgICAjIHNldCB0aGUgYWNjb3VudGVkIHRpbWUgYXMgcGFydCBvZiB0aGUgYXJ0aWNsZXMgaW5mb3JtYXRpb24KICAgICAgICAkQXJ0aWNsZURhdGEtPntUaW1lVW5pdH0gPSAkQWNjb3VudGVkVGltZTsKICAgIH0KCiAgICAjIFBvcHVsYXRlIHRoZSBoYXNoICdDdXN0b21lck1lc3NhZ2VQYXJhbXMnIHdpdGggYWxsIHRoZSBjdXN0b21lci1hcnRpY2xlIGRhdGEKICAgICMgYW5kIG92ZXJ3cml0ZSBpdCB3aXRoICdDdXN0b21lck1lc3NhZ2VQYXJhbXMnIHBhc3NlZCBpbiB0aGUgUGFyYW1zIChidWcgIzEzMzI1KS4KICAgICRQYXJhbXtDdXN0b21lck1lc3NhZ2VQYXJhbXN9ID0gewogICAgICAgICVDdXN0b21lckFydGljbGUsCiAgICAgICAgJXsgJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30gfHwge30gfSwKICAgIH07CgogICAgIyBnZXQgc3lzdGVtIGRlZmF1bHQgbGFuZ3VhZ2UKICAgIG15ICREZWZhdWx0TGFuZ3VhZ2UgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpLT5HZXQoJ0RlZmF1bHRMYW5ndWFnZScpIHx8ICdlbic7CgogICAgbXkgJExhbmd1YWdlcyA9IFsgJFBhcmFte1JlY2lwaWVudH0tPntVc2VyTGFuZ3VhZ2V9LCAkRGVmYXVsdExhbmd1YWdlLCAnZW4nIF07CgogICAgbXkgJExhbmd1YWdlOwogICAgTEFOR1VBR0U6CiAgICBmb3IgbXkgJEl0ZW0gKCBAeyRMYW5ndWFnZXN9ICkgewogICAgICAgIG5leHQgTEFOR1VBR0UgaWYgISRJdGVtOwogICAgICAgIG5leHQgTEFOR1VBR0UgaWYgISROb3RpZmljYXRpb257TWVzc2FnZX0tPnskSXRlbX07CgogICAgICAgICMgc2V0IGxhbmd1YWdlCiAgICAgICAgJExhbmd1YWdlID0gJEl0ZW07CiAgICAgICAgbGFzdCBMQU5HVUFHRTsKICAgIH0KCiAgICAjIGlmIG5vIGxhbmd1YWdlLCB0aGVuIHRha2UgdGhlIGZpcnN0IG9uZSBhdmFpbGFibGUKICAgIGlmICggISRMYW5ndWFnZSApIHsKICAgICAgICBteSBATm90aWZpY2F0aW9uTGFuZ3VhZ2VzID0gc29ydCBrZXlzICV7ICROb3RpZmljYXRpb257TWVzc2FnZX0gfTsKICAgICAgICAkTGFuZ3VhZ2UgPSAkTm90aWZpY2F0aW9uTGFuZ3VhZ2VzWzBdOwogICAgfQoKICAgICMgY29weSB0aGUgY29ycmVjdCBsYW5ndWFnZSBtZXNzYWdlIGF0dHJpYnV0ZXMgdG8gYSBmbGF0IHN0cnVjdHVyZQogICAgZm9yIG15ICRBdHRyaWJ1dGUgKHF3KFN1YmplY3QgQm9keSBDb250ZW50VHlwZSkpIHsKICAgICAgICAkTm90aWZpY2F0aW9ueyRBdHRyaWJ1dGV9ID0gJE5vdGlmaWNhdGlvbntNZXNzYWdlfS0+eyRMYW5ndWFnZX0tPnskQXR0cmlidXRlfTsKICAgIH0KCiAgICAjIEdldCBjdXN0b21lciBhcnRpY2xlIGZpZWxkcy4KICAgIG15ICVDdXN0b21lckFydGljbGVGaWVsZHM7CgogICAgaWYgKCVDdXN0b21lckFydGljbGUpIHsKICAgICAgICAlQ3VzdG9tZXJBcnRpY2xlRmllbGRzID0gJExheW91dE9iamVjdC0+QXJ0aWNsZUZpZWxkcygKICAgICAgICAgICAgVGlja2V0SUQgID0+ICRDdXN0b21lckFydGljbGV7VGlja2V0SUR9LAogICAgICAgICAgICBBcnRpY2xlSUQgPT4gJEN1c3RvbWVyQXJ0aWNsZXtBcnRpY2xlSUR9LAogICAgICAgICAgICBVc2VySUQgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICAgICAgKTsKICAgIH0KCiAgICBBUlRJQ0xFX0ZJRUxEOgogICAgZm9yIG15ICRBcnRpY2xlRmllbGQgKCBzb3J0IGtleXMgJUN1c3RvbWVyQXJ0aWNsZUZpZWxkcyApIHsKICAgICAgICBuZXh0IEFSVElDTEVfRklFTEQgaWYgIWRlZmluZWQgJEN1c3RvbWVyQXJ0aWNsZUZpZWxkc3skQXJ0aWNsZUZpZWxkfS0+e1ZhbHVlfTsKCiAgICAgICAgaWYgKCAhZGVmaW5lZCAkUGFyYW17Q3VzdG9tZXJNZXNzYWdlUGFyYW1zfS0+eyRBcnRpY2xlRmllbGR9ICkgewogICAgICAgICAgICAkUGFyYW17Q3VzdG9tZXJNZXNzYWdlUGFyYW1zfS0+eyRBcnRpY2xlRmllbGR9ID0gJEN1c3RvbWVyQXJ0aWNsZUZpZWxkc3skQXJ0aWNsZUZpZWxkfS0+e1ZhbHVlfTsKICAgICAgICB9CiAgICAgICAgY2hvbXAgJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30tPnskQXJ0aWNsZUZpZWxkfTsKICAgIH0KCiAgICAjIGZvcm1hdCBib2R5IChvbmx5IGlmIGxvbmdlciB0aGUgODYgY2hhcnMpCiAgICBpZiAoICRQYXJhbXtDdXN0b21lck1lc3NhZ2VQYXJhbXN9LT57Qm9keX0gKSB7CiAgICAgICAgaWYgKCBsZW5ndGggJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30tPntCb2R5fSA+IDg2ICkgewogICAgICAgICAgICBteSBATGluZXMgPSBzcGxpdCAvXG4vLCAkUGFyYW17Q3VzdG9tZXJNZXNzYWdlUGFyYW1zfS0+e0JvZHl9OwogICAgICAgICAgICBMSU5FOgogICAgICAgICAgICBmb3IgbXkgJExpbmUgKEBMaW5lcykgewogICAgICAgICAgICAgICAgbXkgJExpbmVXcmFwcGVkID0gJExpbmUgPX4gcy8oXj4uK3wuezQsODZ9KSg/OlxzfFx6KS8kMVxuL2dtOwoKICAgICAgICAgICAgICAgIG5leHQgTElORSBpZiAkTGluZVdyYXBwZWQ7CgogICAgICAgICAgICAgICAgIyBpZiB0aGUgcmVnZXggZG9lcyBub3QgbWF0Y2ggdGhlbiB3ZSBuZWVkCiAgICAgICAgICAgICAgICAjIHRvIGFkZCB0aGUgbWlzc2luZyBuZXcgbGluZSBvZiB0aGUgc3BsaXQKICAgICAgICAgICAgICAgICMgZWxzZSB3ZSB3aWxsIGxvc2UgZS5nLiBlbXB0eSBsaW5lcyBvZiB0aGUgYm9keS4KICAgICAgICAgICAgICAgICMgKGJ1ZyMxMDY3OSkKICAgICAgICAgICAgICAgICRMaW5lIC49ICJcbiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30tPntCb2R5fSA9IGpvaW4gJycsIEBMaW5lczsKICAgICAgICB9CiAgICB9CgogICAgIyBmaWxsIHVwIHJlcXVpcmVkIGF0dHJpYnV0ZXMKICAgIGZvciBteSAkVGV4dCAocXcoU3ViamVjdCBCb2R5KSkgewogICAgICAgIGlmICggISRQYXJhbXtDdXN0b21lck1lc3NhZ2VQYXJhbXN9LT57JFRleHR9ICkgewoKICAgICAgICAgICAgIyBTZXQgdG8gbGFzdCBjdXN0b21lciBhcnRpY2xlIGF0dHJpYnV0ZSBpZiBpdCBpcyBlbXB0eSBzdHJpbmcuCiAgICAgICAgICAgICMgRm9yIGV4YW1wbGUsIGlmIEJvZHkgaXMgZW1wdHkgc3RyaW5nIChub3QgdW5kZWYhKSwgaXQgaXMgbWF5YmUgc2VudCBmcm9tIE5vdGlmaWNhdGlvbk93bmVyVXBkYXRlIGV2ZW50CiAgICAgICAgICAgICMgYW5kIG92ZXJyaWRlcyBsYXN0IGN1c3RvbWVyIGFydGljbGUgYm9keSAoaW4gJUN1c3RvbWVyQXJ0aWNsZSkgYWJvdmUgLSBzZWUgYnVnIzE0Njc4LgogICAgICAgICAgICAkUGFyYW17Q3VzdG9tZXJNZXNzYWdlUGFyYW1zfS0+eyRUZXh0fSA9ICRDdXN0b21lckFydGljbGV7JFRleHR9IHx8ICJObyAkVGV4dCI7CiAgICAgICAgfQogICAgfQoKICAgIG15ICRTdGFydCA9ICc8JzsKICAgIG15ICRFbmQgICA9ICc+JzsKICAgIGlmICggJE5vdGlmaWNhdGlvbntDb250ZW50VHlwZX0gPX4gbXt0ZXh0XC9odG1sfSApIHsKICAgICAgICAkU3RhcnQgPSAnJmx0Oyc7CiAgICAgICAgJEVuZCAgID0gJyZndDsnOwogICAgfQoKICAgICMgcmVwbGFjZSA8T1RPQk9fQ1VTVE9NRVJfREFUQV8qPiB0YWdzIGVhcmx5IGZyb20gQ3VzdG9tZXJNZXNzYWdlUGFyYW1zLCB0aGUgcmVzdHMgd2lsbCBiZSByZXBsYWNlZAogICAgIyBieSB0aWNrZXQgY3VzdG9tZXIgdXNlcgogICAgS0VZOgogICAgZm9yIG15ICRLZXkgKCBzb3J0IGtleXMgJXsgJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30gfHwge30gfSApIHsKCiAgICAgICAgbmV4dCBLRVkgaWYgISRQYXJhbXtDdXN0b21lck1lc3NhZ2VQYXJhbXN9LT57JEtleX07CgogICAgICAgICROb3RpZmljYXRpb257Qm9keX0gICAgPX4gcy8ke1N0YXJ0fU9UT0JPX0NVU1RPTUVSX0RBVEFfJEtleSR7RW5kfS8kUGFyYW17Q3VzdG9tZXJNZXNzYWdlUGFyYW1zfS0+eyRLZXl9L2dpOwogICAgICAgICROb3RpZmljYXRpb257U3ViamVjdH0gPX4gcy88T1RPQk9fQ1VTVE9NRVJfREFUQV8kS2V5Pi8kUGFyYW17Q3VzdG9tZXJNZXNzYWdlUGFyYW1zfS0+eyRLZXl9eyRLZXl9L2dpOwogICAgfQoKICAgICMgZG8gdGV4dC9wbGFpbiB0byB0ZXh0L2h0bWwgY29udmVydAogICAgaWYgKCAkU2VsZi0+e1JpY2hUZXh0fSAmJiAkTm90aWZpY2F0aW9ue0NvbnRlbnRUeXBlfSA9fiAvdGV4dFwvcGxhaW4vaSApIHsKICAgICAgICAkTm90aWZpY2F0aW9ue0NvbnRlbnRUeXBlfSA9ICd0ZXh0L2h0bWwnOwogICAgICAgICROb3RpZmljYXRpb257Qm9keX0gICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0hUTUwoCiAgICAgICAgICAgIFN0cmluZyA9PiAkTm90aWZpY2F0aW9ue0JvZHl9LAogICAgICAgICk7CiAgICB9CgogICAgIyBkbyB0ZXh0L2h0bWwgdG8gdGV4dC9wbGFpbiBjb252ZXJ0CiAgICBpZiAoICEkU2VsZi0+e1JpY2hUZXh0fSAmJiAkTm90aWZpY2F0aW9ue0NvbnRlbnRUeXBlfSA9fiAvdGV4dFwvaHRtbC9pICkgewogICAgICAgICROb3RpZmljYXRpb257Q29udGVudFR5cGV9ID0gJ3RleHQvcGxhaW4nOwogICAgICAgICROb3RpZmljYXRpb257Qm9keX0gICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0FzY2lpKAogICAgICAgICAgICBTdHJpbmcgPT4gJE5vdGlmaWNhdGlvbntCb2R5fSwKICAgICAgICApOwogICAgfQoKICAgICMgZ2V0IG5vdGlmeSB0ZXh0cwogICAgZm9yIG15ICRUZXh0IChxdyhTdWJqZWN0IEJvZHkpKSB7CiAgICAgICAgaWYgKCAhJE5vdGlmaWNhdGlvbnskVGV4dH0gKSB7CiAgICAgICAgICAgICROb3RpZmljYXRpb257JFRleHR9ID0gIk5vIE5vdGlmaWNhdGlvbiAkVGV4dCBmb3IgJFBhcmFte1R5cGV9IGZvdW5kISI7CiAgICAgICAgfQogICAgfQoKICAgICMgcmVwbGFjZSBwbGFjZSBob2xkZXIgc3R1ZmYKICAgICROb3RpZmljYXRpb257Qm9keX0gPSAkU2VsZi0+X1JlcGxhY2UoCiAgICAgICAgUmljaFRleHQgICAgICAgID0+ICRTZWxmLT57UmljaFRleHR9LAogICAgICAgIFRleHQgICAgICAgICAgICA9PiAkTm90aWZpY2F0aW9ue0JvZHl9LAogICAgICAgIFJlY2lwaWVudCAgICAgICA9PiAkUGFyYW17UmVjaXBpZW50fSwKICAgICAgICBEYXRhICAgICAgICAgICAgPT4gJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30sCiAgICAgICAgRGF0YUFnZW50ICAgICAgID0+IFwlQWdlbnRBcnRpY2xlLAogICAgICAgIFRpY2tldERhdGEgICAgICA9PiAkUGFyYW17VGlja2V0RGF0YX0sCiAgICAgICAgVXNlcklEICAgICAgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgIExhbmd1YWdlICAgICAgICA9PiAkTGFuZ3VhZ2UsCiAgICAgICAgQWRkVGltZXpvbmVJbmZvID0+IHsKICAgICAgICAgICAgTm90aWZpY2F0aW9uRXZlbnQgPT4gMSwKICAgICAgICB9LAogICAgKTsKCiAgICAkTm90aWZpY2F0aW9ue1N1YmplY3R9ID0gJFNlbGYtPl9SZXBsYWNlKAogICAgICAgIFJpY2hUZXh0ICAgICAgICA9PiAwLAogICAgICAgIFRleHQgICAgICAgICAgICA9PiAkTm90aWZpY2F0aW9ue1N1YmplY3R9LAogICAgICAgIFJlY2lwaWVudCAgICAgICA9PiAkUGFyYW17UmVjaXBpZW50fSwKICAgICAgICBEYXRhICAgICAgICAgICAgPT4gJFBhcmFte0N1c3RvbWVyTWVzc2FnZVBhcmFtc30sCiAgICAgICAgRGF0YUFnZW50ICAgICAgID0+IFwlQWdlbnRBcnRpY2xlLAogICAgICAgIFRpY2tldERhdGEgICAgICA9PiAkUGFyYW17VGlja2V0RGF0YX0sCiAgICAgICAgVXNlcklEICAgICAgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgIExhbmd1YWdlICAgICAgICA9PiAkTGFuZ3VhZ2UsCiAgICAgICAgQWRkVGltZXpvbmVJbmZvID0+IHsKICAgICAgICAgICAgTm90aWZpY2F0aW9uRXZlbnQgPT4gMSwKICAgICAgICB9LAogICAgKTsKCiAgICAjIEtlZXAgdGhlICJvcmlnaW5hbCIgKHVubW9kaWZpZWQpIHN1YmplY3QgYW5kIGJvZHkgZm9yIGxhdGVyIHVzZS4KICAgICROb3RpZmljYXRpb257T3JpZ2luYWxTdWJqZWN0fSA9ICROb3RpZmljYXRpb257U3ViamVjdH07CiAgICAkTm90aWZpY2F0aW9ue09yaWdpbmFsQm9keX0gICAgPSAkTm90aWZpY2F0aW9ue0JvZHl9OwoKICAgICROb3RpZmljYXRpb257U3ViamVjdH0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VGlja2V0JyktPlRpY2tldFN1YmplY3RCdWlsZCgKICAgICAgICBUaWNrZXROdW1iZXIgPT4gJFBhcmFte1RpY2tldERhdGF9LT57VGlja2V0TnVtYmVyfSwKICAgICAgICBTdWJqZWN0ICAgICAgPT4gJE5vdGlmaWNhdGlvbntTdWJqZWN0fSB8fCAnJywKICAgICAgICBUeXBlICAgICAgICAgPT4gJ05ldycsCiAgICApOwoKICAgICMgYWRkIFVSTHMgYW5kIHZlcmlmeSB0byBiZSBmdWxsIEhUTUwgZG9jdW1lbnQKICAgIGlmICggJFNlbGYtPntSaWNoVGV4dH0gKSB7CgogICAgICAgICROb3RpZmljYXRpb257Qm9keX0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6SFRNTFV0aWxzJyktPkxpbmtRdW90ZSgKICAgICAgICAgICAgU3RyaW5nID0+ICROb3RpZmljYXRpb257Qm9keX0sCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gJU5vdGlmaWNhdGlvbjsKfQoKPWJlZ2luIEludGVybmFsOgoKPWN1dAoKc3ViIF9SZXBsYWNlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoVGV4dCBSaWNoVGV4dCBEYXRhIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICFkZWZpbmVkICRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRfISIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNoZWNrIGZvciBtYWlsdG8gbGlua3MKICAgICMgc2luY2UgdGhlIHN1YmplY3QgYW5kIGJvZHkgb2YgdGhvc2UgbWFpbHRvIGxpbmtzIGFyZQogICAgIyB1cmkgZXNjYXBlZCB3ZSBoYXZlIHRvIHVyaSB1bmVzY2FwZSB0aGVtLCByZXBsYWNlCiAgICAjIHBvc3NpYmxlIHBsYWNlaG9sZGVycyBhbmQgdGhlbiByZS11cmkgZXNjYXBlIHRoZW0KICAgICRQYXJhbXtUZXh0fSA9fiBzewogICAgICAgIChocmVmPSJtYWlsdG86W15cP10rXD8pKFteIl0rIikKICAgIH0KICAgIHsKICAgICAgICBteSAkTWFpbFRvSHJlZiAgICAgICAgPSAkMTsKICAgICAgICBteSAkTWFpbFRvSHJlZkNvbnRlbnQgPSAkMjsKCiAgICAgICAgJE1haWxUb0hyZWZDb250ZW50ID1+IHN7CiAgICAgICAgICAgICgoPzpzdWJqZWN0fGJvZHkpPSkoLis/KSgifCYpCiAgICAgICAgfQogICAgICAgIHsKICAgICAgICAgICAgbXkgJFN1YmplY3RPckJvZHlQcmVmaXggID0gJDE7CiAgICAgICAgICAgIG15ICRTdWJqZWN0T3JCb2R5Q29udGVudCA9ICQyOwogICAgICAgICAgICBteSAkU3ViamVjdE9yQm9keVN1ZmZpeCAgPSAkMzsKCiAgICAgICAgICAgIG15ICRTdWJqZWN0T3JCb2R5Q29udGVudFVuZXNjYXBlZCA9IFVSSTo6RXNjYXBlOjp1cmlfdW5lc2NhcGUgJFN1YmplY3RPckJvZHlDb250ZW50OwoKICAgICAgICAgICAgbXkgJFN1YmplY3RPckJvZHlDb250ZW50UmVwbGFjZWQgPSAkU2VsZi0+X1JlcGxhY2UoCiAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICBUZXh0ICAgICA9PiAkU3ViamVjdE9yQm9keUNvbnRlbnRVbmVzY2FwZWQsCiAgICAgICAgICAgICAgICBSaWNoVGV4dCA9PiAwLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgbXkgJFN1YmplY3RPckJvZHlDb250ZW50RXNjYXBlZCA9IFVSSTo6RXNjYXBlOjp1cmlfZXNjYXBlX3V0ZjggJFN1YmplY3RPckJvZHlDb250ZW50UmVwbGFjZWQ7CgogICAgICAgICAgICAkU3ViamVjdE9yQm9keVByZWZpeCAuICRTdWJqZWN0T3JCb2R5Q29udGVudEVzY2FwZWQgLiAkU3ViamVjdE9yQm9keVN1ZmZpeDsKICAgICAgICB9ZWd4OwoKICAgICAgICAkTWFpbFRvSHJlZiAuICRNYWlsVG9IcmVmQ29udGVudDsKICAgIH1lZ3g7CgogICAgbXkgJFN0YXJ0ID0gJzwnOwogICAgbXkgJEVuZCAgID0gJz4nOwogICAgaWYgKCAkUGFyYW17UmljaFRleHR9ICkgewogICAgICAgICRTdGFydCA9ICcmbHQ7JzsKICAgICAgICAkRW5kICAgPSAnJmd0Oyc7CiAgICAgICAgJFBhcmFte1RleHR9ID1+IHMvKFxufFxyKS8vZzsKICAgIH0KCiAgICBteSAlVGlja2V0OwogICAgaWYgKCAkUGFyYW17VGlja2V0RGF0YX0gKSB7CiAgICAgICAgJVRpY2tldCA9ICV7ICRQYXJhbXtUaWNrZXREYXRhfSB9OwogICAgfQoKICAgIG15ICRDdXN0b21lclVzZXJPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyJyk7CgogICAgIyBEZXRlcm1pbmUgcmVjaXBpZW50J3MgdGltZXpvbmUgaWYgbmVlZGVkLgogICAgbXkgJFJlY2lwaWVudFRpbWVab25lOwogICAgaWYgKCAkUGFyYW17QWRkVGltZXpvbmVJbmZvfSApIHsKICAgICAgICAkUmVjaXBpZW50VGltZVpvbmUgPSAkS2VybmVsOjpPTS0+Q3JlYXRlKCdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnKS0+T1RPQk9UaW1lWm9uZUdldCgpOwoKICAgICAgICBteSAlQ3VzdG9tZXJVc2VyOwogICAgICAgIGlmICggSXNIYXNoUmVmV2l0aERhdGEoIFwlVGlja2V0ICkgJiYgJFRpY2tldHtDdXN0b21lclVzZXJJRH0gKSB7CiAgICAgICAgICAgICVDdXN0b21lclVzZXIgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRUaWNrZXR7Q3VzdG9tZXJVc2VySUR9ICk7CiAgICAgICAgfQoKICAgICAgICBteSAlVXNlclByZWZlcmVuY2VzOwoKICAgICAgICBpZiAoICRQYXJhbXtBZGRUaW1lem9uZUluZm99LT57Tm90aWZpY2F0aW9uRXZlbnR9ICYmICRQYXJhbXtSZWNpcGllbnR9LT57VHlwZX0gZXEgJ0FnZW50JyApIHsKICAgICAgICAgICAgJVVzZXJQcmVmZXJlbmNlcyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpVc2VyJyktPkdldFByZWZlcmVuY2VzKAogICAgICAgICAgICAgICAgVXNlcklEID0+ICRQYXJhbXtSZWNpcGllbnR9LT57VXNlcklEfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgZWxzaWYgKAogICAgICAgICAgICAkUGFyYW17QWRkVGltZXpvbmVJbmZvfS0+e05vdGlmaWNhdGlvbkV2ZW50fQogICAgICAgICAgICAmJiAkUGFyYW17UmVjaXBpZW50fS0+e1R5cGV9IGVxICdDdXN0b21lcicKICAgICAgICAgICAgJiYgJFBhcmFte1JlY2lwaWVudH0tPntVc2VySUR9CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICVVc2VyUHJlZmVyZW5jZXMgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5HZXRQcmVmZXJlbmNlcygKICAgICAgICAgICAgICAgIFVzZXJJRCA9PiAkUGFyYW17UmVjaXBpZW50fS0+e1VzZXJJRH0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGVsc2lmICgKICAgICAgICAgICAgJFBhcmFte0FkZFRpbWV6b25lSW5mb30tPntBdXRvUmVzcG9uc2V9CiAgICAgICAgICAgICYmICRUaWNrZXR7Q3VzdG9tZXJVc2VySUR9CiAgICAgICAgICAgICYmIElzSGFzaFJlZldpdGhEYXRhKCBcJUN1c3RvbWVyVXNlciApCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICVVc2VyUHJlZmVyZW5jZXMgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5HZXRQcmVmZXJlbmNlcygKICAgICAgICAgICAgICAgIFVzZXJJRCA9PiAkVGlja2V0e0N1c3RvbWVyVXNlcklEfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIGlmICggJFVzZXJQcmVmZXJlbmNlc3tVc2VyVGltZVpvbmV9ICkgewogICAgICAgICAgICAkUmVjaXBpZW50VGltZVpvbmUgPSAkVXNlclByZWZlcmVuY2Vze1VzZXJUaW1lWm9uZX07CiAgICAgICAgfQogICAgfQoKICAgICMgUmVwbGFjZSBVbml4IHRpbWUgZm9ybWF0IHRhZ3MuCiAgICAjIElmIGxhbmd1YWdlIGlzIGRlZmluZWQsIHRoZXkgd2lsbCBiZSBjb252ZXJ0ZWQgaW50byBhIGNvcnJlY3QgZm9ybWF0IGluIGJlbG93IElGIHN0YXRlbWVudC4KICAgIGZvciBteSAkVW5peEZvcm1hdFRpbWUgKAogICAgICAgIHF3KFJlYWxUaWxsVGltZU5vdFVzZWQgRXNjYWxhdGlvblJlc3BvbnNlVGltZSBFc2NhbGF0aW9uVXBkYXRlVGltZSBFc2NhbGF0aW9uU29sdXRpb25UaW1lKQogICAgICAgICkKICAgIHsKICAgICAgICBpZiAoICRUaWNrZXR7JFVuaXhGb3JtYXRUaW1lfSApIHsKICAgICAgICAgICAgJFRpY2tldHskVW5peEZvcm1hdFRpbWV9ID0gJEtlcm5lbDo6T00tPkNyZWF0ZSgKICAgICAgICAgICAgICAgICdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnLAogICAgICAgICAgICAgICAgT2JqZWN0UGFyYW1zID0+IHsKICAgICAgICAgICAgICAgICAgICBFcG9jaCA9PiAkVGlja2V0eyRVbml4Rm9ybWF0VGltZX0sCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApLT5Ub1N0cmluZygpOwogICAgICAgIH0KICAgIH0KCiAgICAjIHRyYW5zbGF0ZSB0aWNrZXQgdmFsdWVzIGlmIG5lZWRlZAogICAgaWYgKCAkUGFyYW17TGFuZ3VhZ2V9ICkgewoKICAgICAgICBteSAkTGFuZ3VhZ2VPYmplY3QgPSBLZXJuZWw6Okxhbmd1YWdlLT5uZXcoCiAgICAgICAgICAgIFVzZXJMYW5ndWFnZSA9PiAkUGFyYW17TGFuZ3VhZ2V9LAogICAgICAgICk7CgogICAgICAgICMgVHJhbnNsYXRlIHRoZSBkaWZmZXJlbnQgdmFsdWVzLgogICAgICAgIGZvciBteSAkRmllbGQgKHF3KFR5cGUgU3RhdGUgU3RhdGVUeXBlIExvY2sgUHJpb3JpdHkpKSB7CiAgICAgICAgICAgICRUaWNrZXR7JEZpZWxkfSA9ICRMYW5ndWFnZU9iamVjdC0+VHJhbnNsYXRlKCAkVGlja2V0eyRGaWVsZH0gKTsKICAgICAgICB9CgogICAgICAgICMgVHJhbnNmb3JtIHRoZSBkYXRlIHZhbHVlcyBmcm9tIHRoZSB0aWNrZXQgZGF0YSAoYnV0IG5vdCB0aGUgZHluYW1pYyBmaWVsZCB2YWx1ZXMpLgogICAgICAgIEFUVFJJQlVURToKICAgICAgICBmb3IgbXkgJEF0dHJpYnV0ZSAoIHNvcnQga2V5cyAlVGlja2V0ICkgewogICAgICAgICAgICBuZXh0IEFUVFJJQlVURSBpZiAkQXR0cmlidXRlID1+IG17IFxBIER5bmFtaWNGaWVsZF8gfXhtczsKICAgICAgICAgICAgbmV4dCBBVFRSSUJVVEUgaWYgISRUaWNrZXR7JEF0dHJpYnV0ZX07CgogICAgICAgICAgICBpZiAoICRUaWNrZXR7JEF0dHJpYnV0ZX0gPX4gbXtcQShcZFxkXGRcZCktKFxkXGQpLShcZFxkKVxzKFxkXGQpOihcZFxkKTooXGRcZClcen14aSApIHsKCiAgICAgICAgICAgICAgICAjIENoYW5nZSB0aW1lIHRvIHJlY2lwaWVudCdzIHRpbWV6b25lIGlmIG5lZWRlZAogICAgICAgICAgICAgICAgIyBhbmQgbGF0ZXIgYXBwZW5kIHRpbWV6b25lIGluZm9ybWF0aW9uLgogICAgICAgICAgICAgICAgIyBGb3IgbW9yZSBpbmZvcm1hdGlvbiwKICAgICAgICAgICAgICAgICMgc2VlIGJ1ZyMxMzg2NSAoaHR0cHM6Ly9idWdzLm90cnMub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzg2NSkKICAgICAgICAgICAgICAgICMgYW5kIGJ1ZyMxNDI3MCAoaHR0cHM6Ly9idWdzLm90cnMub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDI3MCkuCiAgICAgICAgICAgICAgICBpZiAoJFJlY2lwaWVudFRpbWVab25lKSB7CiAgICAgICAgICAgICAgICAgICAgbXkgJERhdGVUaW1lT2JqZWN0ID0gJEtlcm5lbDo6T00tPkNyZWF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScsCiAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdFBhcmFtcyA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmcgPT4gJFRpY2tldHskQXR0cmlidXRlfSwKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICREYXRlVGltZU9iamVjdC0+VG9UaW1lWm9uZSggVGltZVpvbmUgPT4gJFJlY2lwaWVudFRpbWVab25lICk7CiAgICAgICAgICAgICAgICAgICAgJFRpY2tldHskQXR0cmlidXRlfSA9ICREYXRlVGltZU9iamVjdC0+VG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAkVGlja2V0eyRBdHRyaWJ1dGV9ID0gJExhbmd1YWdlT2JqZWN0LT5Gb3JtYXRUaW1lU3RyaW5nKAogICAgICAgICAgICAgICAgICAgICRUaWNrZXR7JEF0dHJpYnV0ZX0sCiAgICAgICAgICAgICAgICAgICAgJ0RhdGVGb3JtYXQnLAogICAgICAgICAgICAgICAgICAgICdOb1NlY29uZHMnLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAjIEFwcGVuZCB0aW1lem9uZSBpbmZvcm1hdGlvbiBpZiBuZWVkZWQuCiAgICAgICAgICAgICAgICBpZiAoJFJlY2lwaWVudFRpbWVab25lKSB7CiAgICAgICAgICAgICAgICAgICAgJFRpY2tldHskQXR0cmlidXRlfSAuPSAiICgkUmVjaXBpZW50VGltZVpvbmUpIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgbXkgJExvY2FsTGF5b3V0T2JqZWN0ID0gS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dC0+bmV3KAogICAgICAgICAgICBMYW5nID0+ICRQYXJhbXtMYW5ndWFnZX0sCiAgICAgICAgKTsKCiAgICAgICAgIyBDb252ZXJ0IHRhZ3MgaW4gc2Vjb25kcyB0byBtb3JlIHJlYWRhYmxlIGFwcHJvcHJpYXRlIGZvcm1hdCBpZiBsYW5ndWFnZSBpcyBkZWZpbmVkLgogICAgICAgIGZvciBteSAkVGltZUluU2Vjb25kcyAoCiAgICAgICAgICAgIHF3KFVudGlsVGltZSBFc2NhbGF0aW9uVGltZVdvcmtpbmdUaW1lIEVzY2FsYXRpb25UaW1lIEZpcnN0UmVzcG9uc2VUaW1lV29ya2luZ1RpbWUgRmlyc3RSZXNwb25zZVRpbWUgVXBkYXRlVGltZVdvcmtpbmdUaW1lCiAgICAgICAgICAgIFVwZGF0ZVRpbWUgU29sdXRpb25UaW1lV29ya2luZ1RpbWUgU29sdXRpb25UaW1lKQogICAgICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBpZiAoICRUaWNrZXR7JFRpbWVJblNlY29uZHN9ICkgewogICAgICAgICAgICAgICAgJFRpY2tldHskVGltZUluU2Vjb25kc30gPSAkTG9jYWxMYXlvdXRPYmplY3QtPkN1c3RvbWVyQWdlKAogICAgICAgICAgICAgICAgICAgIEFnZSAgID0+ICRUaWNrZXR7JFRpbWVJblNlY29uZHN9LAogICAgICAgICAgICAgICAgICAgIFNwYWNlID0+ICcgJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBteSAlUXVldWU7CiAgICBpZiAoICRQYXJhbXtRdWV1ZUlEfSApIHsKICAgICAgICAlUXVldWUgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6UXVldWUnKS0+UXVldWVHZXQoCiAgICAgICAgICAgIElEID0+ICRQYXJhbXtRdWV1ZUlEfSwKICAgICAgICApOwogICAgfQoKICAgIG15ICRDb25maWdPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwoKICAgICMgUmVwbGFjZSBjb25maWcgb3B0aW9ucy4KICAgIG15ICRUYWcgPSAkU3RhcnQgLiAnT1RPQk9fQ09ORklHXyc7CiAgICAkUGFyYW17VGV4dH0gPX4gc3skVGFnKC4rPykkRW5kfXsKICAgICAgICBteSAkS2V5ICAgPSAkMTsKICAgICAgICBteSAkVmFsdWUgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJEtleSkgLy8gJyc7CgogICAgICAgICMgTWFzayBzZW5zaXRpdmUgY29uZmlnIG9wdGlvbnMuCiAgICAgICAgbXkgJFJlcGxhY2UgPSAkU2VsZi0+X01hc2tTZW5zaXRpdmVWYWx1ZSgKICAgICAgICAgICAgS2V5ICAgICAgPT4gJEtleSwKICAgICAgICAgICAgVmFsdWUgICAgPT4gJFZhbHVlLAogICAgICAgICAgICBJc0NvbmZpZyA9PiAxLAogICAgICAgICk7CgogICAgICAgICRSZXBsYWNlOwogICAgfWVneDsKCiAgICAjIGNsZWFudXAKICAgICRQYXJhbXtUZXh0fSA9fiBzLyRUYWcuKz8kRW5kLy0vZ2k7CgogICAgbXkgJVJlY2lwaWVudCA9ICV7ICRQYXJhbXtSZWNpcGllbnR9IHx8IHt9IH07CgogICAgIyBnZXQgdXNlciBvYmplY3QKICAgIG15ICRVc2VyT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlVzZXInKTsKCiAgICBpZiAoICElUmVjaXBpZW50ICYmICRQYXJhbXtSZWNpcGllbnRJRH0gKSB7CgogICAgICAgICVSZWNpcGllbnQgPSAkVXNlck9iamVjdC0+R2V0VXNlckRhdGEoCiAgICAgICAgICAgIFVzZXJJRCAgICAgICAgPT4gJFBhcmFte1JlY2lwaWVudElEfSwKICAgICAgICAgICAgTm9PdXRPZk9mZmljZSA9PiAxLAogICAgICAgICk7CiAgICB9CgogICAgbXkgJEhhc2hHbG9iYWxSZXBsYWNlID0gc3ViIHsKICAgICAgICBteSAoICRUYWcsICVIICkgPSBAXzsKCiAgICAgICAgIyBHZW5lcmF0ZSBvbmUgc2luZ2xlIG1hdGNoaW5nIHN0cmluZyBmb3IgYWxsIGtleXMgdG8gc2F2ZSBwZXJmb3JtYW5jZS4KICAgICAgICBteSAkS2V5cyA9IGpvaW4gJ3wnLCBtYXAge3F1b3RlbWV0YX0gZ3JlcCB7IGRlZmluZWQgJEh7JF99IH0ga2V5cyAlSDsKCiAgICAgICAgIyBTZXQgYWxsIGtleXMgYXMgbG93ZXJjYXNlIHRvIGJlIGFibGUgdG8gbWF0Y2ggY2FzZSBpbnNlbnNpdGl2ZSwKICAgICAgICAjICAgZS4gZy4gPE9UT0JPX0NVU1RPTUVSX0Zyb20+IGFuZCA8T1RPQk9fQ1VTVE9NRVJfRlJPTT4uCiAgICAgICAgIyAgIEFsc28gbWFzayBhbnkgdmFsdWVzIGNvbnRhaW5pbmcgc2Vuc2l0aXZlIGRhdGEuCiAgICAgICAgJUggPSBtYXAgewogICAgICAgICAgICBsYyAkXyA9PiAkU2VsZi0+X01hc2tTZW5zaXRpdmVWYWx1ZSgKICAgICAgICAgICAgICAgIEtleSAgID0+ICRfLAogICAgICAgICAgICAgICAgVmFsdWUgPT4gJEh7JF99LAogICAgICAgICAgICApCiAgICAgICAgfSBzb3J0IGtleXMgJUg7CgogICAgICAgICMgSWYgdGFnIGlzICdPVE9CT19DVVNUT01FUl8nIGFkZCB0aGUgYm9keSBhbGlhcyAnZW1haWwvbm90ZScgdG8gYmUgcmVwbGFjZWQuCiAgICAgICAgaWYgKCAkVGFnID1+IG0vT1RPQk9fKENVU1RPTUVSfEFHRU5UKV8vICkgewogICAgICAgICAgICBLRVk6CiAgICAgICAgICAgIGZvciBteSAkS2V5IChxdyggZW1haWwgbm90ZSApKSB7CiAgICAgICAgICAgICAgICBteSAkVmFsdWUgPSAkSHskS2V5fTsKICAgICAgICAgICAgICAgIG5leHQgS0VZIGlmIGRlZmluZWQoJFZhbHVlKTsKCiAgICAgICAgICAgICAgICAkSHskS2V5fSA9ICRIeydib2R5J307CiAgICAgICAgICAgICAgICAkS2V5cyAuPSAnfCcgLiB1Y2ZpcnN0ICRLZXk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRQYXJhbXtUZXh0fSA9fiBzLyg/OiRUYWcpKCRLZXlzKSRFbmQvJEh7IGxjICQxIH0vaWVnOwogICAgfTsKCiAgICAjIGdldCByZWNpcGllbnQgZGF0YSBhbmQgcmVwbGFjZSBpdCB3aXRoIDxPVE9CT18uLi4KICAgICRUYWcgPSAkU3RhcnQgLiAnT1RPQk9fJzsKCiAgICAjIGluY2x1ZGUgbW9yZSByZWFkYWJsZSB0YWcgPE9UT0JPX05PVElGSUNBVElPTl9SRUNJUElFTlQKICAgIG15ICRSZWNpcGllbnRUYWcgPSAkU3RhcnQgLiAnT1RPQk9fTk9USUZJQ0FUSU9OX1JFQ0lQSUVOVF8nOwoKICAgIGlmICglUmVjaXBpZW50KSB7CgogICAgICAgICMgSFRNTCBxdW90aW5nIG9mIGNvbnRlbnQKICAgICAgICBpZiAoICRQYXJhbXtSaWNoVGV4dH0gKSB7CiAgICAgICAgICAgIEFUVFJJQlVURToKICAgICAgICAgICAgZm9yIG15ICRBdHRyaWJ1dGUgKCBzb3J0IGtleXMgJVJlY2lwaWVudCApIHsKICAgICAgICAgICAgICAgIG5leHQgQVRUUklCVVRFIGlmICEkUmVjaXBpZW50eyRBdHRyaWJ1dGV9OwogICAgICAgICAgICAgICAgJFJlY2lwaWVudHskQXR0cmlidXRlfSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+VG9IVE1MKAogICAgICAgICAgICAgICAgICAgIFN0cmluZyA9PiAkUmVjaXBpZW50eyRBdHRyaWJ1dGV9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJEhhc2hHbG9iYWxSZXBsYWNlLT4oICIkVGFnfCRSZWNpcGllbnRUYWciLCAlUmVjaXBpZW50ICk7CiAgICB9CgogICAgIyBjbGVhbnVwCiAgICAkUGFyYW17VGV4dH0gPX4gcy8kUmVjaXBpZW50VGFnLis/JEVuZC8tL2dpOwoKICAgICMgZ2V0IG93bmVyIGRhdGEgYW5kIHJlcGxhY2UgaXQgd2l0aCA8T1RPQk9fT1dORVJfLi4uCiAgICAkVGFnID0gJFN0YXJ0IC4gJ09UT0JPX09XTkVSXyc7CgogICAgIyBpbmNsdWRlIG1vcmUgcmVhZGFibGUgdmVyc2lvbiA8T1RPQk9fVElDS0VUX09XTkVSCiAgICBteSAkT3duZXJUYWcgPSAkU3RhcnQgLiAnT1RPQk9fVElDS0VUX09XTkVSXyc7CgogICAgaWYgKCAkVGlja2V0e093bmVySUR9ICkgewoKICAgICAgICBteSAlT3duZXIgPSAkVXNlck9iamVjdC0+R2V0VXNlckRhdGEoCiAgICAgICAgICAgIFVzZXJJRCAgICAgICAgPT4gJFRpY2tldHtPd25lcklEfSwKICAgICAgICAgICAgTm9PdXRPZk9mZmljZSA9PiAxLAogICAgICAgICk7CgogICAgICAgICMgaHRtbCBxdW90aW5nIG9mIGNvbnRlbnQKICAgICAgICBpZiAoICRQYXJhbXtSaWNoVGV4dH0gKSB7CgogICAgICAgICAgICBBVFRSSUJVVEU6CiAgICAgICAgICAgIGZvciBteSAkQXR0cmlidXRlICggc29ydCBrZXlzICVPd25lciApIHsKICAgICAgICAgICAgICAgIG5leHQgQVRUUklCVVRFIGlmICEkT3duZXJ7JEF0dHJpYnV0ZX07CiAgICAgICAgICAgICAgICAkT3duZXJ7JEF0dHJpYnV0ZX0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6SFRNTFV0aWxzJyktPlRvSFRNTCgKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgPT4gJE93bmVyeyRBdHRyaWJ1dGV9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJEhhc2hHbG9iYWxSZXBsYWNlLT4oICIkVGFnfCRPd25lclRhZyIsICVPd25lciApOwogICAgfQoKICAgICMgY2xlYW51cAogICAgJFBhcmFte1RleHR9ID1+IHMvJFRhZy4rPyRFbmQvLS9naTsKICAgICRQYXJhbXtUZXh0fSA9fiBzLyRPd25lclRhZy4rPyRFbmQvLS9naTsKCiAgICAjIGdldCBvd25lciBkYXRhIGFuZCByZXBsYWNlIGl0IHdpdGggPE9UT0JPX1JFU1BPTlNJQkxFXy4uLgogICAgJFRhZyA9ICRTdGFydCAuICdPVE9CT19SRVNQT05TSUJMRV8nOwoKICAgICMgaW5jbHVkZSBtb3JlIHJlYWRhYmxlIHZlcnNpb24gPE9UT0JPX1RJQ0tFVF9SRVNQT05TSUJMRQogICAgbXkgJFJlc3BvbnNpYmxlVGFnID0gJFN0YXJ0IC4gJ09UT0JPX1RJQ0tFVF9SRVNQT05TSUJMRV8nOwoKICAgIGlmICggJFRpY2tldHtSZXNwb25zaWJsZUlEfSApIHsKICAgICAgICBteSAlUmVzcG9uc2libGUgPSAkVXNlck9iamVjdC0+R2V0VXNlckRhdGEoCiAgICAgICAgICAgIFVzZXJJRCAgICAgICAgPT4gJFRpY2tldHtSZXNwb25zaWJsZUlEfSwKICAgICAgICAgICAgTm9PdXRPZk9mZmljZSA9PiAxLAogICAgICAgICk7CgogICAgICAgICMgSFRNTCBxdW90aW5nIG9mIGNvbnRlbnQKICAgICAgICBpZiAoICRQYXJhbXtSaWNoVGV4dH0gKSB7CgogICAgICAgICAgICBBVFRSSUJVVEU6CiAgICAgICAgICAgIGZvciBteSAkQXR0cmlidXRlICggc29ydCBrZXlzICVSZXNwb25zaWJsZSApIHsKICAgICAgICAgICAgICAgIG5leHQgQVRUUklCVVRFIGlmICEkUmVzcG9uc2libGV7JEF0dHJpYnV0ZX07CiAgICAgICAgICAgICAgICAkUmVzcG9uc2libGV7JEF0dHJpYnV0ZX0gPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6SFRNTFV0aWxzJyktPlRvSFRNTCgKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgPT4gJFJlc3BvbnNpYmxleyRBdHRyaWJ1dGV9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJEhhc2hHbG9iYWxSZXBsYWNlLT4oICIkVGFnfCRSZXNwb25zaWJsZVRhZyIsICVSZXNwb25zaWJsZSApOwogICAgfQoKICAgICMgY2xlYW51cAogICAgJFBhcmFte1RleHR9ID1+IHMvJFRhZy4rPyRFbmQvLS9naTsKICAgICRQYXJhbXtUZXh0fSA9fiBzLyRSZXNwb25zaWJsZVRhZy4rPyRFbmQvLS9naTsKCiAgICAkVGFnID0gJFN0YXJ0IC4gJ09UT0JPX0FnZW50Xyc7CiAgICBteSAkVGFnMiAgICAgICAgPSAkU3RhcnQgLiAnT1RPQk9fQ1VSUkVOVF8nOwogICAgbXkgJUN1cnJlbnRVc2VyID0gJFVzZXJPYmplY3QtPkdldFVzZXJEYXRhKAogICAgICAgIFVzZXJJRCAgICAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICAgICAgTm9PdXRPZk9mZmljZSA9PiAxLAogICAgKTsKCiAgICAjIEhUTUwgcXVvdGluZyBvZiBjb250ZW50CiAgICBpZiAoICRQYXJhbXtSaWNoVGV4dH0gKSB7CgogICAgICAgIEFUVFJJQlVURToKICAgICAgICBmb3IgbXkgJEF0dHJpYnV0ZSAoIHNvcnQga2V5cyAlQ3VycmVudFVzZXIgKSB7CiAgICAgICAgICAgIG5leHQgQVRUUklCVVRFIGlmICEkQ3VycmVudFVzZXJ7JEF0dHJpYnV0ZX07CiAgICAgICAgICAgICRDdXJyZW50VXNlcnskQXR0cmlidXRlfSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+VG9IVE1MKAogICAgICAgICAgICAgICAgU3RyaW5nID0+ICRDdXJyZW50VXNlcnskQXR0cmlidXRlfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgJEhhc2hHbG9iYWxSZXBsYWNlLT4oICIkVGFnfCRUYWcyIiwgJUN1cnJlbnRVc2VyICk7CgogICAgIyByZXBsYWNlIG90aGVyIG5lZWRlZCBzdHVmZgogICAgJFBhcmFte1RleHR9ID1+IHMvJFN0YXJ0IE9UT0JPX0ZJUlNUX05BTUUgJEVuZC8kQ3VycmVudFVzZXJ7VXNlckZpcnN0bmFtZX0vZ3htczsKICAgICRQYXJhbXtUZXh0fSA9fiBzLyRTdGFydCBPVE9CT19MQVNUX05BTUUgJEVuZC8kQ3VycmVudFVzZXJ7VXNlckxhc3RuYW1lfS9neG1zOwoKICAgICMgY2xlYW51cAogICAgJFBhcmFte1RleHR9ID1+IHMvJFRhZzIuKz8kRW5kLy0vZ2k7CgogICAgIyB0aWNrZXQgZGF0YQogICAgJFRhZyA9ICRTdGFydCAuICdPVE9CT19USUNLRVRfJzsKCiAgICAjIGh0bWwgcXVvdGluZyBvZiBjb250ZW50CiAgICBpZiAoICRQYXJhbXtSaWNoVGV4dH0gKSB7CgogICAgICAgIEFUVFJJQlVURToKICAgICAgICBmb3IgbXkgJEF0dHJpYnV0ZSAoIHNvcnQga2V5cyAlVGlja2V0ICkgewogICAgICAgICAgICBuZXh0IEFUVFJJQlVURSBpZiAhJFRpY2tldHskQXR0cmlidXRlfTsKICAgICAgICAgICAgJFRpY2tldHskQXR0cmlidXRlfSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+VG9IVE1MKAogICAgICAgICAgICAgICAgU3RyaW5nID0+ICRUaWNrZXR7JEF0dHJpYnV0ZX0sCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKIyBSb3RoZXIgT1NTIC8gT25lVGltZUF1dGhlbnRpY2F0aW9uTGluawogICAgIyBSZXBsYWNlIGNvbmZpZyBvcHRpb25zLgogICAgJFRhZyA9ICRTdGFydCAuICdPVE9CT19PVEFDdXN0b21lclRpY2tldExpbmsnOwogICAgJFBhcmFte1RleHR9ID1+IHN7JFRhZyRFbmR9ewogICAgICAgIG15ICRSZXBsYWNlID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQXV0aDo6T25lVGltZUF1dGhMaW5rJyktPlRpY2tldExpbmsoCiAgICAgICAgICAgIFRpY2tldE51bWJlciA9PiAkVGlja2V0e1RpY2tldE51bWJlcn0sCiAgICAgICAgICAgIFVzZXIgICAgICAgICA9PiAkVGlja2V0e0N1c3RvbWVyVXNlcklEfSwKICAgICAgICApOwoKICAgICAgICAkUmVwbGFjZTsKICAgIH1lZ3g7CiMgRU8gT25lVGltZUF1dGhlbnRpY2F0aW9uTGluawoKICAgICMgRHJvcGRvd24sIENoZWNrYm94IGFuZCBNdWx0aXBsZVNlbGVjdCBEeW5hbWljRmllbGRzLCBjYW4gc3RvcmUgdmFsdWVzIChrZXlzKSB0aGF0IGFyZQogICAgIyBkaWZmZXJlbnQgZnJvbSB0aGUgdGhlIHZhbHVlcyB0byBkaXNwbGF5CiAgICAjIDxPVE9CT19USUNLRVRfRHluYW1pY0ZpZWxkX05hbWVYPiByZXR1cm5zIHRoZSBzdG9yZWQga2V5CiAgICAjIDxPVE9CT19USUNLRVRfRHluYW1pY0ZpZWxkX05hbWVYX1ZhbHVlPiByZXR1cm5zIHRoZSBkaXNwbGF5IHZhbHVlCgogICAgbXkgJUR5bmFtaWNGaWVsZHM7CgogICAgIyBGb3Igc3lzdGVtcyB3aXRoIG1hbnkgRHluYW1pYyBmaWVsZHMgd2UgZG8gbm90IHdhbnQgdG8gbG9hZCB0aGVtIGFsbCB1bmxlc3MgbmVlZGVkCiAgICAjIEZpbmQgd2hhdCBEeW5hbWljIEZpZWxkIFZhbHVlcyBhcmUgcmVxdWVzdGVkCiAgICB3aGlsZSAoICRQYXJhbXtUZXh0fSA9fiBtLyRUYWcgRHluYW1pY0ZpZWxkXyhcUys/KShfVmFsdWUpPyAkRW5kL2dpeG1zICkgewogICAgICAgICREeW5hbWljRmllbGRzeyQxfSA9IDE7CiAgICB9CgogICAgIyB0byBzdG9yZSBhbGwgdGhlIHJlcXVpcmVkIER5bmFtaWNGaWVsZCBkaXNwbGF5IHZhbHVlcwogICAgbXkgJUR5bmFtaWNGaWVsZERpc3BsYXlWYWx1ZXM7CgogICAgIyBnZXQgZHluYW1pYyBmaWVsZCBvYmplY3RzCiAgICBteSAkRHluYW1pY0ZpZWxkT2JqZWN0ICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQnKTsKICAgIG15ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZCcpOwoKICAgICMgZ2V0IHRoZSBkeW5hbWljIGZpZWxkcyBmb3IgdGlja2V0IG9iamVjdAogICAgbXkgJER5bmFtaWNGaWVsZExpc3QgPSAkRHluYW1pY0ZpZWxkT2JqZWN0LT5EeW5hbWljRmllbGRMaXN0R2V0KAogICAgICAgIFZhbGlkICAgICAgPT4gMSwKICAgICAgICBPYmplY3RUeXBlID0+IFsnVGlja2V0J10sCiAgICApIHx8IFtdOwoKICAgICMgY3ljbGUgdGhyb3VnaCB0aGUgYWN0aXZhdGVkIER5bmFtaWMgRmllbGRzIGZvciB0aGlzIHNjcmVlbgogICAgRFlOQU1JQ0ZJRUxEOgogICAgZm9yIG15ICREeW5hbWljRmllbGRDb25maWcgKCBAeyREeW5hbWljRmllbGRMaXN0fSApIHsKCiAgICAgICAgbmV4dCBEWU5BTUlDRklFTEQgaWYgIUlzSGFzaFJlZldpdGhEYXRhKCREeW5hbWljRmllbGRDb25maWcpOwoKICAgICAgICAjIHdlIG9ubHkgbG9hZCB0aGUgb25lcyByZXF1ZXN0ZWQKICAgICAgICBuZXh0IERZTkFNSUNGSUVMRCBpZiAhJER5bmFtaWNGaWVsZHN7ICREeW5hbWljRmllbGRDb25maWctPntOYW1lfSB9OwoKICAgICAgICBteSAkTGFuZ3VhZ2VPYmplY3Q7CgogICAgICAgICMgdHJhbnNsYXRlIHZhbHVlcyBpZiBuZWVkZWQKICAgICAgICBpZiAoICRQYXJhbXtMYW5ndWFnZX0gKSB7CiAgICAgICAgICAgICRMYW5ndWFnZU9iamVjdCA9IEtlcm5lbDo6TGFuZ3VhZ2UtPm5ldygKICAgICAgICAgICAgICAgIFVzZXJMYW5ndWFnZSA9PiAkUGFyYW17TGFuZ3VhZ2V9LAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgbXkgJERhdGVUaW1lT2JqZWN0OwoKICAgICAgICAjIENoYW5nZSBEYXRlVGltZSBERiB2YWx1ZSBmb3IgdGlja2V0IGlmIG5lZWRlZC4KICAgICAgICBpZiAoCiAgICAgICAgICAgIGRlZmluZWQgJFRpY2tldHsgJ0R5bmFtaWNGaWVsZF8nIC4gJER5bmFtaWNGaWVsZENvbmZpZy0+e05hbWV9IH0KICAgICAgICAgICAgJiYgJER5bmFtaWNGaWVsZENvbmZpZy0+e0ZpZWxkVHlwZX0gZXEgJ0RhdGVUaW1lJwogICAgICAgICAgICAmJiAkUmVjaXBpZW50VGltZVpvbmUKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgJERhdGVUaW1lT2JqZWN0ID0gJEtlcm5lbDo6T00tPkNyZWF0ZSgKICAgICAgICAgICAgICAgICdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnLAogICAgICAgICAgICAgICAgT2JqZWN0UGFyYW1zID0+IHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgPT4gJFRpY2tldHsgJ0R5bmFtaWNGaWVsZF8nIC4gJER5bmFtaWNGaWVsZENvbmZpZy0+e05hbWV9IH0sCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApOwogICAgICAgICAgICAkRGF0ZVRpbWVPYmplY3QtPlRvVGltZVpvbmUoIFRpbWVab25lID0+ICRSZWNpcGllbnRUaW1lWm9uZSApOwogICAgICAgICAgICAkVGlja2V0eyAnRHluYW1pY0ZpZWxkXycgLiAkRHluYW1pY0ZpZWxkQ29uZmlnLT57TmFtZX0gfSA9ICREYXRlVGltZU9iamVjdC0+VG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgICMgZ2V0IHRoZSBkaXNwbGF5IHZhbHVlIGZvciBlYWNoIGR5bmFtaWMgZmllbGQKICAgICAgICBteSAkRGlzcGxheVZhbHVlID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlZhbHVlTG9va3VwKAogICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZENvbmZpZywKICAgICAgICAgICAgS2V5ICAgICAgICAgICAgICAgID0+ICRUaWNrZXR7ICdEeW5hbWljRmllbGRfJyAuICREeW5hbWljRmllbGRDb25maWctPntOYW1lfSB9LAogICAgICAgICAgICBMYW5ndWFnZU9iamVjdCAgICAgPT4gJExhbmd1YWdlT2JqZWN0LAogICAgICAgICk7CgogICAgICAgICMgZ2V0IHRoZSByZWFkYWJsZSB2YWx1ZSAodmFsdWUpIGZvciBlYWNoIGR5bmFtaWMgZmllbGQKICAgICAgICBteSAkRGlzcGxheVZhbHVlU3RyZyA9ICREeW5hbWljRmllbGRCYWNrZW5kT2JqZWN0LT5SZWFkYWJsZVZhbHVlUmVuZGVyKAogICAgICAgICAgICBEeW5hbWljRmllbGRDb25maWcgPT4gJER5bmFtaWNGaWVsZENvbmZpZywKICAgICAgICAgICAgVmFsdWUgICAgICAgICAgICAgID0+ICREaXNwbGF5VmFsdWUsCiAgICAgICAgKTsKCiAgICAgICAgIyBmaWxsIHRoZSBEeW5hbWljRmllbHNEaXNwbGF5VmFsdWVzCiAgICAgICAgaWYgKCREaXNwbGF5VmFsdWVTdHJnKSB7CiAgICAgICAgICAgICREeW5hbWljRmllbGREaXNwbGF5VmFsdWVzeyAnRHluYW1pY0ZpZWxkXycgLiAkRHluYW1pY0ZpZWxkQ29uZmlnLT57TmFtZX0gLiAnX1ZhbHVlJyB9ID0gJERpc3BsYXlWYWx1ZVN0cmctPntWYWx1ZX07CgogICAgICAgICAgICAjIEFkZCB0aW1lem9uZSBpbmZvIGlmIG5lZWRlZC4KICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgZGVmaW5lZCAkVGlja2V0eyAnRHluYW1pY0ZpZWxkXycgLiAkRHluYW1pY0ZpZWxkQ29uZmlnLT57TmFtZX0gfQogICAgICAgICAgICAgICAgJiYgbGVuZ3RoICRUaWNrZXR7ICdEeW5hbWljRmllbGRfJyAuICREeW5hbWljRmllbGRDb25maWctPntOYW1lfSB9CiAgICAgICAgICAgICAgICAmJiAkRHluYW1pY0ZpZWxkQ29uZmlnLT57RmllbGRUeXBlfSBlcSAnRGF0ZVRpbWUnCiAgICAgICAgICAgICAgICAmJiAkUmVjaXBpZW50VGltZVpvbmUKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgJER5bmFtaWNGaWVsZERpc3BsYXlWYWx1ZXN7ICdEeW5hbWljRmllbGRfJyAuICREeW5hbWljRmllbGRDb25maWctPntOYW1lfSAuICdfVmFsdWUnIH0KICAgICAgICAgICAgICAgICAgICAuPSAiICgkUmVjaXBpZW50VGltZVpvbmUpIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBnZXQgdGhlIHJlYWRhYmxlIHZhbHVlIChrZXkpIGZvciBlYWNoIGR5bmFtaWMgZmllbGQKICAgICAgICBteSAkVmFsdWVTdHJnID0gJER5bmFtaWNGaWVsZEJhY2tlbmRPYmplY3QtPlJlYWRhYmxlVmFsdWVSZW5kZXIoCiAgICAgICAgICAgIER5bmFtaWNGaWVsZENvbmZpZyA9PiAkRHluYW1pY0ZpZWxkQ29uZmlnLAogICAgICAgICAgICBWYWx1ZSAgICAgICAgICAgICAgPT4gJFRpY2tldHsgJ0R5bmFtaWNGaWVsZF8nIC4gJER5bmFtaWNGaWVsZENvbmZpZy0+e05hbWV9IH0sCiAgICAgICAgKTsKCiAgICAgICAgIyByZXBsYWNlIHRpY2tldCBjb250ZW50IHdpdGggdGhlIHZhbHVlIGZyb20gUmVhZGFibGVWYWx1ZVJlbmRlciAoaWYgYW55KQogICAgICAgIGlmICggSXNIYXNoUmVmV2l0aERhdGEoJFZhbHVlU3RyZykgKSB7CiAgICAgICAgICAgICRUaWNrZXR7ICdEeW5hbWljRmllbGRfJyAuICREeW5hbWljRmllbGRDb25maWctPntOYW1lfSB9ID0gJFZhbHVlU3RyZy0+e1ZhbHVlfTsKCiAgICAgICAgICAgICMgQWRkIHRpbWV6b25lIGluZm8gaWYgbmVlZGVkLgogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICBkZWZpbmVkICRUaWNrZXR7ICdEeW5hbWljRmllbGRfJyAuICREeW5hbWljRmllbGRDb25maWctPntOYW1lfSB9CiAgICAgICAgICAgICAgICAmJiBsZW5ndGggJFRpY2tldHsgJ0R5bmFtaWNGaWVsZF8nIC4gJER5bmFtaWNGaWVsZENvbmZpZy0+e05hbWV9IH0KICAgICAgICAgICAgICAgICYmICREeW5hbWljRmllbGRDb25maWctPntGaWVsZFR5cGV9IGVxICdEYXRlVGltZScKICAgICAgICAgICAgICAgICYmICRSZWNpcGllbnRUaW1lWm9uZQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAkVGlja2V0eyAnRHluYW1pY0ZpZWxkXycgLiAkRHluYW1pY0ZpZWxkQ29uZmlnLT57TmFtZX0gfSAuPSAiICgkUmVjaXBpZW50VGltZVpvbmUpIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIHJlcGxhY2UgaXQKICAgICRIYXNoR2xvYmFsUmVwbGFjZS0+KCAkVGFnLCAlVGlja2V0LCAlRHluYW1pY0ZpZWxkRGlzcGxheVZhbHVlcyApOwoKICAgICMgQ09NUEFUCiAgICAkUGFyYW17VGV4dH0gPX4gcy8kU3RhcnQgT1RPQk9fVElDS0VUX0lEICRFbmQvJFRpY2tldHtUaWNrZXRJRH0vZ2l4bXM7CiAgICAkUGFyYW17VGV4dH0gPX4gcy8kU3RhcnQgT1RPQk9fVElDS0VUX05VTUJFUiAkRW5kLyRUaWNrZXR7VGlja2V0TnVtYmVyfS9naXhtczsKICAgIGlmICggJFRpY2tldHtUaWNrZXRJRH0gKSB7CiAgICAgICAgJFBhcmFte1RleHR9ID1+IHMvJFN0YXJ0IE9UT0JPX1FVRVVFICRFbmQvJFRpY2tldHtRdWV1ZX0vZ2l4bXM7CiAgICB9CiAgICBpZiAoICRQYXJhbXtRdWV1ZUlEfSApIHsKICAgICAgICAkUGFyYW17VGV4dH0gPX4gcy8kU3RhcnQgT1RPQk9fVElDS0VUX1FVRVVFICRFbmQvJFF1ZXVle05hbWV9L2dpeG1zOwogICAgfQoKICAgICMgY2xlYW51cAogICAgJFBhcmFte1RleHR9ID1+IHMvJFRhZy4rPyRFbmQvLS9naTsKCiAgICAjIEZvbGxvdy11cCBmb3IgYnVnIzEwODI1LgogICAgIyBTZXQgZGF0YSBmb3IgcmVwbGFjaW5nIG9mIHNwZWNpZmljIHRhZ3MgaW4gVGVtcGxhdGVzOgogICAgIyAtIE9UT0JPX0FHRU5UX1NVQkpFQ1QsIE9UT0JPX0FHRU5UX0JPRFkgLSBzdWJqZWN0L2JvZHkgb2YgdGhlIENVUlJFTlQvTEFURVNUIGFnZW50IGFydGljbGUKICAgICMgLSBPVE9CT19DVVNUT01FUl9TVUJKRUNULCBPVE9CT19DVVNUT01FUl9CT0RZIC0gc3ViamVjdC9ib2R5IG9mIHRoZSBDVVJSRU5UL0xBVEVTVCBjdXN0b21lciBhcnRpY2xlCiAgICAjIC0gT1RPQk9fQUdFTlRfU1VCSkVDVFtuXSAgICAtIGZpcnN0IG4gY2hhcmFjdGVycyBvZiB0aGUgc3ViamVjdCBvZiB0aGUgQ1VSUkVOVC9MQVRFU1QgYWdlbnQgYXJ0aWNsZQogICAgIyAtIE9UT0JPX0FHRU5UX0JPRFlbbl0gICAgICAgLSBmaXJzdCBuIGxpbmVzIG9mIHRoZSBib2R5IG9mIHRoZSBDVVJSRU5UL0xBVEVTVCBhZ2VudCBhcnRpY2xlCiAgICAjIC0gT1RPQk9fQ1VTVE9NRVJfU1VCSkVDVFtuXSAtIGZpcnN0IG4gY2hhcmFjdGVycyBvZiB0aGUgc3ViamVjdCBvZiB0aGUgQ1VSUkVOVC9MQVRFU1QgY3VzdG9tZXIgYXJ0aWNsZQogICAgIyAtIE9UT0JPX0NVU1RPTUVSX0JPRFlbbl0gICAgLSBmaXJzdCBuIGxpbmVzIG9mIHRoZSBib2R5IG9mIHRoZSBDVVJSRU5UL0xBVEVTVCBjdXN0b21lciBhcnRpY2xlCiAgICAjCiAgICAjIEZvciBOb3RlIHRlbXBsYXRlIHdlIG5lZWQgdGhlIGxhc3QgYXJ0aWNsZS4KICAgICMgRm9yIEFuc3dlciwgJFBhcmFte0RhdGF9IGhhcyBzZWxlY3RlZCBvciBsYXN0IGFydGljbGUgZGF0YSwgZGVwZW5kcyB3aGV0aGVyIEFydGljbGVJRCBpcyBzZW50IG9yIG5vdC4KICAgICMgRm9yIEZvcndhcmQsICRQYXJhbXtEYXRhfSBoYXMgdGhlIGZvbGxvd2luZyBhcnRpY2xlIGRhdGE6CiAgICAjIC0gaWYgQXJ0aWNsZUlEIGlzIHNlbnQsIGRhdGEgaXMgZnJvbSBzZWxlY3RlZCBhcnRpY2xlLgogICAgIyAtIGlmIEFydGljbGVJRCBpcyBub3Qgc2VudCwgZGF0YSBpcyBmcm9tIGxhc3QgY3VzdG9tZXIvYWdlbnQvYW55IGFydGljbGUuCiAgICBpZiAoICRQYXJhbXtUZW1wbGF0ZX0gJiYgJFRpY2tldHtUaWNrZXRJRH0gKSB7CiAgICAgICAgbXkgJEFydGljbGVPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6VGlja2V0OjpBcnRpY2xlJyk7CgogICAgICAgIGlmICggJFBhcmFte1RlbXBsYXRlfSBlcSAnTm90ZScgKSB7CgogICAgICAgICAgICAjIEdldCBsYXN0IGFydGljbGUgZnJvbSBhZ2VudC4KICAgICAgICAgICAgbXkgQEFnZW50QXJ0aWNsZXMgPSAkQXJ0aWNsZU9iamVjdC0+QXJ0aWNsZUxpc3QoCiAgICAgICAgICAgICAgICBUaWNrZXRJRCAgID0+ICRQYXJhbXtUaWNrZXREYXRhfS0+e1RpY2tldElEfSwKICAgICAgICAgICAgICAgIFNlbmRlclR5cGUgPT4gJ2FnZW50JywKICAgICAgICAgICAgICAgIE9ubHlMYXN0ICAgPT4gMSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIG15ICVBZ2VudEFydGljbGUgPSAkQXJ0aWNsZU9iamVjdC0+QmFja2VuZEZvckFydGljbGUoICV7ICRBZ2VudEFydGljbGVzWzBdIH0gKS0+QXJ0aWNsZUdldCgKICAgICAgICAgICAgICAgICV7ICRBZ2VudEFydGljbGVzWzBdIH0sCiAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRzID0+IDAsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIEdldCBsYXN0IGFydGljbGUgZnJvbSBjdXN0b21lci4KICAgICAgICAgICAgbXkgQEN1c3RvbWVyQXJ0aWNsZXMgPSAkQXJ0aWNsZU9iamVjdC0+QXJ0aWNsZUxpc3QoCiAgICAgICAgICAgICAgICBUaWNrZXRJRCAgID0+ICRQYXJhbXtUaWNrZXREYXRhfS0+e1RpY2tldElEfSwKICAgICAgICAgICAgICAgIFNlbmRlclR5cGUgPT4gJ2N1c3RvbWVyJywKICAgICAgICAgICAgICAgIE9ubHlMYXN0ICAgPT4gMSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIG15ICVDdXN0b21lckFydGljbGUgPSAkQXJ0aWNsZU9iamVjdC0+QmFja2VuZEZvckFydGljbGUoICV7ICRDdXN0b21lckFydGljbGVzWzBdIH0gKS0+QXJ0aWNsZUdldCgKICAgICAgICAgICAgICAgICV7ICRDdXN0b21lckFydGljbGVzWzBdIH0sCiAgICAgICAgICAgICAgICBEeW5hbWljRmllbGRzID0+IDAsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAkUGFyYW17RGF0YUFnZW50fS0+e1N1YmplY3R9ID0gJEFnZW50QXJ0aWNsZXtTdWJqZWN0fTsKICAgICAgICAgICAgJFBhcmFte0RhdGFBZ2VudH0tPntCb2R5fSAgICA9ICRBZ2VudEFydGljbGV7Qm9keX07CiAgICAgICAgICAgICRQYXJhbXtEYXRhfS0+e1N1YmplY3R9ICAgICAgPSAkQ3VzdG9tZXJBcnRpY2xle1N1YmplY3R9OwogICAgICAgICAgICAkUGFyYW17RGF0YX0tPntCb2R5fSAgICAgICAgID0gJEN1c3RvbWVyQXJ0aWNsZXtCb2R5fTsKICAgICAgICB9CiAgICAgICAgZWxzaWYgKCAkUGFyYW17VGVtcGxhdGV9IGVxICdBbnN3ZXInIHx8ICRQYXJhbXtUZW1wbGF0ZX0gZXEgJ0ZvcndhcmQnICkgewoKICAgICAgICAgICAgIyBJZiAkUGFyYW17RGF0YX0gaGFzIGFnZW50IGFydGljbGUgZGF0YSwgd2Ugd2lsbCBzZXQgc3ViamVjdCBhbmQgYm9keSBpbiAkUGFyYW17RGF0YUFnZW50fQogICAgICAgICAgICAjIHRvIHZhbHVlcyBmcm9tICRQYXJhbXtEYXRhfSBpbiBvcmRlciB0byByaWdodCByZXBsYWNpbmcgb2YgT1RPQk9fQUdFTlRfU1VCSkVDVC9CT0RZIHRhZ3MuCiAgICAgICAgICAgIGlmICggJFBhcmFte0RhdGF9LT57U2VuZGVyVHlwZX0gJiYgJFBhcmFte0RhdGF9LT57U2VuZGVyVHlwZX0gZXEgJ2FnZW50JyApIHsKICAgICAgICAgICAgICAgICRQYXJhbXtEYXRhQWdlbnR9LT57U3ViamVjdH0gPSAkUGFyYW17RGF0YX0tPntTdWJqZWN0fTsKICAgICAgICAgICAgICAgICRQYXJhbXtEYXRhQWdlbnR9LT57Qm9keX0gICAgPSAkUGFyYW17RGF0YX0tPntCb2R5fTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCBjdXN0b21lciBhbmQgYWdlbnQgcGFyYW1zIGFuZCByZXBsYWNlIGl0IHdpdGggPE9UT0JPX0NVU1RPTUVSXy4uLiBvciA8T1RPQk9fQUdFTlRfLi4uCiAgICBteSAlQXJ0aWNsZURhdGEgPSAoCiAgICAgICAgJ09UT0JPX0NVU1RPTUVSXycgPT4gJFBhcmFte0RhdGF9ICAgICAgfHwge30sCiAgICAgICAgJ09UT0JPX0FHRU5UXycgICAgPT4gJFBhcmFte0RhdGFBZ2VudH0gfHwge30sCiAgICApOwoKICAgICMgdXNlIGEgbGlzdCB0byBnZXQgY3VzdG9tZXIgZmlyc3QKICAgIGZvciBteSAkRGF0YVR5cGUgKHF3KE9UT0JPX0NVU1RPTUVSXyBPVE9CT19BR0VOVF8pKSB7CiAgICAgICAgbXkgJURhdGEgPSAleyAkQXJ0aWNsZURhdGF7JERhdGFUeXBlfSB9OwoKICAgICAgICAjIEhUTUwgcXVvdGluZyBvZiBjb250ZW50CiAgICAgICAgaWYgKCAkUGFyYW17UmljaFRleHR9ICkgewoKICAgICAgICAgICAgQVRUUklCVVRFOgogICAgICAgICAgICBmb3IgbXkgJEF0dHJpYnV0ZSAoIHNvcnQga2V5cyAlRGF0YSApIHsKICAgICAgICAgICAgICAgIG5leHQgQVRUUklCVVRFIGlmICEkRGF0YXskQXR0cmlidXRlfTsKCiAgICAgICAgICAgICAgICAkRGF0YXskQXR0cmlidXRlfSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpIVE1MVXRpbHMnKS0+VG9IVE1MKAogICAgICAgICAgICAgICAgICAgIFN0cmluZyA9PiAkRGF0YXskQXR0cmlidXRlfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICglRGF0YSkgewoKICAgICAgICAgICAgIyByZXBsYWNlIDxPVE9CT19DVVNUT01FUl8qPiBhbmQgPE9UT0JPX0FHRU5UXyo+IHRhZ3MKICAgICAgICAgICAgJFRhZyA9ICRTdGFydCAuICREYXRhVHlwZTsKICAgICAgICAgICAgJEhhc2hHbG9iYWxSZXBsYWNlLT4oICRUYWcsICVEYXRhICk7CgogICAgICAgICAgICAjIHByZXBhcmUgYm9keSAoaW5zZXJ0IG9sZCBlbWFpbCkgPE9UT0JPX0NVU1RPTUVSX0VNQUlMW25dPiwgPE9UT0JPX0NVU1RPTUVSX05PVEVbbl0+CiAgICAgICAgICAgICMgICA8T1RPQk9fQ1VTVE9NRVJfQk9EWVtuXT4sIDxPVE9CT19BR0VOVF9FTUFJTFtuXT4uLi4sIDxPVE9CT19DT01NRU5UPgoKICAgICAgICAgICAgIyBDaGFuZ2VkIHRoaXMgdG8gYSAnd2hpbGUnIHRvIGFsbG93IHRoZSBzYW1lIGtleS90YWcgbXVsdGlwbGUgdGltZXMgYW5kIGRpZmZlcmVudCBudW1iZXIgb2YgbGluZXMuCiAgICAgICAgICAgIHdoaWxlICgKICAgICAgICAgICAgICAgICRQYXJhbXtUZXh0fSA9fiAvJFN0YXJ0KD86JERhdGFUeXBlKEVNQUlMfE5PVEV8Qk9EWSlcWyguKz8pXF0pJEVuZC8KICAgICAgICAgICAgICAgIHx8CiAgICAgICAgICAgICAgICAkUGFyYW17VGV4dH0gPX4gLyRTdGFydCg/Ok9UT0JPX0NPTU1FTlQoXFsoLis/KVxdKT8pJEVuZC8KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIG15ICRMaW5lICAgICAgID0gJDIgfHwgMjUwMDsKICAgICAgICAgICAgICAgIG15ICROZXdPbGRCb2R5ID0gJyc7CiAgICAgICAgICAgICAgICBteSBAQm9keSAgICAgICA9IHNwbGl0KCAvXG4vLCAkRGF0YXtCb2R5fSApOwoKICAgICAgICAgICAgICAgIGZvciBteSAkQ291bnRlciAoIDAgLi4gJExpbmUgLSAxICkgewoKICAgICAgICAgICAgICAgICAgICAjIDIwMDItMDYtMTQgcGF0Y2ggb2YgUGFibG8gUnVpeiBHYXJjaWEKICAgICAgICAgICAgICAgICAgICAjIGh0dHA6Ly9saXN0cy5vdG9iby5vcmcvcGlwZXJtYWlsL2Rldi8yMDAyLUp1bmUvMDAwMDEyLmh0bWwKICAgICAgICAgICAgICAgICAgICBpZiAoICQjQm9keSA+PSAkQ291bnRlciApIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICMgYWRkIG5vIHF1b3RlIGNoYXIsIGRvIGl0IGxhdGVyIGJ5IHVzaW5nIERvY3VtZW50Q2xlYW51cCgpCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggJFBhcmFte1JpY2hUZXh0fSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICROZXdPbGRCb2R5IC49ICRCb2R5WyRDb3VudGVyXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgIyBhZGQgIj4gIiBhcyBxdW90ZSBjaGFyCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJE5ld09sZEJvZHkgLj0gIj4gJEJvZHlbJENvdW50ZXJdIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgIyBhZGQgbmV3IGxpbmUKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAkQ291bnRlciA8ICggJExpbmUgLSAxICkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkTmV3T2xkQm9keSAuPSAiXG4iOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRDb3VudGVyKys7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2hvbXAgJE5ld09sZEJvZHk7CgogICAgICAgICAgICAgICAgIyBIVE1MIHF1b3Rpbmcgb2YgY29udGVudAogICAgICAgICAgICAgICAgaWYgKCAkUGFyYW17UmljaFRleHR9ICYmICROZXdPbGRCb2R5ICkgewoKICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSB0cmFpbGluZyBuZXcgbGluZXMKICAgICAgICAgICAgICAgICAgICBmb3IgKCAxIC4uIDEwICkgewogICAgICAgICAgICAgICAgICAgICAgICAkTmV3T2xkQm9keSA9fiBzLyg8YnJcLz4pXHN7MCwyMH0kLy9nczsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICMgYWRkIHF1b3RlCiAgICAgICAgICAgICAgICAgICAgJE5ld09sZEJvZHkgPSAiPGJsb2NrcXVvdGUgdHlwZT1cImNpdGVcIj4kTmV3T2xkQm9keTwvYmxvY2txdW90ZT4iOwogICAgICAgICAgICAgICAgICAgICROZXdPbGRCb2R5ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Eb2N1bWVudENsZWFudXAoCiAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyA9PiAkTmV3T2xkQm9keSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICMgcmVwbGFjZSB0YWcKICAgICAgICAgICAgICAgICRQYXJhbXtUZXh0fQogICAgICAgICAgICAgICAgICAgID1+IHMvJFN0YXJ0KD86KD86JERhdGFUeXBlKEVNQUlMfE5PVEV8Qk9EWSlcWyguKz8pXF18KD86T1RPQk9fQ09NTUVOVChcWyguKz8pXF0pPykpKSRFbmQvJE5ld09sZEJvZHkvOwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIHJlcGxhY2UgPE9UT0JPX0NVU1RPTUVSX1NVQkpFQ1RbXT4gIGFuZCAgPE9UT0JPX0FHRU5UX1NVQkpFQ1RbXT4gdGFncwogICAgICAgICAgICAkVGFnID0gIiRTdGFydCREYXRhVHlwZSIgLiAnU1VCSkVDVCc7CiAgICAgICAgICAgIGlmICggJFBhcmFte1RleHR9ID1+IC8kVGFnXFsoLis/KVxdJEVuZC9nICkgewoKICAgICAgICAgICAgICAgIG15ICRTdWJqZWN0Q2hhciA9ICQxOwogICAgICAgICAgICAgICAgbXkgJFN1YmplY3QgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlRpY2tldCcpLT5UaWNrZXRTdWJqZWN0Q2xlYW4oCiAgICAgICAgICAgICAgICAgICAgVGlja2V0TnVtYmVyID0+ICRUaWNrZXR7VGlja2V0TnVtYmVyfSwKICAgICAgICAgICAgICAgICAgICBTdWJqZWN0ICAgICAgPT4gJERhdGF7U3ViamVjdH0sCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICRTdWJqZWN0ID1+IHMvXigueyRTdWJqZWN0Q2hhcn0pLiokLyQxIFsuLi5dLzsKICAgICAgICAgICAgICAgICRQYXJhbXtUZXh0fSA9fiBzLyRUYWdcWy4rP1xdJEVuZC8kU3ViamVjdC9nOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoICREYXRhVHlwZSBlcSAnT1RPQk9fQ1VTVE9NRVJfJyApIHsKCiAgICAgICAgICAgICAgICAjIEdldCA8T1RPQk9fRU1BSUxfREFURVtdPiBmcm9tIGJvZHkgYW5kIHJlcGxhY2Ugd2l0aCByZWNlaXZlZCBkYXRlLgogICAgICAgICAgICAgICAgIyBUaGlzIHRhZyB3aWxsIGJlIGFibGUgdG8gdXNlIHdpdGggc3VwcG9ydGVkIE9UT0JPIHRpbWUgem9uZXMKICAgICAgICAgICAgICAgICMgICAoIGUuZy4gPE9UT0JPX0VNQUlMX0RBVEVbRXVyb3BlL0Jlcmxpbl0+LCA8T1RPQk9fRU1BSUxfREFURVtBc2lhL1Rva3lvXT4sCiAgICAgICAgICAgICAgICAjICAgPE9UT0JPX0VNQUlMX0RBVEVbQW1lcmljYS9EZW52ZXJdPiAsIC4uLikuCiAgICAgICAgICAgICAgICAjIElmIHlvdSB1c2UgdGFnIHdpdGhvdXQgdGltZSBpbiBzaW1wbGUgZm9ybWF0IGFzIDxPVE9CT19FTUFJTF9EQVRFPiwKICAgICAgICAgICAgICAgICMgIHRpbWUgd2lsbCBiZSB0cmFuc2Zvcm1lZCBpbnRvIE9UT0JPIFN5c3RlbVRpbWVab25lLgogICAgICAgICAgICAgICAgJFRhZyA9ICRTdGFydCAuICdPVE9CT19FTUFJTF9EQVRFJzsKCiAgICAgICAgICAgICAgICBteSAkRGF0ZVRpbWVPYmplY3QgPSAkS2VybmVsOjpPTS0+Q3JlYXRlKCdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnKTsKICAgICAgICAgICAgICAgIG15ICRTeXN0ZW1UaW1lWm9uZSA9ICREYXRlVGltZU9iamVjdC0+T1RPQk9UaW1lWm9uZUdldCgpOwogICAgICAgICAgICAgICAgd2hpbGUgKCAkUGFyYW17VGV4dH0gPX4gLyRUYWdcWyguKz8pXF0kRW5kL2cgKSB7CiAgICAgICAgICAgICAgICAgICAgbXkgJFRpbWVab25lICAgICAgPSAkMTsKICAgICAgICAgICAgICAgICAgICBteSAkVGltZVpvbmVWYWxpZCA9ICREYXRlVGltZU9iamVjdC0+SXNUaW1lWm9uZVZhbGlkKCBUaW1lWm9uZSA9PiAkVGltZVpvbmUgKTsKICAgICAgICAgICAgICAgICAgICBpZiAoJFRpbWVab25lVmFsaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJERhdGVUaW1lT2JqZWN0LT5Ub1RpbWVab25lKCBUaW1lWm9uZSA9PiAkVGltZVpvbmUgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRUaW1lWm9uZSA9ICRTeXN0ZW1UaW1lWm9uZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG15ICRFbWFpbERhdGUgPSAkRGF0ZVRpbWVPYmplY3QtPkZvcm1hdCggRm9ybWF0ID0+ICclQSwgJUIgJWUsICVZIGF0ICVUICcgKTsKICAgICAgICAgICAgICAgICAgICAkRW1haWxEYXRlIC49ICIoJFRpbWVab25lKSI7CiAgICAgICAgICAgICAgICAgICAgJFBhcmFte1RleHR9ID1+IHMvJFRhZ1xbJDFcXSRFbmQvJEVtYWlsRGF0ZS9nOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICggJFBhcmFte1RleHR9ID1+IC8kVGFnJEVuZC9nICkgewogICAgICAgICAgICAgICAgICAgIG15ICRUaW1lWm9uZSA9ICRTeXN0ZW1UaW1lWm9uZTsKICAgICAgICAgICAgICAgICAgICAkRGF0ZVRpbWVPYmplY3QtPlRvVGltZVpvbmUoIFRpbWVab25lID0+ICRUaW1lWm9uZSApOwoKICAgICAgICAgICAgICAgICAgICBteSAkRW1haWxEYXRlID0gJERhdGVUaW1lT2JqZWN0LT5Gb3JtYXQoIEZvcm1hdCA9PiAnJUEsICVCICVlLCAlWSBhdCAlVCAnICk7CiAgICAgICAgICAgICAgICAgICAgJEVtYWlsRGF0ZSAuPSAiKCRUaW1lWm9uZSkiOwogICAgICAgICAgICAgICAgICAgICRQYXJhbXtUZXh0fSA9fiBzLyRUYWckRW5kLyRFbWFpbERhdGUvZzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCAkRGF0YVR5cGUgZXEgJ09UT0JPX0NVU1RPTUVSXycgKSB7CgogICAgICAgICAgICAjIGdldCBhbmQgcHJlcGFyZSByZWFsbmFtZQogICAgICAgICAgICAkVGFnID0gJFN0YXJ0IC4gJ09UT0JPX0NVU1RPTUVSX1JFQUxOQU1FJzsKICAgICAgICAgICAgaWYgKCAkUGFyYW17VGV4dH0gPX4gLyRUYWckRW5kL2kgKSB7CgogICAgICAgICAgICAgICAgbXkgJEZyb207CgogICAgICAgICAgICAgICAgaWYgKCAkVGlja2V0e0N1c3RvbWVyVXNlcklEfSApIHsKCiAgICAgICAgICAgICAgICAgICAgJEZyb20gPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lck5hbWUoCiAgICAgICAgICAgICAgICAgICAgICAgIFVzZXJMb2dpbiA9PiAkVGlja2V0e0N1c3RvbWVyVXNlcklEfQogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyB0cnkgdG8gZ2V0IHRoZSByZWFsIG5hbWUgZGlyZWN0bHkgZnJvbSB0aGUgZGF0YQogICAgICAgICAgICAgICAgJEZyb20gLy89ICRSZWNpcGllbnR7UmVhbG5hbWV9OwoKICAgICAgICAgICAgICAgICMgZ2V0IHJlYWwgbmFtZSBiYXNlZCBvbiByZXBseS10bwogICAgICAgICAgICAgICAgaWYgKCAhJEZyb20gJiYgJERhdGF7UmVwbHlUb30gKSB7CgogICAgICAgICAgICAgICAgICAgICRGcm9tID0gJERhdGF7UmVwbHlUb307CgogICAgICAgICAgICAgICAgICAgICMgcmVtb3ZlIGVtYWlsIGFkZHJlc3NlcwogICAgICAgICAgICAgICAgICAgICRGcm9tID1+IHMvJmx0Oy4qJmd0O3w8Lio+fFwoLipcKXxcInwmcXVvdDt8O3wsLy9nOwoKICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBsZWFkaW5nL3RyYWlsaW5nIHNwYWNlcwogICAgICAgICAgICAgICAgICAgICRGcm9tID1+IHMvXlxzKy8vZzsKICAgICAgICAgICAgICAgICAgICAkRnJvbSA9fiBzL1xzKyQvL2c7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyBnZW5lcmF0ZSByZWFsIG5hbWUgYmFzZWQgb24gc2VuZGVyIGxpbmUKICAgICAgICAgICAgICAgIGlmICggISRGcm9tICkgewogICAgICAgICAgICAgICAgICAgICRGcm9tID0gJERhdGF7VG99IHx8ICcnOwoKICAgICAgICAgICAgICAgICAgICAjIHJlbW92ZSBlbWFpbCBhZGRyZXNzZXMKICAgICAgICAgICAgICAgICAgICAkRnJvbSA9fiBzLyZsdDsuKiZndDt8PC4qPnxcKC4qXCl8XCJ8JnF1b3Q7fDt8LC8vZzsKCiAgICAgICAgICAgICAgICAgICAgIyByZW1vdmUgbGVhZGluZy90cmFpbGluZyBzcGFjZXMKICAgICAgICAgICAgICAgICAgICAkRnJvbSA9fiBzL15ccysvL2c7CiAgICAgICAgICAgICAgICAgICAgJEZyb20gPX4gcy9ccyskLy9nOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICMgcmVwbGFjZSA8T1RPQk9fQ1VTVE9NRVJfUkVBTE5BTUU+IHdpdGggZnJvbQogICAgICAgICAgICAgICAgJFBhcmFte1RleHR9ID1+IHMvJFRhZyRFbmQvJEZyb20vZzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCBjdXN0b21lciBkYXRhIGFuZCByZXBsYWNlIGl0IHdpdGggPE9UT0JPX0NVU1RPTUVSX0RBVEFfLi4uCiAgICAkVGFnICA9ICRTdGFydCAuICdPVE9CT19DVVNUT01FUl8nOwogICAgJFRhZzIgPSAkU3RhcnQgLiAnT1RPQk9fQ1VTVE9NRVJfREFUQV8nOwoKICAgIGlmICggJFRpY2tldHtDdXN0b21lclVzZXJJRH0gfHwgJFBhcmFte0RhdGF9LT57Q3VzdG9tZXJVc2VySUR9ICkgewoKICAgICAgICBteSAkQ3VzdG9tZXJVc2VySUQgPSAkUGFyYW17RGF0YX0tPntDdXN0b21lclVzZXJJRH0gfHwgJFRpY2tldHtDdXN0b21lclVzZXJJRH07CgogICAgICAgIG15ICVDdXN0b21lclVzZXIgPSAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgICAgICBVc2VyID0+ICRDdXN0b21lclVzZXJJRCwKICAgICAgICApOwoKICAgICAgICAjIEhUTUwgcXVvdGluZyBvZiBjb250ZW50CiAgICAgICAgaWYgKCAkUGFyYW17UmljaFRleHR9ICkgewoKICAgICAgICAgICAgQVRUUklCVVRFOgogICAgICAgICAgICBmb3IgbXkgJEF0dHJpYnV0ZSAoIHNvcnQga2V5cyAlQ3VzdG9tZXJVc2VyICkgewogICAgICAgICAgICAgICAgbmV4dCBBVFRSSUJVVEUgaWYgISRDdXN0b21lclVzZXJ7JEF0dHJpYnV0ZX07CiAgICAgICAgICAgICAgICAkQ3VzdG9tZXJVc2VyeyRBdHRyaWJ1dGV9ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkhUTUxVdGlscycpLT5Ub0hUTUwoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nID0+ICRDdXN0b21lclVzZXJ7JEF0dHJpYnV0ZX0sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIHJlcGxhY2UgaXQKICAgICAgICAkSGFzaEdsb2JhbFJlcGxhY2UtPiggIiRUYWd8JFRhZzIiLCAlQ3VzdG9tZXJVc2VyICk7CiAgICB9CgogICAgIyBjbGVhbnVwIGFsbCBub3QgbmVlZGVkIDxPVE9CT19DVVNUT01FUl9EQVRBXyB0YWdzCiAgICAkUGFyYW17VGV4dH0gPX4gcy8oPzokVGFnfCRUYWcyKS4rPyRFbmQvLS9naTsKCiAgICAjIGNsZWFudXAgYWxsIG5vdCBuZWVkZWQgPE9UT0JPX0FHRU5UXyB0YWdzCiAgICAkVGFnID0gJFN0YXJ0IC4gJ09UT0JPX0FHRU5UXyc7CiAgICAkUGFyYW17VGV4dH0gPX4gcy8kVGFnLis/JEVuZC8tL2dpOwoKICAgIHJldHVybiAkUGFyYW17VGV4dH07Cn0KCj1oZWFkMiBfUmVtb3ZlVW5TdXBwb3J0ZWRUYWcoKQoKY2xlYW51cCBhbGwgbm90IHN1cHBvcnRlZCB0YWdzCgogICAgbXkgJFRleHQgPSAkVGVtcGxhdGVHZW5lcmF0b3JPYmplY3QtPl9SZW1vdmVVblN1cHBvcnRlZFRhZygKICAgICAgICBUZXh0ID0+ICRTb21lVGV4dFdpdGhUYWdzLAogICAgICAgIExpc3RPZlVuU3VwcG9ydGVkVGFnID0+IFxATGlzdE9mVW5TdXBwb3J0ZWRUYWcsCiAgICApOwoKPWN1dAoKc3ViIF9SZW1vdmVVblN1cHBvcnRlZFRhZyB7CgogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICRJdGVtIChxdyhUZXh0IExpc3RPZlVuU3VwcG9ydGVkVGFnKSkgewogICAgICAgIGlmICggIWRlZmluZWQgJFBhcmFteyRJdGVtfSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEl0ZW0hIgogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIG15ICRTdGFydCA9ICc8JzsKICAgIG15ICRFbmQgICA9ICc+JzsKICAgIGlmICggJFNlbGYtPntSaWNoVGV4dH0gKSB7CiAgICAgICAgJFN0YXJ0ID0gJyZsdDsnOwogICAgICAgICRFbmQgICA9ICcmZ3Q7JzsKICAgICAgICAkUGFyYW17VGV4dH0gPX4gcy8oXG58XHIpLy9nOwogICAgfQoKICAgICMgQ2xlYW51cCBhbGwgbm90IHN1cHBvcnRlZCB0YWdzIHdpdGggYW5kIHdpdGhvdXQgbnVtYmVyLCBlLmcuIE9UT0JPX0NVU1RPTUVSX0JPRFkgYW5kIE9UT0JPX0NVU1RPTUVSX0JPRFlbbl0uCiAgICAjIFNlZSBodHRwczovL2J1Z3Mub3Rycy5vcmcvc2hvd19idWcuY2dpP2lkPTE0MzY5IGFuZCBodHRwczovL2J1Z3Mub3Rycy5vcmcvc2hvd19idWcuY2dpP2lkPTEwODI1LgogICAgbXkgJE5vdFN1cHBvcnRlZFRhZyA9ICRTdGFydCAuICIoPzoiIC4gam9pbiggInwiLCBAeyAkUGFyYW17TGlzdE9mVW5TdXBwb3J0ZWRUYWd9IH0gKSAuICIpKFxcWy4qP1xcXSk/IiAuICRFbmQ7CiAgICAkUGFyYW17VGV4dH0gPX4gcy8kTm90U3VwcG9ydGVkVGFnLy0vZ2k7CgogICAgcmV0dXJuICRQYXJhbXtUZXh0fTsKCn0KCj1oZWFkMiBfTWFza1NlbnNpdGl2ZVZhbHVlKCkKCk1hc2sgc2Vuc2l0aXZlIHZhbHVlLCBpLmUuIGEgcGFzc3dvcmQsIGEgc2VjdXJpdHkgdG9rZW4sIGV0Yy4KCiAgICBteSAkTWFza2VkVmFsdWUgPSAkU2VsZi0+X01hc2tTZW5zaXRpdmVWYWx1ZSgKICAgICAgICBLZXkgICAgICA9PiAnRGF0YWJhc2VQYXNzd29yZCcsICMgKHJlcXVpcmVkKSBOYW1lIG9mIHRoZSBmaWVsZC9rZXkuCiAgICAgICAgVmFsdWUgICAgPT4gJ3NlY3JldHZhbHVlJywgICAgICAjIChvcHRpb25hbCkgVmFsdWUgdG8gcG90ZW50aWFsbHkgbWFzay4KICAgICAgICBJc0NvbmZpZyA9PiAxLCAgICAgICAgICAgICAgICAgICMgKG9wdGlvbmFsKSBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBhIGNvbmZpZyBvcHRpb24sIGRlZmF1bHQ6IDAuCiAgICApOwoKUmV0dXJucyBtYXNrZWQgdmFsdWUsIGluIGNhc2UgdGhlIGtleSBpcyBtYXRjaGVkOgoKICAgJE1hc2tlZFZhbHVlID0gJ3h4eCc7Cgo9Y3V0CgpzdWIgX01hc2tTZW5zaXRpdmVWYWx1ZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIHJldHVybiAnJyBpZiAhJFBhcmFte0tleX0gfHwgIWRlZmluZWQgJFBhcmFte1ZhbHVlfTsKCiAgICAjIFNraXAgbWFza2luZyBzZW5zaXRpdmUgdmFsdWVzIGZvciBEeW5hbWljIEZpZWxkcy4KICAgIHJldHVybiAkUGFyYW17VmFsdWV9IGlmICRQYXJhbXtLZXl9ID1+IHFyeyBkeW5hbWljZmllbGQgfXhpOwoKICAgICMgTWF0Y2ggZ2VuZXJhbCBrZXkgbmFtZXMsIGkuZS4gZnJvbSB0aGUgdXNlciBwcmVmZXJlbmNlcy4KICAgIG15ICRNYXRjaCA9IHFyeyBjb25maWd8c2VjcmV0fHBhc3N3fHVzZXJwd3xhdXRofHRva2VuIH14aTsKCiAgICAjIE1hdGNoIGZvcmJpZGRlbiBjb25maWcga2V5cy4KICAgIGlmICggJFBhcmFte0lzQ29uZmlnfSApIHsKICAgICAgICAkTWF0Y2ggPSBxcnsgKD86cGFzc3dvcmR8cHcpIFxkKiAkIH1zbXhpOwogICAgfQoKICAgIHJldHVybiAkUGFyYW17VmFsdWV9IGlmICRQYXJhbXtLZXl9ICF+ICRNYXRjaDsKCiAgICByZXR1cm4gJ3h4eCc7Cn0KCj1lbmQgSW50ZXJuYWw6Cgo9Y3V0CgoxOwo=
IyAtLQojIE9UT0JPIGlzIGEgd2ViLWJhc2VkIHRpY2tldGluZyBzeXN0ZW0gZm9yIHNlcnZpY2Ugb3JnYW5pc2F0aW9ucy4KIyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIwIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDE5LTIwMjEgUm90aGVyIE9TUyBHbWJILCBodHRwczovL290b2JvLmRlLwojIC0tCiMgJG9yaWdpbjogb3RvYm8gLSBiMDQwYzc5OTI2MzI4OGE0Mjk1NGUyOWFiYjU5ODE2NGZjYWUyNDg0IC0gS2VybmVsL1N5c3RlbS9XZWIvSW50ZXJmYWNlQ3VzdG9tZXIucG0KIyAtLQojIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyCiMgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKIyBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgojIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVAojIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTCiMgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiMgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKIyBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gSWYgbm90LCBzZWUgPGh0dHBzOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6V2ViOjpJbnRlcmZhY2VDdXN0b21lcjsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCiMgY29yZSBtb2R1bGVzCgojIENQQU4gbW9kdWxlcwoKIyBPVE9CTyBtb2R1bGVzCnVzZSBLZXJuZWw6OlN5c3RlbTo6RW1haWw7CnVzZSBLZXJuZWw6OlN5c3RlbTo6VmFyaWFibGVDaGVjayBxdyhJc0FycmF5UmVmV2l0aERhdGEgSXNIYXNoUmVmV2l0aERhdGEpOwp1c2UgS2VybmVsOjpMYW5ndWFnZSBxdyhUcmFuc2xhdGFibGUpOwp1c2UgS2VybmVsOjpTeXN0ZW06OkRhdGVUaW1lOwoKb3VyIEBPYmplY3REZXBlbmRlbmNpZXMgPSAoCiAgICAnS2VybmVsOjpDb25maWcnLAogICAgJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpBdXRoU2Vzc2lvbicsCiAgICAnS2VybmVsOjpTeXN0ZW06OkNhY2hlJywKICAgICdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJBdXRoJywKICAgICdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJHcm91cCcsCiAgICAnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicsCiAgICAnS2VybmVsOjpTeXN0ZW06OkRCJywKICAgICdLZXJuZWw6OlN5c3RlbTo6R3JvdXAnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpMb2cnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpNYWluJywKICAgICdLZXJuZWw6OlN5c3RlbTo6U2NoZWR1bGVyJywKICAgICdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpXZWI6OlJlcXVlc3QnLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpWYWxpZCcsCik7Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OldlYjo6SW50ZXJmYWNlQ3VzdG9tZXIgLSB0aGUgY3VzdG9tZXIgd2ViIGludGVyZmFjZQoKPWhlYWQxIERFU0NSSVBUSU9OCgp0aGUgZ2xvYmFsIGN1c3RvbWVyIHdlYiBpbnRlcmZhY2UgKGF1dGhlbnRpY2F0aW9uLCBzZXNzaW9uIGhhbmRsaW5nLCAuLi4pCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPWhlYWQyIG5ldygpCgpjcmVhdGUgY3VzdG9tZXIgd2ViIGludGVyZmFjZSBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OldlYjo6SW50ZXJmYWNlQ3VzdG9tZXI7CgogICAgbXkgJERlYnVnID0gMDsKICAgIG15ICRJbnRlcmZhY2VDdXN0b21lciA9IEtlcm5lbDo6U3lzdGVtOjpXZWI6OkludGVyZmFjZUN1c3RvbWVyLT5uZXcoCiAgICAgICAgRGVidWcgICAgICA9PiAkRGVidWcsCiAgICAgICAgV2ViUmVxdWVzdCA9PiBDR0k6OlBTR0ktPm5ldygkZW52KSwgIyBvcHRpb25hbCwgZS4gZy4gaWYgUFNHSSBpcyB1c2VkCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgc3RhcnQgd2l0aCBhbiBlbXB0eSBoYXNoIGZvciB0aGUgbmV3IG9iamVjdAogICAgbXkgJFNlbGYgPSBibGVzcyB7fSwgJFR5cGU7CgogICAgIyBnZXQgZGVidWcgbGV2ZWwKICAgICRTZWxmLT57RGVidWd9ID0gJFBhcmFte0RlYnVnfSB8fCAwOwoKICAgICMgcGVyZm9ybWFuY2UgbG9nCiAgICAkU2VsZi0+e1BlcmZvcm1hbmNlTG9nU3RhcnR9ID0gdGltZSgpOwoKICAgICMgcmVnaXN0ZXIgb2JqZWN0IHBhcmFtcwogICAgJEtlcm5lbDo6T00tPk9iamVjdFBhcmFtQWRkKAogICAgICAgICdLZXJuZWw6OlN5c3RlbTo6TG9nJyA9PiB7CiAgICAgICAgICAgIExvZ1ByZWZpeCA9PiAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpLT5HZXQoJ0NHSUxvZ1ByZWZpeCcpLAogICAgICAgIH0sCiAgICAgICAgJ0tlcm5lbDo6U3lzdGVtOjpXZWI6OlJlcXVlc3QnID0+IHsKICAgICAgICAgICAgV2ViUmVxdWVzdCA9PiAkUGFyYW17V2ViUmVxdWVzdH0gfHwgMCwKICAgICAgICB9LAogICAgKTsKCiAgICAjIGRlYnVnIGluZm8KICAgIGlmICggJFNlbGYtPntEZWJ1Z30gKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdkZWJ1ZycsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdHbG9iYWwgaGFuZGxlIHN0YXJ0ZWQuLi4nLAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aGVhZDIgUnVuKCkKCmV4ZWN1dGUgdGhlIG9iamVjdAoKICAgICRJbnRlcmZhY2VDdXN0b21lci0+UnVuKCk7Cgo9Y3V0CgpzdWIgUnVuIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgbXkgJENvbmZpZ09iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyk7CgogICAgbXkgJFF1ZXJ5U3RyaW5nID0gJEVOVntRVUVSWV9TVFJJTkd9IHx8ICcnOwoKICAgICMgQ2hlY2sgaWYgaHR0cHMgZm9yY2luZyBpcyBhY3RpdmUsIGFuZCByZWRpcmVjdCBpZiBuZWVkZWQuCiAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgnSFRUUFNGb3JjZVJlZGlyZWN0JykgKSB7CgogICAgICAgICMgU29tZSB3ZWIgc2VydmVycyBkbyBub3Qgc2V0IEhUVFBTIGVudmlyb25tZW50IHZhcmlhYmxlLCBzbyBpdCdzIG5vdCBwb3NzaWJsZSB0byBlYXNpbHkga25vdyBpZiB3ZSBhcmUgdXNpbmcKICAgICAgICAjICAgaHR0cHMgcHJvdG9jb2wuIExvb2sgYWxzbyBmb3Igc2ltaWxhcmx5IG5hbWVkIGtleXMgaW4gZW52aXJvbm1lbnQgaGFzaCwgc2luY2UgdGhpcyBzaG91bGQgcHJldmVudCBsb29wcyBpbgogICAgICAgICMgICBjZXJ0YWluIGNhc2VzLgogICAgICAgIGlmICgKICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgIWRlZmluZWQgJEVOVntIVFRQU30KICAgICAgICAgICAgICAgICYmICFncmVwIHsvXkhUVFBTKD86X3wkKS99IGtleXMgJUVOVgogICAgICAgICAgICApCiAgICAgICAgICAgIHx8ICRFTlZ7SFRUUFN9IG5lICdvbicKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgbXkgJEhvc3QgPSAkRU5We0hUVFBfSE9TVH0gfHwgJENvbmZpZ09iamVjdC0+R2V0KCdGUUROJyk7CgogICAgICAgICAgICAjIFJlZGlyZWN0IHdpdGggMzAxIGNvZGUuIEFkZCB0d28gbmV3IGxpbmVzIGF0IHRoZSBlbmQsIHNvIEhUVFAgaGVhZGVycyBhcmUgdmFsaWRhdGVkIGNvcnJlY3RseS4KICAgICAgICAgICAgcHJpbnQgIlN0YXR1czogMzAxIE1vdmVkIFBlcm1hbmVudGx5XG5Mb2NhdGlvbjogaHR0cHM6Ly8kSG9zdCRFTlZ7UkVRVUVTVF9VUkl9XG5cbiI7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgbXkgJFBhcmFtT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OldlYjo6UmVxdWVzdCcpOwoKICAgIG15ICVQYXJhbTsKCiAgICAjIGdldCBzZXNzaW9uIGlkCiAgICAkUGFyYW17U2Vzc2lvbk5hbWV9ID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsU2Vzc2lvbk5hbWUnKSAgICAgICAgIHx8ICdDU0lEJzsKICAgICRQYXJhbXtTZXNzaW9uSUR9ICAgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAkUGFyYW17U2Vzc2lvbk5hbWV9ICkgfHwgJyc7CgogICAgIyBkcm9wIG9sZCBzZXNzaW9uIGlkIChpZiBleGlzdHMpCiAgICAkUXVlcnlTdHJpbmcgPX4gcy8oXD98Jnw7fCkkUGFyYW17U2Vzc2lvbk5hbWV9KD0mfD07fD0uKz8mfD0uKz8kKS87L2c7CgogICAgIyBkZWZpbmUgZnJhbWV3b3JrIHBhcmFtcwogICAgbXkgJEZyYW1ld29ya1BhcmFtcyA9IHsKICAgICAgICBMYW5nICAgICAgICAgPT4gJycsCiAgICAgICAgQWN0aW9uICAgICAgID0+ICcnLAogICAgICAgIFN1YmFjdGlvbiAgICA9PiAnJywKICAgICAgICBSZXF1ZXN0ZWRVUkwgPT4gJFF1ZXJ5U3RyaW5nLAogICAgfTsKICAgIGZvciBteSAkS2V5ICggc29ydCBrZXlzICV7JEZyYW1ld29ya1BhcmFtc30gKSB7CiAgICAgICAgJFBhcmFteyRLZXl9ID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJEtleSApCiAgICAgICAgICAgIHx8ICRGcmFtZXdvcmtQYXJhbXMtPnskS2V5fTsKICAgIH0KCiAgICAjIHZhbGlkYXRlIGxhbmd1YWdlCiAgICBpZiAoICRQYXJhbXtMYW5nfSAmJiAkUGFyYW17TGFuZ30gIX4gbXtcQVthLXpdezJ9KD86X1tBLVpdezJ9KT9cen14bXMgKSB7CiAgICAgICAgZGVsZXRlICRQYXJhbXtMYW5nfTsKICAgIH0KCiAgICAjIENoZWNrIGlmIHRoZSBicm93c2VyIHNlbmRzIHRoZSBTZXNzaW9uSUQgY29va2llIGFuZCBzZXQgdGhlIFNlc3Npb25JRC1jb29raWUKICAgICMgYXMgU2Vzc2lvbklEISBHRVQgb3IgUE9TVCBTZXNzaW9uSUQgaGF2ZSB0aGUgbG93ZXN0IHByaW9yaXR5LgogICAgaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoJ1Nlc3Npb25Vc2VDb29raWUnKSApIHsKICAgICAgICAkUGFyYW17U2Vzc2lvbklEQ29va2llfSA9ICRQYXJhbU9iamVjdC0+R2V0Q29va2llKCBLZXkgPT4gJFBhcmFte1Nlc3Npb25OYW1lfSApOwogICAgICAgIGlmICggJFBhcmFte1Nlc3Npb25JRENvb2tpZX0gKSB7CiAgICAgICAgICAgICRQYXJhbXtTZXNzaW9uSUR9ID0gJFBhcmFte1Nlc3Npb25JRENvb2tpZX07CiAgICAgICAgfQogICAgfQoKICAgICRLZXJuZWw6Ok9NLT5PYmplY3RQYXJhbUFkZCgKICAgICAgICAnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcgPT4gewogICAgICAgICAgICBMYW5nID0+ICRQYXJhbXtMYW5nfSwKICAgICAgICB9LAogICAgICAgICdLZXJuZWw6Okxhbmd1YWdlJyA9PiB7CiAgICAgICAgICAgIFVzZXJMYW5ndWFnZSA9PiAkUGFyYW17TGFuZ30KICAgICAgICB9LAogICAgKTsKCiAgICAjIFJlc3RyaWN0IENvb2tpZSB0byBIVFRQUyBpZiBpdCBpcyB1c2VkLgogICAgbXkgJENvb2tpZVNlY3VyZUF0dHJpYnV0ZSA9ICRDb25maWdPYmplY3QtPkdldCgnSHR0cFR5cGUnKSBlcSAnaHR0cHMnID8gMSA6IHVuZGVmOwoKICAgICMgY2hlY2sgd2hldGhlciB3ZSBhcmUgdXNpbmcgdGhlIHJpZ2h0IHNjaGVtZQogICAgaWYgKCAkRU5We1JFUVVFU1RfU0NIRU1FfSAmJiBsYyggJEVOVntSRVFVRVNUX1NDSEVNRX0gKSBuZSAkQ29uZmlnT2JqZWN0LT5HZXQoJ0h0dHBUeXBlJykgKSB7CiAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdub3RpY2UnLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnSHR0cFR5cGUgJwogICAgICAgICAgICAgICAgLiAkQ29uZmlnT2JqZWN0LT5HZXQoJ0h0dHBUeXBlJykKICAgICAgICAgICAgICAgIC4gJyBpcyBzZXQsIGJ1dCAnCiAgICAgICAgICAgICAgICAuICRFTlZ7UkVRVUVTVF9TQ0hFTUV9CiAgICAgICAgICAgICAgICAuICcgaXMgdXNlZCEnLAogICAgICAgICk7CiAgICB9CgogICAgbXkgJERCQ2FuQ29ubmVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEQicpLT5Db25uZWN0KCk7CgogICAgaWYgKCAhJERCQ2FuQ29ubmVjdCB8fCAkUGFyYW1PYmplY3QtPkVycm9yKCkgKSB7CiAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKICAgICAgICBpZiAoICEkREJDYW5Db25uZWN0ICkgewogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5DdXN0b21lckZhdGFsRXJyb3IoCiAgICAgICAgICAgICAgICBDb21tZW50ID0+IFRyYW5zbGF0YWJsZSgnUGxlYXNlIGNvbnRhY3QgdGhlIGFkbWluaXN0cmF0b3IuJyksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKCAkUGFyYW1PYmplY3QtPkVycm9yKCkgKSB7CiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkN1c3RvbWVyRmF0YWxFcnJvcigKICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gJFBhcmFtT2JqZWN0LT5FcnJvcigpLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiBUcmFuc2xhdGFibGUoJ1BsZWFzZSBjb250YWN0IHRoZSBhZG1pbmlzdHJhdG9yLicpLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZ2V0IGNvbW1vbiBhcHBsaWNhdGlvbiBhbmQgYWRkIG9uIGFwcGxpY2F0aW9uIHBhcmFtcwogICAgbXkgJUNvbW1vbk9iamVjdFBhcmFtID0gJXsgJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lckZyb250ZW5kOjpDb21tb25QYXJhbScpIH07CiAgICBmb3IgbXkgJEtleSAoIHNvcnQga2V5cyAlQ29tbW9uT2JqZWN0UGFyYW0gKSB7CiAgICAgICAgJFBhcmFteyRLZXl9ID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJEtleSApIHx8ICRDb21tb25PYmplY3RQYXJhbXskS2V5fTsKICAgIH0KCiAgICAjIHNlY3VyaXR5IGNoZWNrIEFjdGlvbiBQYXJhbSAocmVwbGFjZSBub24td29yZCBjaGFycykKICAgICRQYXJhbXtBY3Rpb259ID1+IHMvXFcvL2c7CgogICAgbXkgJFNlc3Npb25PYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6QXV0aFNlc3Npb24nKTsKICAgIG15ICRVc2VyT2JqZWN0ICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicpOwoKICAgICMgY2hlY2sgcmVxdWVzdCB0eXBlCiAgICBpZiAoICRQYXJhbXtBY3Rpb259IGVxICdQcmVMb2dpbicgKSB7CiAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKCiAgICAgICAgIyBsb2dpbiBzY3JlZW4KICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgT3V0cHV0ID0+IFwkTGF5b3V0T2JqZWN0LT5DdXN0b21lckxvZ2luKAogICAgICAgICAgICAgICAgVGl0bGUgPT4gJ0xvZ2luJywKICAgICAgICAgICAgICAgIE1vZGUgID0+ICdQcmVMb2dpbicsCiAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICksCiAgICAgICAgKTsKCiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZWxzaWYgKCAkUGFyYW17QWN0aW9ufSBlcSAnTG9naW4nICkgewogICAgICAgIG15ICRVc2VyOwogICAgICAgIG15ICRBdXRoT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQXV0aCcpOwoKICAgICAgICAjIGdldCBwYXJhbXMKICAgICAgICBteSAkUG9zdFVzZXIgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnVXNlcicgKSB8fCAnJzsKCiAgICAgICAgbXkgJFByZXZlbnRCcnV0ZUZvcmNlQ29uZmlnID0gJENvbmZpZ09iamVjdC0+R2V0KCdTaW1wbGVCcnV0ZUZvcmNlUHJvdGVjdGlvbjo6R2VuZXJhbFNldHRpbmdzJyk7CgogICAgICAgICMgaWYgc2ltcGxlYnJ1dGVmb3JjZWNvbmZpZyBpcyB2YWxpZAojIFJvdGhlciBPU1MgLyBPbmVUaW1lQXV0aGVudGljYXRpb25MaW5rCiMgICAgICAgIGlmICgkUHJldmVudEJydXRlRm9yY2VDb25maWcpIHsKICAgICAgICBpZiAoICRQb3N0VXNlciAmJiAkUHJldmVudEJydXRlRm9yY2VDb25maWcgKSB7CiMgRU8gT25lVGltZUF1dGhlbnRpY2F0aW9uTGluawoKICAgICAgICAgICAgIyBjaGVjayBpZiB0aGUgbG9naW4gaXMgYmFubmVkCiAgICAgICAgICAgIG15ICRDYWNoZU9iamVjdCAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkNhY2hlJyk7CiAgICAgICAgICAgIG15ICRDaGVja0hhc2hVc2VyID0gJENhY2hlT2JqZWN0LT5HZXQoCiAgICAgICAgICAgICAgICBUeXBlID0+ICdCYW5uZWRMb2dpbnNDdXN0b21lcicsCiAgICAgICAgICAgICAgICBLZXkgID0+ICRQb3N0VXNlciwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICMgY2hlY2sgaWYgQ2FjaGUgQ2hlY2tIYXNoVXNlciBleGlzdHMKICAgICAgICAgICAgaWYgKCRDaGVja0hhc2hVc2VyKSB7CiAgICAgICAgICAgICAgICBteSAlQmFuU3RhdHVzID0gJFNlbGYtPl9DaGVja0FuZFJlbW92ZUZyb21CYW5uZWRMaXN0KAogICAgICAgICAgICAgICAgICAgIFBvc3RVc2VyICAgICAgICAgICAgICAgID0+ICRQb3N0VXNlciwKICAgICAgICAgICAgICAgICAgICBQcmV2ZW50QnJ1dGVGb3JjZUNvbmZpZyA9PiAkUHJldmVudEJydXRlRm9yY2VDb25maWcsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGlmICggJEJhblN0YXR1c3tCYW5uZWR9ICkgewoKICAgICAgICAgICAgICAgICAgICAjIG91dHB1dCBlcnJvciBtZXNzYWdlCiAgICAgICAgICAgICAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgICAgICAgICAgICAgT3V0cHV0ID0+IFwkTGF5b3V0T2JqZWN0LT5DdXN0b21lckxvZ2luKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVGl0bGUgICA9PiAnTG9naW4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSA9PiAkTGF5b3V0T2JqZWN0LT57TGFuZ3VhZ2VPYmplY3R9LT5UcmFuc2xhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1RvbyBtYW55IGZhaWxlZCBsb2dpbiBhdHRlbXB0cywgcGxlYXNlIHJldHJ5IGluICVzIHMuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkQmFuU3RhdHVze1Jlc2lkdWFsVGltZX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dpbkZhaWxlZCA9PiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZVR5cGUgPT4gJ0Vycm9yJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXIgICAgICAgID0+ICRQb3N0VXNlciwKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgbXkgJFBvc3RQdyA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oCiAgICAgICAgICAgIFBhcmFtID0+ICdQYXNzd29yZCcsCiAgICAgICAgICAgIFJhdyAgID0+IDEKICAgICAgICApIHx8ICcnOwogICAgICAgIG15ICRQb3N0VHdvRmFjdG9yVG9rZW4gPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKAogICAgICAgICAgICBQYXJhbSA9PiAnVHdvRmFjdG9yVG9rZW4nLAogICAgICAgICAgICBSYXcgICA9PiAxCiAgICAgICAgKSB8fCAnJzsKCiMgUm90aGVyIE9TUyAvIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKICAgICAgICBteSAlRXh0ZW5kZWRBdXRoUGFyYW1zOwogICAgICAgIGZvciBteSAkTmFtZSAoICRBdXRoT2JqZWN0LT5FeHRlbmRlZFBhcmFtTmFtZXMoKSApIHsKICAgICAgICAgICAgJEV4dGVuZGVkQXV0aFBhcmFtc3skTmFtZX0gPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKAogICAgICAgICAgICAgICAgUGFyYW0gPT4gJE5hbWUsCiAgICAgICAgICAgICAgICBSYXcgICA9PiAxCiAgICAgICAgICAgICkgfHwgJyc7CiAgICAgICAgfQojIEVPIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKCiAgICAgICAgIyBjaGVjayBzdWJtaXR0ZWQgZGF0YQogICAgICAgICRVc2VyID0gJEF1dGhPYmplY3QtPkF1dGgoCiAgICAgICAgICAgIFVzZXIgICAgICAgICAgID0+ICRQb3N0VXNlciwKICAgICAgICAgICAgUHcgICAgICAgICAgICAgPT4gJFBvc3RQdywKICAgICAgICAgICAgVHdvRmFjdG9yVG9rZW4gPT4gJFBvc3RUd29GYWN0b3JUb2tlbiwKIyBSb3RoZXIgT1NTIC8gT25lVGltZUF1dGhlbnRpY2F0aW9uTGluawogICAgICAgICAgICAlRXh0ZW5kZWRBdXRoUGFyYW1zLAojIEVPIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKICAgICAgICApOwoKICAgICAgICBteSAkRXhwaXJlcyA9ICcrJyAuICRDb25maWdPYmplY3QtPkdldCgnU2Vzc2lvbk1heFRpbWUnKSAuICdzJzsKICAgICAgICBpZiAoICEkQ29uZmlnT2JqZWN0LT5HZXQoJ1Nlc3Npb25Vc2VDb29raWVBZnRlckJyb3dzZXJDbG9zZScpICkgewogICAgICAgICAgICAkRXhwaXJlcyA9ICcnOwogICAgICAgIH0KCiAgICAgICAgIyBsb2dpbiBpcyBpbnZhbGlkCiAgICAgICAgaWYgKCAhJFVzZXIgKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5PYmplY3RQYXJhbUFkZCgKICAgICAgICAgICAgICAgICdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0JyA9PiB7CiAgICAgICAgICAgICAgICAgICAgU2V0Q29va2llcyA9PiB7CgogICAgICAgICAgICAgICAgICAgICAgICAjIHNldCBhIGNvb2tpZSB0ZW50YXRpdmVseSBmb3IgY2hlY2tpbmcgY29va2llIHN1cHBvcnQKICAgICAgICAgICAgICAgICAgICAgICAgT1RPQk9Ccm93c2VySGFzQ29va2llID0+ICRQYXJhbU9iamVjdC0+U2V0Q29va2llKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgS2V5ICAgICAgPT4gJ09UT0JPQnJvd3Nlckhhc0Nvb2tpZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSAgICA9PiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwaXJlcyAgPT4gJEV4cGlyZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXRoICAgICA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ1NjcmlwdEFsaWFzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWN1cmUgICA9PiAkQ29va2llU2VjdXJlQXR0cmlidXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSFRUUE9ubHkgPT4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApOwoKICAgICAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKCiAgICAgICAgICAgICMgcmVkaXJlY3QgdG8gYWx0ZXJuYXRlIGxvZ2luCiAgICAgICAgICAgIGlmICggJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsTG9naW5VUkwnKSApIHsKICAgICAgICAgICAgICAgICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ID0gJExheW91dE9iamVjdC0+TGlua0VuY29kZSggJFBhcmFte1JlcXVlc3RlZFVSTH0gKTsKICAgICAgICAgICAgICAgIHByaW50ICRMYXlvdXRPYmplY3QtPlJlZGlyZWN0KAogICAgICAgICAgICAgICAgICAgIEV4dFVSTCA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxMb2dpblVSTCcpCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIj9SZWFzb249TG9naW5GYWlsZWQ7UmVxdWVzdGVkVVJMPSRQYXJhbXtSZXF1ZXN0ZWRVUkx9IiwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiMgUm90aGVyIE9TUyAvIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKIyAgICAgICAgICAgIGlmICgkUHJldmVudEJydXRlRm9yY2VDb25maWcpIHsKICAgICAgICAgICAgaWYgKCAkUG9zdFVzZXIgJiYgJFByZXZlbnRCcnV0ZUZvcmNlQ29uZmlnICkgewojIEVPIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKCiAgICAgICAgICAgICAgICAjIHByZXZlbnQgYnJ1dGUgZm9yY2UKICAgICAgICAgICAgICAgIG15ICRCYW5uZWQgPSAkU2VsZi0+X1N0b3JlRmFpbGVkTG9naW5zKAogICAgICAgICAgICAgICAgICAgIFBvc3RVc2VyICAgICAgICAgICAgICAgID0+ICRQb3N0VXNlciwKICAgICAgICAgICAgICAgICAgICBQcmV2ZW50QnJ1dGVGb3JjZUNvbmZpZyA9PiAkUHJldmVudEJydXRlRm9yY2VDb25maWcsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGlmICgkQmFubmVkKSB7CiAgICAgICAgICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgICAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpdGxlICAgPT4gJ0xvZ2luJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUb28gbWFueSBmYWlsZWQgbG9naW4gYXR0ZW1wdHMsIHBsZWFzZSByZXRyeSBpbiAlcyBzLicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJFByZXZlbnRCcnV0ZUZvcmNlQ29uZmlnLT57QmFuRHVyYXRpb259CiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9naW5GYWlsZWQgPT4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VUeXBlID0+ICdFcnJvcicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBVc2VyICAgICAgICA9PiAkUG9zdFVzZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAjIHNob3cgbm9ybWFsIGxvZ2luCiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPlByaW50KAogICAgICAgICAgICAgICAgT3V0cHV0ID0+IFwkTGF5b3V0T2JqZWN0LT5DdXN0b21lckxvZ2luKAogICAgICAgICAgICAgICAgICAgIFRpdGxlICAgPT4gJ0xvZ2luJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlID0+ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+R2V0TG9nRW50cnkoCiAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgPT4gJ0luZm8nLAogICAgICAgICAgICAgICAgICAgICAgICBXaGF0ID0+ICdNZXNzYWdlJywKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICB8fCAkQXV0aE9iamVjdC0+R2V0TGFzdEVycm9yTWVzc2FnZSgpCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IFRyYW5zbGF0YWJsZSgnTG9naW4gZmFpbGVkISBZb3VyIHVzZXIgbmFtZSBvciBwYXNzd29yZCB3YXMgZW50ZXJlZCBpbmNvcnJlY3RseS4nKSwKICAgICAgICAgICAgICAgICAgICBVc2VyICAgICAgICA9PiAkUG9zdFVzZXIsCiAgICAgICAgICAgICAgICAgICAgTG9naW5GYWlsZWQgPT4gMSwKICAgICAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIGxvZ2luIGlzIHN1Y2Nlc3NmdWwKICAgICAgICBteSAlVXNlckRhdGEgPSAkVXNlck9iamVjdC0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICAgICAgVXNlciAgPT4gJFVzZXIsCiAgICAgICAgICAgIFZhbGlkID0+IDEKICAgICAgICApOwoKICAgICAgICAjIGNoZWNrIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIGNvb2tpZXMKICAgICAgICBpZiAoICRQYXJhbU9iamVjdC0+R2V0Q29va2llKCBLZXkgPT4gJ09UT0JPQnJvd3Nlckhhc0Nvb2tpZScgKSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPk9iamVjdFBhcmFtQWRkKAogICAgICAgICAgICAgICAgJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnID0+IHsKICAgICAgICAgICAgICAgICAgICBCcm93c2VySGFzQ29va2llID0+IDEsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyBjaGVjayBuZWVkZWQgZGF0YQogICAgICAgIGlmICggISRVc2VyRGF0YXtVc2VySUR9IHx8ICEkVXNlckRhdGF7VXNlckxvZ2lufSApIHsKCiAgICAgICAgICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CgogICAgICAgICAgICAjIHJlZGlyZWN0IHRvIGFsdGVybmF0ZSBsb2dpbgogICAgICAgICAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbExvZ2luVVJMJykgKSB7CiAgICAgICAgICAgICAgICBwcmludCAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCgKICAgICAgICAgICAgICAgICAgICBFeHRVUkwgPT4gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsTG9naW5VUkwnKQogICAgICAgICAgICAgICAgICAgICAgICAuICc/UmVhc29uPVN5c3RlbUVycm9yJywKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgc2hvdyBuZWVkIHVzZXIgZGF0YSBlcnJvciBtZXNzYWdlCiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPlByaW50KAogICAgICAgICAgICAgICAgT3V0cHV0ID0+IFwkTGF5b3V0T2JqZWN0LT5DdXN0b21lckxvZ2luKAogICAgICAgICAgICAgICAgICAgIFRpdGxlICAgPT4gJ0Vycm9yJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlID0+IFRyYW5zbGF0YWJsZSgKICAgICAgICAgICAgICAgICAgICAgICAgJ0F1dGhlbnRpY2F0aW9uIHN1Y2NlZWRlZCwgYnV0IG5vIGN1c3RvbWVyIHJlY29yZCBpcyBmb3VuZCBpbiB0aGUgY3VzdG9tZXIgYmFja2VuZC4gUGxlYXNlIGNvbnRhY3QgdGhlIGFkbWluaXN0cmF0b3IuJwogICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgIyBjcmVhdGUgZGF0ZXRpbWUgb2JqZWN0CiAgICAgICAgbXkgJFNlc3Npb25EVE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpOwoKICAgICAgICAjIFJlbW92ZSBjZXJ0YWluIHVzZXIgYXR0cmlidXRlcyB0aGF0IGFyZSBub3QgbmVlZGVkIHRvIGJlIHN0b3JlZCBpbiB0aGUgc2Vzc2lvbi4KICAgICAgICAjICAgLSBTTUlNRSBDZXJ0aWZpY2F0ZSBjb3VsZCBiZSBpbiBiaW5hcnkgZm9ybWF0LCBpZiBzZXNzaW9uIGJhY2tlbmQgaW4gREIgKGRlZmF1bHQpCiAgICAgICAgIyAgIGl0IHdvbnQgYmUgcG9zc2libGUgdG8gYmUgc2F2ZWQgaW4gY2VydGFpbiBkYXRhYmFzZXMgKHNlZSBidWcjMTQ0MDUpLgogICAgICAgIG15ICVVc2VyU2Vzc2lvbkRhdGEgPSAlVXNlckRhdGE7CiAgICAgICAgZGVsZXRlICRVc2VyU2Vzc2lvbkRhdGF7VXNlclNNSU1FQ2VydGlmaWNhdGV9OwoKICAgICAgICAjIGNyZWF0ZSBuZXcgc2Vzc2lvbiBpZAogICAgICAgIG15ICROZXdTZXNzaW9uSUQgPSAkU2Vzc2lvbk9iamVjdC0+Q3JlYXRlU2Vzc2lvbklEKAogICAgICAgICAgICAlVXNlclNlc3Npb25EYXRhLAogICAgICAgICAgICBVc2VyTGFzdFJlcXVlc3QgPT4gJFNlc3Npb25EVE9iamVjdC0+VG9FcG9jaCgpLAogICAgICAgICAgICBVc2VyVHlwZSAgICAgICAgPT4gJ0N1c3RvbWVyJywKICAgICAgICAgICAgU2Vzc2lvblNvdXJjZSAgID0+ICdDdXN0b21lckludGVyZmFjZScsCiAgICAgICAgKTsKCiAgICAgICAgIyBzaG93IGVycm9yIG1lc3NhZ2UgaWYgbm8gc2Vzc2lvbiBpZCBoYXMgYmVlbiBjcmVhdGVkCiAgICAgICAgaWYgKCAhJE5ld1Nlc3Npb25JRCApIHsKCiAgICAgICAgICAgICMgZ2V0IGVycm9yIG1lc3NhZ2UKICAgICAgICAgICAgbXkgJEVycm9yID0gJFNlc3Npb25PYmplY3QtPlNlc3Npb25JREVycm9yTWVzc2FnZSgpIHx8ICcnOwoKICAgICAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKCiAgICAgICAgICAgICMgb3V0cHV0IGVycm9yIG1lc3NhZ2UKICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgICAgICBPdXRwdXQgPT4gXCRMYXlvdXRPYmplY3QtPkN1c3RvbWVyTG9naW4oCiAgICAgICAgICAgICAgICAgICAgVGl0bGUgICA9PiAnTG9naW4nLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gJEVycm9yLAogICAgICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgZXhlY3V0aW9uIGluIDIwIHNlY29uZHMKICAgICAgICBteSAkRXhlY3V0aW9uVGltZU9iaiA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpOwogICAgICAgICRFeGVjdXRpb25UaW1lT2JqLT5BZGQoIFNlY29uZHMgPT4gMjAgKTsKCiAgICAgICAgIyBhZGQgYSBhc3luY2hyb25vdXMgZXhlY3V0b3Igc2NoZWR1bGVyIHRhc2sgdG8gY291bnQgdGhlIGNvbmN1cnJlbnQgdXNlcgogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpTY2hlZHVsZXInKS0+VGFza0FkZCgKICAgICAgICAgICAgRXhlY3V0aW9uVGltZSAgICAgICAgICAgID0+ICRFeGVjdXRpb25UaW1lT2JqLT5Ub1N0cmluZygpLAogICAgICAgICAgICBUeXBlICAgICAgICAgICAgICAgICAgICAgPT4gJ0FzeW5jaHJvbm91c0V4ZWN1dG9yJywKICAgICAgICAgICAgTmFtZSAgICAgICAgICAgICAgICAgICAgID0+ICdQbHVnaW5Bc3luY2hyb25vdXM6OkNvbmN1cnJlbnRVc2VyJywKICAgICAgICAgICAgTWF4aW11bVBhcmFsbGVsSW5zdGFuY2VzID0+IDEsCiAgICAgICAgICAgIERhdGEgICAgICAgICAgICAgICAgICAgICA9PiB7CiAgICAgICAgICAgICAgICBPYmplY3QgICA9PiAnS2VybmVsOjpTeXN0ZW06OlN1cHBvcnREYXRhQ29sbGVjdG9yOjpQbHVnaW5Bc3luY2hyb25vdXM6Ok9UT0JPOjpDb25jdXJyZW50VXNlcnMnLAogICAgICAgICAgICAgICAgRnVuY3Rpb24gPT4gJ1J1bkFzeW5jaHJvbm91cycsCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKCiAgICAgICAgbXkgJFVzZXJUaW1lWm9uZSA9ICRTZWxmLT5fVXNlclRpbWVab25lR2V0KCVVc2VyRGF0YSk7CgogICAgICAgICRTZXNzaW9uT2JqZWN0LT5VcGRhdGVTZXNzaW9uSUQoCiAgICAgICAgICAgIFNlc3Npb25JRCA9PiAkTmV3U2Vzc2lvbklELAogICAgICAgICAgICBLZXkgICAgICAgPT4gJ1VzZXJUaW1lWm9uZScsCiAgICAgICAgICAgIFZhbHVlICAgICA9PiAkVXNlclRpbWVab25lLAogICAgICAgICk7CgogICAgICAgICMgY2hlY2sgaWYgdGhlIHRpbWUgem9uZSBvZmZzZXQgcmVwb3J0ZWQgYnkgdGhlIHVzZXIncyBicm93c2VyIGRpZmZlcnMgZnJvbSB0aGF0CiAgICAgICAgIyBvZiB0aGUgT1RPQk8gdXNlcidzIHRpbWUgem9uZSBvZmZzZXQKICAgICAgICBteSAkRGF0ZVRpbWVPYmplY3QgPSAkS2VybmVsOjpPTS0+Q3JlYXRlKAogICAgICAgICAgICAnS2VybmVsOjpTeXN0ZW06OkRhdGVUaW1lJywKICAgICAgICAgICAgT2JqZWN0UGFyYW1zID0+IHsKICAgICAgICAgICAgICAgIFRpbWVab25lID0+ICRVc2VyVGltZVpvbmUsCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKICAgICAgICBteSAkT1RPQk9Vc2VyVGltZVpvbmVPZmZzZXQgPSAkRGF0ZVRpbWVPYmplY3QtPkZvcm1hdCggRm9ybWF0ID0+ICcle29mZnNldH0nICkgLyA2MDsKICAgICAgICBteSAkQnJvd3NlclRpbWVab25lT2Zmc2V0ICAgPSAoICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICdUaW1lWm9uZU9mZnNldCcgKSB8fCAwICkgKiAtMTsKCiAgICAgICAgIyBUaW1lWm9uZU9mZnNldERpZmZlcmVuY2UgY29udGFpbnMgdGhlIGRpZmZlcmVuY2Ugb2YgdGhlIHRpbWUgem9uZSBvZmZzZXQgYmV0d2VlbgogICAgICAgICMgdGhlIHVzZXIncyBPVE9CTyB0aW1lIHpvbmUgc2V0dGluZyBhbmQgdGhlIG9uZSByZXBvcnRlZCBieSB0aGUgdXNlcidzIGJyb3dzZXIuCiAgICAgICAgIyBJZiB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaXQgY2FuIGJlIGV2YWx1YXRlZCBsYXRlciB0byBlLiBnLiBzaG93IGEgbWVzc2FnZQogICAgICAgICMgZm9yIHRoZSB1c2VyIHRvIGNoZWNrIGhpcyBPVE9CTyB0aW1lIHpvbmUgc2V0dGluZy4KICAgICAgICBteSAkVXNlclRpbWVab25lT2Zmc2V0RGlmZmVyZW5jZSA9IGFicyggJE9UT0JPVXNlclRpbWVab25lT2Zmc2V0IC0gJEJyb3dzZXJUaW1lWm9uZU9mZnNldCApOwogICAgICAgICRTZXNzaW9uT2JqZWN0LT5VcGRhdGVTZXNzaW9uSUQoCiAgICAgICAgICAgIFNlc3Npb25JRCA9PiAkTmV3U2Vzc2lvbklELAogICAgICAgICAgICBLZXkgICAgICAgPT4gJ1VzZXJUaW1lWm9uZU9mZnNldERpZmZlcmVuY2UnLAogICAgICAgICAgICBWYWx1ZSAgICAgPT4gJFVzZXJUaW1lWm9uZU9mZnNldERpZmZlcmVuY2UsCiAgICAgICAgKTsKCiAgICAgICAgJEtlcm5lbDo6T00tPk9iamVjdFBhcmFtQWRkKAogICAgICAgICAgICAnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcgPT4gewogICAgICAgICAgICAgICAgU2V0Q29va2llcyA9PiB7CiAgICAgICAgICAgICAgICAgICAgU2Vzc2lvbklEQ29va2llID0+ICRQYXJhbU9iamVjdC0+U2V0Q29va2llKAogICAgICAgICAgICAgICAgICAgICAgICBLZXkgICAgICA9PiAkUGFyYW17U2Vzc2lvbk5hbWV9LAogICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSAgICA9PiAkTmV3U2Vzc2lvbklELAogICAgICAgICAgICAgICAgICAgICAgICBFeHBpcmVzICA9PiAkRXhwaXJlcywKICAgICAgICAgICAgICAgICAgICAgICAgUGF0aCAgICAgPT4gJENvbmZpZ09iamVjdC0+R2V0KCdTY3JpcHRBbGlhcycpLAogICAgICAgICAgICAgICAgICAgICAgICBTZWN1cmUgICA9PiAkQ29va2llU2VjdXJlQXR0cmlidXRlLAogICAgICAgICAgICAgICAgICAgICAgICBIVFRQT25seSA9PiAxLAogICAgICAgICAgICAgICAgICAgICksCgogICAgICAgICAgICAgICAgICAgICMgZGVsZXRlIHRoZSBPVE9CT0Jyb3dzZXJIYXNDb29raWUgY29va2llCiAgICAgICAgICAgICAgICAgICAgT1RPQk9Ccm93c2VySGFzQ29va2llID0+ICRQYXJhbU9iamVjdC0+U2V0Q29va2llKAogICAgICAgICAgICAgICAgICAgICAgICBLZXkgICAgICA9PiAnT1RPQk9Ccm93c2VySGFzQ29va2llJywKICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgICAgPT4gJycsCiAgICAgICAgICAgICAgICAgICAgICAgIEV4cGlyZXMgID0+ICctMXknLAogICAgICAgICAgICAgICAgICAgICAgICBQYXRoICAgICA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ1NjcmlwdEFsaWFzJyksCiAgICAgICAgICAgICAgICAgICAgICAgIFNlY3VyZSAgID0+ICRDb29raWVTZWN1cmVBdHRyaWJ1dGUsCiAgICAgICAgICAgICAgICAgICAgICAgIEhUVFBPbmx5ID0+IDEsCiAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBTZXNzaW9uSUQgICA9PiAkTmV3U2Vzc2lvbklELAogICAgICAgICAgICAgICAgU2Vzc2lvbk5hbWUgPT4gJFBhcmFte1Nlc3Npb25OYW1lfSwKICAgICAgICAgICAgfSwKICAgICAgICApOwoKICAgICAgICAjIHJlZGlyZWN0IHdpdGggbmV3IHNlc3Npb24gaWQgYW5kIG9sZCBwYXJhbXMKICAgICAgICAjIHByZXBhcmUgb2xkIHJlZGlyZWN0IFVSTCAtLSBkbyBub3QgcmVkaXJlY3QgdG8gTG9naW4gb3IgTG9nb3V0IChsb29wKSEKICAgICAgICBpZiAoICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ID1+IC9BY3Rpb249KExvZ291dHxMb2dpbnxMb3N0UGFzc3dvcmR8UHJlTG9naW4pLyApIHsKICAgICAgICAgICAgJFBhcmFte1JlcXVlc3RlZFVSTH0gPSAnJzsKICAgICAgICB9CgogICAgICAgICMgcmVkaXJlY3Qgd2l0aCBuZXcgc2Vzc2lvbiBpZAogICAgICAgIHByaW50ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKS0+UmVkaXJlY3QoCiAgICAgICAgICAgIE9QICAgID0+ICRQYXJhbXtSZXF1ZXN0ZWRVUkx9LAogICAgICAgICAgICBMb2dpbiA9PiAxLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgIyBsb2dvdXQKICAgIGVsc2lmICggJFBhcmFte0FjdGlvbn0gZXEgJ0xvZ291dCcgKSB7CgogICAgICAgICMgY2hlY2sgc2Vzc2lvbiBpZAogICAgICAgIGlmICggISRTZXNzaW9uT2JqZWN0LT5DaGVja1Nlc3Npb25JRCggU2Vzc2lvbklEID0+ICRQYXJhbXtTZXNzaW9uSUR9ICkgKSB7CgogICAgICAgICAgICAjIG5ldyBsYXlvdXQgb2JqZWN0CiAgICAgICAgICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CgogICAgICAgICAgICAjIHJlZGlyZWN0IHRvIGFsdGVybmF0ZSBsb2dpbgogICAgICAgICAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbExvZ2luVVJMJykgKSB7CiAgICAgICAgICAgICAgICAkUGFyYW17UmVxdWVzdGVkVVJMfSA9ICRMYXlvdXRPYmplY3QtPkxpbmtFbmNvZGUoICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ICk7CiAgICAgICAgICAgICAgICBwcmludCAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCgKICAgICAgICAgICAgICAgICAgICBFeHRVUkwgPT4gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsTG9naW5VUkwnKQogICAgICAgICAgICAgICAgICAgICAgICAuICI/UmVhc29uPUludmFsaWRTZXNzaW9uSUQ7UmVxdWVzdGVkVVJMPSRQYXJhbXtSZXF1ZXN0ZWRVUkx9IiwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgc2hvdyBsb2dpbiBzY3JlZW4KICAgICAgICAgICAgcHJpbnQgJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgIFRpdGxlICAgPT4gJ0xvZ291dCcsCiAgICAgICAgICAgICAgICBNZXNzYWdlID0+IFRyYW5zbGF0YWJsZSgnU2Vzc2lvbiBpbnZhbGlkLiBQbGVhc2UgbG9nIGluIGFnYWluLicpLAogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIGdldCBzZXNzaW9uIGRhdGEKICAgICAgICBteSAlVXNlckRhdGEgPSAkU2Vzc2lvbk9iamVjdC0+R2V0U2Vzc2lvbklERGF0YSgKICAgICAgICAgICAgU2Vzc2lvbklEID0+ICRQYXJhbXtTZXNzaW9uSUR9LAogICAgICAgICk7CgogICAgICAgICRVc2VyRGF0YXtVc2VyVGltZVpvbmV9ID0gJFNlbGYtPl9Vc2VyVGltZVpvbmVHZXQoJVVzZXJEYXRhKTsKCiAgICAgICAgIyBjcmVhdGUgbmV3IExheW91dE9iamVjdCB3aXRoIG5ldyAnJVBhcmFtJyBhbmQgJyVVc2VyRGF0YScKICAgICAgICAkS2VybmVsOjpPTS0+T2JqZWN0UGFyYW1BZGQoCiAgICAgICAgICAgICdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0JyA9PiB7CiAgICAgICAgICAgICAgICBTZXRDb29raWVzID0+IHsKCiAgICAgICAgICAgICAgICAgICAgIyBkZWxldGUgdGhlIE9UT0JPIHNlc3Npb24gY29va2llCiAgICAgICAgICAgICAgICAgICAgU2Vzc2lvbklEQ29va2llID0+ICRQYXJhbU9iamVjdC0+U2V0Q29va2llKAogICAgICAgICAgICAgICAgICAgICAgICBLZXkgICAgICA9PiAkUGFyYW17U2Vzc2lvbk5hbWV9LAogICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSAgICA9PiAnJywKICAgICAgICAgICAgICAgICAgICAgICAgRXhwaXJlcyAgPT4gJy0xeScsCiAgICAgICAgICAgICAgICAgICAgICAgIFBhdGggICAgID0+ICRDb25maWdPYmplY3QtPkdldCgnU2NyaXB0QWxpYXMnKSwKICAgICAgICAgICAgICAgICAgICAgICAgU2VjdXJlICAgPT4gJENvb2tpZVNlY3VyZUF0dHJpYnV0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgSFRUUE9ubHkgPT4gMSwKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgICVVc2VyRGF0YSwKICAgICAgICAgICAgfSwKICAgICAgICApOwoKICAgICAgICAkS2VybmVsOjpPTS0+T2JqZWN0c0Rpc2NhcmQoIE9iamVjdHMgPT4gWydLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0J10gKTsKICAgICAgICBteSAkTGF5b3V0T2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcpOwoKICAgICAgICAjIHJlbW92ZSBzZXNzaW9uIGlkCiAgICAgICAgaWYgKCAhJFNlc3Npb25PYmplY3QtPlJlbW92ZVNlc3Npb25JRCggU2Vzc2lvbklEID0+ICRQYXJhbXtTZXNzaW9uSUR9ICkgKSB7CiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkN1c3RvbWVyRmF0YWxFcnJvcigKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gVHJhbnNsYXRhYmxlKCdQbGVhc2UgY29udGFjdCB0aGUgYWRtaW5pc3RyYXRvci4nKQogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIHJlZGlyZWN0IHRvIGFsdGVybmF0ZSBsb2dpbgogICAgICAgIGlmICggJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsTG9nb3V0VVJMJykgKSB7CiAgICAgICAgICAgIHByaW50ICRMYXlvdXRPYmplY3QtPlJlZGlyZWN0KAogICAgICAgICAgICAgICAgRXh0VVJMID0+ICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbExvZ291dFVSTCcpLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyBzaG93IGxvZ291dCBzY3JlZW4KICAgICAgICBteSAkTG9nb3V0TWVzc2FnZSA9ICRMYXlvdXRPYmplY3QtPntMYW5ndWFnZU9iamVjdH0tPlRyYW5zbGF0ZSgnTG9nb3V0IHN1Y2Nlc3NmdWwuJyk7CgogICAgICAgICRMYXlvdXRPYmplY3QtPlByaW50KAogICAgICAgICAgICBPdXRwdXQgPT4gXCRMYXlvdXRPYmplY3QtPkN1c3RvbWVyTG9naW4oCiAgICAgICAgICAgICAgICBUaXRsZSAgICAgICA9PiAnTG9nb3V0JywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgICAgID0+ICRMb2dvdXRNZXNzYWdlLAogICAgICAgICAgICAgICAgTWVzc2FnZVR5cGUgPT4gJ1N1Y2Nlc3MnLAogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICApLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgIyBjdXN0b21lciBsb3N0IHBhc3N3b3JkCiAgICBlbHNpZiAoICRQYXJhbXtBY3Rpb259IGVxICdDdXN0b21lckxvc3RQYXNzd29yZCcgKSB7CgogICAgICAgICMgbmV3IGxheW91dCBvYmplY3QKICAgICAgICBteSAkTGF5b3V0T2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcpOwoKICAgICAgICAjIGNoZWNrIGZlYXR1cmUKICAgICAgICBpZiAoICEkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxMb3N0UGFzc3dvcmQnKSApIHsKCiAgICAgICAgICAgICMgc2hvdyBub3JtYWwgbG9naW4KICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgICAgICBPdXRwdXQgPT4gXCRMYXlvdXRPYmplY3QtPkN1c3RvbWVyTG9naW4oCiAgICAgICAgICAgICAgICAgICAgVGl0bGUgICA9PiAnTG9naW4nLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gVHJhbnNsYXRhYmxlKCdGZWF0dXJlIG5vdCBhY3RpdmUhJyksCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIGdldCBwYXJhbXMKICAgICAgICBteSAkVXNlciAgPSAkUGFyYW1PYmplY3QtPkdldFBhcmFtKCBQYXJhbSA9PiAnVXNlcicgKSAgfHwgJyc7CiAgICAgICAgbXkgJFRva2VuID0gJFBhcmFtT2JqZWN0LT5HZXRQYXJhbSggUGFyYW0gPT4gJ1Rva2VuJyApIHx8ICcnOwoKICAgICAgICAjIGdldCB1c2VyIGxvZ2luIGJ5IHRva2VuCiAgICAgICAgaWYgKCAhJFVzZXIgJiYgJFRva2VuICkgewoKICAgICAgICAgICAgIyBQcmV2ZW50IGV4dHJhY3RpbmcgcGFzc3dvcmQgcmVzZXQgdG9rZW4gY2hhcmFjdGVyLWJ5LWNoYXJhY3RlciB2aWEgd2lsZGNhcmQgaW5qZWN0aW9uCiAgICAgICAgICAgICMgVGhlIHdpbGQgY2FyZCBjaGFyYWN0ZXJzICIlIiBhbmQgIl8iIGNvdWxkIGJlIHVzZWQgdG8gbWF0Y2ggYXJiaXRyYXJ5IGNoYXJhY3Rlci4KICAgICAgICAgICAgaWYgKCAkVG9rZW4gIX4gbXtcQSAoPzogW2EtekEtWl0gfCBcZCApKyBcen14bXMgKSB7CgogICAgICAgICAgICAgICAgIyBTZWN1cml0eTogcHJldGVuZCB0aGF0IHBhc3N3b3JkIHJlc2V0IGluc3RydWN0aW9ucyB3ZXJlIGFjdHVhbGx5IHNlbnQgdG8KICAgICAgICAgICAgICAgICMgICBtYWtlIHN1cmUgdGhhdCB1c2VycyBjYW5ub3QgZmluZCBvdXQgdmFsaWQgdXNlcm5hbWVzIGJ5CiAgICAgICAgICAgICAgICAjICAganVzdCB0cnlpbmcgYW5kIGNoZWNraW5nIHRoZSByZXN1bHQgbWVzc2FnZS4KICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPlByaW50KAogICAgICAgICAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+TG9naW4oCiAgICAgICAgICAgICAgICAgICAgICAgIFRpdGxlICAgICAgID0+ICdMb2dpbicsCiAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgICAgID0+IFRyYW5zbGF0YWJsZSgnU2VudCBwYXNzd29yZCByZXNldCBpbnN0cnVjdGlvbnMuIFBsZWFzZSBjaGVjayB5b3VyIGVtYWlsLicpLAogICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlVHlwZSA9PiAnU3VjY2VzcycsCiAgICAgICAgICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbXkgJVVzZXJMaXN0ID0gJFVzZXJPYmplY3QtPlNlYXJjaFByZWZlcmVuY2VzKAogICAgICAgICAgICAgICAgS2V5ICAgPT4gJ1VzZXJUb2tlbicsCiAgICAgICAgICAgICAgICBWYWx1ZSA9PiAkVG9rZW4sCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIFVTRVJfSUQ6CiAgICAgICAgICAgIGZvciBteSAkVXNlcklEICggc29ydCBrZXlzICVVc2VyTGlzdCApIHsKICAgICAgICAgICAgICAgIG15ICVVc2VyRGF0YSA9ICRVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgICAgICAgICAgICAgIFVzZXIgID0+ICRVc2VySUQsCiAgICAgICAgICAgICAgICAgICAgVmFsaWQgPT4gMSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoJVVzZXJEYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgJFVzZXIgPSAkVXNlckRhdGF7VXNlckxvZ2lufTsKICAgICAgICAgICAgICAgICAgICBsYXN0IFVTRVJfSUQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgZ2V0IHVzZXIgZGF0YQogICAgICAgIG15ICVVc2VyRGF0YSA9ICRVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRVc2VyICk7CgogICAgICAgICMgdmVyaWZ5IGN1c3RvbWVyIHVzZXIgaXMgdmFsaWQgd2hlbiByZXF1ZXN0aW5nIHBhc3N3b3JkIHJlc2V0CiAgICAgICAgbXkgQFZhbGlkSURzICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlZhbGlkJyktPlZhbGlkSURzR2V0KCk7CiAgICAgICAgbXkgJFVzZXJJc1ZhbGlkID0gZ3JlcCB7ICRVc2VyRGF0YXtWYWxpZElEfSAmJiAkVXNlckRhdGF7VmFsaWRJRH0gPT0gJF8gfSBAVmFsaWRJRHM7CiAgICAgICAgaWYgKCAhJFVzZXJEYXRhe1VzZXJJRH0gfHwgISRVc2VySXNWYWxpZCApIHsKCiAgICAgICAgICAgICMgU2VjdXJpdHk6IHByZXRlbmQgdGhhdCBwYXNzd29yZCByZXNldCBpbnN0cnVjdGlvbnMgd2VyZSBhY3R1YWxseSBzZW50IHRvCiAgICAgICAgICAgICMgICBtYWtlIHN1cmUgdGhhdCB1c2VycyBjYW5ub3QgZmluZCBvdXQgdmFsaWQgdXNlcm5hbWVzIGJ5CiAgICAgICAgICAgICMgICBqdXN0IHRyeWluZyBhbmQgY2hlY2tpbmcgdGhlIHJlc3VsdCBtZXNzYWdlLgogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgICAgICBUaXRsZSAgICAgICA9PiAnTG9naW4nLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgICAgID0+IFRyYW5zbGF0YWJsZSgnU2VudCBwYXNzd29yZCByZXNldCBpbnN0cnVjdGlvbnMuIFBsZWFzZSBjaGVjayB5b3VyIGVtYWlsLicpLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VUeXBlID0+ICdTdWNjZXNzJywKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgY3JlYXRlIGVtYWlsIG9iamVjdAogICAgICAgIG15ICRFbWFpbE9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpFbWFpbC0+bmV3KCAleyRTZWxmfSApOwoKICAgICAgICAjIHNlbmQgcGFzc3dvcmQgcmVzZXQgdG9rZW4KICAgICAgICBpZiAoICEkVG9rZW4gKSB7CgogICAgICAgICAgICAjIGdlbmVyYXRlIHRva2VuCiAgICAgICAgICAgICRVc2VyRGF0YXtUb2tlbn0gPSAkVXNlck9iamVjdC0+VG9rZW5HZW5lcmF0ZSgKICAgICAgICAgICAgICAgIFVzZXJJRCA9PiAkVXNlckRhdGF7VXNlcklEfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICMgc2VuZCB0b2tlbiBub3RpZnkgZW1haWwgd2l0aCBsaW5rCiAgICAgICAgICAgIG15ICRCb2R5ID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsQm9keUxvc3RQYXNzd29yZFRva2VuJykKICAgICAgICAgICAgICAgIHx8ICdFUlJPUjogQ3VzdG9tZXJQYW5lbEJvZHlMb3N0UGFzc3dvcmRUb2tlbiBpcyBtaXNzaW5nISc7CiAgICAgICAgICAgIG15ICRTdWJqZWN0ID0gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsU3ViamVjdExvc3RQYXNzd29yZFRva2VuJykKICAgICAgICAgICAgICAgIHx8ICdFUlJPUjogQ3VzdG9tZXJQYW5lbFN1YmplY3RMb3N0UGFzc3dvcmRUb2tlbiBpcyBtaXNzaW5nISc7CiAgICAgICAgICAgIGZvciAoIHNvcnQga2V5cyAlVXNlckRhdGEgKSB7CiAgICAgICAgICAgICAgICAkQm9keSA9fiBzLzxPVE9CT18kXz4vJFVzZXJEYXRheyRffS9naTsKICAgICAgICAgICAgfQogICAgICAgICAgICBteSAkU2VudCA9ICRFbWFpbE9iamVjdC0+U2VuZCgKICAgICAgICAgICAgICAgIFRvICAgICAgID0+ICRVc2VyRGF0YXtVc2VyRW1haWx9LAogICAgICAgICAgICAgICAgU3ViamVjdCAgPT4gJFN1YmplY3QsCiAgICAgICAgICAgICAgICBDaGFyc2V0ICA9PiAkTGF5b3V0T2JqZWN0LT57VXNlckNoYXJzZXR9LAogICAgICAgICAgICAgICAgTWltZVR5cGUgPT4gJ3RleHQvcGxhaW4nLAogICAgICAgICAgICAgICAgQm9keSAgICAgPT4gJEJvZHkKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCAhJFNlbnQtPntTdWNjZXNzfSApIHsKICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkZhdGFsRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgQ29tbWVudCA9PiBUcmFuc2xhdGFibGUoJ1BsZWFzZSBjb250YWN0IHRoZSBhZG1pbmlzdHJhdG9yLicpLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgICAgICBUaXRsZSAgID0+ICdMb2dpbicsCiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSA9PiBUcmFuc2xhdGFibGUoJ1NlbnQgcGFzc3dvcmQgcmVzZXQgaW5zdHJ1Y3Rpb25zLiBQbGVhc2UgY2hlY2sgeW91ciBlbWFpbC4nKSwKICAgICAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZVR5cGUgPT4gJ1N1Y2Nlc3MnLAogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuIDE7CgogICAgICAgIH0KCiAgICAgICAgIyByZXNldCBwYXNzd29yZAogICAgICAgICMgY2hlY2sgaWYgdG9rZW4gaXMgdmFsaWQKICAgICAgICBteSAkVG9rZW5WYWxpZCA9ICRVc2VyT2JqZWN0LT5Ub2tlbkNoZWNrKAogICAgICAgICAgICBUb2tlbiAgPT4gJFRva2VuLAogICAgICAgICAgICBVc2VySUQgPT4gJFVzZXJEYXRhe1VzZXJJRH0sCiAgICAgICAgKTsKICAgICAgICBpZiAoICEkVG9rZW5WYWxpZCApIHsKICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgICAgICBPdXRwdXQgPT4gXCRMYXlvdXRPYmplY3QtPkN1c3RvbWVyTG9naW4oCiAgICAgICAgICAgICAgICAgICAgVGl0bGUgICA9PiAnTG9naW4nLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gVHJhbnNsYXRhYmxlKCdJbnZhbGlkIFRva2VuIScpLAogICAgICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgZ2V0IG5ldyBwYXNzd29yZAogICAgICAgICRVc2VyRGF0YXtOZXdQV30gPSAkVXNlck9iamVjdC0+R2VuZXJhdGVSYW5kb21QYXNzd29yZCgpOwoKICAgICAgICAjIHVwZGF0ZSBuZXcgcGFzc3dvcmQKICAgICAgICBteSAkU3VjY2VzcyA9ICRVc2VyT2JqZWN0LT5TZXRQYXNzd29yZCgKICAgICAgICAgICAgVXNlckxvZ2luID0+ICRVc2VyLAogICAgICAgICAgICBQVyAgICAgICAgPT4gJFVzZXJEYXRhe05ld1BXfQogICAgICAgICk7CgogICAgICAgIGlmICggISRTdWNjZXNzICkgewogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgICAgICBUaXRsZSAgID0+ICdMb2dpbicsCiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSA9PiBUcmFuc2xhdGFibGUoJ1Jlc2V0IHBhc3N3b3JkIHVuc3VjY2Vzc2Z1bC4gUGxlYXNlIGNvbnRhY3QgdGhlIGFkbWluaXN0cmF0b3IuJyksCiAgICAgICAgICAgICAgICAgICAgVXNlciAgICA9PiAkVXNlciwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgc2VuZCBub3RpZnkgZW1haWwKICAgICAgICBteSAkQm9keSA9ICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbEJvZHlMb3N0UGFzc3dvcmQnKQogICAgICAgICAgICB8fCAnTmV3IFBhc3N3b3JkIGlzOiA8T1RPQk9fTkVXUFc+JzsKICAgICAgICBteSAkU3ViamVjdCA9ICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbFN1YmplY3RMb3N0UGFzc3dvcmQnKQogICAgICAgICAgICB8fCAnTmV3IFBhc3N3b3JkISc7CiAgICAgICAgZm9yICggc29ydCBrZXlzICVVc2VyRGF0YSApIHsKICAgICAgICAgICAgJEJvZHkgPX4gcy88T1RPQk9fJF8+LyRVc2VyRGF0YXskX30vZ2k7CiAgICAgICAgfQogICAgICAgIG15ICRTZW50ID0gJEVtYWlsT2JqZWN0LT5TZW5kKAogICAgICAgICAgICBUbyAgICAgICA9PiAkVXNlckRhdGF7VXNlckVtYWlsfSwKICAgICAgICAgICAgU3ViamVjdCAgPT4gJFN1YmplY3QsCiAgICAgICAgICAgIENoYXJzZXQgID0+ICRMYXlvdXRPYmplY3QtPntVc2VyQ2hhcnNldH0sCiAgICAgICAgICAgIE1pbWVUeXBlID0+ICd0ZXh0L3BsYWluJywKICAgICAgICAgICAgQm9keSAgICAgPT4gJEJvZHkKICAgICAgICApOwogICAgICAgIGlmICggISRTZW50LT57U3VjY2Vzc30gKSB7CiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkN1c3RvbWVyRmF0YWxFcnJvcigKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gVHJhbnNsYXRhYmxlKCdQbGVhc2UgY29udGFjdCB0aGUgYWRtaW5pc3RyYXRvci4nKQogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIG15ICRNZXNzYWdlID0gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAnU2VudCBuZXcgcGFzc3dvcmQgdG8gJXMuIFBsZWFzZSBjaGVjayB5b3VyIGVtYWlsLicsCiAgICAgICAgICAgICRVc2VyRGF0YXtVc2VyRW1haWx9LAogICAgICAgICk7CiAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgIFRpdGxlICAgICAgID0+ICdMb2dpbicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICAgICA9PiAkTWVzc2FnZSwKICAgICAgICAgICAgICAgIFVzZXIgICAgICAgID0+ICRVc2VyLAogICAgICAgICAgICAgICAgTWVzc2FnZVR5cGUgPT4gJ1N1Y2Nlc3MnLAogICAgICAgICAgICApLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgIyBjcmVhdGUgbmV3IGN1c3RvbWVyIGFjY291bnQKICAgIGVsc2lmICggJFBhcmFte0FjdGlvbn0gZXEgJ0N1c3RvbWVyQ3JlYXRlQWNjb3VudCcgKSB7CgogICAgICAgICMgbmV3IGxheW91dCBvYmplY3QKICAgICAgICBteSAkTGF5b3V0T2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcpOwoKICAgICAgICAjIGNoZWNrIGZlYXR1cmUKICAgICAgICBpZiAoICEkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxDcmVhdGVBY2NvdW50JykgKSB7CgogICAgICAgICAgICAjIHNob3cgbm9ybWFsIGxvZ2luCiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPlByaW50KAogICAgICAgICAgICAgICAgT3V0cHV0ID0+IFwkTGF5b3V0T2JqZWN0LT5DdXN0b21lckxvZ2luKAogICAgICAgICAgICAgICAgICAgIFRpdGxlICAgPT4gJ0xvZ2luJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlID0+IFRyYW5zbGF0YWJsZSgnRmVhdHVyZSBub3QgYWN0aXZlIScpLAogICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgIyBnZXQgcGFyYW1zCiAgICAgICAgbXkgJUdldFBhcmFtczsKICAgICAgICBmb3IgbXkgJEVudHJ5ICggQHsgJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclVzZXInKS0+e01hcH0gfSApIHsKICAgICAgICAgICAgJEdldFBhcmFtc3sgJEVudHJ5LT5bMF0gfSA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oIFBhcmFtID0+ICRFbnRyeS0+WzFdICkKICAgICAgICAgICAgICAgIHx8ICcnOwogICAgICAgIH0KICAgICAgICAkR2V0UGFyYW1ze1ZhbGlkSUR9ID0gMTsKCiAgICAgICAgIyBjaGVjayBuZWVkZWQgcGFyYW1zCiAgICAgICAgaWYgKCAhJEdldFBhcmFtc3tVc2VyQ3VzdG9tZXJJRH0gKSB7CiAgICAgICAgICAgICRHZXRQYXJhbXN7VXNlckN1c3RvbWVySUR9ID0gJEdldFBhcmFtc3tVc2VyRW1haWx9OwogICAgICAgIH0KICAgICAgICBpZiAoICEkR2V0UGFyYW1ze1VzZXJMb2dpbn0gKSB7CiAgICAgICAgICAgICRHZXRQYXJhbXN7VXNlckxvZ2lufSA9ICRHZXRQYXJhbXN7VXNlckVtYWlsfTsKICAgICAgICB9CgogICAgICAgICMgZ2V0IG5ldyBwYXNzd29yZAogICAgICAgICRHZXRQYXJhbXN7VXNlclBhc3N3b3JkfSA9ICRVc2VyT2JqZWN0LT5HZW5lcmF0ZVJhbmRvbVBhc3N3b3JkKCk7CgogICAgICAgICMgZ2V0IHVzZXIgZGF0YQogICAgICAgIG15ICVVc2VyRGF0YSA9ICRVc2VyT2JqZWN0LT5DdXN0b21lclVzZXJEYXRhR2V0KCBVc2VyID0+ICRHZXRQYXJhbXN7VXNlckxvZ2lufSApOwogICAgICAgIGlmICggJFVzZXJEYXRhe1VzZXJJRH0gfHwgISRHZXRQYXJhbXN7VXNlckxvZ2lufSApIHsKCiAgICAgICAgICAgICMgc2VuZCBkYXRhIHRvIEpTCiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkFkZEpTRGF0YSgKICAgICAgICAgICAgICAgIEtleSAgID0+ICdTaWdudXBFcnJvcicsCiAgICAgICAgICAgICAgICBWYWx1ZSA9PiAxLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgICAgICBPdXRwdXQgPT4gXCRMYXlvdXRPYmplY3QtPkN1c3RvbWVyTG9naW4oCiAgICAgICAgICAgICAgICAgICAgVGl0bGUgPT4gJ0xvZ2luJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlID0+CiAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGF0YWJsZSgnVGhpcyBlLW1haWwgYWRkcmVzcyBhbHJlYWR5IGV4aXN0cy4gUGxlYXNlIGxvZyBpbiBvciByZXNldCB5b3VyIHBhc3N3b3JkLicpLAogICAgICAgICAgICAgICAgICAgIFVzZXJUaXRsZSAgICAgPT4gJEdldFBhcmFtc3tVc2VyVGl0bGV9LAogICAgICAgICAgICAgICAgICAgIFVzZXJGaXJzdG5hbWUgPT4gJEdldFBhcmFtc3tVc2VyRmlyc3RuYW1lfSwKICAgICAgICAgICAgICAgICAgICBVc2VyTGFzdG5hbWUgID0+ICRHZXRQYXJhbXN7VXNlckxhc3RuYW1lfSwKICAgICAgICAgICAgICAgICAgICBVc2VyRW1haWwgICAgID0+ICRHZXRQYXJhbXN7VXNlckVtYWlsfSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgY2hlY2sgZm9yIG1haWwgYWRkcmVzcyByZXN0cmljdGlvbnMKICAgICAgICBteSBAV2hpdGVsaXN0ID0gQHsKICAgICAgICAgICAgJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsQ3JlYXRlQWNjb3VudDo6TWFpbFJlc3RyaWN0aW9uczo6V2hpdGVsaXN0JykgLy8gW10KICAgICAgICB9OwogICAgICAgIG15IEBCbGFja2xpc3QgPSBAewogICAgICAgICAgICAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxDcmVhdGVBY2NvdW50OjpNYWlsUmVzdHJpY3Rpb25zOjpCbGFja2xpc3QnKSAvLyBbXQogICAgICAgIH07CgogICAgICAgIG15ICRXaGl0ZWxpc3RNYXRjaGVkOwogICAgICAgIGZvciBteSAkV2hpdGVsaXN0RW50cnkgKEBXaGl0ZWxpc3QpIHsKICAgICAgICAgICAgbXkgJFJlZ2V4ID0gZXZhbCB7cXIvJFdoaXRlbGlzdEVudHJ5L2l9OwogICAgICAgICAgICBpZiAoJEApIHsKICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT57TGFuZ3VhZ2VPYmplY3R9LT5UcmFuc2xhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICdUaGUgY3VzdG9tZXIgcGFuZWwgbWFpbCBhZGRyZXNzIHdoaXRlbGlzdCBjb250YWlucyB0aGUgaW52YWxpZCByZWd1bGFyIGV4cHJlc3Npb24gJFdoaXRlbGlzdEVudHJ5LCBwbGVhc2UgY2hlY2sgYW5kIGNvcnJlY3QgaXQuJwogICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoICRHZXRQYXJhbXN7VXNlckVtYWlsfSA9fiAkUmVnZXggKSB7CiAgICAgICAgICAgICAgICAkV2hpdGVsaXN0TWF0Y2hlZCsrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG15ICRCbGFja2xpc3RNYXRjaGVkOwogICAgICAgIGZvciBteSAkQmxhY2tsaXN0RW50cnkgKEBCbGFja2xpc3QpIHsKICAgICAgICAgICAgbXkgJFJlZ2V4ID0gZXZhbCB7cXIvJEJsYWNrbGlzdEVudHJ5L2l9OwogICAgICAgICAgICBpZiAoJEApIHsKICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAgICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT57TGFuZ3VhZ2VPYmplY3R9LT5UcmFuc2xhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICdUaGUgY3VzdG9tZXIgcGFuZWwgbWFpbCBhZGRyZXNzIGJsYWNrbGlzdCBjb250YWlucyB0aGUgaW52YWxpZCByZWd1bGFyIGV4cHJlc3Npb24gJEJsYWNrbGlzdEVudHJ5LCBwbGVhc2UgY2hlY2sgYW5kIGNvcnJlY3QgaXQuJwogICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoICRHZXRQYXJhbXN7VXNlckVtYWlsfSA9fiAkUmVnZXggKSB7CiAgICAgICAgICAgICAgICAkQmxhY2tsaXN0TWF0Y2hlZCsrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoICggQFdoaXRlbGlzdCAmJiAhJFdoaXRlbGlzdE1hdGNoZWQgKSB8fCAoIEBCbGFja2xpc3QgJiYgJEJsYWNrbGlzdE1hdGNoZWQgKSApIHsKCiAgICAgICAgICAgICMgc2VuZCBkYXRhIHRvIEpTCiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkFkZEpTRGF0YSgKICAgICAgICAgICAgICAgIEtleSAgID0+ICdTaWdudXBFcnJvcicsCiAgICAgICAgICAgICAgICBWYWx1ZSA9PiAxLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgICAgICBPdXRwdXQgPT4gXCRMYXlvdXRPYmplY3QtPkN1c3RvbWVyTG9naW4oCiAgICAgICAgICAgICAgICAgICAgVGl0bGUgPT4gJ0xvZ2luJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlID0+CiAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zbGF0YWJsZSgnVGhpcyBlbWFpbCBhZGRyZXNzIGlzIG5vdCBhbGxvd2VkIHRvIHJlZ2lzdGVyLiBQbGVhc2UgY29udGFjdCBzdXBwb3J0IHN0YWZmLicpLAogICAgICAgICAgICAgICAgICAgIFVzZXJUaXRsZSAgICAgPT4gJEdldFBhcmFtc3tVc2VyVGl0bGV9LAogICAgICAgICAgICAgICAgICAgIFVzZXJGaXJzdG5hbWUgPT4gJEdldFBhcmFtc3tVc2VyRmlyc3RuYW1lfSwKICAgICAgICAgICAgICAgICAgICBVc2VyTGFzdG5hbWUgID0+ICRHZXRQYXJhbXN7VXNlckxhc3RuYW1lfSwKICAgICAgICAgICAgICAgICAgICBVc2VyRW1haWwgICAgID0+ICRHZXRQYXJhbXN7VXNlckVtYWlsfSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIGNyZWF0ZSBhY2NvdW50CiAgICAgICAgbXkgJERhdGVUaW1lT2JqZWN0ID0gJEtlcm5lbDo6T00tPkNyZWF0ZSgnS2VybmVsOjpTeXN0ZW06OkRhdGVUaW1lJyk7CgogICAgICAgIG15ICROb3cgPSAkRGF0ZVRpbWVPYmplY3QtPlRvU3RyaW5nKCk7CgogICAgICAgIG15ICRBZGQgPSAkVXNlck9iamVjdC0+Q3VzdG9tZXJVc2VyQWRkKAogICAgICAgICAgICAlR2V0UGFyYW1zLAogICAgICAgICAgICBDb21tZW50ID0+ICRMYXlvdXRPYmplY3QtPntMYW5ndWFnZU9iamVjdH0tPlRyYW5zbGF0ZSggJ0FkZGVkIHZpYSBDdXN0b21lciBQYW5lbCAoJXMpJywgJE5vdyApLAogICAgICAgICAgICBWYWxpZElEID0+IDEsCiAgICAgICAgICAgIFVzZXJJRCAgPT4gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsVXNlcklEJyksCiAgICAgICAgKTsKICAgICAgICBpZiAoICEkQWRkICkgewoKICAgICAgICAgICAgIyBzZW5kIGRhdGEgdG8gSlMKICAgICAgICAgICAgJExheW91dE9iamVjdC0+QWRkSlNEYXRhKAogICAgICAgICAgICAgICAgS2V5ICAgPT4gJ1NpZ251cEVycm9yJywKICAgICAgICAgICAgICAgIFZhbHVlID0+IDEsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgICAgICBUaXRsZSAgICAgICAgID0+ICdMb2dpbicsCiAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSAgICAgICA9PiBUcmFuc2xhdGFibGUoJ0N1c3RvbWVyIHVzZXIgY2FuXCd0IGJlIGFkZGVkIScpLAogICAgICAgICAgICAgICAgICAgIFVzZXJUaXRsZSAgICAgPT4gJEdldFBhcmFtc3tVc2VyVGl0bGV9LAogICAgICAgICAgICAgICAgICAgIFVzZXJGaXJzdG5hbWUgPT4gJEdldFBhcmFtc3tVc2VyRmlyc3RuYW1lfSwKICAgICAgICAgICAgICAgICAgICBVc2VyTGFzdG5hbWUgID0+ICRHZXRQYXJhbXN7VXNlckxhc3RuYW1lfSwKICAgICAgICAgICAgICAgICAgICBVc2VyRW1haWwgICAgID0+ICRHZXRQYXJhbXN7VXNlckVtYWlsfSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgc2VuZCBub3RpZnkgZW1haWwKICAgICAgICBteSAkRW1haWxPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RW1haWwtPm5ldyggJXskU2VsZn0gKTsKICAgICAgICBteSAkQm9keSAgICAgICAgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxCb2R5TmV3QWNjb3VudCcpCiAgICAgICAgICAgIHx8ICdObyBDb25maWcgT3B0aW9uIGZvdW5kISc7CiAgICAgICAgbXkgJFN1YmplY3QgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxTdWJqZWN0TmV3QWNjb3VudCcpCiAgICAgICAgICAgIHx8ICdOZXcgT1RPQk8gQWNjb3VudCEnOwogICAgICAgIGZvciAoIHNvcnQga2V5cyAlR2V0UGFyYW1zICkgewogICAgICAgICAgICAkQm9keSA9fiBzLzxPVE9CT18kXz4vJEdldFBhcmFtc3skX30vZ2k7CiAgICAgICAgfQoKICAgICAgICAjIHNlbmQgYWNjb3VudCBpbmZvCiAgICAgICAgbXkgJFNlbnQgPSAkRW1haWxPYmplY3QtPlNlbmQoCiAgICAgICAgICAgIFRvICAgICAgID0+ICRHZXRQYXJhbXN7VXNlckVtYWlsfSwKICAgICAgICAgICAgU3ViamVjdCAgPT4gJFN1YmplY3QsCiAgICAgICAgICAgIENoYXJzZXQgID0+ICRMYXlvdXRPYmplY3QtPntVc2VyQ2hhcnNldH0sCiAgICAgICAgICAgIE1pbWVUeXBlID0+ICd0ZXh0L3BsYWluJywKICAgICAgICAgICAgQm9keSAgICAgPT4gJEJvZHkKICAgICAgICApOwogICAgICAgIGlmICggISRTZW50LT57U3VjY2Vzc30gKSB7CiAgICAgICAgICAgIG15ICRPdXRwdXQgPSAkTGF5b3V0T2JqZWN0LT5DdXN0b21lckhlYWRlcigKICAgICAgICAgICAgICAgIEFyZWEgID0+ICdDb3JlJywKICAgICAgICAgICAgICAgIFRpdGxlID0+ICdFcnJvcicKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJE91dHB1dCAuPSAkTGF5b3V0T2JqZWN0LT5DdXN0b21lcldhcm5pbmcoCiAgICAgICAgICAgICAgICBDb21tZW50ID0+IFRyYW5zbGF0YWJsZSgnQ2FuXCd0IHNlbmQgYWNjb3VudCBpbmZvIScpCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRPdXRwdXQgLj0gJExheW91dE9iamVjdC0+Q3VzdG9tZXJGb290ZXIoKTsKICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoIE91dHB1dCA9PiBcJE91dHB1dCApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIHNob3cgc2VudCBhY2NvdW50IGluZm8KICAgICAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbExvZ2luVVJMJykgKSB7CgogICAgICAgICAgICAjIHJlZGlyZWN0IHRvIGFsdGVybmF0ZSBsb2dpbgogICAgICAgICAgICAkUGFyYW17UmVxdWVzdGVkVVJMfSA9ICRMYXlvdXRPYmplY3QtPkxpbmtFbmNvZGUoICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ICk7CiAgICAgICAgICAgIHByaW50ICRMYXlvdXRPYmplY3QtPlJlZGlyZWN0KAogICAgICAgICAgICAgICAgRXh0VVJMID0+ICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbExvZ2luVVJMJykKICAgICAgICAgICAgICAgICAgICAuICI/UmVxdWVzdGVkVVJMPSRQYXJhbXtSZXF1ZXN0ZWRVUkx9O1VzZXI9JEdldFBhcmFtc3tVc2VyTG9naW59OyIKICAgICAgICAgICAgICAgICAgICAuICJFbWFpbD0kR2V0UGFyYW1ze1VzZXJFbWFpbH07UmVhc29uPU5ld0FjY291bnRDcmVhdGVkIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQoKICAgICAgICBteSAkQWNjb3VudENyZWF0ZWRNZXNzYWdlID0gJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKAogICAgICAgICAgICAnTmV3IGFjY291bnQgY3JlYXRlZC4gU2VudCBsb2dpbiBpbmZvcm1hdGlvbiB0byAlcy4gUGxlYXNlIGNoZWNrIHlvdXIgZW1haWwuJywKICAgICAgICAgICAgJEdldFBhcmFtc3tVc2VyRW1haWx9LAogICAgICAgICk7CgogICAgICAgICMgbG9naW4gc2NyZWVuCiAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgIFRpdGxlICAgICAgID0+ICdMb2dpbicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICAgICA9PiAkQWNjb3VudENyZWF0ZWRNZXNzYWdlLAogICAgICAgICAgICAgICAgVXNlciAgICAgICAgPT4gJEdldFBhcmFtc3tVc2VyTG9naW59LAogICAgICAgICAgICAgICAgTWVzc2FnZVR5cGUgPT4gJ1N1Y2Nlc3MnLAogICAgICAgICAgICApLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgIyBzaG93IGxvZ2luIHNpdGUKICAgIGVsc2lmICggISRQYXJhbXtTZXNzaW9uSUR9ICkgewoKICAgICAgICAjIG5ldyBsYXlvdXQgb2JqZWN0CiAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKCiAgICAgICAgIyBjcmVhdGUgQXV0aE9iamVjdAogICAgICAgIG15ICRBdXRoT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQXV0aCcpOwogICAgICAgIGlmICggJEF1dGhPYmplY3QtPkdldE9wdGlvbiggV2hhdCA9PiAnUHJlQXV0aCcgKSApIHsKCiAgICAgICAgICAgICMgYXV0b21hdGljIGxvZ2luCiAgICAgICAgICAgICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ID0gJExheW91dE9iamVjdC0+TGlua0VuY29kZSggJFBhcmFte1JlcXVlc3RlZFVSTH0gKTsKICAgICAgICAgICAgcHJpbnQgJExheW91dE9iamVjdC0+UmVkaXJlY3QoCiAgICAgICAgICAgICAgICBPUCA9PiAiQWN0aW9uPVByZUxvZ2luO1JlcXVlc3RlZFVSTD0kUGFyYW17UmVxdWVzdGVkVVJMfSIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgZWxzaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxMb2dpblVSTCcpICkgewoKICAgICAgICAgICAgIyByZWRpcmVjdCB0byBhbHRlcm5hdGUgbG9naW4KICAgICAgICAgICAgJFBhcmFte1JlcXVlc3RlZFVSTH0gPSAkTGF5b3V0T2JqZWN0LT5MaW5rRW5jb2RlKCAkUGFyYW17UmVxdWVzdGVkVVJMfSApOwogICAgICAgICAgICBwcmludCAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCgKICAgICAgICAgICAgICAgIEV4dFVSTCA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxMb2dpblVSTCcpCiAgICAgICAgICAgICAgICAgICAgLiAiP1JlcXVlc3RlZFVSTD0kUGFyYW17UmVxdWVzdGVkVVJMfSIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgojIFJvdGhlciBPU1MgLyBPbmVUaW1lQXV0aGVudGljYXRpb25MaW5rCiAgICAgICAgbXkgJUV4dGVuZGVkQXV0aFBhcmFtczsKICAgICAgICBmb3IgbXkgJE5hbWUgKCAkQXV0aE9iamVjdC0+RXh0ZW5kZWRQYXJhbU5hbWVzKCkgKSB7CiAgICAgICAgICAgIG15ICRFeHRQYXJhbSA9ICRQYXJhbU9iamVjdC0+R2V0UGFyYW0oCiAgICAgICAgICAgICAgICBQYXJhbSA9PiAkTmFtZSwKICAgICAgICAgICAgICAgIFJhdyAgID0+IDEKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCBkZWZpbmVkICRFeHRQYXJhbSApIHsKICAgICAgICAgICAgICAgICRFeHRlbmRlZEF1dGhQYXJhbXN7JE5hbWV9ID0gJEV4dFBhcmFtOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIHJlZGlyZWN0IGRpcmVjdGx5IHRvIExvZ2luIGlmIG5lY2Vzc2FyeSBwYXJhbWV0ZXJzIGFyZSBwcmVzZW50CiAgICAgICAgaWYgKCAlRXh0ZW5kZWRBdXRoUGFyYW1zICkgewogICAgICAgICAgICBteSAkTG9naW5TdHJpbmcgPSAnQWN0aW9uPUxvZ2luJzsKICAgICAgICAgICAgZm9yIG15ICRLZXkgKCBrZXlzICVFeHRlbmRlZEF1dGhQYXJhbXMgKSB7CiAgICAgICAgICAgICAgICAkTG9naW5TdHJpbmcgLj0gIjskS2V5PSRFeHRlbmRlZEF1dGhQYXJhbXN7JEtleX0iOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkUGFyYW17UmVxdWVzdGVkVVJMfSA9ICRMYXlvdXRPYmplY3QtPkxpbmtFbmNvZGUoICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ICk7CiAgICAgICAgICAgIHByaW50ICRMYXlvdXRPYmplY3QtPlJlZGlyZWN0KAogICAgICAgICAgICAgICAgT1AgPT4gIiRMb2dpblN0cmluZztSZXF1ZXN0ZWRVUkw9JFBhcmFte1JlcXVlc3RlZFVSTH0iLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQojIEVPIE9uZVRpbWVBdXRoZW50aWNhdGlvbkxpbmsKCiAgICAgICAgIyBsb2dpbiBzY3JlZW4KICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgT3V0cHV0ID0+IFwkTGF5b3V0T2JqZWN0LT5DdXN0b21lckxvZ2luKAogICAgICAgICAgICAgICAgVGl0bGUgPT4gJ0xvZ2luJywKICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgKSwKICAgICAgICApOwogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgICMgcnVuIG1vZHVsZXMgaWYgYSB2ZXJzaW9uIHZhbHVlIGV4aXN0cwogICAgZWxzaWYgKCAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TWFpbicpLT5SZXF1aXJlKCJLZXJuZWw6Ok1vZHVsZXM6OiRQYXJhbXtBY3Rpb259IikgKSB7CgogICAgICAgICMgY2hlY2sgc2Vzc2lvbiBpZAogICAgICAgIGlmICggISRTZXNzaW9uT2JqZWN0LT5DaGVja1Nlc3Npb25JRCggU2Vzc2lvbklEID0+ICRQYXJhbXtTZXNzaW9uSUR9ICkgKSB7CgogICAgICAgICAgICAjIGNyZWF0ZSBuZXcgTGF5b3V0T2JqZWN0IHdpdGggbmV3ICclUGFyYW0nCiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5PYmplY3RQYXJhbUFkZCgKICAgICAgICAgICAgICAgICdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0JyA9PiB7CiAgICAgICAgICAgICAgICAgICAgU2V0Q29va2llcyA9PiB7CgogICAgICAgICAgICAgICAgICAgICAgICAjIGRlbGV0ZSB0aGUgT1RPQk8gc2Vzc2lvbiBjb29raWUKICAgICAgICAgICAgICAgICAgICAgICAgU2Vzc2lvbklEQ29va2llID0+ICRQYXJhbU9iamVjdC0+U2V0Q29va2llKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgS2V5ICAgICAgPT4gJFBhcmFte1Nlc3Npb25OYW1lfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlICAgID0+ICcnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhwaXJlcyAgPT4gJy0xeScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXRoICAgICA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ1NjcmlwdEFsaWFzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWN1cmUgICA9PiAkQ29va2llU2VjdXJlQXR0cmlidXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSFRUUE9ubHkgPT4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIGlmIHRoZSB3cm9uZyBzY2hlbWUgaXMgdXNlZCwgZGVsZXRlIGFsc28gdGhlICJvdGhlciIgY29va2llIC0gaXNzdWUgIzI1MQogICAgICAgICAgICBpZiAoICRFTlZ7UkVRVUVTVF9TQ0hFTUV9ICYmIGxjKCAkRU5We1JFUVVFU1RfU0NIRU1FfSApIG5lICRDb25maWdPYmplY3QtPkdldCgnSHR0cFR5cGUnKSApIHsKICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5PYmplY3RQYXJhbUFkZCgKICAgICAgICAgICAgICAgICAgICAnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcgPT4gewogICAgICAgICAgICAgICAgICAgICAgICBTZXRDb29raWVzID0+IHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGRlbGV0ZSB0aGUgT1RPQk8gc2Vzc2lvbiBjb29raWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlc3Npb25JRENvb2tpZWh0dHAgPT4gJFBhcmFtT2JqZWN0LT5TZXRDb29raWUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2V5ICAgICAgPT4gJFBhcmFte1Nlc3Npb25OYW1lfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSAgICA9PiAnJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFeHBpcmVzICA9PiAnLTF5JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXRoICAgICA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ1NjcmlwdEFsaWFzJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VjdXJlICAgPT4gJycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSFRUUE9ubHkgPT4gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICksCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBkZWxldGUgdGhlIE9UT0JPIHNlc3Npb24gY29va2llCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXNzaW9uSURDb29raWVodHRwcyA9PiAkUGFyYW1PYmplY3QtPlNldENvb2tpZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBLZXkgICAgICA9PiAkUGFyYW17U2Vzc2lvbk5hbWV9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlICAgID0+ICcnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cGlyZXMgID0+ICctMXknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhdGggICAgID0+ICRDb25maWdPYmplY3QtPkdldCgnU2NyaXB0QWxpYXMnKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWN1cmUgICA9PiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhUVFBPbmx5ID0+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5PYmplY3RzRGlzY2FyZCggT2JqZWN0cyA9PiBbJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnXSApOwogICAgICAgICAgICBteSAkTGF5b3V0T2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcpOwoKICAgICAgICAgICAgIyBjcmVhdGUgQXV0aE9iamVjdAogICAgICAgICAgICBteSAkQXV0aE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lckF1dGgnKTsKICAgICAgICAgICAgaWYgKCAkQXV0aE9iamVjdC0+R2V0T3B0aW9uKCBXaGF0ID0+ICdQcmVBdXRoJyApICkgewoKICAgICAgICAgICAgICAgICMgYXV0b21hdGljIHJlLWxvZ2luCiAgICAgICAgICAgICAgICAkUGFyYW17UmVxdWVzdGVkVVJMfSA9ICRMYXlvdXRPYmplY3QtPkxpbmtFbmNvZGUoICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ICk7CiAgICAgICAgICAgICAgICBwcmludCAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCgKICAgICAgICAgICAgICAgICAgICBPUCA9PiAiP0FjdGlvbj1QcmVMb2dpbiZSZXF1ZXN0ZWRVUkw9JFBhcmFte1JlcXVlc3RlZFVSTH0iLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyByZWRpcmVjdCB0byBhbHRlcm5hdGUgbG9naW4KICAgICAgICAgICAgZWxzaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxMb2dpblVSTCcpICkgewoKICAgICAgICAgICAgICAgICMgcmVkaXJlY3QgdG8gYWx0ZXJuYXRlIGxvZ2luCiAgICAgICAgICAgICAgICAkUGFyYW17UmVxdWVzdGVkVVJMfSA9ICRMYXlvdXRPYmplY3QtPkxpbmtFbmNvZGUoICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ICk7CiAgICAgICAgICAgICAgICBwcmludCAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCgKICAgICAgICAgICAgICAgICAgICBFeHRVUkwgPT4gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsTG9naW5VUkwnKQogICAgICAgICAgICAgICAgICAgICAgICAuICI/UmVhc29uPUludmFsaWRTZXNzaW9uSUQ7UmVxdWVzdGVkVVJMPSRQYXJhbXtSZXF1ZXN0ZWRVUkx9IiwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgc2hvdyBsb2dpbgogICAgICAgICAgICAkTGF5b3V0T2JqZWN0LT5QcmludCgKICAgICAgICAgICAgICAgIE91dHB1dCA9PiBcJExheW91dE9iamVjdC0+Q3VzdG9tZXJMb2dpbigKICAgICAgICAgICAgICAgICAgICBUaXRsZSA9PiAnTG9naW4nLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4KICAgICAgICAgICAgICAgICAgICAgICAgJExheW91dE9iamVjdC0+e0xhbmd1YWdlT2JqZWN0fS0+VHJhbnNsYXRlKCAkU2Vzc2lvbk9iamVjdC0+U2Vzc2lvbklERXJyb3JNZXNzYWdlKCkgKSwKICAgICAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICApLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAjIGdldCBzZXNzaW9uIGRhdGEKICAgICAgICBteSAlVXNlckRhdGEgPSAkU2Vzc2lvbk9iamVjdC0+R2V0U2Vzc2lvbklERGF0YSgKICAgICAgICAgICAgU2Vzc2lvbklEID0+ICRQYXJhbXtTZXNzaW9uSUR9LAogICAgICAgICk7CgogICAgICAgICRVc2VyRGF0YXtVc2VyVGltZVpvbmV9ID0gJFNlbGYtPl9Vc2VyVGltZVpvbmVHZXQoJVVzZXJEYXRhKTsKCiAgICAgICAgIyBjaGVjayBuZWVkZWQgZGF0YQogICAgICAgIGlmICggISRVc2VyRGF0YXtVc2VySUR9IHx8ICEkVXNlckRhdGF7VXNlckxvZ2lufSB8fCAkVXNlckRhdGF7VXNlclR5cGV9IG5lICdDdXN0b21lcicgKSB7CiAgICAgICAgICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CgogICAgICAgICAgICAjIHJlZGlyZWN0IHRvIGFsdGVybmF0ZSBsb2dpbgogICAgICAgICAgICBpZiAoICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJQYW5lbExvZ2luVVJMJykgKSB7CiAgICAgICAgICAgICAgICBwcmludCAkTGF5b3V0T2JqZWN0LT5SZWRpcmVjdCgKICAgICAgICAgICAgICAgICAgICBFeHRVUkwgPT4gJENvbmZpZ09iamVjdC0+R2V0KCdDdXN0b21lclBhbmVsTG9naW5VUkwnKQogICAgICAgICAgICAgICAgICAgICAgICAuICI/UmVhc29uPVN5c3RlbUVycm9yIiwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgc2hvdyBsb2dpbiBzY3JlZW4KICAgICAgICAgICAgJExheW91dE9iamVjdC0+UHJpbnQoCiAgICAgICAgICAgICAgICBPdXRwdXQgPT4gXCRMYXlvdXRPYmplY3QtPkN1c3RvbWVyTG9naW4oCiAgICAgICAgICAgICAgICAgICAgVGl0bGUgICA9PiAnRXJyb3InLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gVHJhbnNsYXRhYmxlKCdFcnJvcjogaW52YWxpZCBzZXNzaW9uLicpLAogICAgICAgICAgICAgICAgICAgICVQYXJhbSwKICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgICMgY2hlY2sgbW9kdWxlIHJlZ2lzdHJ5CiAgICAgICAgbXkgJE1vZHVsZVJlZyA9ICRDb25maWdPYmplY3QtPkdldCgnQ3VzdG9tZXJGcm9udGVuZDo6TW9kdWxlJyktPnsgJFBhcmFte0FjdGlvbn0gfTsKICAgICAgICBpZiAoICEkTW9kdWxlUmVnICkgewoKICAgICAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAgICAgICAgICJNb2R1bGUgS2VybmVsOjpNb2R1bGVzOjokUGFyYW17QWN0aW9ufSBub3QgcmVnaXN0ZXJlZCBpbiBLZXJuZWwvQ29uZmlnLnBtISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkN1c3RvbWVyRmF0YWxFcnJvcigKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gVHJhbnNsYXRhYmxlKCdQbGVhc2UgY29udGFjdCB0aGUgYWRtaW5pc3RyYXRvci4nKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgIyBtb2R1bGUgcGVybWlzc2lvbiBjaGVjayBmb3IgYWN0aW9uCiAgICAgICAgaWYgKAogICAgICAgICAgICByZWYgJE1vZHVsZVJlZy0+e0dyb3VwUm99IGVxICdBUlJBWScKICAgICAgICAgICAgJiYgIXNjYWxhciBAeyAkTW9kdWxlUmVnLT57R3JvdXBSb30gfQogICAgICAgICAgICAmJiByZWYgJE1vZHVsZVJlZy0+e0dyb3VwfSBlcSAnQVJSQVknCiAgICAgICAgICAgICYmICFzY2FsYXIgQHsgJE1vZHVsZVJlZy0+e0dyb3VwfSB9CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICRQYXJhbXtBY2Nlc3NSb30gPSAxOwogICAgICAgICAgICAkUGFyYW17QWNjZXNzUnd9ID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CgogICAgICAgICAgICAoICRQYXJhbXtBY2Nlc3NSb30sICRQYXJhbXtBY2Nlc3NSd30gKSA9ICRTZWxmLT5fQ2hlY2tNb2R1bGVQZXJtaXNzaW9uKAogICAgICAgICAgICAgICAgTW9kdWxlUmVnID0+ICRNb2R1bGVSZWcsCiAgICAgICAgICAgICAgICAlVXNlckRhdGEsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoICEkUGFyYW17QWNjZXNzUm99ICkgewoKICAgICAgICAgICAgICAgICMgbmV3IGxheW91dCBvYmplY3QKICAgICAgICAgICAgICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CiAgICAgICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdObyBQZXJtaXNzaW9uIHRvIHVzZSB0aGlzIGZyb250ZW5kIGFjdGlvbiBtb2R1bGUhJwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkN1c3RvbWVyRmF0YWxFcnJvcigKICAgICAgICAgICAgICAgICAgICBDb21tZW50ID0+IFRyYW5zbGF0YWJsZSgnUGxlYXNlIGNvbnRhY3QgdGhlIGFkbWluaXN0cmF0b3IuJyksCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgICAgbXkgJE5hdmlnYXRpb25Db25maWcgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyRnJvbnRlbmQ6Ok5hdmlnYXRpb24nKS0+eyAkUGFyYW17QWN0aW9ufSB9OwoKICAgICAgICAjIG1vZHVsZSBwZXJtaXNzaW9uIGNoZWNrIGZvciBzdWJtZW51IGl0ZW0KICAgICAgICBpZiAoIElzSGFzaFJlZldpdGhEYXRhKCROYXZpZ2F0aW9uQ29uZmlnKSApIHsKCiAgICAgICAgICAgIEtFWToKICAgICAgICAgICAgZm9yIG15ICRLZXkgKCBzb3J0IGtleXMgJXskTmF2aWdhdGlvbkNvbmZpZ30gKSB7CiAgICAgICAgICAgICAgICBuZXh0IEtFWSBpZiAkS2V5ICAgICAgICAgICAgICAgICAhfiBtL15cZCsvaTsKICAgICAgICAgICAgICAgIG5leHQgS0VZIGlmICRQYXJhbXtSZXF1ZXN0ZWRVUkx9ICF+IG0vU3ViYWN0aW9uL2k7CgogICAgICAgICAgICAgICAgbXkgQE1vZHVsZU5hdmlnYXRpb25Db25maWdzOwoKICAgICAgICAgICAgICAgICMgRklYTUU6IFN1cHBvcnQgYm90aCBvbGQgKEhBU0gpIGFuZCBuZXcgKEFSUkFZIG9mIEhBU0gpIG5hdmlnYXRpb24gY29uZmlndXJhdGlvbnMsIGZvciByZWFzb25zIG9mCiAgICAgICAgICAgICAgICAjICAgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuIE9uY2Ugd2UgYXJlIHN1cmUgZXZlcnl0aGluZyBoYXMgYmVlbiBtaWdyYXRlZCBjb3JyZWN0bHksIHN1cHBvcnQgZm9yCiAgICAgICAgICAgICAgICAjICAgSEFTSC1vbmx5IGNvbmZpZ3VyYXRpb24gY2FuIGJlIGRyb3BwZWQgaW4gZnV0dXJlIG1ham9yIHJlbGVhc2UuCiAgICAgICAgICAgICAgICBpZiAoIElzSGFzaFJlZldpdGhEYXRhKCAkTmF2aWdhdGlvbkNvbmZpZy0+eyRLZXl9ICkgKSB7CiAgICAgICAgICAgICAgICAgICAgcHVzaCBATW9kdWxlTmF2aWdhdGlvbkNvbmZpZ3MsICROYXZpZ2F0aW9uQ29uZmlnLT57JEtleX07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNpZiAoIElzQXJyYXlSZWZXaXRoRGF0YSggJE5hdmlnYXRpb25Db25maWctPnskS2V5fSApICkgewogICAgICAgICAgICAgICAgICAgIHB1c2ggQE1vZHVsZU5hdmlnYXRpb25Db25maWdzLCBAeyAkTmF2aWdhdGlvbkNvbmZpZy0+eyRLZXl9IH07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyBTa2lwIGluY29tcGF0aWJsZSBjb25maWd1cmF0aW9uLgogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCBLRVk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgSVRFTToKICAgICAgICAgICAgICAgIGZvciBteSAkSXRlbSAoQE1vZHVsZU5hdmlnYXRpb25Db25maWdzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAkSXRlbS0+e0xpbmt9ID1+IG0vU3ViYWN0aW9uPS9pCiAgICAgICAgICAgICAgICAgICAgICAgICYmICRJdGVtLT57TGlua30gIX4gbS8kUGFyYW17U3ViYWN0aW9ufS9pCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgSVRFTTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJFBhcmFte0FjY2Vzc1JvfSA9IDA7CiAgICAgICAgICAgICAgICAgICAgJFBhcmFte0FjY2Vzc1J3fSA9IDA7CgogICAgICAgICAgICAgICAgICAgICMgbW9kdWxlIHBlcm1pc3Npb24gY2hlY2sgZm9yIHN1Ym1lbnUgaXRlbQogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgcmVmICRJdGVtLT57R3JvdXBSb30gZXEgJ0FSUkFZJwogICAgICAgICAgICAgICAgICAgICAgICAmJiAhc2NhbGFyIEB7ICRJdGVtLT57R3JvdXBSb30gfQogICAgICAgICAgICAgICAgICAgICAgICAmJiByZWYgJEl0ZW0tPntHcm91cH0gZXEgJ0FSUkFZJwogICAgICAgICAgICAgICAgICAgICAgICAmJiAhc2NhbGFyIEB7ICRJdGVtLT57R3JvdXB9IH0KICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgJFBhcmFte0FjY2Vzc1JvfSA9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgICRQYXJhbXtBY2Nlc3NSd30gPSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICggJFBhcmFte0FjY2Vzc1JvfSwgJFBhcmFte0FjY2Vzc1J3fSApID0gJFNlbGYtPl9DaGVja01vZHVsZVBlcm1pc3Npb24oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVSZWcgPT4gJEl0ZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAlVXNlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoICEkUGFyYW17QWNjZXNzUm99ICkgewoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbmV3IGxheW91dCBvYmplY3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdObyBQZXJtaXNzaW9uIHRvIHVzZSB0aGlzIGZyb250ZW5kIHN1YmFjdGlvbiBtb2R1bGUhJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPkN1c3RvbWVyRmF0YWxFcnJvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb21tZW50ID0+IFRyYW5zbGF0YWJsZSgnUGxlYXNlIGNvbnRhY3QgdGhlIGFkbWluaXN0cmF0b3IuJykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgY3JlYXRlIG5ldyBMYXlvdXRPYmplY3Qgd2l0aCBuZXcgJyVQYXJhbScgYW5kICclVXNlckRhdGEnCiAgICAgICAgJEtlcm5lbDo6T00tPk9iamVjdFBhcmFtQWRkKAogICAgICAgICAgICAnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCcgPT4gewogICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgJVVzZXJEYXRhLAogICAgICAgICAgICAgICAgTW9kdWxlUmVnID0+ICRNb2R1bGVSZWcsCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKCiAgICAgICAgJEtlcm5lbDo6T00tPk9iamVjdHNEaXNjYXJkKCBPYmplY3RzID0+IFsnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkxheW91dCddICk7CiAgICAgICAgbXkgJExheW91dE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnKTsKCiAgICAgICAgIyB1cGRhdGUgbGFzdCByZXF1ZXN0IHRpbWUKICAgICAgICBpZiAoCiAgICAgICAgICAgICEkUGFyYW1PYmplY3QtPklzQUpBWFJlcXVlc3QoKQogICAgICAgICAgICB8fCAkUGFyYW17QWN0aW9ufSBlcSAnQ3VzdG9tZXJWaWRlb0NoYXQnCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG15ICREYXRlVGltZU9iamVjdCA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpOwoKICAgICAgICAgICAgJFNlc3Npb25PYmplY3QtPlVwZGF0ZVNlc3Npb25JRCgKICAgICAgICAgICAgICAgIFNlc3Npb25JRCA9PiAkUGFyYW17U2Vzc2lvbklEfSwKICAgICAgICAgICAgICAgIEtleSAgICAgICA9PiAnVXNlckxhc3RSZXF1ZXN0JywKICAgICAgICAgICAgICAgIFZhbHVlICAgICA9PiAkRGF0ZVRpbWVPYmplY3QtPlRvRXBvY2goKSwKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICMgcHJlIGFwcGxpY2F0aW9uIG1vZHVsZQogICAgICAgIG15ICRQcmVNb2R1bGUgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJ0N1c3RvbWVyUGFuZWxQcmVBcHBsaWNhdGlvbk1vZHVsZScpOwogICAgICAgIGlmICgkUHJlTW9kdWxlKSB7CiAgICAgICAgICAgIG15ICVQcmVNb2R1bGVMaXN0OwogICAgICAgICAgICBpZiAoIHJlZiAkUHJlTW9kdWxlIGVxICdIQVNIJyApIHsKICAgICAgICAgICAgICAgICVQcmVNb2R1bGVMaXN0ID0gJXskUHJlTW9kdWxlfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRQcmVNb2R1bGVMaXN0e0luaXR9ID0gJFByZU1vZHVsZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTU9EVUxFOgogICAgICAgICAgICBmb3IgbXkgJFByZU1vZHVsZUtleSAoIHNvcnQga2V5cyAlUHJlTW9kdWxlTGlzdCApIHsKICAgICAgICAgICAgICAgIG15ICRQcmVNb2R1bGUgPSAkUHJlTW9kdWxlTGlzdHskUHJlTW9kdWxlS2V5fTsKICAgICAgICAgICAgICAgIG5leHQgTU9EVUxFIGlmICEkUHJlTW9kdWxlOwogICAgICAgICAgICAgICAgbmV4dCBNT0RVTEUgaWYgISRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpNYWluJyktPlJlcXVpcmUoJFByZU1vZHVsZSk7CgogICAgICAgICAgICAgICAgIyBkZWJ1ZyBpbmZvCiAgICAgICAgICAgICAgICBpZiAoICRTZWxmLT57RGVidWd9ICkgewogICAgICAgICAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiQ3VzdG9tZXJQYW5lbFByZUFwcGxpY2F0aW9uIG1vZHVsZSAkUHJlTW9kdWxlIGlzIHVzZWQuIiwKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICMgdXNlIG1vZHVsZQogICAgICAgICAgICAgICAgbXkgJFByZU1vZHVsZU9iamVjdCA9ICRQcmVNb2R1bGUtPm5ldygKICAgICAgICAgICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgICAgICAgICAgJVVzZXJEYXRhLAoKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBteSAkT3V0cHV0ID0gJFByZU1vZHVsZU9iamVjdC0+UHJlUnVuKCk7CiAgICAgICAgICAgICAgICBpZiAoJE91dHB1dCkgewogICAgICAgICAgICAgICAgICAgICRMYXlvdXRPYmplY3QtPlByaW50KCBPdXRwdXQgPT4gXCRPdXRwdXQgKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBkZWJ1ZyBpbmZvCiAgICAgICAgaWYgKCAkU2VsZi0+e0RlYnVnfSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0tlcm5lbDo6TW9kdWxlczo6JyAuICRQYXJhbXtBY3Rpb259IC4gJy0+bmV3JywKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIG15ICRGcm9udGVuZE9iamVjdCA9ICggJ0tlcm5lbDo6TW9kdWxlczo6JyAuICRQYXJhbXtBY3Rpb259ICktPm5ldygKICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAlVXNlckRhdGEsCiAgICAgICAgICAgIE1vZHVsZVJlZyA9PiAkTW9kdWxlUmVnLAogICAgICAgICAgICBEZWJ1ZyAgICAgPT4gJFNlbGYtPntEZWJ1Z30sCiAgICAgICAgKTsKCiAgICAgICAgIyBkZWJ1ZyBpbmZvCiAgICAgICAgaWYgKCAkU2VsZi0+e0RlYnVnfSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0tlcm5lbDo6TW9kdWxlczo6JyAuICRQYXJhbXtBY3Rpb259IC4gJy0+cnVuJywKICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgICMgLT5SdW4gJEFjdGlvbiB3aXRoICRGcm9udGVuZE9iamVjdAogICAgICAgICRMYXlvdXRPYmplY3QtPlByaW50KCBPdXRwdXQgPT4gXCRGcm9udGVuZE9iamVjdC0+UnVuKCkgKTsKCiAgICAgICAgIyBsb2cgcmVxdWVzdCB0aW1lCiAgICAgICAgaWYgKCAkQ29uZmlnT2JqZWN0LT5HZXQoJ1BlcmZvcm1hbmNlTG9nJykgKSB7CiAgICAgICAgICAgIGlmICggKCAhJFF1ZXJ5U3RyaW5nICYmICRQYXJhbXtBY3Rpb259ICkgfHwgJFF1ZXJ5U3RyaW5nICF+IC9BY3Rpb249LyApIHsKICAgICAgICAgICAgICAgICRRdWVyeVN0cmluZyA9ICdBY3Rpb249JyAuICRQYXJhbXtBY3Rpb259IC4gJztTdWJhY3Rpb249JyAuICRQYXJhbXtTdWJhY3Rpb259OwogICAgICAgICAgICB9CiAgICAgICAgICAgIG15ICRGaWxlID0gJENvbmZpZ09iamVjdC0+R2V0KCdQZXJmb3JtYW5jZUxvZzo6RmlsZScpOwoKICAgICAgICAgICAgaWYgKCBvcGVuIG15ICRPdXQsICc+PicsICRGaWxlICkgewogICAgICAgICAgICAgICAgcHJpbnQgJE91dCB0aW1lKCkKICAgICAgICAgICAgICAgICAgICAuICc6OkN1c3RvbWVyOjonCiAgICAgICAgICAgICAgICAgICAgLiAoIHRpbWUoKSAtICRTZWxmLT57UGVyZm9ybWFuY2VMb2dTdGFydH0gKQogICAgICAgICAgICAgICAgICAgIC4gIjo6JFVzZXJEYXRhe1VzZXJMb2dpbn06OiRRdWVyeVN0cmluZ1xuIjsKICAgICAgICAgICAgICAgIGNsb3NlICRPdXQ7CiAgICAgICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdSZXNwb25zZTo6Q3VzdG9tZXI6ICcKICAgICAgICAgICAgICAgICAgICAgICAgLiAoIHRpbWUoKSAtICRTZWxmLT57UGVyZm9ybWFuY2VMb2dTdGFydH0gKQogICAgICAgICAgICAgICAgICAgICAgICAuICJzIHRha2VuIChVUkw6JFF1ZXJ5U3RyaW5nOiRVc2VyRGF0YXtVc2VyTG9naW59KSIsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiQ2FuJ3Qgd3JpdGUgJEZpbGU6ICQhIiwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgIyBwcmludCBhbiBlcnJvciBzY3JlZW4KICAgIG15ICVEYXRhID0gJFNlc3Npb25PYmplY3QtPkdldFNlc3Npb25JRERhdGEoCiAgICAgICAgU2Vzc2lvbklEID0+ICRQYXJhbXtTZXNzaW9uSUR9LAogICAgKTsKICAgICREYXRhe1VzZXJUaW1lWm9uZX0gPSAkU2VsZi0+X1VzZXJUaW1lWm9uZUdldCglRGF0YSk7CiAgICAkS2VybmVsOjpPTS0+T2JqZWN0UGFyYW1BZGQoCiAgICAgICAgJ0tlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXQnID0+IHsKICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAlRGF0YSwKICAgICAgICB9LAogICAgKTsKICAgIG15ICRMYXlvdXRPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0Jyk7CiAgICAkTGF5b3V0T2JqZWN0LT5DdXN0b21lckZhdGFsRXJyb3IoCiAgICAgICAgQ29tbWVudCA9PiBUcmFuc2xhdGFibGUoJ1BsZWFzZSBjb250YWN0IHRoZSBhZG1pbmlzdHJhdG9yLicpLAogICAgKTsKICAgIHJldHVybjsKfQoKPWJlZ2luIEludGVybmFsOgoKPWhlYWQyIF9TdG9yZUZhaWxlZExvZ2lucygpCgo9Y3V0CgpzdWIgX1N0b3JlRmFpbGVkTG9naW5zIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CiAgICBteSAkQ3VycmVudFRpbWVPYmplY3QgICA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpOwogICAgbXkgJEN1cnJlbnROZXdUaW1lU3RhbXAgPSAkQ3VycmVudFRpbWVPYmplY3QtPlRvU3RyaW5nKCk7CiAgICBteSAkQ2FjaGVPYmplY3QgICAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDYWNoZScpOwogICAgbXkgJENoZWNrSGFzaCAgICAgICAgICAgPSAkQ2FjaGVPYmplY3QtPkdldCgKICAgICAgICBUeXBlID0+ICdGYWlsZWRMb2dpbnNDdXN0b21lcicsCiAgICAgICAgS2V5ICA9PiAkUGFyYW17UG9zdFVzZXJ9LAogICAgKTsKCiAgICBpZiAoICEkQ2hlY2tIYXNoICkgewogICAgICAgICRDYWNoZU9iamVjdC0+U2V0KAogICAgICAgICAgICBUeXBlICA9PiAnRmFpbGVkTG9naW5zQ3VzdG9tZXInLAogICAgICAgICAgICBLZXkgICA9PiAkUGFyYW17UG9zdFVzZXJ9LAogICAgICAgICAgICBWYWx1ZSA9PiBbJEN1cnJlbnROZXdUaW1lU3RhbXBdLAogICAgICAgICAgICBUVEwgICA9PiAkUGFyYW17UHJldmVudEJydXRlRm9yY2VDb25maWd9e0tlZXBDYWNoZUR1cmF0aW9ufSwKICAgICAgICApOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBteSBATG9naW5UcnlBcnJheSA9IEB7JENoZWNrSGFzaH07CgogICAgIyBkZWxldGUgZXhwaXJlZCBjYWNoZSBlbnRyaWVzCiAgICBMT0dJTjoKICAgIGZvciBteSAkTG9naW5UaW1lICggQHskQ2hlY2tIYXNofSApIHsKICAgICAgICBteSAkTG9naW5UaW1lT2JqZWN0ID0gJEtlcm5lbDo6T00tPkNyZWF0ZSgKICAgICAgICAgICAgJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScsCiAgICAgICAgICAgIE9iamVjdFBhcmFtcyA9PiB7CiAgICAgICAgICAgICAgICBTdHJpbmcgPT4gJExvZ2luVGltZSwKICAgICAgICAgICAgfSwKICAgICAgICApOwogICAgICAgIG15ICRPZmZzZXQgPSAkQ3VycmVudFRpbWVPYmplY3QtPkRlbHRhKAogICAgICAgICAgICBEYXRlVGltZU9iamVjdCA9PiAkTG9naW5UaW1lT2JqZWN0LAogICAgICAgICk7CgogICAgICAgIGlmICggJE9mZnNldC0+e0Fic29sdXRlU2Vjb25kc30gPiAkUGFyYW17UHJldmVudEJydXRlRm9yY2VDb25maWd9LT57S2VlcENhY2hlRHVyYXRpb259ICkgewogICAgICAgICAgICBzaGlmdCBATG9naW5UcnlBcnJheTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxhc3QgTE9HSU47CiAgICAgICAgfQogICAgfQoKICAgICMgYWRkIG5ldyBmYWlsZWQgbG9naW4gdG8gY2FjaGUKICAgIHB1c2ggQExvZ2luVHJ5QXJyYXksICRDdXJyZW50TmV3VGltZVN0YW1wOwogICAgJENhY2hlT2JqZWN0LT5TZXQoCiAgICAgICAgVHlwZSAgPT4gJ0ZhaWxlZExvZ2luc0N1c3RvbWVyJywKICAgICAgICBLZXkgICA9PiAkUGFyYW17UG9zdFVzZXJ9LAogICAgICAgIFZhbHVlID0+IFxATG9naW5UcnlBcnJheSwKICAgICAgICBUVEwgICA9PiAkUGFyYW17UHJldmVudEJydXRlRm9yY2VDb25maWd9e0tlZXBDYWNoZUR1cmF0aW9ufSwKICAgICk7CgogICAgaWYgKCBzY2FsYXIgQExvZ2luVHJ5QXJyYXkgPj0gJFBhcmFte1ByZXZlbnRCcnV0ZUZvcmNlQ29uZmlnfXtNYXhBdHRlbXB0fSApIHsKICAgICAgICAkQ2FjaGVPYmplY3QtPlNldCgKICAgICAgICAgICAgVHlwZSAgPT4gJ0Jhbm5lZExvZ2luc0N1c3RvbWVyJywKICAgICAgICAgICAgS2V5ICAgPT4gJFBhcmFte1Bvc3RVc2VyfSwKICAgICAgICAgICAgVmFsdWUgPT4gJEN1cnJlbnROZXdUaW1lU3RhbXAsCiAgICAgICAgICAgIFRUTCAgID0+ICRQYXJhbXtQcmV2ZW50QnJ1dGVGb3JjZUNvbmZpZ317QmFuRHVyYXRpb259LAogICAgICAgICk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCnN1YiBfQ2hlY2tBbmRSZW1vdmVGcm9tQmFubmVkTGlzdCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgZ2V0IGNhY2hlCiAgICBteSAkQ2FjaGVPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q2FjaGUnKTsKCiAgICBteSAkQmFuVGltZSA9ICRDYWNoZU9iamVjdC0+R2V0KAogICAgICAgIFR5cGUgPT4gJ0Jhbm5lZExvZ2luc0N1c3RvbWVyJywKICAgICAgICBLZXkgID0+ICRQYXJhbXtQb3N0VXNlcn0sCiAgICApOwoKICAgIGlmICggISRCYW5UaW1lICkgewogICAgICAgIHJldHVybiAoCiAgICAgICAgICAgIEJhbm5lZCA9PiAwLAogICAgICAgICk7CiAgICB9CgogICAgIyBjYWxjdWxhdGUgZWxhcHNlZCB0aW1lCiAgICBteSAkQ3VyVGltZU9iamVjdCA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpOwogICAgbXkgJEJhblRpbWVPYmplY3QgPSAkS2VybmVsOjpPTS0+Q3JlYXRlKAogICAgICAgICdLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUnLAogICAgICAgIE9iamVjdFBhcmFtcyA9PiB7CiAgICAgICAgICAgIFN0cmluZyA9PiAkQmFuVGltZSwKICAgICAgICB9LAogICAgKTsKICAgIG15ICRPZmZzZXQgPSAkQ3VyVGltZU9iamVjdC0+RGVsdGEoCiAgICAgICAgRGF0ZVRpbWVPYmplY3QgPT4gJEJhblRpbWVPYmplY3QsCiAgICApOwoKICAgICMgaWYgdGhlIGJhbiBkdXJhdGlvbiBoYXMgYmVlbiBzdXJwYXNzZWQsIGRlbGV0ZSB0aGUgY2FjaGUgZW50cnkKICAgIGlmICggJE9mZnNldC0+e0Fic29sdXRlU2Vjb25kc30gPiAkUGFyYW17UHJldmVudEJydXRlRm9yY2VDb25maWd9e0JhbkR1cmF0aW9ufSApIHsKICAgICAgICAkQ2FjaGVPYmplY3QtPkRlbGV0ZSgKICAgICAgICAgICAgVHlwZSA9PiAnQmFubmVkTG9naW5zQ3VzdG9tZXInLAogICAgICAgICAgICBLZXkgID0+ICRQYXJhbXtQb3N0VXNlcn0sCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gKAogICAgICAgICAgICBCYW5uZWQgPT4gMCwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAoCiAgICAgICAgQmFubmVkICAgICAgID0+IDEsCiAgICAgICAgUmVzaWR1YWxUaW1lID0+ICRQYXJhbXtQcmV2ZW50QnJ1dGVGb3JjZUNvbmZpZ317QmFuRHVyYXRpb259IC0gJE9mZnNldC0+e0Fic29sdXRlU2Vjb25kc30sCiAgICApOwp9Cgo9aGVhZDIgX0NoZWNrTW9kdWxlUGVybWlzc2lvbigpCgptb2R1bGUgcGVybWlzc2lvbiBjaGVjawoKICAgICgkQWNjZXNzUm8sICRBY2Nlc3NSdyA9ICRBdXRvUmVzcG9uc2VPYmplY3QtPl9DaGVja01vZHVsZVBlcm1pc3Npb24oCiAgICAgICAgTW9kdWxlUmVnID0+ICRNb2R1bGVSZWcsCiAgICAgICAgJVVzZXJEYXRhLAogICAgKTsKCj1jdXQKCnN1YiBfQ2hlY2tNb2R1bGVQZXJtaXNzaW9uIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJEFjY2Vzc1JvID0gMDsKICAgIG15ICRBY2Nlc3NSdyA9IDA7CgogICAgUEVSTUlTU0lPTjoKICAgIGZvciBteSAkUGVybWlzc2lvbiAocXcoR3JvdXBSbyBHcm91cCkpIHsKICAgICAgICBteSAkQWNjZXNzT2sgPSAwOwogICAgICAgIG15ICRHcm91cCAgICA9ICRQYXJhbXtNb2R1bGVSZWd9LT57JFBlcm1pc3Npb259OwoKICAgICAgICBuZXh0IFBFUk1JU1NJT04gaWYgISRHcm91cDsKCiAgICAgICAgbXkgJEdyb3VwT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyR3JvdXAnKTsKCiAgICAgICAgaWYgKCBJc0FycmF5UmVmV2l0aERhdGEoJEdyb3VwKSApIHsKICAgICAgICAgICAgR1JPVVA6CiAgICAgICAgICAgIGZvciBteSAkSXRlbSAoIEB7JEdyb3VwfSApIHsKICAgICAgICAgICAgICAgIG5leHQgR1JPVVAgaWYgISRJdGVtOwogICAgICAgICAgICAgICAgbmV4dCBHUk9VUCBpZiAhJEdyb3VwT2JqZWN0LT5QZXJtaXNzaW9uQ2hlY2soCiAgICAgICAgICAgICAgICAgICAgVXNlcklEICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICAgICAgICAgICAgIEdyb3VwTmFtZSA9PiAkSXRlbSwKICAgICAgICAgICAgICAgICAgICBUeXBlICAgICAgPT4gJFBlcm1pc3Npb24gZXEgJ0dyb3VwUm8nID8gJ3JvJyA6ICdydycsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICRBY2Nlc3NPayA9IDE7CiAgICAgICAgICAgICAgICBsYXN0IEdST1VQOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBteSAkSGFzUGVybWlzc2lvbiA9ICRHcm91cE9iamVjdC0+UGVybWlzc2lvbkNoZWNrKAogICAgICAgICAgICAgICAgVXNlcklEICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICAgICAgICAgR3JvdXBOYW1lID0+ICRHcm91cCwKICAgICAgICAgICAgICAgIFR5cGUgICAgICA9PiAkUGVybWlzc2lvbiBlcSAnR3JvdXBSbycgPyAncm8nIDogJ3J3JywKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCRIYXNQZXJtaXNzaW9uKSB7CiAgICAgICAgICAgICAgICAkQWNjZXNzT2sgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICggJFBlcm1pc3Npb24gZXEgJ0dyb3VwJyAmJiAkQWNjZXNzT2sgKSB7CiAgICAgICAgICAgICRBY2Nlc3NSbyA9IDE7CiAgICAgICAgICAgICRBY2Nlc3NSdyA9IDE7CiAgICAgICAgfQogICAgICAgIGVsc2lmICggJFBlcm1pc3Npb24gZXEgJ0dyb3VwUm8nICYmICRBY2Nlc3NPayApIHsKICAgICAgICAgICAgJEFjY2Vzc1JvID0gMTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuICggJEFjY2Vzc1JvLCAkQWNjZXNzUncgKTsKfQoKPWhlYWQyIF9Vc2VyVGltZVpvbmVHZXQoKQoKR2V0IHRpbWUgem9uZSBmb3IgdGhlIGN1cnJlbnQgdXNlci4gVGhpcyBmdW5jdGlvbiB3aWxsIHZhbGlkYXRlIHBhc3NlZCB0aW1lIHpvbmUgcGFyYW1ldGVyIGFuZCByZXR1cm4gZGVmYXVsdCB1c2VyIHRpbWUKem9uZSBpZiBpdCdzIG5vdCB2YWxpZC4KCiAgICBteSAkVXNlclRpbWVab25lID0gJFNlbGYtPl9Vc2VyVGltZVpvbmVHZXQoCiAgICAgICAgVXNlclRpbWVab25lID0+ICdFdXJvcGUvQmVybGluJywKICAgICk7Cgo9Y3V0CgpzdWIgX1VzZXJUaW1lWm9uZUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRVc2VyVGltZVpvbmU7CgogICAgIyBSZXR1cm4gcGFzc2VkIHRpbWUgem9uZSBvbmx5IGlmIGl0J3MgdmFsaWQuIEl0IGNhbiBoYXBwZW4gdGhhdCB1c2VyIHByZWZlcmVuY2VzIG9yIHNlc3Npb24gc3RvcmUgYW4gb2xkLXN0eWxlCiAgICAjICAgb2Zmc2V0IHdoaWNoIGlzIG5vdCB2YWxpZCBhbnltb3JlLiBJbiB0aGlzIGNhc2UsIHJldHVybiB0aGUgZGVmYXVsdCB2YWx1ZS4KICAgICMgICBQbGVhc2Ugc2VlIGJ1ZyMxMzM3NCBmb3IgbW9yZSBpbmZvcm1hdGlvbi4KICAgIGlmICgKICAgICAgICAkUGFyYW17VXNlclRpbWVab25lfQogICAgICAgICYmIEtlcm5lbDo6U3lzdGVtOjpEYXRlVGltZS0+SXNUaW1lWm9uZVZhbGlkKCBUaW1lWm9uZSA9PiAkUGFyYW17VXNlclRpbWVab25lfSApCiAgICAgICAgKQogICAgewogICAgICAgICRVc2VyVGltZVpvbmUgPSAkUGFyYW17VXNlclRpbWVab25lfTsKICAgIH0KCiAgICAkVXNlclRpbWVab25lIHx8PSBLZXJuZWw6OlN5c3RlbTo6RGF0ZVRpbWUtPlVzZXJEZWZhdWx0VGltZVpvbmVHZXQoKTsKCiAgICByZXR1cm4gJFVzZXJUaW1lWm9uZTsKfQoKPWVuZCBJbnRlcm5hbDoKCj1jdXQKCnN1YiBERVNUUk9ZIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgIyBkZWJ1ZyBpbmZvCiAgICBpZiAoICRTZWxmLT57RGVidWd9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnR2xvYmFsIGhhbmRsZSBzdG9wcGVkLicsCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKMTsK
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxvdG9ib19jb25maWcgdmVyc2lvbj0iMi4wIiBpbml0PSJBcHBsaWNhdGlvbiI+CiAgICA8U2V0dGluZyBOYW1lPSJPbmVUaW1lQXV0aDo6Q3VzdG9tZXJFcnJvck1lc3NhZ2VSZWZyZXNoRmFpbGVkIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBUcmFuc2xhdGFibGU9IjEiPlRoZSBtZXNzYWdlIHdoaWNoIHdpbGwgYmUgc2VudCB0byB0aGUgY3VzdG9tZXIgaWYgYSBsaW5rIGNvdWxkIG5vdCBiZSBnZW5lcmF0ZWQuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8TmF2aWdhdGlvbj5Db3JlOjpBdXRoOjpDdXN0b21lcjwvTmF2aWdhdGlvbj4KICAgICAgICA8VmFsdWU+CiAgICAgICAgICAgIDxJdGVtIFZhbHVlVHlwZT0iU3RyaW5nIiBWYWx1ZVJlZ2V4PSIiPkxpbmsga29ubnRlIG5pY2h0IGVyemV1Z3Qgd2VyZGVuLCBiaXR0ZSBzZW5kZW4gU2llIGVpbmUgZW1haWwgYW4gc3VwcG9ydEB3ZS5jb20uPC9JdGVtPgogICAgICAgIDwvVmFsdWU+CiAgICA8L1NldHRpbmc+CiAgICA8U2V0dGluZyBOYW1lPSJPbmVUaW1lQXV0aDo6Q3VzdG9tZXJFcnJvck1lc3NhZ2VMaW5rRXhwaXJlZCIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gVHJhbnNsYXRhYmxlPSIxIj5UaGUgbWVzc2FnZSB3aGljaCB0aGUgY3VzdG9tZXIgdXNlciB3aWxsIHNlZSBpZiBoZSB1c2VzIGFuIGludmFsaWQgdG9rZW4uPC9EZXNjcmlwdGlvbj4KICAgICAgICA8TmF2aWdhdGlvbj5Db3JlOjpBdXRoOjpDdXN0b21lcjwvTmF2aWdhdGlvbj4KICAgICAgICA8VmFsdWU+CiAgICAgICAgICAgIDxJdGVtIFZhbHVlVHlwZT0iU3RyaW5nIiBWYWx1ZVJlZ2V4PSIiPklociBMaW5rIHZlcndlaXN0IGF1ZiBrZWluIG5vY2ggZ8O8bHRpZ2VzIFRpY2tldC48L0l0ZW0+CiAgICAgICAgPC9WYWx1ZT4KICAgIDwvU2V0dGluZz4KICAgIDxTZXR0aW5nIE5hbWU9Ik9uZVRpbWVBdXRoOjpDdXN0b21lckVycm9yTWVzc2FnZVdyb25nTGluayIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gVHJhbnNsYXRhYmxlPSIxIj5UaGUgbWVzc2FnZSB3aGljaCB0aGUgY3VzdG9tZXIgdXNlciB3aWxsIHNlZSBpZiBoZSB1c2VzIGFuIG9sZCB0b2tlbiB3aXRoIGFuIGFjdGl2ZSBvbmUgYWxyZWFkeSBiZWluZyBwcmVzZW50LjwvRGVzY3JpcHRpb24+CiAgICAgICAgPE5hdmlnYXRpb24+Q29yZTo6QXV0aDo6Q3VzdG9tZXI8L05hdmlnYXRpb24+CiAgICAgICAgPFZhbHVlPgogICAgICAgICAgICA8SXRlbSBWYWx1ZVR5cGU9IlN0cmluZyIgVmFsdWVSZWdleD0iIj5BdXMgU2ljaGVyaGVpdHNncsO8bmRlbiBtw7xzc2VuIFNpZSBkZW4gbmV1ZXN0ZW4gSWhuZW4genVnZXNhbmR0ZW4gTGluayBudXR6ZW4gdW0gYXVmIGRpZXNlcyBUaWNrZXQgenV6dWdyZWlmZW4uPC9JdGVtPgogICAgICAgIDwvVmFsdWU+CiAgICA8L1NldHRpbmc+CiAgICA8U2V0dGluZyBOYW1lPSJPbmVUaW1lQXV0aDo6Q3VzdG9tZXJFcnJvck1lc3NhZ2VOZXdMaW5rIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBUcmFuc2xhdGFibGU9IjEiPlRoZSBtZXNzYWdlIHdoaWNoIHRoZSBjdXN0b21lciB1c2VyIHdpbGwgc2VlIGlmIGEgbmV3IG9uZSBpcyBzZW50IHRvIGhpcyBlbWFpbCBhZGRyZXNzLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPE5hdmlnYXRpb24+Q29yZTo6QXV0aDo6Q3VzdG9tZXI8L05hdmlnYXRpb24+CiAgICAgICAgPFZhbHVlPgogICAgICAgICAgICA8SXRlbSBWYWx1ZVR5cGU9IlN0cmluZyIgVmFsdWVSZWdleD0iIj5JaHJlIFNlc3Npb24gaXN0IGxlaWRlciBhYmdlbGF1ZmVuIC0gZWluIG5ldWVyIExpbmsgd3VyZGUgYW4gSWhyZSBFbWFpbC1BZHJlc3NlIGdlc2VuZGV0LjwvSXRlbT4KICAgICAgICA8L1ZhbHVlPgogICAgPC9TZXR0aW5nPgogICAgPFNldHRpbmcgTmFtZT0iT25lVGltZUF1dGg6OkFjY2Vzc0RheXNBZnRlckNsb3NlIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBUcmFuc2xhdGFibGU9IjEiPlRoZSBudW1iZXIgb2YgZGF5cyBjdXN0b21lciB1c2VycyBjYW4gdXNlIGRpcmVjdCBsaW5rcyB0byBvcGVuIHRpY2tldHMgYWZ0ZXIgdGhleSBhcmUgY2xvc2VkLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPE5hdmlnYXRpb24+Q29yZTo6QXV0aDo6Q3VzdG9tZXI8L05hdmlnYXRpb24+CiAgICAgICAgPFZhbHVlPgogICAgICAgICAgICA8SXRlbSBWYWx1ZVR5cGU9IlN0cmluZyIgVmFsdWVSZWdleD0iXlxkKiQiPjE0PC9JdGVtPgogICAgICAgIDwvVmFsdWU+CiAgICA8L1NldHRpbmc+CiAgICA8U2V0dGluZyBOYW1lPSJPbmVUaW1lQXV0aDo6VG9rZW5SZWZyZXNoTm90aWZpY2F0aW9uSUQiIFJlcXVpcmVkPSIwIiBWYWxpZD0iMCI+CiAgICAgICAgPERlc2NyaXB0aW9uIFRyYW5zbGF0YWJsZT0iMSI+U2VuZCB0aGUgdGV4dCBvZiBhIG5vdGlmaWNhdGlvbiB0byB0aGUgY3VzdG9tZXIgdXNlciBpZiBoZSByZWZyZXNocyBoaXMgdG9rZW4uPC9EZXNjcmlwdGlvbj4KICAgICAgICA8TmF2aWdhdGlvbj5Db3JlOjpBdXRoOjpDdXN0b21lcjwvTmF2aWdhdGlvbj4KICAgICAgICA8VmFsdWU+CiAgICAgICAgICAgIDxJdGVtIFZhbHVlVHlwZT0iU3RyaW5nIiBWYWx1ZVJlZ2V4PSJeXGQqJCI+MDwvSXRlbT4KICAgICAgICA8L1ZhbHVlPgogICAgPC9TZXR0aW5nPgogICAgPFNldHRpbmcgTmFtZT0iUG9zdE1hc3Rlcjo6UHJlRmlsdGVyTW9kdWxlIyMjMDAwLUNyZWF0ZUN1c3RvbWVyVXNlciIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIwIj4KICAgICAgICA8RGVzY3JpcHRpb24gVHJhbnNsYXRhYmxlPSIxIj5DcmVhdGUgYSBDdXN0b21lclVzZXIgaW4gYSBzcGVjaWZpYyBiYWNrZW5kIGlmIG5vbmUgZXhpc3RzIGZvciB0aGUgc2VuZGVyIGVtYWlsLiBDdXN0b21lckhlYWRlclNwb29mUHJvdGVjdGlvbiBzZXRzIChhbmQgcG9zc2libHkgb3ZlcndyaXRlcykgdGhlIFgtT1RPQk8tQ3VzdG9tZXIgaGVhZGVyIGlmIGEgY3VzdG9tZXIgdXNlciBleGlzdHMgZm9yIGFuIGVtYWlsIGFkZHJlc3MgdG8gcHJldmVudCBzcG9vZmluZy4gQ3VzdG9tZXJVc2VyQmFja2VuZCBkZWZpbmVzIHRoZSBiYWNrZW5kIGluIHdoaWNoIHRoZSBDdXN0b21lclVzZXIgd2lsbCBiZSBjcmVhdGVkLCBpZiBTZXRDaGVja0JveE5hbWUgaXMgc2V0IHRvIHRoZSBuYW1lIG9mIGEgZHluYW1pYyBmaWVsZCBvZiB0aGUgdHlwZSBjaGVja2JveCwgaXQgd2lsbCBiZSBzZXQgdG8gY2hlY2tlZCBmb3IgdGlja2V0cyBjcmVhdGVkIGJ5IGN1c3RvbWVyIHVzZXJzIGZyb20gdGhpcyBiYWNrZW5kLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPE5hdmlnYXRpb24+Q29yZTo6RW1haWw6OlBvc3RNYXN0ZXI8L05hdmlnYXRpb24+CiAgICAgICAgPFZhbHVlPgogICAgICAgICAgICA8SGFzaD4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iTW9kdWxlIj5LZXJuZWw6OlN5c3RlbTo6UG9zdE1hc3Rlcjo6RmlsdGVyOjpDcmVhdGVOZXdDdXN0b21lclVzZXI8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IkN1c3RvbWVySGVhZGVyU3Bvb2ZQcm90ZWN0aW9uIj4xPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJDdXN0b21lclVzZXJCYWNrZW5kIj48L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IlNldENoZWNrQm94TmFtZSI+PC9JdGVtPgogICAgICAgICAgICA8L0hhc2g+CiAgICAgICAgPC9WYWx1ZT4KICAgIDwvU2V0dGluZz4KICAgIDxTZXR0aW5nIE5hbWU9IkRhZW1vbjo6U2NoZWR1bGVyQ3JvblRhc2tNYW5hZ2VyOjpUYXNrIyMjRGVsZXRlRXhwaXJlZE9UQVRva2VucyIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIiBDb25maWdMZXZlbD0iMTAwIj4KICAgICAgICA8RGVzY3JpcHRpb24gVHJhbnNsYXRhYmxlPSIxIj5EZWxldGVzIE9UQSBUb2tlbnMgb2YgY2xvc2VkIHRpY2tldHMuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8TmF2aWdhdGlvbj5EYWVtb246OlNjaGVkdWxlckNyb25UYXNrTWFuYWdlcjo6VGFzazwvTmF2aWdhdGlvbj4KICAgICAgICA8VmFsdWU+CiAgICAgICAgICAgIDxIYXNoPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJUYXNrTmFtZSI+RGVsZXRlRXhwaXJlZE9UQVRva2VuczwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iU2NoZWR1bGUiPjAgNCAqICogKjwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iTW9kdWxlIj5LZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJBdXRoOjpPbmVUaW1lQXV0aExpbms8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IkZ1bmN0aW9uIj5EZWFjdGl2YXRlQ2xvc2VkVGlja2V0czwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iTWF4aW11bVBhcmFsbGVsSW5zdGFuY2VzIj4xPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJQYXJhbXMiPgogICAgICAgICAgICAgICAgICAgIDxBcnJheT4KICAgICAgICAgICAgICAgICAgICA8L0FycmF5PgogICAgICAgICAgICAgICAgPC9JdGVtPgogICAgICAgICAgICA8L0hhc2g+CiAgICAgICAgPC9WYWx1ZT4KICAgIDwvU2V0dGluZz4KPC9vdG9ib19jb25maWc+Cg==
IyAtLQojIE9UT0JPIGlzIGEgd2ViLWJhc2VkIHRpY2tldGluZyBzeXN0ZW0gZm9yIHNlcnZpY2Ugb3JnYW5pc2F0aW9ucy4KIyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIwIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDE5LTIwMjEgUm90aGVyIE9TUyBHbWJILCBodHRwczovL290b2JvLmRlLwojIC0tCiMgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIKIyB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQojIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiMgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKIyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiBJZiBub3QsIHNlZSA8aHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpDb25zb2xlOjpDb21tYW5kOjpNYWludDo6Q3VzdG9tZXJBdXRoOjpEZWxldGVFeHBpcmVkT1RBVG9rZW5zOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHBhcmVudCBxdyhLZXJuZWw6OlN5c3RlbTo6Q29uc29sZTo6QmFzZUNvbW1hbmQpOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYXJpYWJsZUNoZWNrIHF3KDphbGwpOwoKb3VyIEBPYmplY3REZXBlbmRlbmNpZXMgPSAoCiAgICAnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyQXV0aDo6T25lVGltZUF1dGhMaW5rJywKKTsKCnN1YiBDb25maWd1cmUgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAkU2VsZi0+RGVzY3JpcHRpb24oJ0RlbGV0ZXMgZXhwaXJlZCBPbmVUaW1lQXV0aGVudGlmaWNhdGlvblRva2Vucy4nKTsKCiAgICByZXR1cm47Cn0KCnN1YiBQcmVSdW4gewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICByZXR1cm47Cn0KCnN1YiBSdW4gewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkU3VjY2VzcyA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lckF1dGg6Ok9uZVRpbWVBdXRoTGluaycpLT5EZWFjdGl2YXRlQ2xvc2VkVGlja2V0cygpOwoKICAgIGlmICgkU3VjY2VzcykgewogICAgICAgICRTZWxmLT5QcmludCgiPGdyZWVuPkRvbmUuPC9ncmVlbj5cblxuIik7CiAgICAgICAgcmV0dXJuICRTZWxmLT5FeGl0Q29kZU9rKCk7CiAgICB9CgogICAgJFNlbGYtPlByaW50RXJyb3IoIkZhaWxlZC5cblxuIik7CiAgICByZXR1cm4gJFNlbGYtPkV4aXRDb2RlRXJyb3IoKTsKfQoKMTsK
IyAtLQojIE9UT0JPIGlzIGEgd2ViLWJhc2VkIHRpY2tldGluZyBzeXN0ZW0gZm9yIHNlcnZpY2Ugb3JnYW5pc2F0aW9ucy4KIyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIwIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDE5LTIwMjEgUm90aGVyIE9TUyBHbWJILCBodHRwczovL290b2JvLmRlLwojIC0tCiMgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIKIyB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQojIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiMgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKIyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiBJZiBub3QsIHNlZSA8aHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lckF1dGg6Ok9uZVRpbWVBdXRoTGluazsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKdXNlIHV0Zjg7CgpvdXIgQE9iamVjdERlcGVuZGVuY2llcyA9ICgKICAgICdLZXJuZWw6OkNvbmZpZycsCiAgICAnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicsCiAgICAnS2VybmVsOjpTeXN0ZW06OkRCJywKICAgICdLZXJuZWw6OlN5c3RlbTo6TG9nJywKKTsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBnZXQgZGF0YWJhc2Ugb2JqZWN0CiAgICAkU2VsZi0+e0RCT2JqZWN0fSA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpEQicpOwogICAgCiAgICAkU2VsZi0+e1RhYmxlfSA9ICdvdGFfdG9rZW5zJzsKCiAgICByZXR1cm4gJFNlbGY7Cn0KCnN1YiBHZXRPcHRpb24gewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte1doYXR9ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCBXaGF0ISIKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIG1vZHVsZSBvcHRpb25zCiAgICBteSAlT3B0aW9uID0gKAogICAgICAgIFByZUF1dGggPT4gMCwKICAgICk7CgogICAgIyByZXR1cm4gb3B0aW9uCiAgICByZXR1cm4gJE9wdGlvbnsgJFBhcmFte1doYXR9IH07Cn0KCnN1YiBFeHRlbmRlZFBhcmFtTmFtZXMgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKICAgIAogICAgcmV0dXJuIHF3L09UQVRva2VuLzsKfQoKc3ViIEF1dGggewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte09UQVRva2VufSApIHsKICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2RlYnVnJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIFRva2VuIHByb3ZpZGVkISIKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICBTUUwgPT4gIlNFTEVDVCB1c2VkLHVzZXIsdGlja2V0X251bWJlciBGUk9NICRTZWxmLT57VGFibGV9IFdIRVJFIHRva2VuID0gPyIsCiAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17T1RBVG9rZW59IF0sCiAgICApOwoKICAgIG15IEBSb3cgPSAgJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKTsKICAgIG15ICggJFVzZWQsICRVc2VyLCAkVGlja2V0TnVtYmVyICkgPSAoIDAgKTsKCiAgICBpZiAoIEBSb3cgKSB7CiAgICAgICAgKCAkVXNlZCwgJFVzZXIsICRUaWNrZXROdW1iZXIgKSA9IEBSb3c7CiAgICB9CgogICAgaWYgKCAhJFVzZWQgfHwgISRVc2VyICkgewogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIEVycm9yID0+ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyktPkdldCgnT25lVGltZUF1dGg6OkN1c3RvbWVyRXJyb3JNZXNzYWdlTGlua0V4cGlyZWQnKSB8fCAnSWhyIExpbmsgdmVyd2Vpc3QgYXVmIGtlaW4gbm9jaCBnw7xsdGlnZXMgVGlja2V0LicsCiAgICAgICAgfQogICAgfQoKICAgIG15ICRDdXN0b21lclVzZXJPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyJyk7CgogICAgIyBzZW5kIG91dCBuZXcgZW1haWwgaWYgdGhlIHRpY2tldCBpcyBzdGlsbCBjb25zaWRlcmVkIGFjdGl2ZSBidXQgbm8gY3VycmVudCBsaW5rIGV4aXN0cwogICAgaWYgKCAkVXNlZCA9PSAxICkgewogICAgICAgICMgc3RvcmUgZmFpbGVkIGxvZ2luIGNvdW50CiAgICAgICAgbXkgJUN1c3RvbWVyRGF0YSA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckRhdGFHZXQoIFVzZXIgPT4gJFBhcmFte1VzZXJ9ICk7CiAgICAgICAgaWYgKCVDdXN0b21lckRhdGEpIHsKICAgICAgICAgICAgbXkgJENvdW50ID0gJEN1c3RvbWVyRGF0YXtVc2VyTG9naW5GYWlsZWR9IHx8IDA7CiAgICAgICAgICAgICRDb3VudCsrOwogICAgICAgICAgICAkQ3VzdG9tZXJVc2VyT2JqZWN0LT5TZXRQcmVmZXJlbmNlcygKICAgICAgICAgICAgICAgIEtleSAgICA9PiAnVXNlckxvZ2luRmFpbGVkJywKICAgICAgICAgICAgICAgIFZhbHVlICA9PiAkQ291bnQsCiAgICAgICAgICAgICAgICBVc2VySUQgPT4gJEN1c3RvbWVyRGF0YXtVc2VyTG9naW59LAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyBjaGVjayB3aGV0aGVyIGFjdGl2ZSBsb2dpbiBsaW5rIHN0aWxsIGV4aXN0cwogICAgICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKAogICAgICAgICAgICBTUUwgPT4gIlNFTEVDVCB1c2VyIEZST00gJFNlbGYtPntUYWJsZX0gV0hFUkUgdGlja2V0X251bWJlciA9ID8gQU5EIHVzZWQgPSA/IiwKICAgICAgICAgICAgQmluZCA9PiBbIFwkVGlja2V0TnVtYmVyLCBcMiBdLAogICAgICAgICk7CgogICAgICAgIGlmICggJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIkN1c3RvbWVyVXNlciAnJFVzZXInIHRyaWVkIHRvIGxvZyBpbiB3aXRoIGFuIG9sZCB0b2tlbi4gTmV3IHRva2VuIGV4aXN0cyAtIG5vdGhpbmcgdG8gZG8uIgogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIEVycm9yID0+ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyktPkdldCgnT25lVGltZUF1dGg6OkN1c3RvbWVyRXJyb3JNZXNzYWdlV3JvbmdMaW5rJykgfHwgJ0F1cyBTaWNoZXJoZWl0c2dyw7xuZGVuIG3DvHNzZW4gU2llIGRlbiBuZXVlc3RlbiBJaG5lbiB6dWdlc2FuZHRlbiBMaW5rIG51dHplbiB1bSBhdWYgZGllc2VzIFRpY2tldCB6dXp1Z3JlaWZlbi4nLAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdkZWJ1ZycsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiQ3VzdG9tZXJVc2VyICckVXNlcicgdHJpZWQgdG8gbG9nIGluIHdpdGggYW4gb2xkIHRva2VuLiBObyBhY3RpdmUgdG9rZW4gbGVmdCAtIHNlbmRpbmcgYSBuZXcgb25lIHZpYSBtYWlsLiIKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICRTZWxmLT5TZW5kTmV3VG9rZW4oCiAgICAgICAgICAgICAgICBVc2VyICAgICAgICAgPT4gJFVzZXIsCiAgICAgICAgICAgICAgICBUaWNrZXROdW1iZXIgPT4gJFRpY2tldE51bWJlciwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBFcnJvciA9PiAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpLT5HZXQoJ09uZVRpbWVBdXRoOjpDdXN0b21lckVycm9yTWVzc2FnZU5ld0xpbmsnKSB8fCAnSWhyZSBTZXNzaW9uIGlzdCBsZWlkZXIgYWJnZWxhdWZlbiAtIGVpbiBuZXVlciBMaW5rIHd1cmRlIGFuIElocmUgRW1haWwtQWRyZXNzZSBnZXNlbmRldC4nLAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZWxzaWYgKCAkVXNlZCA9PSAyICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiQ3VzdG9tZXJVc2VyICckVXNlcicgbG9nZ2VkIGluIHZpYSB0b2tlbi4iCiAgICAgICAgKTsKCiAgICAgICAgJFNlbGYtPkRlYWN0aXZhdGVUaWNrZXRUb2tlbnMoCiAgICAgICAgICAgIFRpY2tldE51bWJlciA9PiAkVGlja2V0TnVtYmVyLAogICAgICAgICk7CgogICAgICAgIHJldHVybiAkVXNlcjsKICAgIH0KCiAgICByZXR1cm47Cn0KCnN1YiBHZW5lcmF0ZVRva2VuIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkTmVlZGVkICggcXcvVXNlciBUaWNrZXROdW1iZXIvICkgewogICAgICAgIGlmICggISRQYXJhbXskTmVlZGVkfSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJE5lZWRlZCEiCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBkZWFjdGl2YXRlIGFsbCBvdGhlciB0b2tlbnMgZm9yIHRoaXMgdGlja2V0CiAgICAkU2VsZi0+RGVhY3RpdmF0ZVRpY2tldFRva2VucygKICAgICAgICBUaWNrZXROdW1iZXIgPT4gJFBhcmFte1RpY2tldE51bWJlcn0sCiAgICApOwoKICAgIG15ICRPVEFUb2tlbkxlbmd0aCA9IDI0OwogICAgbXkgJFJhbmRvbVN0cmluZzsKCiAgICBteSAkVHJ5ID0gMTsKICAgIHdoaWxlICggJFRyeSApIHsKICAgICAgICAkUmFuZG9tU3RyaW5nID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06Ok1haW4nKS0+R2VuZXJhdGVSYW5kb21TdHJpbmcoCiAgICAgICAgICAgIExlbmd0aCA9PiAkT1RBVG9rZW5MZW5ndGgsCiAgICAgICAgKTsKCiAgICAgICAgIyBjaGVjayB3aGV0aGVyIHRoZSBzdHJpbmcgYWxyZWFkeSBleGlzdHMKICAgICAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSgKICAgICAgICAgICAgU1FMID0+ICJTRUxFQ1QgdXNlciBGUk9NICRTZWxmLT57VGFibGV9IFdIRVJFIHRva2VuID0gPyIsCiAgICAgICAgICAgIEJpbmQgPT4gWyBcJFBhcmFte09UQVRva2VufSBdLAogICAgICAgICk7CgogICAgICAgIGlmICggJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICAgICAgJFRyeSsrOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJFRyeSA9IDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoICRUcnkgPiA1ICkgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiQ291bGQgbm90IGdlbmVyYXRlIGEgdW5pcXVlIHJhbmRvbSBzdHJpbmcgYWZ0ZXIgZml2ZSByZXRyaWVzIC0gc29tZXRoaW5nIGlzIG5vdCByaWdodCEiCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMID0+ICJJTlNFUlQgSU5UTyAkU2VsZi0+e1RhYmxlfSAoIHRva2VuLCB0aWNrZXRfbnVtYmVyLCB1c2VkLCB1c2VyLCBjcmVhdGVfdGltZSwgY2hhbmdlX3RpbWUgKQogICAgICAgICAgICBWQUxVRVMgKCA/LCA/LCA/LCA/LCBjdXJyZW50X3RpbWVzdGFtcCwgY3VycmVudF90aW1lc3RhbXAgKSIsCiAgICAgICAgQmluZCA9PiBbIFwkUmFuZG9tU3RyaW5nLCBcJFBhcmFte1RpY2tldE51bWJlcn0sIFwyLCBcJFBhcmFte1VzZXJ9IF0sCiAgICApOwogICAgCiAgICByZXR1cm4gJFJhbmRvbVN0cmluZzsKfQoKc3ViIERlYWN0aXZhdGVUaWNrZXRUb2tlbnMgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICROZWVkZWQgKCBxdy9UaWNrZXROdW1iZXIvICkgewogICAgICAgIGlmICggISRQYXJhbXskTmVlZGVkfSApIHsKICAgICAgICAgICAgJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkxvZycpLT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJE5lZWRlZCEiCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGlmICEkU2VsZi0+e0RCT2JqZWN0fS0+RG8oCiAgICAgICAgU1FMID0+ICJVUERBVEUgJFNlbGYtPntUYWJsZX0gU0VUIHVzZWQgPSAxLCBjaGFuZ2VfdGltZSA9IGN1cnJlbnRfdGltZXN0YW1wIFdIRVJFIHRpY2tldF9udW1iZXIgPSA/IEFORCB1c2VkID0gMiIsCiAgICAgICAgQmluZCA9PiBbIFwkUGFyYW17VGlja2V0TnVtYmVyfSBdLAogICAgKTsKCiAgICByZXR1cm4gMTsKfQoKc3ViIERlbGV0ZVRpY2tldFRva2VucyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJE5lZWRlZCAoIHF3L1RpY2tldE51bWJlci8gKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyROZWVkZWR9ICkgewogICAgICAgICAgICAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6TG9nJyktPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkTmVlZGVkISIKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaWYgISRTZWxmLT57REJPYmplY3R9LT5EbygKICAgICAgICBTUUwgPT4gIkRFTEVURSBGUk9NICRTZWxmLT57VGFibGV9IFdIRVJFIHRpY2tldF9udW1iZXIgPSA/IiwKICAgICAgICBCaW5kID0+IFsgXCRQYXJhbXtUaWNrZXROdW1iZXJ9IF0sCiAgICApOwoKICAgIHJldHVybiAxOwp9CgpzdWIgVGlja2V0TGluayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRDb25maWdPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJE5lZWRlZCAoIHF3L1RpY2tldE51bWJlciBVc2VyLyApIHsKICAgICAgICBpZiAoICEkUGFyYW17JE5lZWRlZH0gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICROZWVkZWQhIgogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuICRDb25maWdPYmplY3QtPkdldCgnT25lVGltZUF1dGg6OkN1c3RvbWVyRXJyb3JNZXNzYWdlUmVmcmVzaEZhaWxlZCcpIC8vICdMaW5rIGNvdWxkIG5vdCBiZSBnZW5lcmF0ZWQsIHBsZWFzZSBjb250YWN0IHVzIGRpcmVjdGx5ISc7CiAgICAgICAgfQogICAgfQoKICAgIG15ICRUaWNrZXRMaW5rID0gJENvbmZpZ09iamVjdC0+R2V0KCdIdHRwVHlwZScpIC4gJzovLycgLiAkQ29uZmlnT2JqZWN0LT5HZXQoJ0ZRRE4nKSAuICcvb3RvYm8vY3VzdG9tZXIucGwnOwogICAgJFRpY2tldExpbmsgLj0gIj9BY3Rpb249Q3VzdG9tZXJUaWNrZXRab29tO1RpY2tldE51bWJlcj0kUGFyYW17VGlja2V0TnVtYmVyfSI7CgogICAgIyBjaGVjayBpZiB0aGUgdXNlciBhbHJlYWR5IGhhcyBhIHBhc3Nzd29yZCAtIHRoZW4gbm8gZGlyZWN0IGxpbmsgaXMgbmVlZGVkCiAgICBteSAlVXNlciA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXInKS0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICBVc2VyID0+ICRQYXJhbXtVc2VyfSwKICAgICk7CgogICAgdW5sZXNzICggJFVzZXJ7VXNlclBhc3N3b3JkfSApIHsKICAgICAgICAjIGdlbmVyYXRlIHRva2VuCiAgICAgICAgbXkgJFRva2VuID0gJFNlbGYtPkdlbmVyYXRlVG9rZW4oCiAgICAgICAgICAgICVQYXJhbSwKICAgICAgICApOwoKICAgICAgICBpZiAoICEkVG9rZW4gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJFcnJvciBpbiB0b2tlbiBnZW5lcmF0aW9uISIKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHJldHVybiAkQ29uZmlnT2JqZWN0LT5HZXQoJ09uZVRpbWVBdXRoOjpDdXN0b21lckVycm9yTWVzc2FnZScpIC8vICdMaW5rIGNvdWxkIG5vdCBiZSBnZW5lcmF0ZWQsIHBsZWFzZSBjb250YWN0IHVzIGRpcmVjdGx5ISc7CiAgICAgICAgfQoKICAgICAgICAkVGlja2V0TGluayAuPSAiO09UQVRva2VuPSRUb2tlbiI7CiAgICB9CgogICAgcmV0dXJuICI8YSBocmVmPSckVGlja2V0TGluaycgdGFyZ2V0PSdfYmxhbmsnPiRUaWNrZXRMaW5rPC9hPiI7Cn0KCnN1YiBEZWFjdGl2YXRlQ2xvc2VkVGlja2V0cyB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRDb25maWdPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OkNvbmZpZycpOwogICAgbXkgJFRpY2tldE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpUaWNrZXQnKTsKCiAgICAjIGdldCB0aGUgY29tcGFyZSB0aW1lIGlmIGEgZGVsYXkgaXMgZ2l2ZW4KICAgIG15ICREZWxheSAgICAgICA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6Q29uZmlnJyktPkdldCgnT25lVGltZUF1dGg6OkFjY2Vzc0RheXNBZnRlckNsb3NlJykgfHwgMDsKICAgIG15ICRTdGlsbE9LVGltZSA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScpLT5Ub0Vwb2NoKCkgLSAyNCo2MCo2MCokRGVsYXk7CgogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoCiAgICAgICAgU1FMID0+ICJTRUxFQ1QgRElTVElOQ1QodGlja2V0X251bWJlcikgRlJPTSAkU2VsZi0+e1RhYmxlfSIsCiAgICApOwogICAgCiAgICBteSBAVGlja2V0TnVtYmVyczsKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgcHVzaCBAVGlja2V0TnVtYmVycywgJFJvd1swXTsKICAgIH0KICAgIAogICAgVElDS0VUOgogICAgZm9yIG15ICRUTiAoIEBUaWNrZXROdW1iZXJzICkgewogICAgICAgIG15ICRUaWNrZXRJRCA9ICRUaWNrZXRPYmplY3QtPlRpY2tldElETG9va3VwKAogICAgICAgICAgICBUaWNrZXROdW1iZXIgPT4gJFROLAogICAgICAgICk7CgogICAgICAgIG15ICVUaWNrZXQgPSAkVGlja2V0T2JqZWN0LT5UaWNrZXRHZXQoCiAgICAgICAgICAgIFRpY2tldElEID0+ICRUaWNrZXRJRCwKICAgICAgICApOwoKICAgICAgICAjIHJlbW92ZSBvbGQgdG9rZW5zCiAgICAgICAgaWYgKCAkVGlja2V0e1N0YXRlVHlwZX0gZXEgJ2Nsb3NlZCcgfHwgJFRpY2tldHtTdGF0ZVR5cGV9IGVxICdyZW1vdmVkJyB8fCAkVGlja2V0e1N0YXRlVHlwZX0gZXEgJ21lcmdlZCcgKSB7CiAgICAgICAgICAgIGlmICggJERlbGF5ICkgewogICAgICAgICAgICAgICAgbXkgJExhc3RDaGFuZ2VkVGltZSA9ICRLZXJuZWw6Ok9NLT5DcmVhdGUoCiAgICAgICAgICAgICAgICAgICAgJ0tlcm5lbDo6U3lzdGVtOjpEYXRlVGltZScsCiAgICAgICAgICAgICAgICAgICAgT2JqZWN0UGFyYW1zID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nICAgPT4gJFRpY2tldHtDaGFuZ2VkfSwKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICApLT5Ub0Vwb2NoKCk7CgogICAgICAgICAgICAgICAgbmV4dCBUSUNLRVQgaWYgJExhc3RDaGFuZ2VkVGltZSA+ICRTdGlsbE9LVGltZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJFNlbGYtPkRlbGV0ZVRpY2tldFRva2VucygKICAgICAgICAgICAgICAgIFRpY2tldE51bWJlciA9PiAkVE4sCiAgICAgICAgICAgICk7IAogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMTsKfQoKc3ViIFNlbmROZXdUb2tlbiB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJE5lZWRlZCAoIHF3L1RpY2tldE51bWJlciBVc2VyLyApIHsKICAgICAgICBpZiAoICEkUGFyYW17JE5lZWRlZH0gKSB7CiAgICAgICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICROZWVkZWQhIgogICAgICAgICAgICApOwoKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBteSAkQ29uZmlnT2JqZWN0ICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpDb25maWcnKTsKICAgIG15ICRDdXN0b21lclVzZXJPYmplY3QgPSAkS2VybmVsOjpPTS0+R2V0KCdLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyJyk7CiAgICBteSAkVGlja2V0T2JqZWN0ICAgICAgID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlRpY2tldCcpOwoKICAgIG15ICRUaWNrZXRJRCA9ICRUaWNrZXRPYmplY3QtPlRpY2tldElETG9va3VwKAogICAgICAgIFRpY2tldE51bWJlciA9PiAkUGFyYW17VGlja2V0TnVtYmVyfSwKICAgICk7CiAgICBteSAlVGlja2V0ID0gJFRpY2tldE9iamVjdC0+VGlja2V0R2V0KAogICAgICAgIFRpY2tldElEID0+ICRUaWNrZXRJRCwKICAgICk7CiAgICBteSAlVXNlciA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXInKS0+Q3VzdG9tZXJVc2VyRGF0YUdldCgKICAgICAgICBVc2VyID0+ICRQYXJhbXtVc2VyfSwKICAgICk7CgogICAgbXkgJFRlbXBsYXRlR2VuZXJhdG9yID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OlRlbXBsYXRlR2VuZXJhdG9yJyk7CiAgICBteSAkU2VuZGVyICAgICAgICAgICAgPSAkVGVtcGxhdGVHZW5lcmF0b3ItPlNlbmRlcigKICAgICAgICBRdWV1ZUlEID0+ICRUaWNrZXR7UXVldWVJRH0sCiAgICAgICAgVXNlcklEICA9PiAxLAogICAgKTsKCiAgICBteSAkTm90aWZpY2F0aW9uSUQgPSAkQ29uZmlnT2JqZWN0LT5HZXQoJ09uZVRpbWVBdXRoOjpUb2tlblJlZnJlc2hOb3RpZmljYXRpb25JRCcpOwoKICAgIG15ICggJEJvZHksICRTdWJqZWN0ICk7CgogICAgaWYgKCAkTm90aWZpY2F0aW9uSUQgKSB7CiAgICAgICAgbXkgJU5vdGlmaWNhdGlvbiA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpOb3RpZmljYXRpb25FdmVudCcpLT5Ob3RpZmljYXRpb25HZXQoCiAgICAgICAgICAgIElEID0+ICROb3RpZmljYXRpb25JRCwKICAgICAgICApOwoKICAgICAgICBteSAlTGFuZ3VhZ2VzID0gbWFwIHsgJF8gPT4gJF8gfSBAeyAkTm90aWZpY2F0aW9ue0RhdGF9e0xhbmd1YWdlSUR9IH07CiAgICAgICAgbXkgJExhbmd1YWdlICA9ICRMYW5ndWFnZXN7ZGV9IHx8ICRMYW5ndWFnZXN7ZW59IHx8ICROb3RpZmljYXRpb257RGF0YX17TGFuZ3VhZ2VJRH1bMF07CgogICAgICAgICMgcmVwbGFjZSBwbGFjZSBob2xkZXIgc3R1ZmYKICAgICAgICAkQm9keSA9ICRUZW1wbGF0ZUdlbmVyYXRvci0+X1JlcGxhY2UoCiAgICAgICAgICAgIFJpY2hUZXh0ICAgICAgICA9PiAkQ29uZmlnT2JqZWN0LT5HZXQoJ0Zyb250ZW5kOjpSaWNoVGV4dCcpLAogICAgICAgICAgICBUZXh0ICAgICAgICAgICAgPT4gJE5vdGlmaWNhdGlvbntNZXNzYWdlfXskTGFuZ3VhZ2V9e0JvZHl9LAogICAgICAgICAgICBEYXRhICAgICAgICAgICAgPT4ge30sCiAgICAgICAgICAgIFRpY2tldERhdGEgICAgICA9PiBcJVRpY2tldCwKICAgICAgICAgICAgVXNlcklEICAgICAgICAgID0+IDEsCiAgICAgICAgKTsKCiAgICAgICAgJFN1YmplY3QgPSAkVGVtcGxhdGVHZW5lcmF0b3ItPl9SZXBsYWNlKAogICAgICAgICAgICBSaWNoVGV4dCAgICAgICAgPT4gMCwKICAgICAgICAgICAgVGV4dCAgICAgICAgICAgID0+ICROb3RpZmljYXRpb257TWVzc2FnZX17JExhbmd1YWdlfXtTdWJqZWN0fSwKICAgICAgICAgICAgRGF0YSAgICAgICAgICAgID0+IHt9LAogICAgICAgICAgICBUaWNrZXREYXRhICAgICAgPT4gXCVUaWNrZXQsCiAgICAgICAgICAgIFVzZXJJRCAgICAgICAgICA9PiAxLAogICAgICAgICk7CiAgICB9CgogICAgZWxzZSB7CiAgICAgICAgbXkgJFRpY2tldExpbmsgPSAkU2VsZi0+VGlja2V0TGluayggJVBhcmFtICk7CgogICAgICAgICRTdWJqZWN0ID0gIk5ldWVyIEF1dGhlbnRpZml6aWVydW5nc2xpbmsgZsO8ciBUaWNrZXQjJFRpY2tldHtUaWNrZXROdW1iZXJ9IjsKICAgICAgICAkQm9keSAgICA9ICJHdXRlbiBUYWc8YnIvPklociBha3R1ZWxsZXIgTGluayB1bSBhdWYgVGlja2V0IyRUaWNrZXR7VGlja2V0TnVtYmVyfSB6dWdyZWlmZW4genUga8O2bm5lbiBsYXV0ZXQ6PGJyLz4kVGlja2V0TGluayI7CiAgICB9CgoKICAgIG15ICRFbWFpbE9iamVjdCA9ICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpFbWFpbCcpOwogICAgbXkgJFNlbnQgPSAkRW1haWxPYmplY3QtPlNlbmQoCiAgICAgICAgRnJvbSAgICAgPT4gJFNlbmRlciwKICAgICAgICBUbyAgICAgICA9PiAkVXNlcntVc2VyRW1haWx9LAogICAgICAgIFN1YmplY3QgID0+ICRTdWJqZWN0LAogICAgICAgIENoYXJzZXQgID0+ICd1dGYtOCcsCiAgICAgICAgTWltZVR5cGUgPT4gJ3RleHQvaHRtbCcsCiAgICAgICAgQm9keSAgICAgPT4gJEJvZHksCiAgICApOwoKICAgIGlmICggISRTZW50ICkgewogICAgICAgICRLZXJuZWw6Ok9NLT5HZXQoJ0tlcm5lbDo6U3lzdGVtOjpMb2cnKS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiQ291bGQgbm90IHNlbmQgbmV3IHRva2VuIHRvICRQYXJhbXtVc2VyfSBmb3IgVGlja2V0IyRQYXJhbXtUaWNrZXROdW1iZXJ9ISIKICAgICAgICApOwoKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCjE7Cg==
IyAtLQojIE9UT0JPIGlzIGEgd2ViLWJhc2VkIHRpY2tldGluZyBzeXN0ZW0gZm9yIHNlcnZpY2Ugb3JnYW5pc2F0aW9ucy4KIyAtLQojIENvcHlyaWdodCAoQykgMjAwMS0yMDIwIE9UUlMgQUcsIGh0dHBzOi8vb3Rycy5jb20vCiMgQ29weXJpZ2h0IChDKSAyMDE5LTIwMjEgUm90aGVyIE9TUyBHbWJILCBodHRwczovL290b2JvLmRlLwojIC0tCiMgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIKIyB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQojIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiMgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUCiMgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKIyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KIyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQojIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiBJZiBub3QsIHNlZSA8aHR0cHM6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpQb3N0TWFzdGVyOjpGaWx0ZXI6OkNyZWF0ZU5ld0N1c3RvbWVyVXNlcjsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSBLZXJuZWw6OlN5c3RlbTo6VmFyaWFibGVDaGVjayBxdyg6YWxsKTsKCm91ciBAT2JqZWN0RGVwZW5kZW5jaWVzID0gKAogICAgJ0tlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXInLAogICAgJ0tlcm5lbDo6U3lzdGVtOjpMb2cnLAopOwoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGdldCBwYXJzZXIgb2JqZWN0CiAgICAkU2VsZi0+e1BhcnNlck9iamVjdH0gPSAkUGFyYW17UGFyc2VyT2JqZWN0fSB8fCBkaWUgIkdvdCBubyBQYXJzZXJPYmplY3QhIjsKCiAgICAjIEdldCBjb21tdW5pY2F0aW9uIGxvZyBvYmplY3QuCiAgICAkU2VsZi0+e0NvbW11bmljYXRpb25Mb2dPYmplY3R9ID0gJFBhcmFte0NvbW11bmljYXRpb25Mb2dPYmplY3R9IHx8IGRpZSAiR290IG5vIENvbW11bmljYXRpb25Mb2dPYmplY3QhIjsKCiAgICByZXR1cm4gJFNlbGY7Cn0KCnN1YiBSdW4gewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIG9ubHkgbmVlZGVkIGZvciBuZXcgdGlja2V0cwogICAgcmV0dXJuIDEgaWYgJFBhcmFte1RpY2tldElEfTsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyhHZXRQYXJhbSBKb2JDb25maWcpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntDb21tdW5pY2F0aW9uTG9nT2JqZWN0fS0+T2JqZWN0TG9nKAogICAgICAgICAgICAgICAgT2JqZWN0TG9nVHlwZSA9PiAnTWVzc2FnZScsCiAgICAgICAgICAgICAgICBQcmlvcml0eSAgICAgID0+ICdFcnJvcicsCiAgICAgICAgICAgICAgICBLZXkgICAgICAgICAgID0+ICdLZXJuZWw6OlN5c3RlbTo6UG9zdE1hc3Rlcjo6RmlsdGVyOjpDcmVhdGVOZXdDdXN0b21lclVzZXInLAogICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICA9PiAiTmVlZCAkXyEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIG15IEBFbWFpbEFkZHJlc3NPbkZpZWxkID0gJFNlbGYtPntQYXJzZXJPYmplY3R9LT5TcGxpdEFkZHJlc3NMaW5lKAogICAgICAgIExpbmUgPT4gJFNlbGYtPntQYXJzZXJPYmplY3R9LT5HZXRQYXJhbSggV0hBVCA9PiAnRnJvbScgKSwKICAgICk7CgogICAgbXkgJEluY29taW5nTWFpbEFkZHJlc3M7CgogICAgZm9yIG15ICRFbWFpbEFkZHJlc3MgKEBFbWFpbEFkZHJlc3NPbkZpZWxkKSB7CiAgICAgICAgJEluY29taW5nTWFpbEFkZHJlc3MgPSAkU2VsZi0+e1BhcnNlck9iamVjdH0tPkdldEVtYWlsQWRkcmVzcygKICAgICAgICAgICAgRW1haWwgPT4gJEVtYWlsQWRkcmVzcywKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAxIGlmICEkSW5jb21pbmdNYWlsQWRkcmVzczsKCiAgICBteSAkQ3VzdG9tZXJVc2VyT2JqZWN0ID0gJEtlcm5lbDo6T00tPkdldCgnS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlcicpOwoKICAgIG15ICVMaXN0ID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJTZWFyY2goCiAgICAgICAgUG9zdE1hc3RlclNlYXJjaCA9PiBsYyggJEluY29taW5nTWFpbEFkZHJlc3MgKSwKICAgICAgICBWYWxpZCAgICAgICAgICAgID0+IDAsCiAgICApOwoKICAgICMgdXNlciBhbHJlYWR5IGV4aXN0cwogICAgaWYgKCAlTGlzdCApIHsKCiAgICAgICAgIyByZXR1cm4gaWYgbm8gWC1PVE9CTy1DdXN0b21lclVzZXIgc3Bvb2ZpbmcgaXMgcG9zc2libGUvZGFuZ2Vyb3VzCiAgICAgICAgcmV0dXJuIDEgaWYgISRQYXJhbXtKb2JDb25maWd9e0N1c3RvbWVySGVhZGVyU3Bvb2ZQcm90ZWN0aW9ufSAmJiAhJFBhcmFte0pvYkNvbmZpZ317U2V0Q2hlY2tCb3hOYW1lfTsKCiAgICAgICAgbXkgJUN1c3RvbWVyRGF0YTsKICAgICAgICBMT0dJTjoKICAgICAgICBmb3IgbXkgJFVzZXJMb2dpbiAoIHNvcnQga2V5cyAlTGlzdCApIHsKICAgICAgICAgICAgbXkgJUN1c3RvbWVyVXNlciA9ICRDdXN0b21lclVzZXJPYmplY3QtPkN1c3RvbWVyVXNlckRhdGFHZXQoCiAgICAgICAgICAgICAgICBVc2VyID0+ICRVc2VyTG9naW4sCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoICRDdXN0b21lclVzZXJ7VmFsaWRJRH0gPT0gMSApIHsKICAgICAgICAgICAgICAgICVDdXN0b21lckRhdGEgPSAlQ3VzdG9tZXJVc2VyOwogICAgICAgICAgICAgICAgbGFzdCBMT0dJTjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBpZiB1c2VyIGV4aXN0cyBidXQgaXMgbm90IHZhbGlkLCBkbyBub3RoaW5nCiAgICAgICAgcmV0dXJuIDEgaWYgISVDdXN0b21lckRhdGE7CgogICAgICAgIGlmICggJFBhcmFte0pvYkNvbmZpZ317U2V0Q2hlY2tCb3hOYW1lfSAmJiAkQ3VzdG9tZXJEYXRhe1NvdXJjZX0gZXEgKCAkUGFyYW17Sm9iQ29uZmlnfXtDdXN0b21lclVzZXJCYWNrZW5kfSB8fCAnQ3VzdG9tZXJVc2VyJyApICkgewogICAgICAgICAgICAkUGFyYW17R2V0UGFyYW19eyAnWC1PVE9CTy1EeW5hbWljRmllbGQtJyAuICRQYXJhbXtKb2JDb25maWd9e1NldENoZWNrQm94TmFtZX0gfSA9IDE7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gMSBpZiAhJFBhcmFte0pvYkNvbmZpZ317Q3VzdG9tZXJIZWFkZXJTcG9vZlByb3RlY3Rpb259OwoKICAgICAgICAjIHRha2UgQ3VzdG9tZXJJRCBmcm9tIGN1c3RvbWVyIGJhY2tlbmQgbG9va3VwIG9yIGZyb20gZnJvbSBmaWVsZAogICAgICAgIGlmICggJEN1c3RvbWVyRGF0YXtVc2VyTG9naW59ICkgewogICAgICAgICAgICAkUGFyYW17R2V0UGFyYW19eydYLU9UT0JPLUN1c3RvbWVyVXNlcid9ID0gJEN1c3RvbWVyRGF0YXtVc2VyTG9naW59OwoKICAgICAgICAgICAgIyBub3RpY2UgdGhhdCBVc2VyTG9naW4gaXMgZnJvbSBjdXN0b21lciBzb3VyY2UgYmFja2VuZAogICAgICAgICAgICAkU2VsZi0+e0NvbW11bmljYXRpb25Mb2dPYmplY3R9LT5PYmplY3RMb2coCiAgICAgICAgICAgICAgICBPYmplY3RMb2dUeXBlID0+ICdNZXNzYWdlJywKICAgICAgICAgICAgICAgIFByaW9yaXR5ICAgICAgPT4gJ05vdGljZScsCiAgICAgICAgICAgICAgICBLZXkgICAgICAgICAgID0+ICdLZXJuZWw6OlN5c3RlbTo6UG9zdE1hc3Rlcjo6RmlsdGVyOjpDcmVhdGVOZXdDdXN0b21lclVzZXInLAogICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICA9PiAiVGFrZSBVc2VyTG9naW4gKCRDdXN0b21lckRhdGF7VXNlckxvZ2lufSkgZnJvbSAiCiAgICAgICAgICAgICAgICAgICAgLiAiY3VzdG9tZXIgc291cmNlIGJhY2tlbmQgYmFzZWQgb24gKCRJbmNvbWluZ01haWxBZGRyZXNzKS4iLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBpZiAoICRDdXN0b21lckRhdGF7VXNlckN1c3RvbWVySUR9ICkgewogICAgICAgICAgICAkUGFyYW17R2V0UGFyYW19eydYLU9UT0JPLUN1c3RvbWVyTm8nfSA9ICRDdXN0b21lckRhdGF7VXNlckN1c3RvbWVySUR9OwoKICAgICAgICAgICAgIyBub3RpY2UgdGhhdCBVc2VyQ3VzdG9tZXJJRCBpcyBmcm9tIGN1c3RvbWVyIHNvdXJjZSBiYWNrZW5kCiAgICAgICAgICAgICRTZWxmLT57Q29tbXVuaWNhdGlvbkxvZ09iamVjdH0tPk9iamVjdExvZygKICAgICAgICAgICAgICAgIE9iamVjdExvZ1R5cGUgPT4gJ01lc3NhZ2UnLAogICAgICAgICAgICAgICAgUHJpb3JpdHkgICAgICA9PiAnTm90aWNlJywKICAgICAgICAgICAgICAgIEtleSAgICAgICAgICAgPT4gJ0tlcm5lbDo6U3lzdGVtOjpQb3N0TWFzdGVyOjpGaWx0ZXI6OkNyZWF0ZU5ld0N1c3RvbWVyVXNlcicsCiAgICAgICAgICAgICAgICBWYWx1ZSAgICAgICAgID0+ICJUYWtlIFVzZXJDdXN0b21lcklEICgkQ3VzdG9tZXJEYXRhe1VzZXJDdXN0b21lcklEfSkiCiAgICAgICAgICAgICAgICAgICAgLiAiIGZyb20gY3VzdG9tZXIgc291cmNlIGJhY2tlbmQgYmFzZWQgb24gKCRJbmNvbWluZ01haWxBZGRyZXNzKS4iLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAjIHVzZXIgZG9lcyBub3QgeWV0IGV4aXN0IC0gY3JlYXRlIGl0IQogICAgZWxzZSB7CiAgICAgICAgbXkgJFVzZXJMb2dpbiA9IGxjKCAkSW5jb21pbmdNYWlsQWRkcmVzcyApOwogICAgICAgIAogICAgICAgIG15ICRTdWNjZXNzID0gJEN1c3RvbWVyVXNlck9iamVjdC0+Q3VzdG9tZXJVc2VyQWRkKAogICAgICAgICAgICBTb3VyY2UgICAgICAgICA9PiAkUGFyYW17Sm9iQ29uZmlnfXtDdXN0b21lclVzZXJCYWNrZW5kfSB8fCAnQ3VzdG9tZXJVc2VyJywKICAgICAgICAgICAgVXNlckZpcnN0bmFtZSAgPT4gJyAnLAogICAgICAgICAgICBVc2VyTGFzdG5hbWUgICA9PiAnICcsCiAgICAgICAgICAgIFVzZXJDdXN0b21lcklEID0+ICRVc2VyTG9naW4sCiAgICAgICAgICAgIFVzZXJMb2dpbiAgICAgID0+ICRVc2VyTG9naW4sCiAgICAgICAgICAgIFVzZXJFbWFpbCAgICAgID0+ICRVc2VyTG9naW4sCiAgICAgICAgICAgIFZhbGlkSUQgICAgICAgID0+IDEsCiAgICAgICAgICAgIFVzZXJJRCAgICAgICAgID0+IDEsCiAgICAgICAgKTsKCiAgICAgICAgaWYgKCAkU3VjY2VzcyApIHsKICAgICAgICAgICAgIyBub3RpY2UgdGhhdCBVc2VyTG9naW4gaXMgZnJvbSBjdXN0b21lciBzb3VyY2UgYmFja2VuZAogICAgICAgICAgICAkU2VsZi0+e0NvbW11bmljYXRpb25Mb2dPYmplY3R9LT5PYmplY3RMb2coCiAgICAgICAgICAgICAgICBPYmplY3RMb2dUeXBlID0+ICdNZXNzYWdlJywKICAgICAgICAgICAgICAgIFByaW9yaXR5ICAgICAgPT4gJ05vdGljZScsCiAgICAgICAgICAgICAgICBLZXkgICAgICAgICAgID0+ICdLZXJuZWw6OlN5c3RlbTo6UG9zdE1hc3Rlcjo6RmlsdGVyOjpDcmVhdGVOZXdDdXN0b21lclVzZXInLAogICAgICAgICAgICAgICAgVmFsdWUgICAgICAgICA9PiAiQ3JlYXRlIGFuZCBzZXQgbmV3IFVzZXJMb2dpbiAoJFVzZXJMb2dpbikuIiwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICRQYXJhbXtHZXRQYXJhbX17J1gtT1RPQk8tQ3VzdG9tZXJVc2VyJ30gPSAkVXNlckxvZ2luOwogICAgICAgICAgICAkUGFyYW17R2V0UGFyYW19eydYLU9UT0JPLUN1c3RvbWVyTm8nfSAgID0gJFVzZXJMb2dpbjsKCiAgICAgICAgICAgIGlmICggJFBhcmFte0pvYkNvbmZpZ317U2V0Q2hlY2tCb3hOYW1lfSApIHsKICAgICAgICAgICAgICAgICRQYXJhbXtHZXRQYXJhbX17ICdYLU9UT0JPLUR5bmFtaWNGaWVsZC0nIC4gJFBhcmFte0pvYkNvbmZpZ317U2V0Q2hlY2tCb3hOYW1lfSB9ID0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgIyBzZXQgcHJlZmVyZW5jZXMKICAgICAgICAgICAgJEN1c3RvbWVyVXNlck9iamVjdC0+U2V0UHJlZmVyZW5jZXMoCiAgICAgICAgICAgICAgICBVc2VySUQgPT4gJFVzZXJMb2dpbiwKICAgICAgICAgICAgICAgIEtleSAgICA9PiAnVXNlclRpbWVab25lJywKICAgICAgICAgICAgICAgIFZhbHVlICA9PiAnRXVyb3BlL0JlcmxpbicsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRDdXN0b21lclVzZXJPYmplY3QtPlNldFByZWZlcmVuY2VzKAogICAgICAgICAgICAgICAgVXNlcklEID0+ICRVc2VyTG9naW4sCiAgICAgICAgICAgICAgICBLZXkgICAgPT4gJ1VzZXJTaG93VGlja2V0cycsCiAgICAgICAgICAgICAgICBWYWx1ZSAgPT4gJzI1JywKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJEN1c3RvbWVyVXNlck9iamVjdC0+U2V0UHJlZmVyZW5jZXMoCiAgICAgICAgICAgICAgICBVc2VySUQgPT4gJFVzZXJMb2dpbiwKICAgICAgICAgICAgICAgIEtleSAgICA9PiAnVXNlclJlZnJlc2hUaW1lJywKICAgICAgICAgICAgICAgIFZhbHVlICA9PiAnMCcsCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgoxOwo=