LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogICBDb3B5cmlnaHQgKEMpIDIwMDMsIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMKKiAgIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgIGZpbGUgbmFtZTogIGdlbmxkbWwuY3BwCiovCgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAiZ2VubGRtbC5oIgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlICJ1bmljb2RlL3VzdHJpbmcuaCIKCiNkZWZpbmUgTUFYX0RJR0lUUyAxMAojaWZuZGVmIEdFTkxETUxfTk9TRVRBUFBEQVRBCi8qCiAqICBSZXNvdXJjZSBEYXRhIFJlZmVyZW5jZS4gIFRoZSBkYXRhIGlzIHBhY2thZ2VkIGFzIGEgZGxsIChvciAuc28gb3IKICogICAgICAgICAgIHdoYXRldmVyLCBkZXBlbmRpbmcgb24gdGhlIHBsYXRmb3JtKSB0aGF0IGV4cG9ydHMgYSBkYXRhCiAqICAgICAgICAgICBzeW1ib2wuICBUaGUgYXBwbGljYXRpb24gKHRoYXQncyB1cykgcmVmZXJlbmNlcyB0aGF0IHN5bWJvbCwKICogICAgICAgICAgIGhlcmUsIGFuZCB3aWxsIHBhc3MgdGhlIGRhdGEgYWRkcmVzcyB0byBJQ1UsIHdoaWNoIHdpbGwgdGhlbgogKiAgICAgICAgICAgYmUgYWJsZSB0byBmZXRjaCByZXNvdXJjZXMgZnJvbSB0aGUgZGF0YS4KICovCgpleHRlcm4gIkMiIHsKCWV4dGVybiBjb25zdCB2b2lkIFVfSU1QT1JUICpnZW5sZG1sX3Jlc291cmNlc19kYXQ7Cn0KCiNlbmRpZgoKI2RlZmluZSBYTUxfRU5EX1NMQVNIICIvIgplbnVtCnsKICAgIEhFTFAxLAogICAgSEVMUDIsCiAgICBTT1VSQ0VESVIsCglERVNURElSLAoJUEFDS0FHRV9OQU1FLAogICAgSUdOT1JFX0NPTExBVElPTiwKICAgIEJBU0UsCiAgICBCQVNFX1RZUEUsCiAgICBJR05PUkVfU1BFQ0lBTFMsCiAgICBJR05PUkVfTEFZT1VULAogICAgRFJBRlQsCiAgICBPTkxZX1NQRUNJQUxTCn07CgoKVU9wdGlvbiBvcHRpb25zW109ewogICAgICAgICAgICAgICAgICAgICAgVU9QVElPTl9IRUxQX0gsCiAgICAgICAgICAgICAgICAgICAgICBVT1BUSU9OX0hFTFBfUVVFU1RJT05fTUFSSywKICAgICAgICAgICAgICAgICAgICAgIFVPUFRJT05fU09VUkNFRElSLAoJCQkJCSAgVU9QVElPTl9ERVNURElSLAoJCQkJCSAgVU9QVElPTl9ERUYoInBhY2thZ2UiLCAncCcsIFVPUFRfUkVRVUlSRVNfQVJHKSwKICAgICAgICAgICAgICAgICAgICAgIFVPUFRJT05fREVGKCJpZ25vcmUtY29sbGF0aW9uIiwgJ2knLCBVT1BUX05PX0FSRyksCiAgICAgICAgICAgICAgICAgICAgICBVT1BUSU9OX0RFRigiYmFzZSIsICdiJywgVU9QVF9SRVFVSVJFU19BUkcpLAogICAgICAgICAgICAgICAgICAgICAgVU9QVElPTl9ERUYoImJhc2UtdHlwZSIsICd0JywgVU9QVF9SRVFVSVJFU19BUkcpLAogICAgICAgICAgICAgICAgICAgICAgVU9QVElPTl9ERUYoImlnbm9yZS1zcGVjaWFscyIsICdjJywgVU9QVF9OT19BUkcpLAogICAgICAgICAgICAgICAgICAgICAgVU9QVElPTl9ERUYoImlnbm9yZS1sYXlvdXQiLCAnbCcsIFVPUFRfTk9fQVJHKSwKICAgICAgICAgICAgICAgICAgICAgIFVPUFRJT05fREVGKCJkcmFmdCIsICdyJywgVU9QVF9OT19BUkcpLAogICAgICAgICAgICAgICAgICAgICAgVU9QVElPTl9ERUYoIm9ubHktc3BlY2lhbHMiLCAnZycsIFVPUFRfTk9fQVJHKQogICAgICAgICAgICAgICAgICAgfTsKCmNvbnN0IGNoYXIqIHVzYWdlU3RyaW5nID0KICAgICAgICAgICAgICAgICJVc2FnZTogZ2VubGRtbCBbT1BUSU9OU10gW0ZJTEVTXVxuIgogICAgICAgICAgICAgICAgIlx0Q29udmVydCB0aGUgaW5wdXQgcmVzIGZpbGUgdG8gWE1MXG4iCiAgICAgICAgICAgICAgICAiT3B0aW9uczpcbiIKICAgICAgICAgICAgICAgICJcdC1oIG9yIC0/IG9yIC0taGVscCAgICAgICB0aGlzIHVzYWdlIHRleHRcbiIKICAgICAgICAgICAgICAgICJcdC1zIG9yIC0tc291cmNlZGlyICAgICAgICBzb3VyY2UgZGlyZWN0b3J5IGZvciBmaWxlcyBmb2xsb3dlZCBieSBwYXRoXG4iCiAgICAgICAgICAgICAgICAiXHQgICAgICAgICAgICAgICAgICAgICAgICAgZm9sbG93ZWQgYnkgcGF0aFxuIgogICAgICAgICAgICAgICAgIlx0LWQgb3IgLS1kZXN0ZGlyICAgICAgICAgIGRlc3QgZGlyZWN0b3J5IGZvciBmaWxlcyBmb2xsb3dlZCBieSBwYXRoXG4iCiAgICAgICAgICAgICAgICAiXHQgICAgICAgICAgICAgICAgICAgICAgICAgZm9sbG93ZWQgYnkgcGF0aFxuIgoJCQkJIlx0LXAgb3IgLS1wYWNrYWdlCQkJbmFtZSBvZiB0aGUgcGFja2FnZSB0aGF0IGlzIHByZXBlbmRlZCB0byB0aGUgcmVzb3VyY2UgYnVuZGxlc1xuIgoJCQkJIlx0ICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzIHRvIElDVSdzIGRhdGFcbiIKICAgICAgICAgICAgICAgICJcdC1pIG9yIC0taWdub3JlLWNvbGxhdGlvbiBJZ25vcmVzIGNvbGxhdGlvbiBnZW5lcmF0aW9uXG4iCiAgICAgICAgICAgICAgICAiXHQtYiBvciAtLWJhc2UgICAgICAgICAgICAgdGhlIGJhc2UgdGFpbG9yaW5nIGZvciBjb2xsYXRpb24gaWYgYW55XG4iCiAgICAgICAgICAgICAgICAiXHQtdCBvciAtLWJhc2UtdHlwZSAgICAgICAgdGhlIHR5cGUgb2YgYmFzZSB0YWlsb3JpbmcgZm9yIGNvbGxhdGlvbiBpbiB0aGUgYmFzZS4gRGVmYXVsdHMgdG8gc3RhbmRhcmRcbiIKICAgICAgICAgICAgICAgICJcdC1jIG9yIC0taWdub3JlLXNwZWNpYWxzICBJZ25vcmVzIHNwZWNpYWxzIGluIGNvbGxhdGlvbnNcbiIKICAgICAgICAgICAgICAgICJcdC1sIG9yIC0taWdub3JlLWxheW91dCAgICBJZ25vcmVzIGxheW91dCBlbGVtZW50XG4iCiAgICAgICAgICAgICAgICAiXHQtciBvciAtLWRyYWZ0ICAgICAgICAgICAgVGhlIExETUwgZmlsZSBiZWluZyBnZW5lcmF0ZWQgd2lsbCBtYXJrZWQgYXMgZHJhZnRcbiIKICAgICAgICAgICAgICAgICJcdC1nIG9yIC0tb25seS1zcGVjaWFscyAgICBQcm9kdWNlcyBvbiBzcGVjaWFsIGVsZW1lbnRzXG4iCiAgICAgICAgICAgICAgIDsKClVCb29sIGlnbm9yZUNvbGxhdGlvbiA9IEZBTFNFOwpjb25zdCBjaGFyKiBiYXNlQ29sbGF0aW9uID0gTlVMTDsKY29uc3QgY2hhciogYmFzZVR5cGUgPSBOVUxMOwpVQm9vbCBpZ25vcmVTcGVjaWFscyA9IEZBTFNFOwpVQm9vbCBpZ25vcmVMYXlvdXQgPSBGQUxTRTsKVUJvb2wgaXNEcmFmdCA9IEZBTFNFOwpVQm9vbCBvbmx5U3BlY2lhbHMgPSBGQUxTRTsKCmludCBtYWluIChpbnQzMl90IGFyZ2MsIGNvbnN0IGNoYXIqIGFyZ3ZbXSkgewoJY29uc3QgY2hhciogc3JjRGlyID1OVUxMOwoJY29uc3QgY2hhciogZGVzdERpciA9IE5VTEw7Cgljb25zdCBjaGFyKiBwYWNrYWdlTmFtZT1OVUxMOwoJVUVycm9yQ29kZSBlcnI9IFVfWkVST19FUlJPUjsKCWNoYXIqIHBhdGg9IE5VTEw7CgkvL2luaXRpYWxpemUgdGhlIGFyZ3VtZW50IGxpc3QKICAgIFVfTUFJTl9JTklUX0FSR1MoYXJnYywgYXJndik7CiAgICAvL3BhcnNlIHRoZSBhcmd1bWVudHMKICAgIGludDMyX3QgX3JlbWFpbmluZ0FyZ2MgPSB1X3BhcnNlQXJncyhhcmdjLCAoY2hhcioqKWFyZ3YsIChpbnQzMl90KShzaXplb2Yob3B0aW9ucykvc2l6ZW9mKG9wdGlvbnNbMF0pKSwgb3B0aW9ucyk7CgogICAgLy8gTm93IHNldHVwIHRoZSBhcmd1bWVudHMKICAgIGlmKGFyZ2M9PTEgfHwgb3B0aW9uc1tIRUxQMV0uZG9lc09jY3VyIHx8IG9wdGlvbnNbSEVMUDJdLmRvZXNPY2N1cikgewogICAgICAgIGZwcmludGYoc3RkZXJyLHVzYWdlU3RyaW5nKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYob3B0aW9uc1tTT1VSQ0VESVJdLmRvZXNPY2N1cikgewogICAgICAgIHNyY0RpciA9IG9wdGlvbnNbU09VUkNFRElSXS52YWx1ZTsKICAgIH0KICAgIGlmKG9wdGlvbnNbREVTVERJUl0uZG9lc09jY3VyKSB7CiAgICAgICAgZGVzdERpciA9IG9wdGlvbnNbREVTVERJUl0udmFsdWU7CiAgICB9CglpZihvcHRpb25zW1BBQ0tBR0VfTkFNRV0uZG9lc09jY3VyKSB7CiAgICAgICAgcGFja2FnZU5hbWUgPSBvcHRpb25zW1BBQ0tBR0VfTkFNRV0udmFsdWU7CiAgICB9CiAgICBpZihvcHRpb25zW0lHTk9SRV9DT0xMQVRJT05dLmRvZXNPY2N1cil7CiAgICAgICAgaWdub3JlQ29sbGF0aW9uID0gVFJVRTsKICAgIH0KICAgIGlmKG9wdGlvbnNbQkFTRV0uZG9lc09jY3VyKXsKICAgICAgICBiYXNlQ29sbGF0aW9uID0gb3B0aW9uc1tCQVNFXS52YWx1ZTsKICAgIH0KICAgIGlmKG9wdGlvbnNbQkFTRV9UWVBFXS5kb2VzT2NjdXIpewogICAgICAgIGJhc2VDb2xsYXRpb24gPSBvcHRpb25zW0JBU0VfVFlQRV0udmFsdWU7CiAgICB9CiAgICBpZihvcHRpb25zW0lHTk9SRV9TUEVDSUFMU10uZG9lc09jY3VyKXsKICAgICAgICBpZ25vcmVTcGVjaWFscyA9IFRSVUU7CiAgICB9CiAgICBpZihvcHRpb25zW0lHTk9SRV9MQVlPVVRdLmRvZXNPY2N1cil7CiAgICAgICAgaWdub3JlTGF5b3V0ID0gVFJVRTsKICAgIH0KICAgIGlmKG9wdGlvbnNbRFJBRlRdLmRvZXNPY2N1cil7CiAgICAgICAgaXNEcmFmdCA9IFRSVUU7CiAgICB9CiAgICBpZihvcHRpb25zW09OTFlfU1BFQ0lBTFNdLmRvZXNPY2N1cil7CiAgICAgICAgb25seVNwZWNpYWxzID0gVFJVRTsKICAgIH0KI2lmbmRlZiBHRU5MRE1MX05PU0VUQVBQREFUQQogICAgLyogVGVsbCBJQ1Ugd2hlcmUgb3VyIHJlc291cmNlIGRhdGEgaXMgbG9jYXRlZCBpbiBtZW1vcnkuCiAgICAgKiAgIFRoZSBkYXRhIGxpdmVzIGluIHRoZSBnZW5sZG1sX3Jlc291cmNlcyBkbGwsIGFuZCB3ZSBqdXN0CiAgICAgKiAgIHBhc3MgdGhlIGFkZHJlc3Mgb2YgYW4gZXhwb3J0ZWQgc3ltYm9sIGZyb20gdGhhdCBsaWJyYXJ5CiAgICAgKiAgIHRvIElDVS4KICAgICAqLwogICAgdWRhdGFfc2V0QXBwRGF0YSgiZ2VubGRtbF9yZXNvdXJjZXMiLCAmZ2VubGRtbF9yZXNvdXJjZXNfZGF0LCAmZXJyKTsKICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiJXM6IHVyZXNfb3BlbiBmYWlsZWQgd2l0aCBlcnJvciBcIiVzXCJcbiIsIGFyZ3ZbMF0sIHVfZXJyb3JOYW1lKGVycikpOwogICAgICAgIGV4aXQoLTEpOwogICAgfQojZW5kaWYKCglpZihzcmNEaXIhPU5VTEwpewoJCXBhdGggPSAoY2hhciopIG1hbGxvYyhzdHJsZW4oc3JjRGlyKSsoKHBhY2thZ2VOYW1lIT1OVUxMKSA/IHN0cmxlbihwYWNrYWdlTmFtZSkgOiAwICkrMik7CgkJc3RyY3B5KHBhdGgsc3JjRGlyKTsKCQlpZihwYXRoWyhzdHJsZW4oc3JjRGlyKS0xKV0hPVVfRklMRV9TRVBfQ0hBUil7CgkJCXN0cmNhdChwYXRoLFVfRklMRV9TRVBfU1RSSU5HKTsKCQl9CgkJaWYocGFja2FnZU5hbWUhPU5VTEwpewoJCQlzdHJjYXQocGF0aCxwYWNrYWdlTmFtZSk7CgkJfQoJfQogICAgaWYoX3JlbWFpbmluZ0FyZ2M8MCkgewogICAgICAgIGZwcmludGYoc3RkZXJyLHVzYWdlU3RyaW5nKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9Cglmb3IoaW50IGk9MTsgaTxfcmVtYWluaW5nQXJnYzsgaSsrKXsKCgkJR2VuZXJhdGVYTUwgZ2VuKHBhdGgsYXJndltpXSxkZXN0RGlyLGVycik7CgkJaWYoVV9GQUlMVVJFKGVycikpewoJCQlmcHJpbnRmKHN0ZGVyciwiUmVhZGluZyBvZiByZXNvdXJjZSBmaWxlIGZhaWxlZC4gRXJyb3I6ICVzXG4iLHVfZXJyb3JOYW1lKGVycikpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWdlbi5Eb0l0KCk7CgkJCgl9CglmcmVlKHBhdGgpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQzMl90Cml0b3UgKFVDaGFyICogYnVmZmVyLCB1aW50MzJfdCBpLCB1aW50MzJfdCByYWRpeCwgaW50MzJfdCBwYWQpCnsKICAgIGludDMyX3QgbGVuZ3RoID0gMDsKICAgIGludDMyX3QgbnVtID0gMDsKICAgIGludCBkaWdpdDsKICAgIGludDMyX3QgajsKICAgIFVDaGFyIHRlbXA7CgogICAgZG97CiAgICAgICAgZGlnaXQgPSAoaW50KShpICUgcmFkaXgpOwogICAgICAgIGJ1ZmZlcltsZW5ndGgrK109KFVDaGFyKShkaWdpdDw9OT8oMHgwMDMwK2RpZ2l0KTooMHgwMDMwK2RpZ2l0KzcpKTsKICAgICAgICBpPWkvcmFkaXg7CiAgICB9IHdoaWxlKGkpOwoKICAgIHdoaWxlIChsZW5ndGggPCBwYWQpewogICAgICAgIGJ1ZmZlcltsZW5ndGgrK10gPSAoVUNoYXIpIDB4MDAzMDsvKnplcm8gcGFkZGluZyAqLwogICAgfQogICAgLyogbnVsbCB0ZXJtaW5hdGUgdGhlIGJ1ZmZlciAqLwogICAgaWYobGVuZ3RoPE1BWF9ESUdJVFMpewogICAgICAgIGJ1ZmZlcltsZW5ndGhdID0gKFVDaGFyKSAweDAwMDA7CiAgICB9CiAgICBudW09IChwYWQ+PWxlbmd0aCkgPyBwYWQgOmxlbmd0aDsKCiAgICAvKiBSZXZlcnNlcyB0aGUgc3RyaW5nICovCiAgICBmb3IgKGogPSAwOyBqIDwgKG51bSAvIDIpOyBqKyspewogICAgICAgIHRlbXAgPSBidWZmZXJbKGxlbmd0aC0xKSAtIGpdOwogICAgICAgIGJ1ZmZlclsobGVuZ3RoLTEpIC0gal0gPSBidWZmZXJbal07CiAgICAgICAgYnVmZmVyW2pdID0gdGVtcDsKICAgIH0KICAgIHJldHVybiBsZW5ndGg7Cn0KCgpHZW5lcmF0ZVhNTDo6R2VuZXJhdGVYTUwoY29uc3QgY2hhciogcGF0aCwgY29uc3QgY2hhciogbG9jTmFtZSxjb25zdCBjaGFyKiBkZXN0RGlyLCBVRXJyb3JDb2RlJiBlcnIpCgkJCQkJCSA6ICBtU291cmNlQnVuZGxlKHBhdGgsIGxvY05hbWUsZXJyKSwgbVN0cmluZ3NCdW5kbGUoImdlbmxkbWxfcmVzb3VyY2VzIiwicm9vdCIsIGVyciksbUVycm9yKGVycil7CiAgICBtRmlsZT1OVUxMOwogICAgaWYoVV9TVUNDRVNTKGVycikpewogICAgICAgCgkgICAgbUxvY2FsZT1Mb2NhbGUobG9jTmFtZSk7CgkgICAgbUZpbGU9Z2V0RmlsZUhhbmRsZShkZXN0RGlyLGxvY05hbWUpOwogICAgICAgIEdlbmVyYXRlWE1MOjpsb2NOYW1lID0gbG9jTmFtZTsKICAgICAgICBHZW5lcmF0ZVhNTDo6cGF0aCA9IHBhdGg7CiAgICAgICAgR2VuZXJhdGVYTUw6OmRlc3REaXIgPSBkZXN0RGlyOwovLwkJR2VuZXJhdGVYTUw6OnBhY2thZ2VOYW1lID0gcGFja2FnZU5hbWU7CgkgICAgaWYobUZpbGU9PU5VTEwpewogICAgICAgICAgICBjbG9zZUZpbGVIYW5kbGUoKTsKCQkgICAgZXhpdChVX0ZJTEVfQUNDRVNTX0VSUk9SKTsKICAgICAgICB9CgoJICAgIGluZGVudE9mZnNldD0iIjsKICAgIH0KCn0KR2VuZXJhdGVYTUw6On5HZW5lcmF0ZVhNTCgpCnsKCiAgICBjbG9zZUZpbGVIYW5kbGUoKTsKCn0KCnZvaWQgR2VuZXJhdGVYTUw6OmNsb3NlRmlsZUhhbmRsZSgpewogICAgaWYobUZpbGUpewoJICAgIGZjbG9zZShtRmlsZSk7CiAgICB9Cn0Kdm9pZCBHZW5lcmF0ZVhNTDo6RG9JdCgpewogICAgd3JpdGVYTUxWZXJzaW9uQW5kQ29tbWVudHMoKTsKICAgIHdyaXRlSWRlbnRpdHkoKTsKICAgIGlmKG9ubHlTcGVjaWFscz09RkFMU0UpewoJICAgIHdyaXRlRGlzcGxheU5hbWVzKCk7CgkgICAgd3JpdGVMYXlvdXQoKTsKICAgIH0KCS8vIFdBUk5JTkc6IGRvIG5vdCBjaGFuZ2UgdGhlIG9yZGVyCiAgICAvLyB0aGUgZ2VuZXJhdGVkIFhNTCB3aWxsIG5vdCB2YWxpZGF0ZSEhIQogICAgd3JpdGVFbmNvZGluZ3MoKTsKICAgIAogICAgaWYob25seVNwZWNpYWxzPT1GQUxTRSl7CgkgICAgd3JpdGVEZWxpbWl0ZXJzKCk7CgkgICAgd3JpdGVNZWFzdXJlbWVudCgpOwoJICAgIHdyaXRlRGF0ZXMoKTsKCSAgICB3cml0ZU51bWJlckZvcm1hdCgpOwogICAgfQogICAgaWYoaWdub3JlQ29sbGF0aW9uID09IEZBTFNFKXsKCSAgICB3cml0ZUNvbGxhdGlvbnMoKTsKICAgIH0KICAgIHdyaXRlU3BlY2lhbCgpOwogICAgLy9pZihzdHJjbXAobG9jTmFtZSwgInJvb3QiKT09MCl7CiAgICAgICAgd3JpdGVTdXBwbGVtZW50YWxEYXRhKCk7CiAgICAvL30KLyoJCgl3cml0ZVRyYW5zbGl0ZXJhdGlvbigpOwoJd3JpdGVCb3VuZGFyeSgpOwovLwl3cml0ZU1pc2MoKTsKICAgIHdyaXRlUG9zaXhBZGRpdGlvbnMoKTsKICAgIHdyaXRlUG9zaXhDb21wRGF0YSgpOwoqLwogCWNsb3NlWE1MRG9jdW1lbnQoKTsJCn0Kdm9pZCBHZW5lcmF0ZVhNTDo6Y2hvcEluZGVudCgpewoKCWluZGVudE9mZnNldC5yZW1vdmUoKGluZGVudE9mZnNldC5sZW5ndGgoKS0xKSwxKTsKfQppbnQzMl90IEdlbmVyYXRlWE1MOjpjb3B5VW5pY29kZVN0cmluZ1RvQ2hhcnMoY29uc3QgVW5pY29kZVN0cmluZyYgc3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyKiBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYnVmQ2FwYWNpdHkpIHsKICAgIGludDMyX3QgbGVuID0gc3RyLmxlbmd0aCgpOwogICAgaWYgKGJ1ZiAhPSAwKSB7CiAgICAgICAgLy8gY29weSB3aGF0ZXZlciB3aWxsIGZpdCBpbnRvIGJ1ZgogICAgICAgIGludDMyX3QgbGVuMiA9ICAobGVuPChidWZDYXBhY2l0eSAtIDEpKT8gbGVuIDogKGJ1ZkNhcGFjaXR5LTEpOwogICAgICAgIHN0ci5leHRyYWN0KDAsIGxlbjIsIGJ1ZiwgIiIpOwogICAgICAgIGJ1ZltsZW4yXSA9IDA7IC8vIHplcm8tdGVybWluYXRlCiAgICB9CiAgICByZXR1cm4gbGVuOyAvLyByZXR1cm4gYWN0dWFsIGxlbmd0aCAgICAKfQp2b2lkIEdlbmVyYXRlWE1MOjpjbG9zZVhNTERvY3VtZW50KCl7CgljaG9wSW5kZW50KCk7CglGb3JtYXR0YWJsZSBhcmdzW10gPSB7VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKSwgIiJ9OwoJVW5pY29kZVN0cmluZyB4bWxTdHJpbmc7Cglmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImxvY2FsZURhdGEiLG1FcnJvciksYXJncywyLHhtbFN0cmluZyk7CglwcmludFN0cmluZygmeG1sU3RyaW5nKTsKfQpVbmljb2RlU3RyaW5nIEdlbmVyYXRlWE1MOjpmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyYgc3RyLFVuaWNvZGVTdHJpbmcmIGFyZ3VtZW50LFVuaWNvZGVTdHJpbmcmIHJlc3VsdCl7CglGb3JtYXR0YWJsZSBhcmdzW10gPXsgYXJndW1lbnR9OwoJTWVzc2FnZUZvcm1hdCBmb3JtYXQoc3RyLG1FcnJvcik7CglGaWVsZFBvc2l0aW9uIGZwb3M9MDsKCXJlc3VsdC5yZW1vdmUoKTsKCWZvcm1hdC5mb3JtYXQoYXJncywxLCByZXN1bHQsZnBvcyxtRXJyb3IpOwovLwlpZihVX0ZBSUxVUkUobUVycm9yKSkgewovLwkJcmV0dXJuIFVuaWNvZGVTdHJpbmcoIklsbGVnYWwgYXJndW1lbnQiKTsKLy8JfQoKCXJldHVybiByZXN1bHQ7Cn0KCgpVbmljb2RlU3RyaW5nIEdlbmVyYXRlWE1MOjpmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyYgc3RyLGNvbnN0IEZvcm1hdHRhYmxlKiBhcmdzLGludDMyX3QgbnVtLFVuaWNvZGVTdHJpbmcmIHJlc3VsdCl7CglGaWVsZFBvc2l0aW9uIGZwb3M9MDsKCU1lc3NhZ2VGb3JtYXQgZm9ybWF0KHN0cixtRXJyb3IpOwoJcmVzdWx0LnJlbW92ZSgpOwoJZm9ybWF0LmZvcm1hdChhcmdzLG51bSwgcmVzdWx0LGZwb3MsbUVycm9yKTsKLy8JaWYoVV9GQUlMVVJFKG1FcnJvcikpIHsKLy8JCXJldHVybiBVbmljb2RlU3RyaW5nKCJJbGxlZ2FsIGFyZ3VtZW50Iik7Ci8vCX0KCXJldHVybiByZXN1bHQ7Cn0KCgpGSUxFKiBHZW5lcmF0ZVhNTDo6Z2V0RmlsZUhhbmRsZShjb25zdCBjaGFyKiBwYXRoLCBjb25zdCBjaGFyKiBuYW1lKQp7CgkKCUZJTEUqIGZpbGU7CgljaGFyIGZpbGVOYW1lWzI1Nl07CiAgICBpZighcGF0aCl7CiAgICAgICAgcGF0aD0iLiI7CiAgICB9CiAgICBpZihVX0ZBSUxVUkUobUVycm9yKSApIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gCglzdHJjcHkoZmlsZU5hbWUscGF0aCk7CiAgICBpZihwYXRoWyBzdHJsZW4ocGF0aCktMV0gIT0nXFwnKXsKICAgICAgICAgc3RyY2F0KGZpbGVOYW1lLCJcXCIpOwogICAgfQoJIHN0cmNhdChmaWxlTmFtZSwgbmFtZSApOwogICAgIHN0cmNhdChmaWxlTmFtZSwgIi54bWwiKTsKCiAgICAvKiBvcGVuIHRoZSBvdXRwdXQgZmlsZSAqLwogICAgZmlsZT1mb3BlbihmaWxlTmFtZSwidyIpOwoKICAgIAogICAgaWYoZmlsZT09TlVMTCkgewoJCQogICAgICAgIG1FcnJvcj1VX0ZJTEVfQUNDRVNTX0VSUk9SOwoJCXByaW50ZigiQ291bGQgbm90IG9wZW4gZmlsZSAlcyBmb3Igd3JpdGluZy5cbiIsZmlsZU5hbWUpOwoJCWV4aXQoVV9GSUxFX0FDQ0VTU19FUlJPUik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9ZWxzZXsKICAgICAgICBwcmludGYoIm9wZW5lZCBmaWxlICVzIGluIGRpcmVjdG9yeSAlc1xuIiwgZmlsZU5hbWUsIHBhdGgpOwogICAgfQoKCXJldHVybiBmaWxlOwp9CgoKaW50MzJfdCAKR2VuZXJhdGVYTUw6OmZpbGxPdXRwdXRTdHJpbmcoY29uc3QgVW5pY29kZVN0cmluZyAmdGVtcCwKICAgICAgICAgICAgICAgICAgICAgIFVDaGFyICpkZXN0LCAKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgZGVzdENhcGFjaXR5KSB7CiAgaW50MzJfdCBsZW5ndGggPSB0ZW1wLmxlbmd0aCgpOwoKICBpZiAoZGVzdENhcGFjaXR5ID4gMCkgewogICAgLy8gY29weSB0aGUgY29udGVudHM7IGV4dHJhY3QoKSB3aWxsIGNoZWNrIGlmIGl0IG5lZWRzIHRvIGNvcHkgYW55dGhpbmcgYXQgYWxsCiAgICB0ZW1wLmV4dHJhY3QoMCwgZGVzdENhcGFjaXR5LCBkZXN0LCAwKTsKCiAgICAvLyB6ZXJvLXRlcm1pbmF0ZSB0aGUgZGVzdCBidWZmZXIgaWYgcG9zc2libGUKICAgIGlmIChsZW5ndGggPCBkZXN0Q2FwYWNpdHkpIHsKICAgICAgZGVzdFtsZW5ndGhdID0gMDsKICAgIH0KICB9CgogIC8vIHNldCB0aGUgZXJyb3IgY29kZSBhY2NvcmRpbmcgdG8gdGhlIG5lY2Vzc2FyeSBidWZmZXIgbGVuZ3RoCiAgaWYgKGxlbmd0aCA+IGRlc3RDYXBhY2l0eSAmJiBVX1NVQ0NFU1MobUVycm9yKSkgewogICAgbUVycm9yID0gVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1I7CiAgfQoKICAvLyByZXR1cm4gdGhlIGZ1bGwgc3RyaW5nIGxlbmd0aAogIHJldHVybiBsZW5ndGg7Cn0Kdm9pZCBHZW5lcmF0ZVhNTDo6cHJpbnRTdHJpbmcoVW5pY29kZVN0cmluZyogdVN0cmluZyl7CiAgICBwcmludFN0cmluZyh1U3RyaW5nLG1GaWxlKTsKfQp2b2lkIEdlbmVyYXRlWE1MOjpwcmludFN0cmluZyhVbmljb2RlU3RyaW5nKiB1U3RyaW5nLCBGSUxFKiBmaWxlKXsKCgkvL1VDaGFyIHJlc3VsdFsyNTZdOwoJY2hhciAqZGVzdCA9IE5VTEw7CglpbnQzMl90IGRlc3RMZW4gPSAwOwoJaW50MzJfdCBkZXN0Q2FwID0wOwoJY29uc3QgVUNoYXIqIHNyYyA9IHVTdHJpbmctPmdldEJ1ZmZlcigpOwogICAgaW50MzJfdCBzcmNMZW49dVN0cmluZy0+bGVuZ3RoKCk7CiAgICBpZihVX0ZBSUxVUkUobUVycm9yKSl7CiAgICAgICBmcHJpbnRmKHN0ZGVyciwiRXJyb3Igb24gZW50ZXJpbmcgdGhlIHByaW50U3RyaW5nIGZ1Y250aW9uLiBFcnJvcjogJXMuIFJldHVybmluZy4iLCB1X2Vycm9yTmFtZShtRXJyb3IpKTsKICAgIH0KCXVfc3RyVG9VVEY4KGRlc3QsZGVzdENhcCwgJmRlc3RMZW4sc3JjLHNyY0xlbiwmbUVycm9yKTsKCWlmKG1FcnJvciA9PSBVX0JVRkZFUl9PVkVSRkxPV19FUlJPUil7CgkJCWRlc3RDYXAgPSBkZXN0TGVuKzI7CgkJCWRlc3QgPSAoY2hhciopIG1hbGxvYyhkZXN0Q2FwKTsKCQkJbUVycm9yID0gVV9aRVJPX0VSUk9SOwoJCQlkZXN0ID0gdV9zdHJUb1VURjgoZGVzdCxkZXN0Q2FwLCAmZGVzdExlbixzcmMsc3JjTGVuLCZtRXJyb3IpOwoJCQlmd3JpdGUoZGVzdCxkZXN0TGVuLHNpemVvZihjaGFyKSxmaWxlKTsKCX0KCgl1U3RyaW5nLT5yZWxlYXNlQnVmZmVyKCk7CglmcmVlKGRlc3QpOwoJaWYoVV9GQUlMVVJFKG1FcnJvcikpewoJCWZwcmludGYoc3RkZXJyLCJDb252ZXJzaW9uIG9mIHN0cmluZyB0byBVVEYtOCBmYWlsZWQgd2l0aCBlcnJvcjogJXNcbiIsdV9lcnJvck5hbWUobUVycm9yKSk7CgkJZXhpdChtRXJyb3IpOwoJfQp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZVhNTFZlcnNpb25BbmRDb21tZW50cygpewoJCglVbmljb2RlU3RyaW5nIHhtbFN0cmluZzsKCWlmKFVfRkFJTFVSRShtRXJyb3IpKSB7CiAgICAgICAgcmV0dXJuOwoJfQoJVW5pY29kZVN0cmluZyB0ZW1wOwogICAgaWYoaWdub3JlU3BlY2lhbHM9PUZBTFNFKXsKICAgICAgICB0ZW1wID0gbVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImRlY2xhcmF0aW9uIixtRXJyb3IpOwogICAgfWVsc2V7CiAgICAgICAgdGVtcCA9IG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkZWNsYXJhdGlvbk5vU3BlY2lhbHMiLG1FcnJvcik7CiAgICB9CiAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXApOwogICAgRm9ybWF0dGFibGUgYXJndW1lbnRzW10gPSB7IiIsIChpc0RyYWZ0PT1UUlVFKT8gIiBkcmFmdD1cInRydWVcIiIgOiAiIn07CglVbmljb2RlU3RyaW5nIHRlbXBTdHI7Cgl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibG9jYWxlRGF0YSIsbUVycm9yKSxhcmd1bWVudHMsMix0ZW1wU3RyKSk7CglwcmludFN0cmluZygmeG1sU3RyaW5nKTsKICAgIG1FcnJvcj1VX1pFUk9fRVJST1I7Cn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlVmVyc2lvbihVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoJVW5pY29kZVN0cmluZyB0ZW1wU3RyOwoJVW5pY29kZVN0cmluZyB2ZXJzaW9uOwoJaWYoVV9GQUlMVVJFKG1FcnJvcikpIHsKICAgICAgICByZXR1cm47Cgl9Cgl2ZXJzaW9uPW1Tb3VyY2VCdW5kbGUuZ2V0U3RyaW5nRXgoIlZlcnNpb24iLG1FcnJvcik7CgkvLyBpZiB2ZXJzaW9uIGlzIG5vdCBhdmFpbGFibGUgcHJvdmlkZSBhIGRlZmF1bHQgdmVyc2lvbi4KICAgIGlmKCBtRXJyb3IgPT0gVV9VU0lOR19ERUZBVUxUX1dBUk5JTkcgfHwKCQltRXJyb3IgPT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HIHx8IAoJCW1FcnJvciA9PSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1IpewogICAgICAgIHZlcnNpb249IjEuMCI7CiAgICAgICAgbUVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgfQoJRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwiIn07CglVbmljb2RlU3RyaW5nIHJlc3VsdDsKCWlmKCF2ZXJzaW9uLmlzRW1wdHkoKSl7CgkJYXJnc1swXT1pbmRlbnRPZmZzZXQ7CgkJYXJnc1sxXT12ZXJzaW9uOwogICAgICAgIC8vVE9ETzogcmVtb3ZlIHRoaXMKICAgICAgICAvL2FyZ3NbMV0gPSAiMS4wLWFscGhhIjsKICAgICAgIAl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgidmVyc2lvbiIsbUVycm9yKSxhcmdzLDIscmVzdWx0KSk7CgoJfQoJYXJnc1swXT1pbmRlbnRPZmZzZXQ7CglhcmdzWzFdPSBVbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwoJYXJnc1syXT0iIjsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJ2ZXJzaW9uaW5nIixtRXJyb3IpLCBhcmdzLDMscmVzdWx0KSk7CgkvL3ByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwogICAgbUVycm9yPVVfWkVST19FUlJPUjsKCn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlSWRlbnRpdHkoKXsKCVVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nLCB0ZW1wU3RyLHRlbXBTdHIxLHRlbXBTdHIyOwoJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCUZvcm1hdHRhYmxlIGFyZ3NbXT17aW5kZW50T2Zmc2V0LCIiLCIifTsKCQoJZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJpZGVudGl0eSIsbUVycm9yKSxhcmdzLDIseG1sU3RyaW5nKTsKICAgIAoJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCS8vdmVyc2lvbgoJd3JpdGVWZXJzaW9uKHhtbFN0cmluZyk7CgkvL2dlbnJhdGlvbkRhdGUKCVNpbXBsZURhdGVGb3JtYXQgZm9ybWF0KFVuaWNvZGVTdHJpbmcoInl5eXktTU0tZGQiKSwgbUVycm9yKTsKCWZvcm1hdC5mb3JtYXQoQ2FsZW5kYXI6OmdldE5vdygpLHRlbXBTdHIpOwoJYXJnc1swXT1pbmRlbnRPZmZzZXQ7CiAgICBhcmdzWzFdPXRlbXBTdHI7Cgl0ZW1wU3RyLnJlbW92ZSgpOwoJCiAgICAKICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJnZW5lcmF0aW9uRGF0ZSIsbUVycm9yKSxhcmdzLDIsdGVtcFN0cikpOwoKCXRlbXBTdHIxPW1Mb2NhbGUuZ2V0SVNPM0xhbmd1YWdlKCkgOwoJdGVtcFN0cjI9bUxvY2FsZS5nZXRMYW5ndWFnZSgpOwogICAgCglpZighIHRlbXBTdHIyLmlzRW1wdHkoKSl7CiAgICAgICAgLy9pZih0ZW1wU3RyMiA9PSAicm9vdCIpewogICAgICAgIC8vICAgIHRlbXBTdHIyID0iIjsKICAgICAgICAvL30KCQlGb3JtYXR0YWJsZSBhcmdzMVtdID0ge2luZGVudE9mZnNldCwgdGVtcFN0cjIsIiJ9OwoJCVVuaWNvZGVTdHJpbmcgdDsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibGFuZ3VhZ2VFbGVtIixtRXJyb3IpLGFyZ3MxLDMsdCkpOwoJfQoJdGVtcFN0cjEucmVtb3ZlKCk7Cgl0ZW1wU3RyMi5yZW1vdmUoKTsKCiAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7CgogICAgdGVtcFN0ci5yZW1vdmUoKTsKICAgIHRlbXBTdHIgPSBtTG9jYWxlLmdldFNjcmlwdCgpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpICYmIHRlbXBTdHIhPSJ0Iil7CgkJRm9ybWF0dGFibGUgYXJnczFbXSA9IHtpbmRlbnRPZmZzZXQsIHRlbXBTdHJ9OwoJCVVuaWNvZGVTdHJpbmcgdDsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgic2NyaXB0RWxlbSIsbUVycm9yKSxhcmdzMSwyLHQpKTsKCX0KCiAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7CgoJdGVtcFN0cjE9bUxvY2FsZS5nZXRDb3VudHJ5KCk7Cgl0ZW1wU3RyMj1tTG9jYWxlLmdldElTTzNDb3VudHJ5KCk7CgoJaWYoISh0ZW1wU3RyMS5pc0VtcHR5KCkgJiYgdGVtcFN0cjIuaXNFbXB0eSgpKSl7CgkJRm9ybWF0dGFibGUgYXJnczFbXSA9IHtpbmRlbnRPZmZzZXQsdGVtcFN0cjEsdGVtcFN0cjJ9OwoJCVVuaWNvZGVTdHJpbmcgdDsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgidGVycml0b3J5RWxlbSIsbUVycm9yKSxhcmdzMSwyLHQpKTsKCX0KCWlmKG1FcnJvcj09VV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SKXsKCQltRXJyb3I9VV9aRVJPX0VSUk9SOwoJfQoJCiAgICB0ZW1wU3RyLnJlbW92ZSgpOwoJdGVtcFN0cj1tTG9jYWxlLmdldFZhcmlhbnQoKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSAmJiB0ZW1wU3RyIT0idCIpewoJCUZvcm1hdHRhYmxlIGFyZ3MxW10gPSB7aW5kZW50T2Zmc2V0LCB0ZW1wU3RyfTsKCQlVbmljb2RlU3RyaW5nIHQ7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInZhcmlhbnRFbGVtIixtRXJyb3IpLGFyZ3MxLDIsdCkpOwoJfQogICAgCglSZXNvdXJjZUJ1bmRsZSB0YiAgPSBtU291cmNlQnVuZGxlLmdldCgiTG9jYWxlSUQiLG1FcnJvcik7CiAgICBVUmVzVHlwZSB0eXBlID0gdGIuZ2V0VHlwZSgpOwoJY2hvcEluZGVudCgpOwoJYXJnc1swXT1pbmRlbnRPZmZzZXQ7CglhcmdzWzFdPQkoVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKSk7CglhcmdzWzJdPSAiIjsKICAgIG1FcnJvciA9VV9aRVJPX0VSUk9SOwoJVW5pY29kZVN0cmluZyB0OwoJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImlkZW50aXR5IixtRXJyb3IpLGFyZ3MsMix0KSk7CglwcmludFN0cmluZygmeG1sU3RyaW5nKTsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVEaXNwbGF5TmFtZXMoKXsKCVVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nOwoJVUJvb2wgcHJpbnQgPSBGQUxTRTsKCWlmKFVfRkFJTFVSRShtRXJyb3IpKSB7CgkJcmV0dXJuOwoJfQoJRm9ybWF0dGFibGUgYXJnc1tdPXtpbmRlbnRPZmZzZXQsIiIsIiJ9OwoJVW5pY29kZVN0cmluZyB0OwoJeG1sU3RyaW5nPSBmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImxvY2FsZURpc3BsYXlOYW1lcyIsbUVycm9yKSxhcmdzLDMsdCk7CglVbmljb2RlU3RyaW5nIHRlbXBTdHI7CglpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoKCgl3cml0ZUxhbmd1YWdlKHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KCgl3cml0ZVNjcmlwdCh0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9CgoJd3JpdGVDb3VudHJ5TmFtZXModGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoKCXdyaXRlVmFyaWFudE5hbWVzKHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KCXdyaXRlS2V5d29yZE5hbWVzKHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KCXdyaXRlVHlwZU5hbWVzKHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KCWNob3BJbmRlbnQoKTsKCglGb3JtYXR0YWJsZSBhcmdzMVtdPXtpbmRlbnRPZmZzZXQsKFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCkpLCIifTsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJsb2NhbGVEaXNwbGF5TmFtZXMiLG1FcnJvcikgLGFyZ3MxLDMsdCkpOwoJaWYocHJpbnQpICBwcmludFN0cmluZygmeG1sU3RyaW5nKTsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVUYWJsZShjb25zdCBjaGFyKiBrZXksIGNvbnN0IGNoYXIqIHJlc01haW4sIGNvbnN0IGNoYXIqIHJlc0VsZW1lbnQsIFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgoJaWYoVV9GQUlMVVJFKG1FcnJvcikpIHsKCQlyZXR1cm47Cgl9CglGb3JtYXR0YWJsZSBhcmdzW109e2luZGVudE9mZnNldCwiIiwiIn07CglVbmljb2RlU3RyaW5nIHQ7Cgl4bWxTdHJpbmc9IGZvcm1hdFN0cmluZyhVbmljb2RlU3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KHJlc01haW4sbUVycm9yKSksYXJncywzLHQpOwoKICAgIFJlc291cmNlQnVuZGxlIGRCdW5kbGU9bVNvdXJjZUJ1bmRsZS5nZXQoa2V5LG1FcnJvcik7CgogICAgaWYoIFVfU1VDQ0VTUyhtRXJyb3IpICAmJiAKICAgICAgICBtRXJyb3IgIT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAogICAgICAgIG1FcnJvciAhPSBVX1VTSU5HX0RFRkFVTFRfV0FSTklORyl7ICAKCQlVbmljb2RlU3RyaW5nIGZhbGxiYWNrTmFtZSA9IGRCdW5kbGUuZ2V0U3RyaW5nRXgoIkZhbGxiYWNrIixtRXJyb3IpOwoJCWlmKFVfU1VDQ0VTUyhtRXJyb3IpICYmIGZhbGxiYWNrTmFtZS5sZW5ndGgoKT4wKXsKCQkJLy8gd2Uga25vdyB0aGF0IHdlIGFyZSBwcm9jZXNzaW5nIElDVSBidW5kbGVzCgkJCWNoYXIgZmJOYW1lWzEwMF09ezB9OwoJCQlpbnQzMl90IGxlbiA9IGZhbGxiYWNrTmFtZS5leHRyYWN0KDAsZmFsbGJhY2tOYW1lLmxlbmd0aCgpLGZiTmFtZSwgMTAwKTsKCQkJZmJOYW1lW2xlbl09MDsvL251bGwgdGVybWluYXRlIHRoZSBhcnJheQoJCQlSZXNvdXJjZUJ1bmRsZSByb290QnVuZGxlKE5VTEwsICJyb290IixtRXJyb3IpOwoJCQlSZXNvdXJjZUJ1bmRsZSBmYWxsYmFja0J1bmRsZShOVUxMLCBmYk5hbWUsIG1FcnJvcik7CgkJCVJlc291cmNlQnVuZGxlIHJvb3REZWx0YSA9IHJvb3RCdW5kbGUuZ2V0KGtleSwgbUVycm9yKTsKICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUgZmFsbGJhY2tEZWx0YSA9IGZhbGxiYWNrQnVuZGxlLmdldChrZXksIG1FcnJvcik7CgkJCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgkJCXdoaWxlKHJvb3REZWx0YS5oYXNOZXh0KCkpewoJCQkJUmVzb3VyY2VCdW5kbGUgZGVsdGExID0gcm9vdERlbHRhLmdldE5leHQobUVycm9yKTsKCQkJCWNvbnN0IGNoYXIqIG15a2V5ID0gZGVsdGExLmdldEtleSgpOwoJCQkJVW5pY29kZVN0cmluZyBzdHJpbmcgPSBkQnVuZGxlLmdldFN0cmluZ0V4KG15a2V5LCBtRXJyb3IpOwogICAgICAgICAgICAgICAgaWYoc3RyY21wKG15a2V5LCAiRmFsbGJhY2siKSA9PSAwKXsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCQkJCWlmKGZhbGxiYWNrTmFtZS5sZW5ndGgoKSA+IDAgJiYgCiAgICAgICAgICAgICAgICAgICAgKG1FcnJvciA9PSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1IpKXsKCQkJCQkvLyBleHBsaWNpdCBmYWxsYmFjayBpcyBzZXQgCiAgICAgICAgICAgICAgICAgICAgbUVycm9yPVVfWkVST19FUlJPUjsKCQkJCQlzdHJpbmcgPSBmYWxsYmFja0RlbHRhLmdldFN0cmluZ0V4KG15a2V5LCBtRXJyb3IpOwoJCQkJfWVsc2UgaWYoc3RyaW5nLmxlbmd0aCgpPT0wKXsKCQkJCQlzdHJpbmcgPSByb290RGVsdGEuZ2V0U3RyaW5nRXgobXlrZXksIG1FcnJvcik7CgkJCQl9CgkJCQlGb3JtYXR0YWJsZSBhcmdzMVtdPXtpbmRlbnRPZmZzZXQsbXlrZXksc3RyaW5nfTsKCQkJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KHJlc0VsZW1lbnQsbUVycm9yKSxhcmdzMSwzLHQpKTsKCQkJCW1FcnJvcj1VX1pFUk9fRVJST1I7CgkJCX0KCQkJY2hvcEluZGVudCgpOwoJCQlGb3JtYXR0YWJsZSBhcmdzMVtdPXtpbmRlbnRPZmZzZXQsKFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCkpLCIifTsKCQkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgocmVzTWFpbixtRXJyb3IpICxhcmdzMSwzLHQpKTsKCQkJcmV0dXJuOwoKCQl9ZWxzZXsKCQkJbUVycm9yID0gVV9aRVJPX0VSUk9SOwoJCQlpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoJCQl3aGlsZShkQnVuZGxlLmhhc05leHQoKSl7CgkJCQlSZXNvdXJjZUJ1bmRsZSBkQnVuZGxlMSA9IGRCdW5kbGUuZ2V0TmV4dChtRXJyb3IpOwoJCQkJY29uc3QgY2hhciogbXlrZXk9ZEJ1bmRsZTEuZ2V0S2V5KCk7CiAgICAgICAgICAgICAgICBpZihzdHJjbXAobXlrZXksICJGYWxsYmFjayIpPT0wKXsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCQkJCVVuaWNvZGVTdHJpbmcgc3RyaW5nID0gZEJ1bmRsZS5nZXRTdHJpbmdFeChteWtleSxtRXJyb3IpOwogICAgICAgICAgICAgICAgCgkJCQlGb3JtYXR0YWJsZSBhcmdzMVtdPXtpbmRlbnRPZmZzZXQsbXlrZXksc3RyaW5nfTsKCQkJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KHJlc0VsZW1lbnQsbUVycm9yKSxhcmdzMSwzLHQpKTsKCQkJCW1FcnJvcj1VX1pFUk9fRVJST1I7CgkJCX0KCQkJY2hvcEluZGVudCgpOwoJCQlGb3JtYXR0YWJsZSBhcmdzMVtdPXtpbmRlbnRPZmZzZXQsKFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCkpLCIifTsKCQkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgocmVzTWFpbixtRXJyb3IpICxhcmdzMSwzLHQpKTsKCQkJcmV0dXJuOwoJCX0KICAgIH0KCQkJCQoJbUVycm9yPVVfWkVST19FUlJPUjsKCXhtbFN0cmluZy5yZW1vdmUoKTsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVMb2NhbGVTY3JpcHQoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKICAgIGlmKGlnbm9yZVNwZWNpYWxzID09IEZBTFNFKXsKICAgICAgICBSZXNvdXJjZUJ1bmRsZSBzY3JpcHRzPSBtU291cmNlQnVuZGxlLmdldCgiTG9jYWxlU2NyaXB0IixtRXJyb3IpOwoJICAgIFVuaWNvZGVTdHJpbmcgdDsKCgkgICAgaWYoIG1FcnJvciE9VV9VU0lOR19ERUZBVUxUX1dBUk5JTkcgJiYgCgkJICAgIG1FcnJvciE9VV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAoJCSAgICBVX1NVQ0NFU1MobUVycm9yKSl7CgoJICAgICAgICBGb3JtYXR0YWJsZSBhcmdzW109e2luZGVudE9mZnNldCxtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgieG1sbnNfaWN1IixtRXJyb3IpLCIiLCIifTsKCSAgICAgICAgVW5pY29kZVN0cmluZyB0OwoJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggInNwZWNpYWwiLG1FcnJvciksYXJncyw0LHQpKTsKCSAgICAgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsJCQogICAgICAgIAogICAgICAgICAgICBhcmdzWzBdPWluZGVudE9mZnNldDsKICAgICAgICAgICAgYXJnc1sxXT0iIjsKCQkgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImljdV9zY3JpcHRzIixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgICAgIGZvcihpbnQgaT0wO3NjcmlwdHMuaGFzTmV4dCgpO2krKyl7CiAgICAgICAgICAgICAgICBjaGFyIGNbMTBdPXswfTsKCQkJICAgIGl0b2EoaSsxLGMsMTApOwoJCQkgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkJICAgIGFyZ3NbMV0gPSBVbmljb2RlU3RyaW5nKGMpOwoJCQkgICAgYXJnc1syXSA9IHNjcmlwdHMuZ2V0TmV4dFN0cmluZyhtRXJyb3IpOwoJCQkgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImljdV9zY3JpcHQiLG1FcnJvciksYXJncywzLHQpKTsKCQkgICAgfQoJCSAgICBjaG9wSW5kZW50KCk7CgkJICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgkJICAgIGFyZ3NbMV0gPSBVbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwoJCSAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiaWN1X3NjcmlwdHMiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAKICAgICAgICAgICAgY2hvcEluZGVudCgpOwoJCSAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCSAgICBhcmdzWzFdID0gVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKCQkgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInNwZWNpYWxFbmQiLG1FcnJvciksYXJncywyLHQpKTsKCgkJICAgIG1FcnJvcj1VX1pFUk9fRVJST1I7CgkJICAgIHJldHVybjsKCSAgICB9CgkgICAgeG1sU3RyaW5nLnJlbW92ZSgpOwoJICAgIG1FcnJvcj0gVV9aRVJPX0VSUk9SOwogICAgfQoKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVTY3JpcHQoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCgl3cml0ZVRhYmxlKCJTY3JpcHRzIiwic2NyaXB0cyIsInNjcmlwdCIseG1sU3RyaW5nKTsJCQp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUxhbmd1YWdlKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgoJd3JpdGVUYWJsZSgiTGFuZ3VhZ2VzIiwibGFuZ3VhZ2VzIiwibGFuZ3VhZ2UiLHhtbFN0cmluZyk7Cn0KCgoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVDb3VudHJ5TmFtZXMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCgl3cml0ZVRhYmxlKCJDb3VudHJpZXMiLCJ0ZXJyaXRvcmllcyIsInRlcnJpdG9yeSIseG1sU3RyaW5nKTsKfQoKCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlVmFyaWFudE5hbWVzKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgogICAgd3JpdGVUYWJsZSgiVmFyaWFudHMiLCJ2YXJpYW50cyIsInZhcmlhbnQiLHhtbFN0cmluZyk7Cn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlS2V5d29yZE5hbWVzKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CiAgICB3cml0ZVRhYmxlKCJLZXlzIiwia2V5cyIsImtleSIseG1sU3RyaW5nKTsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVUeXBlTmFtZXMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCglVbmljb2RlU3RyaW5nIHRlbXBTdHI7CglGb3JtYXR0YWJsZSBhcmdzW10gPSB7IGluZGVudE9mZnNldCwgIiIsIiIsIiJ9OwogICAgZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJ0eXBlcyIsbUVycm9yKSxhcmdzLDIseG1sU3RyaW5nKTsKICAgIFJlc291cmNlQnVuZGxlIGRCdW5kbGU9bVNvdXJjZUJ1bmRsZS5nZXQoIlR5cGVzIixtRXJyb3IpOwoJVW5pY29kZVN0cmluZyB0OwoKICAgIGlmKCBVX1NVQ0NFU1MobUVycm9yKSAgJiYgCiAgICAgICAgbUVycm9yICE9IFVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiAKICAgICAgICBtRXJyb3IgIT0gVV9VU0lOR19ERUZBVUxUX1dBUk5JTkcpeyAgCgkJCgkJbUVycm9yID0gVV9aRVJPX0VSUk9SOwoJCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgkJd2hpbGUoZEJ1bmRsZS5oYXNOZXh0KCkpewoJCQlSZXNvdXJjZUJ1bmRsZSBkQnVuZGxlMSA9IGRCdW5kbGUuZ2V0TmV4dChtRXJyb3IpOwoJCQljb25zdCBjaGFyKiBrZXk9ZEJ1bmRsZTEuZ2V0S2V5KCk7CiAgICAgICAgICAgIGlmKHN0cmNtcChrZXksICJGYWxsYmFjayIpPT0wKXsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgkJCVJlc291cmNlQnVuZGxlIGRCdW5kbGUyID0gZEJ1bmRsZS5nZXQoa2V5LG1FcnJvcik7CiAgICAgICAgICAgIHdoaWxlKGRCdW5kbGUyLmhhc05leHQoKSl7CiAgICAgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZSBkQnVuZGxlMyA9IGRCdW5kbGUyLmdldE5leHQobUVycm9yKTsKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHR5cGUgPSBkQnVuZGxlMy5nZXRLZXkoKTsKICAgICAgICAgICAgICAgIGlmKHN0cmNtcCh0eXBlLCAiRmFsbGJhY2siKT09MCl7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHZhbHVlID0gZEJ1bmRsZTMuZ2V0U3RyaW5nKG1FcnJvcik7CgkJCSAgICBGb3JtYXR0YWJsZSBhcmdzMVtdPXtpbmRlbnRPZmZzZXQsdHlwZSwga2V5LCB2YWx1ZX07CgoJCQkgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInR5cGUiLG1FcnJvciksYXJnczEsNCx0KSk7CiAgICAgICAgICAgIH0KCQkJbUVycm9yPVVfWkVST19FUlJPUjsKCQl9CgkJY2hvcEluZGVudCgpOwoJCUZvcm1hdHRhYmxlIGFyZ3MxW109e2luZGVudE9mZnNldCwoVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKSksIiJ9OwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJ0eXBlcyIsbUVycm9yKSAsYXJnczEsMyx0KSk7CgkJcmV0dXJuOwoJCQoJfQoJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCWFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CglhcmdzWzFdID0gIi8iOwoJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInR5cGVzIixtRXJyb3IpLGFyZ3MsMix0KSk7CglpZih0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLnJlbW92ZSgpOwoJfQogICAgbUVycm9yID1VX1pFUk9fRVJST1I7Cn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlTGF5b3V0KCl7CiAgICBpZihpZ25vcmVMYXlvdXQgPT0gRkFMU0UpewoJICAgIFVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nOwoJICAgIEZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsIiIsIiJ9OwoJICAgIFVuaWNvZGVTdHJpbmcgdDsKCSAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibGF5b3V0IiwgbUVycm9yKSwgYXJncywyLHQpKTsKCSAgICBVbmljb2RlU3RyaW5nIGxhbmcgPSBtTG9jYWxlLmdldExhbmd1YWdlKCk7CgkgICAgVW5pY29kZVN0cmluZyBjb3VudHJ5ID0gbUxvY2FsZS5nZXRDb3VudHJ5KCk7CgkgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKICAgICAgICBVQm9vbCByaWdodFRvTGVmdCA9IEZBTFNFOwoJICAgIGlmKGxhbmc9PSJhciIgfHwgbGFuZz09ImhlIiB8fCBsYW5nPT0iaWwiIHx8IGxhbmc9PSJwcyIgfHwgbGFuZz09ImZhIiApewoJCSAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCSAgICBhcmdzWzFdID0gInRvcC10by1ib3R0b20iOwoJCSAgICBhcmdzWzJdID0gInJpZ2h0LXRvLWxlZnQiOwoJCSAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgib3JpZW50YXRpb24iLG1FcnJvciksIGFyZ3MsMyx0KSk7CgkgICAgICAgIHJpZ2h0VG9MZWZ0ID0gVFJVRTsKICAgICAgICB9ZWxzZSBpZihsYW5nPT0gInJvb3QiKXsKCQkgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkgICAgYXJnc1sxXSA9ICJ0b3AtdG8tYm90dG9tIjsKCQkgICAgYXJnc1syXSA9ICJsZWZ0LXRvLXJpZ2h0IjsKCQkgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIm9yaWVudGF0aW9uIixtRXJyb3IpLCBhcmdzLDMsdCkpOwoJICAgIH0KCSAgICBjaG9wSW5kZW50KCk7CgkgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCSAgICBhcmdzWzFdID0gIi8iOwoJICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJsYXlvdXQiLG1FcnJvciksYXJncywyLHQpKTsKCSAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7CgkgICAgLy9wcmludCB0aGlzIG9ubHkgaW4gdGhlIHJvb3QgbGFuZ3VhZ2UgbG9jYWxlCgkgICAgaWYobGFuZz09InJvb3QiIHx8IHJpZ2h0VG9MZWZ0ID09IFRSVUUpewoJCSAgICBwcmludFN0cmluZygmeG1sU3RyaW5nKTsKCSAgICB9CiAgICB9Cn0Kdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVFbmNvZGluZ3MoKXsKCVVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nOwoJRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwiIiwiIn07CglVbmljb2RlU3RyaW5nIHQ7Cgl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY2hhcmFjdGVycyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKICAgIFVuaWNvZGVTdHJpbmcgdGVtcDsKICAgIFVCb29sIHdyaXRlRGF0YSA9IEZBTFNFOwoKICAgIGlmKG9ubHlTcGVjaWFscz09RkFMU0UpewogICAgICAgIHdyaXRlRXhlbXBsYXJDaGFyYWN0ZXJzKHRlbXApOwogICAgfQogICAgaWYodGVtcC5sZW5ndGgoKT4wKXsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXApOwogICAgICAgIHdyaXRlRGF0YSA9IFRSVUU7CiAgICB9CiAgICB0ZW1wLnJlbW92ZSgpOwogICAgLy9pZihpZ25vcmVTcGVjaWFscz09VFJVRSl7CiAgICAgICAgd3JpdGVMb2NhbGVTY3JpcHQodGVtcCk7CiAgICAvL30KICAgIGlmKHRlbXAubGVuZ3RoKCk+MCl7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wKTsKICAgICAgICB3cml0ZURhdGEgPSBUUlVFOwogICAgfQogICAgLy8gY3VycmVudGx5IG5vIG1hcHBpbmdzIGFyZSBkZWZpbmVkIGluIElDVSAKICAgIC8vIHNvIHdlIGRvbm90IGFkZCB0aGVtCiAgICBpZih3cml0ZURhdGEgPT0gVFJVRSl7CiAgICAgICAgY2hvcEluZGVudCgpOwogICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgkgICAgYXJnc1sxXSA9ICIvIjsKCSAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY2hhcmFjdGVycyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJICAgIHByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwogICAgfWVsc2V7CiAgICAgICAgeG1sU3RyaW5nLnJlbW92ZSgpOwogICAgfQoKICAgIG1FcnJvciA9IFVfWkVST19FUlJPUjsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVFeGVtcGxhckNoYXJhY3RlcnMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKICAgIEZvcm1hdHRhYmxlIGFyZ3NbXSA9IHsiIiwiIiwiIn07CiAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJYXJnc1sxXSA9IG1Tb3VyY2VCdW5kbGUuZ2V0U3RyaW5nRXgoIkV4ZW1wbGFyQ2hhcmFjdGVycyIsbUVycm9yKTsKCVVuaWNvZGVTdHJpbmcgdDsKCWlmKAltRXJyb3IgIT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAoJCW1FcnJvciAhPSBVX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQlVX1NVQ0NFU1MobUVycm9yKSl7CgkKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZXhlbXBsYXJDaGFyYWN0ZXJzIixtRXJyb3IpLGFyZ3MsMix0KSk7Cgl9CiAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7Cn0Kdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVEZWxpbWl0ZXJzKCl7Ci8vIERhdGEgbm90IGF2YWlsYWJsZSBpbiBJQ1UKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVNZWFzdXJlbWVudCgpewogICAgVW5pY29kZVN0cmluZyB4bWxTdHJpbmc7CiAgICB3cml0ZU1lYXN1cmVtZW50KHhtbFN0cmluZyk7CiAgICBpZih4bWxTdHJpbmcubGVuZ3RoKCk+MCkgIHByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwp9CgoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVEYXRlcygpewoJVW5pY29kZVN0cmluZyB4bWxTdHJpbmc7CglVQm9vbCBwcmludCA9IEZBTFNFOwoJaWYoVV9GQUlMVVJFKG1FcnJvcikpIHsKCQlyZXR1cm47Cgl9CglGb3JtYXR0YWJsZSBhcmdzW109e2luZGVudE9mZnNldCwiIiwiIn07Cglmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImRhdGVzIixtRXJyb3IpLGFyZ3MsMyx4bWxTdHJpbmcpOwoJVW5pY29kZVN0cmluZyB0ZW1wU3RyOwoJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQoJd3JpdGVMb2NhbGVQYXR0ZXJuQ2hhcnModGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoJCgl0ZW1wU3RyLnJlbW92ZSgpOwoJd3JpdGVDYWxlbmRhcnModGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoKCXRlbXBTdHIucmVtb3ZlKCk7Cgl3cml0ZVRpbWVab25lTmFtZXModGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoKCWNob3BJbmRlbnQoKTsKCglGb3JtYXR0YWJsZSBhcmdzMVtdPXtpbmRlbnRPZmZzZXQsKFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCkpLCIifTsKCVVuaWNvZGVTdHJpbmcgdDsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkYXRlcyIsbUVycm9yKSAsYXJnczEsMyx0KSk7CglpZihwcmludCkgIHByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZVRpbWVab25lTmFtZXMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCglpZihVX0ZBSUxVUkUobUVycm9yKSkgewoJCXJldHVybjsKCX0KCVVCb29sIGlzRGVmYXVsdCA9VFJVRTsKCUZvcm1hdHRhYmxlIGFyZ3NbNF0gPXtpbmRlbnRPZmZzZXQsIiIsIiIsIiJ9OwoKCVVuaWNvZGVTdHJpbmcgdDsKCiAgICBSZXNvdXJjZUJ1bmRsZSBkQnVuZGxlID0gbVNvdXJjZUJ1bmRsZS5nZXQoInpvbmVTdHJpbmdzIiwgbUVycm9yKTsKICAgIFVCb29sIHJlbW92ZSA9IFRSVUU7CgoJaWYobUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiBVX1NVQ0NFU1MobUVycm9yKSAmJiBtRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyl7CiAgICAgICAgCgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInRpbWVab25lIixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJCgkJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKICAgICAgICB3aGlsZShkQnVuZGxlLmhhc05leHQoKSl7CiAgICAgICAgICAgIFJlc291cmNlQnVuZGxlIGRCdW5kbGUxID0gZEJ1bmRsZS5nZXROZXh0KG1FcnJvcik7CgogICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaW50IGkgPSAwOwoKICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgZGF0YSA9ZEJ1bmRsZTEuZ2V0U3RyaW5nRXgoKGludDMyX3QpMCxtRXJyb3IpOwogICAgICAgICAgICAgICAgaWYoVV9TVUNDRVNTKG1FcnJvcikpewogICAgICAgICAgICAgICAgICAgICByZW1vdmUgPSBGQUxTRTsKICAgICAgICAgICAgIAkgICAgIGFyZ3NbMF0gPWluZGVudE9mZnNldDsKCQkJCQkgYXJnc1sxXSA9IGRhdGE7CgkJCQkJIGFyZ3NbMl0gPSAiIjsKCQkJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiem9uZVN0YXJ0IixtRXJyb3IpLGFyZ3MsMyx0KSk7CgoJCQkgICAgICAgIGlzRGVmYXVsdD1GQUxTRTsKCQkJICAgICAgICBpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwogICAgICAgICAgICAgICAgICAgIAoJCQkJCWFyZ3NbMF0gPWluZGVudE9mZnNldDsKCQkJCQlhcmdzWzFdID0gIiI7CiAgICAgICAgICAgICAgICAgICAgLy9sb25nIGZvcm1hdCAKCQkJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibG9uZyIsbUVycm9yKSxhcmdzLDIsdCkpOwoKCQkJICAgICAgICBpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwogICAgICAgICAJICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudGx5IElDVSBkb2VzIG5vdCBoYXZlIHN1cHBvcnQgZm9yIGdlbmVyaWMKICAgICAgICAgICAgICAgICAgICBhcmdzWzBdPWluZGVudE9mZnNldDsKCQkJICAgICAgICBhcmdzWzFdPWRCdW5kbGUxLmdldFN0cmluZ0V4KChpbnQzMl90KTEsbUVycm9yKTsKICAgICAgICAgICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CgkJCSAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJnZW5lcmljIixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgbUVycm9yPVVfWkVST19FUlJPUjsKICAgICAgICAgICAgICAgICAgICBhcmdzWzFdPWRCdW5kbGUxLmdldFN0cmluZ0V4KChpbnQzMl90KTEsbUVycm9yKTsKICAgICAgICAgICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CgkJCSAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJzdGFuZGFyZCIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBtRXJyb3IgPVVfWkVST19FUlJPUjsKICAgICAgICAgICAgICAgICAgICBhcmdzWzFdPWRCdW5kbGUxLmdldFN0cmluZ0V4KChpbnQzMl90KTMsbUVycm9yKTsKICAgICAgICAgICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CgkJCSAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkYXlsaWdodCIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBtRXJyb3I9VV9aRVJPX0VSUk9SOwogICAgICAgICAgICAgICAgICAgIGNob3BJbmRlbnQoKTsKCQkJICAgICAgICBhcmdzWzBdPWluZGVudE9mZnNldDsKCQkJCQlhcmdzWzFdPVVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CgkJCSAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImxvbmciLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAgICAgICAgICAgICAKCQkJCQlhcmdzWzFdPSIiOwogICAgICAgICAgICAgICAgICAgIC8vIHNob3J0IGZvcm1hdCAKCQkJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgic2hvcnQiLG1FcnJvciksYXJncywyLHQpKTsKCgkJCSAgICAgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQkJICAgICAgICBhcmdzWzBdPWluZGVudE9mZnNldDsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnRseSBJQ1UgZG9lcyBub3QgaGF2ZSBzdXBwb3J0IGZvciBnZW5lcmljCiAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBkYXRhPWRCdW5kbGUxLmdldFN0cmluZ0V4KChpbnQzMl90KTAsbUVycm9yKTsKICAgICAgICAgICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CgkJCSAgICAgICAgICAgIGFyZ3NbMV09ZGF0YTsKCQkJICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImdlbmVyaWMiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBkYXRhPWRCdW5kbGUxLmdldFN0cmluZ0V4KChpbnQzMl90KTIsbUVycm9yKTsKICAgICAgICAgICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CgkJCSAgICAgICAgICAgIGFyZ3NbMV09ZGF0YTsKCQkJICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInN0YW5kYXJkIixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkQnVuZGxlMS5nZXRTdHJpbmdFeCgoaW50MzJfdCk0LG1FcnJvcik7CiAgICAgICAgICAgICAgICAgICAgaWYoVV9TVUNDRVNTKG1FcnJvcikpewogICAgCQkJICAgICAgICBhcmdzWzFdPWRhdGE7CiAgICAJCQkgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkYXlsaWdodCIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7CgkJCSAgICAgICAgY2hvcEluZGVudCgpOwoJCQkgICAgICAgIGFyZ3NbMF09aW5kZW50T2Zmc2V0OwoJCQkJCWFyZ3NbMV09VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKCQkJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgic2hvcnQiLG1FcnJvciksYXJncywyLHQpKTsKCQkJICAgICAgICAKCQkJICAgICAgICBhcmdzWzFdLnNldFN0cmluZyhkQnVuZGxlMS5nZXRTdHJpbmdFeCgoaW50MzJfdCk1LG1FcnJvcikpOwogICAgICAgICAgICAgICAgICAgIGlmKFVfU1VDQ0VTUyhtRXJyb3IpKXsKCQkJICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImV4ZW1wbGFyQ2l0eSIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBtRXJyb3I9VV9aRVJPX0VSUk9SOwoJCQkgICAgICAgIGNob3BJbmRlbnQoKTsKCQkJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiem9uZUVuZCIsbUVycm9yKSxpbmRlbnRPZmZzZXQsdCkpOwoJCQkJCQoKICAgICAgICAgICAgICAgIH0KCQkgICAgfQogICAgICAgICAgICBtRXJyb3I9VV9aRVJPX0VSUk9SOwoKICAgICAgICB9CgkJY2hvcEluZGVudCgpOwoJCWFyZ3NbMF09aW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV09VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgidGltZVpvbmUiLG1FcnJvciksYXJncywyLHQpKTsKCQkvL3ByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwogICAgICAgIGlmKHJlbW92ZT09VFJVRSl7CiAgICAgICAgICAgIHhtbFN0cmluZy5yZW1vdmUoKTsKICAgICAgICB9CiAgICAgICAgbUVycm9yPVVfWkVST19FUlJPUjsKCQlyZXR1cm47CiAgICB9CgltRXJyb3I9VV9aRVJPX0VSUk9SOwp9CgoJCQp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUNhbGVuZGFycyhVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoJVW5pY29kZVN0cmluZyB0ZW1wU3RyOwoJVUJvb2wgcHJpbnQgPUZBTFNFOwoJRm9ybWF0dGFibGUgYXJnc1syXT17aW5kZW50T2Zmc2V0LCIifTsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJjYWxlbmRhcnMiLG1FcnJvciksYXJncywyLHRlbXBTdHIpKTsKICAgIAogICAgUmVzb3VyY2VCdW5kbGUgY2FsZW5kYXJzID0gbVNvdXJjZUJ1bmRsZS5nZXQoImNhbGVuZGFyIiwgbUVycm9yKTsKICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICBpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiAKICAgICAgICAgICAgVV9TVUNDRVNTKG1FcnJvcikpewoKCiAgICAgICAgUmVzb3VyY2VCdW5kbGUgZGVmYXVsdENhbGVuZGFyID0gY2FsZW5kYXJzLmdldFdpdGhGYWxsYmFjaygiZGVmYXVsdCIsIG1FcnJvcik7CiAgICAgICAgVW5pY29kZVN0cmluZyBkZWZhdWx0QyA9IGRlZmF1bHRDYWxlbmRhci5nZXRTdHJpbmcobUVycm9yKTsKICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgIGFyZ3NbMV0gPSBkZWZhdWx0QzsKICAgICAgICBpZihVX0ZBSUxVUkUobUVycm9yKSl7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90IGZpbmQgdGhlIGRlZmF1bHQgY2FsZW5kYXIuIER5aW5nLlxuIik7CiAgICAgICAgICAgIGV4aXQoVV9JTlRFUk5BTF9QUk9HUkFNX0VSUk9SKTsKICAgICAgICB9CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoICJkZWZhdWx0IixtRXJyb3IpLGFyZ3MsMix0ZW1wU3RyKSk7CgogICAgICAgIHdoaWxlKGNhbGVuZGFycy5oYXNOZXh0KCkpewogICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZSBjYWxlbmRhciA9IGNhbGVuZGFycy5nZXROZXh0KG1FcnJvcik7CiAgICAgICAgICAgIGlmKFVfU1VDQ0VTUyhtRXJyb3IpKXsKICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcga2V5ID0gVW5pY29kZVN0cmluZyhjYWxlbmRhci5nZXRLZXkoKSk7CiAgICAgICAgICAgICAgICBtRXJyb3I9VV9aRVJPX0VSUk9SOwoJICAgICAgICAgICAgdGVtcFN0ci5yZW1vdmUoKTsKICAgICAgICAgICAgICAgIHdyaXRlQ2FsZW5kYXIoY2FsZW5kYXIsIGtleSwgKGRlZmF1bHRDPT1rZXkpLHRlbXBTdHIpOyAKCSAgICAgICAgICAgIGlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQkgICAgICAgICAgICBwcmludCA9IFRSVUU7CgkgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgljaG9wSW5kZW50KCk7CiAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJYXJnc1sxXT1Vbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwogICAgaWYocHJpbnQgPT1UUlVFKXsKCSAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY2FsZW5kYXJzIixtRXJyb3IpLGFyZ3MsMix0ZW1wU3RyKSk7CiAgICB9ZWxzZXsKICAgICAgICB4bWxTdHJpbmcucmVtb3ZlKCk7CiAgICB9Cn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlQ2FsZW5kYXIoUmVzb3VyY2VCdW5kbGUmIGNhbGVuZGFyLCBVbmljb2RlU3RyaW5nJiBjYWwsVUJvb2wgaXNEZWZhdWx0LFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgkKCVVuaWNvZGVTdHJpbmcgdGVtcFN0cjsKCVVCb29sIHByaW50ID1GQUxTRTsKCUZvcm1hdHRhYmxlIGFyZ3NbXT17aW5kZW50T2Zmc2V0LGNhbH07CgkvLyBUT0RPIDogRmlndXJlIG91dCBhIHdheSB0byBmaW5kIGRlZmF1bHQKCS8vIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAiZGVmYXVsdCIsbUVycm9yKSxhcmdzLDIsdGVtcFN0cikpOwoJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImNhbGVuZGFyU3RhcnQiLG1FcnJvciksYXJncywyLHRlbXBTdHIpKTsKCglpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoJdGVtcFN0ci5yZW1vdmUoKTsKCXdyaXRlTW9udGhOYW1lcyhjYWxlbmRhciwgdGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoKCXRlbXBTdHIucmVtb3ZlKCk7Cgl3cml0ZURheU5hbWVzKGNhbGVuZGFyLCB0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9CgogICAgdGVtcFN0ci5yZW1vdmUoKTsKCXdyaXRlV2VlayhjYWxlbmRhciwgdGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoJdGVtcFN0ci5yZW1vdmUoKTsKCXdyaXRlQU1QTW1hcmtlcnMoY2FsZW5kYXIsIHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KICAgIHRlbXBTdHIucmVtb3ZlKCk7Cgl3cml0ZUVyYShjYWxlbmRhciwgdGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoJdGVtcFN0ci5yZW1vdmUoKTsKCXdyaXRlRGF0ZUZvcm1hdChjYWxlbmRhcix0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9CiAgICB0ZW1wU3RyLnJlbW92ZSgpOwoJd3JpdGVUaW1lRm9ybWF0KGNhbGVuZGFyLCB0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9CiAgICB0ZW1wU3RyLnJlbW92ZSgpOwoJd3JpdGVEYXRlVGltZUZvcm1hdChjYWxlbmRhciwgdGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoJY2hvcEluZGVudCgpOwogICAgbUVycm9yID1VX1pFUk9fRVJST1I7CiAgICBpZihwcmludCA9PSBUUlVFKXsKCSAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY2FsZW5kYXJFbmQiLG1FcnJvciksaW5kZW50T2Zmc2V0LHRlbXBTdHIpKTsKICAgIH1lbHNlewogICAgICAgIHhtbFN0cmluZy5yZW1vdmUoKTsKICAgIH0KfQoKY29uc3QgY2hhciogZ2V0RGF5TmFtZShpbnQgaW5kZXgpewoJc3dpdGNoKGluZGV4KXsKCWNhc2UgMDoKCQlyZXR1cm4gInN1biI7CgljYXNlIDE6CgkJcmV0dXJuICJtb24iOwoJY2FzZSAyOgoJCXJldHVybiAidHVlIjsKCWNhc2UgMzoKCQlyZXR1cm4gIndlZCI7CgljYXNlIDQ6CgkJcmV0dXJuICJ0aHUiOwoJY2FzZSA1OgoJCXJldHVybiAiZnJpIjsKCWNhc2UgNjoKCQlyZXR1cm4gInNhdCI7CglkZWZhdWx0OgoJCXJldHVybiAiIjsKCX0KfQpjb25zdCBjaGFyKiBnZXREYXlOYW1lRFRFKGludCBpbmRleCl7Cglzd2l0Y2goaW5kZXgpewoJY2FzZSAxOgoJCXJldHVybiAic3VuIjsKCWNhc2UgMjoKCQlyZXR1cm4gIm1vbiI7CgljYXNlIDM6CgkJcmV0dXJuICJ0dWUiOwoJY2FzZSA0OgoJCXJldHVybiAid2VkIjsKCWNhc2UgNToKCQlyZXR1cm4gInRodSI7CgljYXNlIDY6CgkJcmV0dXJuICJmcmkiOwoJY2FzZSA3OgoJCXJldHVybiAic2F0IjsKCWRlZmF1bHQ6CgkJcmV0dXJuICIiOwoJfQp9CnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlTW9udGhOYW1lcyhSZXNvdXJjZUJ1bmRsZSYgY2FsZW5kYXIsIFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgogICAgUmVzb3VyY2VCdW5kbGUgbW9udGhOYW1lcyA9IGNhbGVuZGFyLmdldCgibW9udGhOYW1lcyIsbUVycm9yKTsKCVVuaWNvZGVTdHJpbmcgdDsKICAgIGlmKCBtRXJyb3IhPVVfVVNJTkdfREVGQVVMVF9XQVJOSU5HICYmIAoJCW1FcnJvciE9VV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAoJCVVfU1VDQ0VTUyhtRXJyb3IpKXsKICAgICAgICAKICAgICAgICBGb3JtYXR0YWJsZSBhcmdzWzRdID17IGluZGVudE9mZnNldCwgIiIsICIiLCAiIiB9OwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJtb250aHMiLCBtRXJyb3IpLCBhcmdzLCAyLCB0KSk7CiAgICAgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCiAgICAgICAgd2hpbGUobW9udGhOYW1lcy5oYXNOZXh0KCkpewogICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZSBjb250ZXh0ID0gbW9udGhOYW1lcy5nZXROZXh0KG1FcnJvcik7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgY3R4S2V5ID0gVW5pY29kZVN0cmluZyhjb250ZXh0LmdldEtleSgpKTsKICAgICAgICAgICAgaWYoVV9GQUlMVVJFKG1FcnJvcikpewogICAgICAgICAgICAgICAgZXhpdChVX0lOVEVSTkFMX1BST0dSQU1fRVJST1IpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGN0eEtleT09ImRlZmF1bHQiKXsKICAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CiAgICAgICAgICAgICAgICBhcmdzWzFdID0gY29udGV4dC5nZXRTdHJpbmcobUVycm9yKTsKICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkZWZhdWx0IixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICBhcmdzWzFdID0gY3R4S2V5OwogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibW9udGhDb250ZXh0IixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgICAgIAogICAgICAgICAgICBVbmljb2RlU3RyaW5nIGRlZmF1bHRXaWR0aCA9IGNvbnRleHQuZ2V0U3RyaW5nRXgoImRlZmF1bHQiLCBtRXJyb3IpOwogICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CiAgICAgICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICAgICAgYXJnc1sxXSA9IGRlZmF1bHRXaWR0aDsKICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkZWZhdWx0IixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbUVycm9yID0gVV9aRVJPX0VSUk9SOwoKICAgICAgICAgICAgd2hpbGUoY29udGV4dC5oYXNOZXh0KCkpewogICAgICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUgd2lkdGggPSBjb250ZXh0LmdldE5leHQobUVycm9yKTsKICAgICAgICAgICAgICAgIGlmKFVfRkFJTFVSRShtRXJyb3IpKXsKICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuZXhwZWN0ZWQgRXJyb3I6ICVzIFxuIiwgdV9lcnJvck5hbWUobUVycm9yKSk7CiAgICAgICAgICAgICAgICAgICAgZXhpdChVX0lOVEVSTkFMX1BST0dSQU1fRVJST1IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyB3aWR0aEtleSA9IFVuaWNvZGVTdHJpbmcod2lkdGguZ2V0S2V5KCkpOwogICAgICAgICAgICAgICAgaWYod2lkdGhLZXk9PSJkZWZhdWx0Iil7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICAgICAgYXJnc1sxXSA9IHdpZHRoS2V5OwogICAgICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIm1vbnRoV2lkdGgiLG1FcnJvciksYXJncywyLHQpKTsKCQkgICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgogICAgICAgICAgICAgICAgZm9yKGludCBpPTA7d2lkdGguaGFzTmV4dCgpO2krKyl7CiAgICAgICAgICAgICAgICAgICAgY2hhciBjWzEwXT17MH07CgkJCSAgICAgICAgaXRvYShpKzEsYywxMCk7CgkJCSAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkJICAgICAgICBhcmdzWzFdID0gVW5pY29kZVN0cmluZyhjKTsKCQkJICAgICAgICBhcmdzWzJdID0gd2lkdGguZ2V0TmV4dFN0cmluZyhtRXJyb3IpOwoJCQkgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJtb250aCIsbUVycm9yKSxhcmdzLDMsdCkpOwoJCSAgICAgICAgfQoJCSAgICAgICAgY2hvcEluZGVudCgpOwoJCSAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJtb250aFdpZHRoRW5kIixtRXJyb3IpLGFyZ3MsMSx0KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hvcEluZGVudCgpOwogICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibW9udGhDb250ZXh0RW5kIixtRXJyb3IpLGFyZ3MsMSx0KSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgIGFyZ3NbMV0gPSBVbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJtb250aHMiLG1FcnJvciksYXJncywyLHQpKTsKCiAgICAgICAgbUVycm9yPVVfWkVST19FUlJPUjsKCQlyZXR1cm47CiAgICB9Cgl4bWxTdHJpbmcucmVtb3ZlKCk7CgltRXJyb3I9IFVfWkVST19FUlJPUjsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVEYXlOYW1lcyhSZXNvdXJjZUJ1bmRsZSYgY2FsZW5kYXIsIFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CiAgIFJlc291cmNlQnVuZGxlIGRheU5hbWVzID0gY2FsZW5kYXIuZ2V0KCJkYXlOYW1lcyIsbUVycm9yKTsKCVVuaWNvZGVTdHJpbmcgdDsKICAgIGlmKCBtRXJyb3IhPVVfVVNJTkdfREVGQVVMVF9XQVJOSU5HICYmIAoJCW1FcnJvciE9VV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAoJCVVfU1VDQ0VTUyhtRXJyb3IpKXsKICAgICAgICAKICAgICAgICBGb3JtYXR0YWJsZSBhcmdzWzRdID17IGluZGVudE9mZnNldCwgIiIsICIiLCAiIiB9OwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkYXlzIiwgbUVycm9yKSwgYXJncywgMiwgdCkpOwogICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgogICAgICAgIHdoaWxlKGRheU5hbWVzLmhhc05leHQoKSl7CiAgICAgICAgICAgIFJlc291cmNlQnVuZGxlIGNvbnRleHQgPSBkYXlOYW1lcy5nZXROZXh0KG1FcnJvcik7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgY3R4S2V5ID0gVW5pY29kZVN0cmluZyhjb250ZXh0LmdldEtleSgpKTsKICAgICAgICAgICAgaWYoY3R4S2V5PT0iZGVmYXVsdCIpewogICAgICAgICAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBjb250ZXh0LmdldFN0cmluZyhtRXJyb3IpOwogICAgICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImRlZmF1bHQiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKFVfRkFJTFVSRShtRXJyb3IpKXsKICAgICAgICAgICAgICAgIGV4aXQoVV9JTlRFUk5BTF9QUk9HUkFNX0VSUk9SKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICBhcmdzWzFdID0gY3R4S2V5OwogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZGF5Q29udGV4dCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCSAgICBpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwogICAgICAgICAgICBVbmljb2RlU3RyaW5nIGRlZmF1bHRXaWR0aCA9IGNvbnRleHQuZ2V0U3RyaW5nRXgoImRlZmF1bHQiLCBtRXJyb3IpOwogICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CiAgICAgICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICAgICAgYXJnc1sxXSA9IGRlZmF1bHRXaWR0aDsKICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkZWZhdWx0IixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbUVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICB3aGlsZShjb250ZXh0Lmhhc05leHQoKSl7CiAgICAgICAgICAgICAgICBSZXNvdXJjZUJ1bmRsZSB3aWR0aCA9IGNvbnRleHQuZ2V0TmV4dChtRXJyb3IpOwogICAgICAgICAgICAgICAgaWYoVV9GQUlMVVJFKG1FcnJvcikpewogICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5leHBlY3RlZCBFcnJvcjogJXMgXG4iLCB1X2Vycm9yTmFtZShtRXJyb3IpKTsKICAgICAgICAgICAgICAgICAgICBleGl0KFVfSU5URVJOQUxfUFJPR1JBTV9FUlJPUik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHdpZHRoS2V5ID0gVW5pY29kZVN0cmluZyh3aWR0aC5nZXRLZXkoKSk7CiAgICAgICAgICAgICAgICBpZih3aWR0aEtleSA9PSAiZGVmYXVsdCIpewogICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CiAgICAgICAgICAgICAgICBhcmdzWzFdID0gd2lkdGhLZXk7CiAgICAgICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZGF5V2lkdGgiLG1FcnJvciksYXJncywyLHQpKTsKCQkgICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgogICAgICAgICAgICAgICAgZm9yKGludCBpPTA7d2lkdGguaGFzTmV4dCgpO2krKyl7CiAgICAgICAgICAgICAgICAgICAgCgkJCSAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkJICAgICAgICBhcmdzWzFdID0gZ2V0RGF5TmFtZShpKTsKCQkJICAgICAgICBhcmdzWzJdID0gd2lkdGguZ2V0TmV4dFN0cmluZyhtRXJyb3IpOwoJCQkgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkYXkiLG1FcnJvciksYXJncywzLHQpKTsKCQkgICAgICAgIH0KCQkgICAgICAgIGNob3BJbmRlbnQoKTsKCQkgICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgkJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZGF5V2lkdGhFbmQiLG1FcnJvciksYXJncywxLHQpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjaG9wSW5kZW50KCk7CiAgICAgICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CiAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkYXlDb250ZXh0RW5kIixtRXJyb3IpLGFyZ3MsMSx0KSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgIGFyZ3NbMV0gPSBVbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkYXlzIixtRXJyb3IpLGFyZ3MsMix0KSk7CgogICAgICAgIG1FcnJvcj1VX1pFUk9fRVJST1I7CgkJcmV0dXJuOwogICAgfQoJeG1sU3RyaW5nLnJlbW92ZSgpOwoJbUVycm9yPSBVX1pFUk9fRVJST1I7Cn0KVW5pY29kZVN0cmluZyBnZXRUaW1lU3RyaW5nKFVuaWNvZGVTdHJpbmcmIHZhbCwgaW50MzJfdCBtaWxsaVNlY3MpewogICAgaW50MzJfdCBtaW51dGVzID0gbWlsbGlTZWNzIC8gKDYwMDAwKTsgLyogbnVtYmVyIG9mIG1pbGxpIHNlY29uZHMgaW4gMSBociovCiAgICBpbnQzMl90IGRlbHRhTWluID0gbWludXRlcyAlIDYwOwogICAgaW50MzJfdCBob3VycyA9IChtaW51dGVzLWRlbHRhTWluKS82MDsKICAgIGNoYXIgY1sxMF09ezB9OwogICAgaXRvYShob3VycywgYywgMTApOwogICAgaWYoc3RyY21wKGMsIjAiKT09MCl7CiAgICAgICAgdmFsLmFwcGVuZCgiMDAiKTsKICAgIH1lbHNlewogICAgICAgIGlmKHN0cmxlbihjKT09MSl7CiAgICAgICAgICAgIHZhbC5hcHBlbmQoIjAiKTsKICAgICAgICB9CiAgICAgICAgdmFsLmFwcGVuZChjKTsKICAgIH0KICAgIHZhbC5hcHBlbmQoIjoiKTsKICAgIGNbMF0gPSAwOwogICAgaXRvYShtaW51dGVzLCBjLCAxMCk7CiAgICBpZihzdHJjbXAoYywiMCIpPT0wKXsKICAgICAgICB2YWwuYXBwZW5kKCIwMCIpOwogICAgfWVsc2V7CiAgICAgICAgaWYoc3RybGVuKGMpPT0xKXsKICAgICAgICAgICAgdmFsLmFwcGVuZCgiMCIpOwogICAgICAgIH0KICAgICAgICB2YWwuYXBwZW5kKGMpOwogICAgfQogICAgcmV0dXJuIHZhbDsKfQp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZVdlZWsoUmVzb3VyY2VCdW5kbGUmIGNhbGVuZGFyLCBVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoJVW5pY29kZVN0cmluZyB0OwogICAgRm9ybWF0dGFibGUgYXJnc1szXSA9IHtpbmRlbnRPZmZzZXQsIiIsIiJ9OwoJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIndlZWsiLG1FcnJvciksYXJncywyLHQpKTsKCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgogICAgUmVzb3VyY2VCdW5kbGUgZHRFbGVtZW50cyA9IGNhbGVuZGFyLmdldCgiRGF0ZVRpbWVFbGVtZW50cyIsIG1FcnJvcik7CglVbmljb2RlU3RyaW5nIHRlbXA7CgogICAgaWYoIG1FcnJvciE9VV9VU0lOR19ERUZBVUxUX1dBUk5JTkcgJiYgCgkJbUVycm9yIT1VX1VTSU5HX0ZBTExCQUNLX1dBUk5JTkcgJiYgCgkJVV9TVUNDRVNTKG1FcnJvcikpewoJICAgIGludDMyX3QgbGVuID0wOwoJICAgIGNvbnN0IGludDMyX3QqIHZlY3RvciA9IGR0RWxlbWVudHMuZ2V0SW50VmVjdG9yKGxlbixtRXJyb3IpOwoKCQlhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgIC8vIHdyaXRlIG1pbiBkYXlzIGluIGEgd2VlawogICAgICAgIGlmKGxlbiA+IDEpewoJCSAgICBhcmdzWzFdID0gdmVjdG9yWzFdOwkKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgYXJnc1sxXSA9ICIiOwogICAgICAgIH0KICAgICAgICB0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIm1pbkRheXMiLG1FcnJvciksYXJncywyLHQpKTsKCiAgICAgICAgLy8gd3JpdGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrCiAgICAgICAgYXJnc1sxXSA9IGdldERheU5hbWVEVEUodmVjdG9yWzBdKTsKCQl0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImZpcnN0RGF5IixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgCiAgICB9CgogICAgbUVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgLy8gbm93IHdyaXRlIHdlZWtlbmQgaW5mb3JtYXRpb24KICAgIFJlc291cmNlQnVuZGxlIHdlZWtlbmQgPSBjYWxlbmRhci5nZXQoIndlZWtlbmQiLCBtRXJyb3IpOwogICAgaWYoVV9TVUNDRVNTKG1FcnJvcikpewogICAgICAgIGludDMyX3QgbGVuID0gMDsKICAgICAgICBjb25zdCBpbnQzMl90KiB2ZWN0b3IgPSB3ZWVrZW5kLmdldEludFZlY3RvcihsZW4sIG1FcnJvcik7CiAgICAgICAgVW5pY29kZVN0cmluZyB0aW1lOwogICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgogICAgICAgIGFyZ3NbMV0gPSBnZXREYXlOYW1lRFRFKHZlY3RvclswXSk7CiAgICAgICAgYXJnc1syXSA9IGdldFRpbWVTdHJpbmcodGltZSwgdmVjdG9yWzFdKTsKICAgICAgICB0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIndlZWtlbmRTdGFydCIsIG1FcnJvciksIGFyZ3MsIDMsIHQpKTsKICAgICAgICAKICAgICAgICB0aW1lLnJlbW92ZSgpOwogICAgICAgIGFyZ3NbMV0gPSBnZXREYXlOYW1lRFRFKHZlY3RvclsyXSk7CiAgICAgICAgYXJnc1syXSA9IGdldFRpbWVTdHJpbmcodGltZSwgdmVjdG9yWzNdKTsKICAgICAgICB0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIndlZWtlbmRFbmQiLCBtRXJyb3IpLCBhcmdzLCAzLCB0KSk7CgogICAgfQogICAgCiAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7CiAgICBpZih0ZW1wLmxlbmd0aCgpPjApewogICAgICAgIHhtbFN0cmluZy5hcHBlbmQodGVtcCk7CiAgICAJY2hvcEluZGVudCgpOwoJCWFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgkJYXJnc1sxXSA9IFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIndlZWsiLG1FcnJvciksYXJncywyLHQpKTsKCQltRXJyb3I9VV9aRVJPX0VSUk9SOwoJCXJldHVybjsKICAgIH0KICAgIGNob3BJbmRlbnQoKTsKCXhtbFN0cmluZy5yZW1vdmUoKTsKCW1FcnJvcj0gVV9aRVJPX0VSUk9SOwp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUVyYShSZXNvdXJjZUJ1bmRsZSYgY2FsZW5kYXIsVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCiAgICBSZXNvdXJjZUJ1bmRsZSBlcmFzPSBjYWxlbmRhci5nZXQoImVyYXMiLG1FcnJvcik7CglVbmljb2RlU3RyaW5nIHQ7CglpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiAKCQlVX1NVQ0NFU1MobUVycm9yKSl7CgkJCgkJRm9ybWF0dGFibGUgYXJnc1szXSA9IHtpbmRlbnRPZmZzZXQsIiIsIiJ9OwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJlcmFzIixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQkKICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJlcmFBYmJyIixtRXJyb3IpLGFyZ3MsMix0KSk7CgogICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgkJYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICBmb3IoaW50IGk9MDtlcmFzLmhhc05leHQoKTtpKyspewogICAgICAgICAgICBjaGFyIGNbMTBdPXswfTsKCQkJaXRvYShpKzEsYywxMCk7CgkJCWFyZ3NbMV0gPSBVbmljb2RlU3RyaW5nKGMpOwoJCQlhcmdzWzJdID0gZXJhcy5nZXROZXh0U3RyaW5nKG1FcnJvcik7CgkJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJlcmEiLG1FcnJvciksYXJncywzLHQpKTsKCQl9CgkJY2hvcEluZGVudCgpOwoJCWFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgkJYXJnc1sxXSA9IFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImVyYUFiYnIiLG1FcnJvciksYXJncywyLHQpKTsKCiAgICAgICAgY2hvcEluZGVudCgpOwoJCWFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgkJYXJnc1sxXSA9IFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImVyYXMiLG1FcnJvciksYXJncywyLHQpKTsKCQltRXJyb3I9VV9aRVJPX0VSUk9SOwoJCXJldHVybjsKCX0KCXhtbFN0cmluZy5yZW1vdmUoKTsKCW1FcnJvciA9VV9aRVJPX0VSUk9SOwp9CgoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVBTVBNbWFya2VycyggUmVzb3VyY2VCdW5kbGUmIGNhbGVuZGFyLCBVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoJUmVzb3VyY2VCdW5kbGUgbWFya2VycyA9IGNhbGVuZGFyLmdldCgiQW1QbU1hcmtlcnMiLG1FcnJvcik7CglVbmljb2RlU3RyaW5nIHQ7CglpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiAKICAgICAgICBVX1NVQ0NFU1MobUVycm9yKSl7CgkJRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCxtYXJrZXJzLmdldFN0cmluZ0V4KChpbnQzMl90KTAsbUVycm9yKX07CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImFtIixtRXJyb3IpLGFyZ3MgLDMsdCkpOwoJCWFyZ3NbMV0gPSBtYXJrZXJzLmdldFN0cmluZ0V4KChpbnQzMl90KTEsbUVycm9yKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicG0iLG1FcnJvciksYXJncyAsMyx0KSk7CgkJbUVycm9yPSBVX1pFUk9fRVJST1I7CgkJcmV0dXJuOwoJfQoJeG1sU3RyaW5nLnJlbW92ZSgpOwoJbUVycm9yPSBVX1pFUk9fRVJST1I7Cgp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUZvcm1hdChjb25zdCBjaGFyKiBlbGVtTmFtZSwgY29uc3QgY2hhciogc3R5bGUsIGNvbnN0IGNoYXIqIHN0YXJ0LCBjb25zdCBjaGFyKiBlbmQsIGNvbnN0IGNoYXIqIHR5cGVOYW1lLFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCgkJCQkJCSAgICAgIFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZywgVUJvb2wgc3BsaXQpewoKICAgIGlmKCBtRXJyb3IhPVVfVVNJTkdfREVGQVVMVF9XQVJOSU5HICYmIAoJCW1FcnJvciE9VV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAogICAgICAgIFVfU1VDQ0VTUyhtRXJyb3IpKXsKICAgICAgICBVbmljb2RlU3RyaW5nIHQ7CiAgICAgICAgRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwiIiwiIn07CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoZWxlbU5hbWUsbUVycm9yKSxhcmdzICwzLHQpKTsKICAgICAgICBpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwogICAgICAgIHdyaXRlRm9ybWF0KHN0eWxlLCBzdGFydCwgZW5kLCBOVUxMLCBwYXR0ZXJuLCB4bWxTdHJpbmcsIHNwbGl0KTsKICAgICAgICBjaG9wSW5kZW50KCk7CgogICAgICAgIGFyZ3NbMV09VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggZWxlbU5hbWUsbUVycm9yKSxhcmdzLDMsdCkpOwoJCW1FcnJvcj0gVV9aRVJPX0VSUk9SOwoJCXJldHVybjsKICAgICB9CgkgeG1sU3RyaW5nLnJlbW92ZSgpOwoJIG1FcnJvcj0gVV9aRVJPX0VSUk9SOwoKCgp9CnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlRm9ybWF0KGNvbnN0IGNoYXIqIHN0eWxlLCBjb25zdCBjaGFyKiBzdGFydCwgY29uc3QgY2hhciogZW5kLCBjb25zdCBjaGFyKiB0eXBlTmFtZSxVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAoJCQkJCQkgICAgICBVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcsIFVCb29sIHNwbGl0KXsKCVVuaWNvZGVTdHJpbmcgdDsKICAgIFVuaWNvZGVTdHJpbmcgdHlwZTsKCiAgICBpZih0eXBlTmFtZSE9TlVMTCl7CiAgICAgICAgdHlwZS5hcHBlbmQoInR5cGU9XCIiKTsKICAgICAgICB0eXBlLmFwcGVuZCh0eXBlTmFtZSk7CiAgICAgICAgdHlwZS5hcHBlbmQoIlwiIik7CiAgICB9CglpZighc3BsaXQpewoKCQlGb3JtYXR0YWJsZSBhcmdzWzRdPXtpbmRlbnRPZmZzZXQsIiIsdHlwZSwiIn07CiAgICAgICAgaWYoKnN0eWxlIT0wKXsKICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoc3R5bGUsbUVycm9yKSxhcmdzLDMsdCkpOwoKCgkgICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgkJICAgIGFyZ3NbMF09IGluZGVudE9mZnNldDsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgYXJnc1sxXSA9IHR5cGU7CiAgICAgICAgfQoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KHN0YXJ0LG1FcnJvciksYXJncywyLHQpKTsKCQkKCQlpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoJCWFyZ3NbMF09aW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV09cGF0dGVybjsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicGF0dGVybiIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoKCQljaG9wSW5kZW50KCk7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoZW5kLCBtRXJyb3IpLCBpbmRlbnRPZmZzZXQsdCkpOwogICAgICAgIAogICAgICAgIGlmKCpzdHlsZSE9MCl7CiAgICAgICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICAgICAgYXJnc1swXT1pbmRlbnRPZmZzZXQ7CiAgICAgICAgICAgIGFyZ3NbMV09VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKICAgICAgICAgICAgYXJnc1syXT0iIjsKICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoc3R5bGUsbUVycm9yKSxhcmdzLDMsdCkpOwogICAgICAgIH0KCgl9ZWxzZXsKCQlGb3JtYXR0YWJsZSBhcmdzWzRdPXtpbmRlbnRPZmZzZXQsIiIsdHlwZSwiIn07CiAgICAgICAgaWYoKnN0eWxlIT0wKXsKICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoc3R5bGUsbUVycm9yKSxhcmdzLDMsdCkpOwoKCSAgICAgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQkgICAgYXJnc1swXT0gaW5kZW50T2Zmc2V0OwogICAgICAgIH1lbHNlewogICAgICAgICAgICBhcmdzWzFdPXR5cGU7CiAgICAgICAgfQoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KHN0YXJ0LG1FcnJvciksYXJncywyLHQpKTsKCQlVbmljb2RlU3RyaW5nIHBvc2l0aXZlOwoJCVVuaWNvZGVTdHJpbmcgbmVnYXRpdmU7CgkJcGF0dGVybi5leHRyYWN0QmV0d2VlbigwLHBhdHRlcm4uaW5kZXhPZigiOyIpLHBvc2l0aXZlKTsKCQlwYXR0ZXJuLmV4dHJhY3RCZXR3ZWVuKHBhdHRlcm4uaW5kZXhPZigiOyIpKzEscGF0dGVybi5sZW5ndGgoKSxuZWdhdGl2ZSk7CgkJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQlhcmdzWzBdPWluZGVudE9mZnNldDsKCQlpZighcG9zaXRpdmUuaXNFbXB0eSgpKXsKCQkJYXJnc1sxXT1wb3NpdGl2ZTsKCQkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInBhdHRlcm4iLG1FcnJvciksYXJncywyLHQpKTsKCQl9CgkJaWYoIW5lZ2F0aXZlLmlzRW1wdHkoKSl7CgkJCWFyZ3NbMV09bmVnYXRpdmU7CgkJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJwYXR0ZXJuIixtRXJyb3IpLGFyZ3MsMix0KSk7CQkKCQl9CgkJY2hvcEluZGVudCgpOwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KGVuZCwgbUVycm9yKSwgaW5kZW50T2Zmc2V0LHQpKTsKICAgICAgICAKICAgICAgICBpZigqc3R5bGUhPTApewogICAgICAgICAgICBjaG9wSW5kZW50KCk7CiAgICAgICAgICAgIGFyZ3NbMF09aW5kZW50T2Zmc2V0OwogICAgICAgICAgICBhcmdzWzFdPVVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CiAgICAgICAgICAgIGFyZ3NbMl09IiI7CiAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KHN0eWxlLG1FcnJvciksYXJncywzLHQpKTsKICAgICAgICB9CgogICAgfQoJCn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlRGF0ZUZvcm1hdChSZXNvdXJjZUJ1bmRsZSYgY2FsZW5kYXIsIFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgoJUmVzb3VyY2VCdW5kbGUgZHRQYXR0ZXJucyA9IGNhbGVuZGFyLmdldCgiRGF0ZVRpbWVQYXR0ZXJucyIsIG1FcnJvcik7CglVbmljb2RlU3RyaW5nIHQ7CglpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiAKICAgICAgICBVX1NVQ0NFU1MobUVycm9yKSl7CgkJCgkJLy8gaGFyZCBjb2RlIGRlZmF1bHQgdG8gbWVkaXVtIHBhdHRlcm4gZm9yIElDVQoJCUZvcm1hdHRhYmxlIGFyZ3NbNF09IHtpbmRlbnRPZmZzZXQsIiIsIiIsIiJ9OwoKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZGF0ZUZvcm1hdHMiLG1FcnJvciksYXJncywyLHQpKTsKCgkJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQlhcmdzWzBdPSBpbmRlbnRPZmZzZXQ7CgkJYXJnc1sxXSA9ICJtZWRpdW0iOwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAiZGVmYXVsdCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCVVuaWNvZGVTdHJpbmcgdGVtcFN0cjsKCQkKCQl3cml0ZUZvcm1hdCgiZGF0ZUZvcm1hdExlbmd0aCIsImRhdGVGb3JtYXRTdGFydCIsImRhdGVGb3JtYXRFbmQiLCJmdWxsIixkdFBhdHRlcm5zLmdldFN0cmluZ0V4KChpbnQzMl90KTQsbUVycm9yKSx4bWxTdHJpbmcpOwoJCXdyaXRlRm9ybWF0KCJkYXRlRm9ybWF0TGVuZ3RoIiwiZGF0ZUZvcm1hdFN0YXJ0IiwiZGF0ZUZvcm1hdEVuZCIsImxvbmciLGR0UGF0dGVybnMuZ2V0U3RyaW5nRXgoKGludDMyX3QpNSxtRXJyb3IpLHhtbFN0cmluZyk7CgkJd3JpdGVGb3JtYXQoImRhdGVGb3JtYXRMZW5ndGgiLCJkYXRlRm9ybWF0U3RhcnQiLCJkYXRlRm9ybWF0RW5kIiwibWVkaXVtIixkdFBhdHRlcm5zLmdldFN0cmluZ0V4KChpbnQzMl90KTYsbUVycm9yKSx4bWxTdHJpbmcpOwoJCXdyaXRlRm9ybWF0KCJkYXRlRm9ybWF0TGVuZ3RoIiwiZGF0ZUZvcm1hdFN0YXJ0IiwiZGF0ZUZvcm1hdEVuZCIsInNob3J0IixkdFBhdHRlcm5zLmdldFN0cmluZ0V4KChpbnQzMl90KTcsbUVycm9yKSx4bWxTdHJpbmcpOwoKCQljaG9wSW5kZW50KCk7CgoJCWFyZ3NbMF09aW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV09VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZGF0ZUZvcm1hdHMiLG1FcnJvciksYXJncywyLHQpKTsKCiAgCX0KCgltRXJyb3I9IFVfWkVST19FUlJPUjsKLy8JaWYoIXByaW50KSB4bWxTdHJpbmcucmVtb3ZlKCk7CQp9CgoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVUaW1lRm9ybWF0KFJlc291cmNlQnVuZGxlJiBjYWxlbmRhciwgVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCVJlc291cmNlQnVuZGxlIGR0UGF0dGVybnMgPSBjYWxlbmRhci5nZXQoIkRhdGVUaW1lUGF0dGVybnMiLCBtRXJyb3IpOwoJVW5pY29kZVN0cmluZyB0OwoJaWYoIG1FcnJvciE9VV9VU0lOR19ERUZBVUxUX1dBUk5JTkcgJiYgCgkJbUVycm9yIT1VX1VTSU5HX0ZBTExCQUNLX1dBUk5JTkcgJiYgCiAgICAgICAgVV9TVUNDRVNTKG1FcnJvcikpewoJCS8vIGhhcmQgY29kZSBkZWZhdWx0IHRvIG1lZGl1bSBwYXR0ZXJuIGZvciBJQ1UKCQlGb3JtYXR0YWJsZSBhcmdzWzRdPSB7aW5kZW50T2Zmc2V0LCIiLCIiLCIifTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgidGltZUZvcm1hdHMiLG1FcnJvciksYXJncywyLHQpKTsKCQkKCQlpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoJCWFyZ3NbMF09IGluZGVudE9mZnNldDsKCQlhcmdzWzFdPSJtZWRpdW0iOwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAiZGVmYXVsdCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCVVuaWNvZGVTdHJpbmcgdGVtcFN0cjsKCQkKCQl3cml0ZUZvcm1hdCgidGltZUZvcm1hdExlbmd0aCIsInRpbWVGb3JtYXRTdGFydCIsInRpbWVGb3JtYXRFbmQiLCJmdWxsIixkdFBhdHRlcm5zLmdldFN0cmluZ0V4KChpbnQzMl90KTAsbUVycm9yKSx4bWxTdHJpbmcpOwoJCXdyaXRlRm9ybWF0KCJ0aW1lRm9ybWF0TGVuZ3RoIiwidGltZUZvcm1hdFN0YXJ0IiwidGltZUZvcm1hdEVuZCIsImxvbmciLGR0UGF0dGVybnMuZ2V0U3RyaW5nRXgoKGludDMyX3QpMSxtRXJyb3IpLHhtbFN0cmluZyk7CgkJd3JpdGVGb3JtYXQoInRpbWVGb3JtYXRMZW5ndGgiLCJ0aW1lRm9ybWF0U3RhcnQiLCJ0aW1lRm9ybWF0RW5kIiwibWVkaXVtIixkdFBhdHRlcm5zLmdldFN0cmluZ0V4KChpbnQzMl90KTIsbUVycm9yKSx4bWxTdHJpbmcpOwoJCXdyaXRlRm9ybWF0KCJ0aW1lRm9ybWF0TGVuZ3RoIiwidGltZUZvcm1hdFN0YXJ0IiwidGltZUZvcm1hdEVuZCIsInNob3J0IixkdFBhdHRlcm5zLmdldFN0cmluZ0V4KChpbnQzMl90KTMsbUVycm9yKSx4bWxTdHJpbmcpOwoKCQljaG9wSW5kZW50KCk7CgoJCWFyZ3NbMF09aW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV09VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgidGltZUZvcm1hdHMiLG1FcnJvciksYXJncywyLHQpKTsKCgl9CgoJbUVycm9yPSBVX1pFUk9fRVJST1I7CgovLwlpZighcHJpbnQpIHhtbFN0cmluZy5yZW1vdmUoKTsJCn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlRGF0ZVRpbWVGb3JtYXQoUmVzb3VyY2VCdW5kbGUmIGNhbGVuZGFyLCBVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoJUmVzb3VyY2VCdW5kbGUgZHRQYXR0ZXJucyA9IGNhbGVuZGFyLmdldCgiRGF0ZVRpbWVQYXR0ZXJucyIsIG1FcnJvcik7CiAgICBVbmljb2RlU3RyaW5nIHQ7CglpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiAKICAgICAgICBVX1NVQ0NFU1MobUVycm9yKSl7CgkJCgkJRm9ybWF0dGFibGUgYXJnc1s0XT0ge2luZGVudE9mZnNldCwiIiwiIiwiIn07CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImRhdGVUaW1lRm9ybWF0cyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgkJYXJnc1swXT0gaW5kZW50T2Zmc2V0OwoJCQoJCVVuaWNvZGVTdHJpbmcgdGVtcFN0cjsKCQkKCQl3cml0ZUZvcm1hdCgiZGF0ZVRpbWVGb3JtYXRMZW5ndGgiLCJkYXRlVGltZUZvcm1hdFN0YXJ0IiwiZGF0ZVRpbWVGb3JtYXRFbmQiLE5VTEwsZHRQYXR0ZXJucy5nZXRTdHJpbmdFeCgoaW50MzJfdCk4LG1FcnJvcikseG1sU3RyaW5nKTsKCiAgICAgICAgY2hvcEluZGVudCgpOwoKCQlhcmdzWzBdPWluZGVudE9mZnNldDsKCQlhcmdzWzFdPVVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImRhdGVUaW1lRm9ybWF0cyIsbUVycm9yKSxhcmdzLDIsdCkpOwoKCX0KCgltRXJyb3I9IFVfWkVST19FUlJPUjsKCi8vCWlmKCFwcmludCkgeG1sU3RyaW5nLnJlbW92ZSgpOwkKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVMb2NhbGVQYXR0ZXJuQ2hhcnMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCglVbmljb2RlU3RyaW5nIHRlbXA9bVNvdXJjZUJ1bmRsZS5nZXRTdHJpbmdFeCgibG9jYWxQYXR0ZXJuQ2hhcnMiLG1FcnJvcik7CglGb3JtYXR0YWJsZSBhcmdzW109e2luZGVudE9mZnNldCwiIn07CglVbmljb2RlU3RyaW5nIHQ7CglpZihVX1NVQ0NFU1MobUVycm9yKSAmJiBtRXJyb3IhPVVfVVNJTkdfREVGQVVMVF9XQVJOSU5HICYmIG1FcnJvciE9VV9VU0lOR19GQUxMQkFDS19XQVJOSU5HKXsKCQlhcmdzWzFdID0gdGVtcDsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggImxvY2FsaXplZENoYXJzIixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJbUVycm9yID0gVV9aRVJPX0VSUk9SOwoJCXJldHVybjsKCX0KCXhtbFN0cmluZy5yZW1vdmUoKTsKCW1FcnJvciA9IFVfWkVST19FUlJPUjsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVOdW1iZXJGb3JtYXQoKXsKCglVbmljb2RlU3RyaW5nIHhtbFN0cmluZywgdGVtcFN0cjsKCUZvcm1hdHRhYmxlIGFyZ3NbMl09e2luZGVudE9mZnNldCwiIn07CglVbmljb2RlU3RyaW5nIHQ7Cgl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggIm51bWJlcnMiLG1FcnJvciksYXJncywyLHQpKTsKCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CglVQm9vbCBwcmludCA9IEZBTFNFOwoJCgl3cml0ZU51bWJlckVsZW1lbnRzKHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KCgl0ZW1wU3RyLnJlbW92ZSgpOwoJd3JpdGVOdW1iZXJQYXR0ZXJucyh0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9CgoJdGVtcFN0ci5yZW1vdmUoKTsKCXdyaXRlQ3VycmVuY2llcyh0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9CgkKCWNob3BJbmRlbnQoKTsKCWFyZ3NbMV09VW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAibnVtYmVycyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJaWYocHJpbnQpIHByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZU51bWJlckVsZW1lbnRzKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgoJRGVjaW1hbEZvcm1hdFN5bWJvbHMgbXlTeW1ib2xzKG1Mb2NhbGUsbUVycm9yKTsKCVVuaWNvZGVTdHJpbmcgc3ltYm9sOwoJbUVycm9yID0gVV9aRVJPX0VSUk9SOwoJUmVzb3VyY2VCdW5kbGUgbnVtRm9ybWF0cyA9IG1Tb3VyY2VCdW5kbGUuZ2V0KCJOdW1iZXJFbGVtZW50cyIsIG1FcnJvcik7CglVbmljb2RlU3RyaW5nIHQ7CglpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IgIT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAoJCVVfU1VDQ0VTUyhtRXJyb3IpKXsKCQkKCQlGb3JtYXR0YWJsZSBhcmdzW109e2luZGVudE9mZnNldCwiIn07CgoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAic3ltYm9scyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgCgkJVW5pY29kZVN0cmluZyBwYXR0ZXJuPSBudW1Gb3JtYXRzLmdldFN0cmluZ0V4KChpbnQzMl90KTAsbUVycm9yKTsKCQkKCQlhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV0gPSBwYXR0ZXJuOwoJCQoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAiZGVjaW1hbCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCWFyZ3NbMV09bnVtRm9ybWF0cy5nZXRTdHJpbmdFeCgoaW50MzJfdCkxLG1FcnJvcik7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoICJncm91cCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCWFyZ3NbMV09bnVtRm9ybWF0cy5nZXRTdHJpbmdFeCgoaW50MzJfdCkyLG1FcnJvcik7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoICJsaXN0IixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJCgkJYXJnc1sxXT1udW1Gb3JtYXRzLmdldFN0cmluZ0V4KChpbnQzMl90KTMsbUVycm9yKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggInBlcmNlbnRTaWduIixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJCgkJYXJnc1sxXT1udW1Gb3JtYXRzLmdldFN0cmluZ0V4KChpbnQzMl90KTQsbUVycm9yKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggIm5lZ2F0aXZlWmVybyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCWFyZ3NbMV09bnVtRm9ybWF0cy5nZXRTdHJpbmdFeCgoaW50MzJfdCk1LG1FcnJvcik7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoICJwYXR0ZXJuRGlnaXQiLG1FcnJvciksYXJncywyLHQpKTsKCQkKCQlhcmdzWzFdPW51bUZvcm1hdHMuZ2V0U3RyaW5nRXgoKGludDMyX3QpMTEsbUVycm9yKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggInBsdXNTaWduIixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgaWYobUVycm9yID09IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUil7CiAgICAgICAgICAgIG1FcnJvciA9IFVfWkVST19FUlJPUjsKICAgICAgICB9CgkJYXJnc1sxXT1udW1Gb3JtYXRzLmdldFN0cmluZ0V4KChpbnQzMl90KTYsbUVycm9yKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggIm1pbnVzU2lnbiIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCWFyZ3NbMV09bnVtRm9ybWF0cy5nZXRTdHJpbmdFeCgoaW50MzJfdCk3LG1FcnJvcik7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoICJleHBvbmVudGlhbCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQogICAgICAgIGFyZ3NbMV09bnVtRm9ybWF0cy5nZXRTdHJpbmdFeCgoaW50MzJfdCk4LG1FcnJvcik7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoICJwZXJNaWxsZSIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCQoJCWFyZ3NbMV09bnVtRm9ybWF0cy5nZXRTdHJpbmdFeCgoaW50MzJfdCk5LG1FcnJvcik7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoICJpbmZpbml0eSIsbUVycm9yKSxhcmdzLDIsdCkpOwoKCQlhcmdzWzFdPW51bUZvcm1hdHMuZ2V0U3RyaW5nRXgoKGludDMyX3QpMTAsbUVycm9yKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggIm5hbiIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCWNob3BJbmRlbnQoKTsKCQlhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV0gPSBVbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAic3ltYm9scyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJCXJldHVybjsKCgl9CgltRXJyb3I9IFVfWkVST19FUlJPUjsKCXhtbFN0cmluZy5yZW1vdmUoKTsKfQoKCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlTnVtYmVyUGF0dGVybnMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCgltRXJyb3IgPVVfWkVST19FUlJPUjsKCVJlc291cmNlQnVuZGxlIGR0UGF0dGVybnMgPSBtU291cmNlQnVuZGxlLmdldCgiTnVtYmVyUGF0dGVybnMiLCBtRXJyb3IpOwoJVW5pY29kZVN0cmluZyB0OwoJaWYoIG1FcnJvciE9VV9VU0lOR19ERUZBVUxUX1dBUk5JTkcgJiYgCgkJbUVycm9yIT1VX1VTSU5HX0ZBTExCQUNLX1dBUk5JTkcgJiYgCiAgICAgICAgVV9TVUNDRVNTKG1FcnJvcikpewoKCQlVbmljb2RlU3RyaW5nIHRlbXBTdHI7CgkJCgkJd3JpdGVGb3JtYXQoImRlY2ltYWxGb3JtYXRzIiwiZGVjaW1hbEZvcm1hdExlbmd0aCIsImRlY2ltYWxGb3JtYXRTdGFydCIsImRlY2ltYWxGb3JtYXRFbmQiLE5VTEwsZHRQYXR0ZXJucy5nZXRTdHJpbmdFeCgoaW50MzJfdCkwLG1FcnJvcikseG1sU3RyaW5nLEZBTFNFKTsKCQl3cml0ZUZvcm1hdCgic2NpZW50aWZpY0Zvcm1hdHMiLCJzY2llbnRpZmljRm9ybWF0TGVuZ3RoIiwic2NpZW50aWZpY0Zvcm1hdFN0YXJ0Iiwic2NpZW50aWZpY0Zvcm1hdEVuZCIsTlVMTCxkdFBhdHRlcm5zLmdldFN0cmluZ0V4KChpbnQzMl90KTMsbUVycm9yKSx4bWxTdHJpbmcsRkFMU0UpOwoJCXdyaXRlRm9ybWF0KCJwZXJjZW50Rm9ybWF0cyIsInBlcmNlbnRGb3JtYXRMZW5ndGgiLCJwZXJjZW50Rm9ybWF0U3RhcnQiLCJwZXJjZW50Rm9ybWF0RW5kIixOVUxMLGR0UGF0dGVybnMuZ2V0U3RyaW5nRXgoKGludDMyX3QpMixtRXJyb3IpLHhtbFN0cmluZyxGQUxTRSk7CgkJd3JpdGVGb3JtYXQoImN1cnJlbmN5Rm9ybWF0cyIsImN1cnJlbmN5Rm9ybWF0TGVuZ3RoIiwiY3VycmVuY3lGb3JtYXRTdGFydCIsImN1cnJlbmN5Rm9ybWF0RW5kIixOVUxMLGR0UGF0dGVybnMuZ2V0U3RyaW5nRXgoKGludDMyX3QpMSxtRXJyb3IpLHhtbFN0cmluZyxGQUxTRSk7CgogICAgICAgIGlmKG1FcnJvciA9PSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1IpewoJCQltRXJyb3IgPSBVX1pFUk9fRVJST1I7CgkJfQoJCQoJfQoKCW1FcnJvcj0gVV9aRVJPX0VSUk9SOwp9CgoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVDdXJyZW5jaWVzKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CgoJVW5pY29kZVN0cmluZyB0ZW1wU3RyOwoJRm9ybWF0dGFibGUgYXJnc1syXSA9IHsgaW5kZW50T2Zmc2V0LCIiIH07CglVbmljb2RlU3RyaW5nIHQ7Cgl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY3VycmVuY2llcyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCXdyaXRlQ3VycmVuY3kodGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCWNob3BJbmRlbnQoKTsKCQlhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV0gPSBVbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJjdXJyZW5jaWVzIixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJLy9wcmludFN0cmluZygmeG1sU3RyaW5nKTsKICAgICAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgcmV0dXJuOwoJfQoKCXhtbFN0cmluZy5yZW1vdmUoKTsKCgljaG9wSW5kZW50KCk7CgltRXJyb3I9IFVfWkVST19FUlJPUjsKfQoKCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlQ3VycmVuY3koVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCQoJVUJvb2wgaXNEZWZhdWx0ID1UUlVFOwoJUmVzb3VyY2VCdW5kbGUgY3VycmVuY3kgPW1Tb3VyY2VCdW5kbGUuZ2V0KCJDdXJyZW5jaWVzIiwgbUVycm9yKTsKICAgIFVuaWNvZGVTdHJpbmcgdDsKCiAgICBpZiggVV9TVUNDRVNTKG1FcnJvcikgICYmIAogICAgICAgIG1FcnJvciAhPSBVX1VTSU5HX0ZBTExCQUNLX1dBUk5JTkcgJiYgCiAgICAgICAgbUVycm9yICE9IFVfVVNJTkdfREVGQVVMVF9XQVJOSU5HKXsgIAogICAgICAgIAogICAgICAgIHdoaWxlKGN1cnJlbmN5Lmhhc05leHQoKSl7CgkJCVJlc291cmNlQnVuZGxlIGRCdW5kbGUxID0gY3VycmVuY3kuZ2V0TmV4dChtRXJyb3IpOwogICAgICAgICAgICBjb25zdCBjaGFyKiBteWtleT1kQnVuZGxlMS5nZXRLZXkoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3ltYm9sID0gZEJ1bmRsZTEuZ2V0U3RyaW5nRXgoKGludDMyX3QpMCwgbUVycm9yKTsKICAgICAgICAgICAgVW5pY29kZVN0cmluZyBkaXNwbGF5TmFtZSA9IGRCdW5kbGUxLmdldFN0cmluZ0V4KChpbnQzMl90KTEsIG1FcnJvcik7CgkJICAgIEZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsVW5pY29kZVN0cmluZyhteWtleSksIiJ9OwogICAgICAgICAgICAKCQkgICAgLy94bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggImRlZmF1bHQiLG1FcnJvciksYXJncywyLHQpKTsKCQkgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImN1cnJlbmN5U3RhcnQiLG1FcnJvciksYXJncywzLHQpKTsKCgkJICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgkJICAgIAoJCSAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCSAgICBhcmdzWzFdID0gZGlzcGxheU5hbWU7CgkJICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkaXNwbGF5TmFtZSIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgICAKICAgICAgICAgICAgZXNjYXBlKHN5bWJvbCk7CiAgICAgICAgICAgIGFyZ3NbMV0gPSBzeW1ib2w7CgkJICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJzeW1ib2wiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGludDMyX3Qgc2l6ZSA9IGRCdW5kbGUxLmdldFNpemUoKTsKICAgICAgICAgICAgaWYoc2l6ZT4yKXsKICAgICAgICAgICAgICAgIFJlc291cmNlQnVuZGxlIGVsZW1lbnRzID0gZEJ1bmRsZTEuZ2V0KChpbnQzMl90KTIsIG1FcnJvcik7CiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIGtleSA9IGVsZW1lbnRzLmdldEtleSgpOwogICAgICAgICAgICAgICAgaWYoZWxlbWVudHMuZ2V0VHlwZSgpIT0gVVJFU19BUlJBWSl7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsIkRpZCBub3QgZ2V0IHRoZSBleHBlY3RlZCB0eXBlIGZvciBFbGVtZW50c1xuIik7CiAgICAgICAgICAgICAgICAgICAgZXhpdCgtMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CiAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBwYXR0ZXJuID0gZWxlbWVudHMuZ2V0U3RyaW5nRXgoKGludDMyX3QpMCwgbUVycm9yKTsKICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIGRlY2ltYWxTZXAgPSBlbGVtZW50cy5nZXRTdHJpbmdFeCgoaW50MzJfdCkxLCBtRXJyb3IpOwogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgZ3JvdXBTZXAgPSBlbGVtZW50cy5nZXRTdHJpbmdFeCgoaW50MzJfdCkyLCBtRXJyb3IpOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXR0ZXJuOwogICAgICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJwYXR0ZXJuIixtRXJyb3IpLGFyZ3MsMix0KSk7CgogICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBkZWNpbWFsU2VwOwogICAgICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJkZWNpbWFsIixtRXJyb3IpLGFyZ3MsMix0KSk7CgogICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBncm91cFNlcDsKICAgICAgICAgICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZ3JvdXAiLG1FcnJvciksYXJncywyLHQpKTsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hvcEluZGVudCgpOwogICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICBhcmdzWzFdID0gIiI7CiAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJjdXJyZW5jeUVuZCIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgIAoKCSAgICB9CgkJcmV0dXJuOwogICAgfQoKCXhtbFN0cmluZy5yZW1vdmUoKTsKCW1FcnJvcj1VX1pFUk9fRVJST1I7Cn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlU3BlY2lhbCgpewogICAgaWYoaWdub3JlU3BlY2lhbHMgPT0gRkFMU0UpewoJICAgIFVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nLCB0ZW1wU3RyOwoJICAgIEZvcm1hdHRhYmxlIGFyZ3NbXT17aW5kZW50T2Zmc2V0LG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJ4bWxuc19pY3UiLG1FcnJvciksIiIsIiJ9OwoJICAgIFVuaWNvZGVTdHJpbmcgdDsKCSAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCggInNwZWNpYWwiLG1FcnJvciksYXJncyw0LHQpKTsKCSAgICBpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoJICAgIFVCb29sIHByaW50ID0gRkFMU0U7CgkgICAgCgkgICAgd3JpdGVCb3VuZGFyeSh0ZW1wU3RyKTsKCSAgICBpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCSAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCSAgICBwcmludCA9IFRSVUU7CgkgICAgfQoJICAgIHRlbXBTdHIucmVtb3ZlKCk7CgkgICAgd3JpdGVSdWxlQmFzZWROdW1iZXJGb3JtYXQodGVtcFN0cik7CgkgICAgaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQkgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQkgICAgcHJpbnQgPSBUUlVFOwoJICAgIH0KCSAgICBjaG9wSW5kZW50KCk7CgkgICAgYXJnc1sxXT1Vbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwoJICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCAic3BlY2lhbEVuZCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJICAgIGlmKHByaW50KSBwcmludFN0cmluZygmeG1sU3RyaW5nKTsKICAgIH0KfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVSdWxlQmFzZWROdW1iZXJGb3JtYXQoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKICAgIGlmKGlnbm9yZVNwZWNpYWxzID09IEZBTFNFKXsKCSAgICBVbmljb2RlU3RyaW5nIHRlbXBTdHI7CgkgICAgRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwiIiwiIiwiIn07CgkgICAgVUJvb2wgcHJpbnQgPSBGQUxTRTsKCSAgICBVbmljb2RlU3RyaW5nIHQ7CgogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJydWxlQmFzZWRORlMiLG1FcnJvciksYXJncywyLHQpKTsKCSAgICBpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoKCSAgICBVbmljb2RlU3RyaW5nIHNwZWxsb3V0ID0gbVNvdXJjZUJ1bmRsZS5nZXRTdHJpbmdFeCgiU3BlbGxvdXRSdWxlcyIsbUVycm9yKTsKCSAgICBpZiggbUVycm9yICE9IFVfVVNJTkdfREVGQVVMVF9XQVJOSU5HICYmIAoJCSAgICBVX1NVQ0NFU1MobUVycm9yKSAmJgoJCSAgICBtRXJyb3IgIT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HKXsKCQkgICAgZXNjYXBlKHNwZWxsb3V0KTsKCQkgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkgICAgYXJnc1sxXSA9ICJzcGVsbG91dCI7CgkJICAgIGFyZ3NbMl0gPSBzcGVsbG91dDsKICAgICAgICAgICAgYXJnc1szXSA9IGluZGVudE9mZnNldDsKCQkgICAgdGVtcFN0ci5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJydWxlQmFzZWRORiIsbUVycm9yKSxhcmdzLDQsdCkpOwoKCSAgICB9CgoJICAgIG1FcnJvcj1VX1pFUk9fRVJST1I7CgkgICAgVW5pY29kZVN0cmluZyBvcmRpbmFsID0gbVNvdXJjZUJ1bmRsZS5nZXRTdHJpbmdFeCgiT3JkaW5hbFJ1bGVzIiwgbUVycm9yKTsKCSAgICBpZiggbUVycm9yICE9IFVfVVNJTkdfREVGQVVMVF9XQVJOSU5HICYmIAoJCSAgICBVX1NVQ0NFU1MobUVycm9yKSAmJgoJCSAgICBtRXJyb3IgIT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HKXsKCQkgICAgZXNjYXBlKG9yZGluYWwpOwoJCSAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCSAgICBhcmdzWzFdID0gIm9yZGluYWwiOwoJCSAgICBhcmdzWzJdID0gb3JkaW5hbDsKICAgICAgICAgICAgYXJnc1szXSA9IGluZGVudE9mZnNldDsKCQkgICAgdGVtcFN0ci5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJydWxlQmFzZWRORiIsbUVycm9yKSxhcmdzLDQsdCkpOwoJICAgIH0KCgkgICAgbUVycm9yPVVfWkVST19FUlJPUjsKCSAgICBVbmljb2RlU3RyaW5nIGR1cmF0aW9uID0gbVNvdXJjZUJ1bmRsZS5nZXRTdHJpbmdFeCgiRHVyYXRpb25SdWxlcyIsIG1FcnJvcik7CgkgICAgaWYoIG1FcnJvciAhPSBVX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQkgICAgVV9TVUNDRVNTKG1FcnJvcikgJiYKCQkgICAgbUVycm9yICE9IFVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyl7CgkJICAgIGVzY2FwZShkdXJhdGlvbik7CgkJICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CgkJICAgIGFyZ3NbMV0gPSAiZHVyYXRpb24iOwoJCSAgICBhcmdzWzJdID0gZHVyYXRpb247CiAgICAgICAgICAgIGFyZ3NbM10gPSBpbmRlbnRPZmZzZXQ7CgkJICAgIHRlbXBTdHIuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicnVsZUJhc2VkTkYiLG1FcnJvciksYXJncyw0LHQpKTsKCSAgICB9CgkgICAgaWYodGVtcFN0ci5pc0VtcHR5KCkpewoJCSAgICB4bWxTdHJpbmcucmVtb3ZlKCk7CgkgICAgfWVsc2V7CgkJICAgIGNob3BJbmRlbnQoKTsKCQkgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQkgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkgICAgYXJnc1sxXSA9IFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CgkgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJydWxlQmFzZWRORlMiLG1FcnJvciksYXJncywyLHQpKTsKCSAgICB9CgkgICAgbUVycm9yPSBVX1pFUk9fRVJST1I7CiAgICB9Cn0KLyoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVUcmFuc2xpdGVyYXRpb24oKXsKCVVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nOwoJY29uc3QgVW5pY29kZVN0cmluZyB0cmFuc2xpdD0gbVNvdXJjZUJ1bmRsZS5nZXRTdHJpbmdFeCgiVHJhbnNsaXRlcmF0b3JOYW1lUGF0dGVybiIsbUVycm9yKTsKCWlmKG1FcnJvciAhPSBVX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiBtRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiBVX1NVQ0NFU1MobUVycm9yKSl7CgkJRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCx0cmFuc2xpdH07CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyhUTF9OQU1FKSxhcmdzLDIpKTsKCQlwcmludFN0cmluZygmeG1sU3RyaW5nKTsKCX0KCW1FcnJvcj1VX1pFUk9fRVJST1I7Cn0KKi8Kdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVDaGFyQnJrUnVsZXMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCiAgICBSZXNvdXJjZUJ1bmRsZSBicmtSdWxlcyA9IG1Tb3VyY2VCdW5kbGUuZ2V0KCJDaGFyYWN0ZXJCcmVha1J1bGVzIixtRXJyb3IpOwoJVW5pY29kZVN0cmluZyB0OwoJaWYoIG1FcnJvciAhPSBVX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IgIT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAoJCVVfU1VDQ0VTUyhtRXJyb3IpKXsKCQkKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZ3JhcGhlbWVTdGFydCIsbUVycm9yKSxpbmRlbnRPZmZzZXQsdCkpOwoJCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgd2hpbGUoYnJrUnVsZXMuaGFzTmV4dCgpKXsKCQkJVW5pY29kZVN0cmluZyBydWxlID1icmtSdWxlcy5nZXROZXh0U3RyaW5nKG1FcnJvcik7CgkJCWVzY2FwZShydWxlKTsKCQkJeG1sU3RyaW5nLmFwcGVuZCgiXG4iKTsKCQkJeG1sU3RyaW5nLmFwcGVuZChpbmRlbnRPZmZzZXQpOwoJCQl4bWxTdHJpbmcuYXBwZW5kKHJ1bGUpOwoJCX0KCQl4bWxTdHJpbmcuYXBwZW5kKCJcblxuIik7CgkJY2hvcEluZGVudCgpOwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJncmFwaGVtZUVuZCIsbUVycm9yKSxpbmRlbnRPZmZzZXQsdCkpOwoJCXJldHVybjsKCX0KCXhtbFN0cmluZy5yZW1vdmUoKTsKCW1FcnJvcj0gVV9aRVJPX0VSUk9SOwoKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVTZW50QnJrUnVsZXMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCglSZXNvdXJjZUJ1bmRsZSBicmtSdWxlcyA9IG1Tb3VyY2VCdW5kbGUuZ2V0KCJTZW50ZW5jZUJyZWFrUnVsZXMiLG1FcnJvcik7CglVbmljb2RlU3RyaW5nIHQ7Cgl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgic2VudGVuY2VTdGFydCIsbUVycm9yKSxpbmRlbnRPZmZzZXQsdCkpOwoJaWYoIG1FcnJvciAhPSBVX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IgIT0gVV9VU0lOR19GQUxMQkFDS19XQVJOSU5HICYmIAoJCVVfU1VDQ0VTUyhtRXJyb3IpKXsKCQlpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwogICAgICAgIHdoaWxlKGJya1J1bGVzLmhhc05leHQoKSl7CgkJCVVuaWNvZGVTdHJpbmcgcnVsZSA9YnJrUnVsZXMuZ2V0TmV4dFN0cmluZyhtRXJyb3IpOwoJCQllc2NhcGUocnVsZSk7CgkJCXhtbFN0cmluZy5hcHBlbmQoIlxuIik7CgkJCXhtbFN0cmluZy5hcHBlbmQoaW5kZW50T2Zmc2V0KTsKCQkJeG1sU3RyaW5nLmFwcGVuZChydWxlKTsKCQl9CgkJeG1sU3RyaW5nLmFwcGVuZCgiXG5cbiIpOwoJCWNob3BJbmRlbnQoKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZ3JhcGhlbWVFbmQiLG1FcnJvciksaW5kZW50T2Zmc2V0LHQpKTsKCQlyZXR1cm47Cgl9Cgl4bWxTdHJpbmcucmVtb3ZlKCk7CgltRXJyb3I9IFVfWkVST19FUlJPUjsKCn0Kdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVMaW5lQnJrUnVsZXMoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCglSZXNvdXJjZUJ1bmRsZSBicmtSdWxlcyA9IG1Tb3VyY2VCdW5kbGUuZ2V0KCJMaW5lQnJlYWtSdWxlcyIsbUVycm9yKTsKCVVuaWNvZGVTdHJpbmcgdDsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJsaW5lU3RhcnQiLG1FcnJvciksaW5kZW50T2Zmc2V0LHQpKTsKCglpZiggbUVycm9yICE9IFVfVVNJTkdfREVGQVVMVF9XQVJOSU5HICYmIAoJCW1FcnJvciAhPSBVX1VTSU5HX0ZBTExCQUNLX1dBUk5JTkcgJiYgCgkJVV9TVUNDRVNTKG1FcnJvcikpewoJICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKICAgICAgIHdoaWxlKGJya1J1bGVzLmhhc05leHQoKSl7CgkJCVVuaWNvZGVTdHJpbmcgcnVsZSA9YnJrUnVsZXMuZ2V0TmV4dFN0cmluZyhtRXJyb3IpOwoJCQllc2NhcGUocnVsZSk7CgkJCXhtbFN0cmluZy5hcHBlbmQoIlxuIik7CgkJCXhtbFN0cmluZy5hcHBlbmQoaW5kZW50T2Zmc2V0KTsKCQkJeG1sU3RyaW5nLmFwcGVuZChydWxlKTsKCQl9CgkJeG1sU3RyaW5nLmFwcGVuZCgiXG5cbiIpOwoJCWNob3BJbmRlbnQoKTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibGluZUVuZCIsbUVycm9yKSxpbmRlbnRPZmZzZXQsdCkpOwoJCXJldHVybjsKCX0KCXhtbFN0cmluZy5yZW1vdmUoKTsKCW1FcnJvcj0gVV9aRVJPX0VSUk9SOwp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUJvdW5kYXJ5KFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CglVbmljb2RlU3RyaW5nIHRlbXBTdHI7CglVQm9vbCBwcmludD1GQUxTRTsKCUZvcm1hdHRhYmxlIGFyZ3NbM10gPSB7IGluZGVudE9mZnNldCwiIiwiIn07CglVbmljb2RlU3RyaW5nIHQ7Cgl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiYm91bmRhcmllcyIsbUVycm9yKSxhcmdzLDIsdCkpOwoJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQoJd3JpdGVDaGFyQnJrUnVsZXModGVtcFN0cik7CglpZighdGVtcFN0ci5pc0VtcHR5KCkpewoJCXhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CgkJcHJpbnQgPSBUUlVFOwoJfQoJdGVtcFN0ci5yZW1vdmUoKTsKCXdyaXRlU2VudEJya1J1bGVzKHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KCXRlbXBTdHIucmVtb3ZlKCk7Cgl3cml0ZUxpbmVCcmtSdWxlcyh0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9Cgl0ZW1wU3RyLnJlbW92ZSgpOwoJY2hvcEluZGVudCgpOwoJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImJvdW5kYXJpZXMiLG1FcnJvciksYXJncywyLHQpKTsKCglpZighcHJpbnQpIHhtbFN0cmluZy5yZW1vdmUoKTsKfQoKCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlQ29sbGF0aW9ucygpewoJVW5pY29kZVN0cmluZyB0ZW1wU3RyLHhtbFN0cmluZzsKCVVCb29sIHByaW50PUZBTFNFOwoJRm9ybWF0dGFibGUgYXJnc1szXSA9IHsgaW5kZW50T2Zmc2V0LCIifTsKCVVuaWNvZGVTdHJpbmcgdDsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJjb2xsYXRpb25zIixtRXJyb3IpLGFyZ3MsMix0KSk7CglpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoJICAKICAgIFJlc291cmNlQnVuZGxlIGRCdW5kbGUgPSBtU291cmNlQnVuZGxlLmdldCgiY29sbGF0aW9ucyIsIG1FcnJvcik7CgogICAgaWYoVV9TVUNDRVNTKG1FcnJvcikpewoKICAgICAgICB3aGlsZShkQnVuZGxlLmhhc05leHQoKSl7CiAgICAgICAgICAgIHdyaXRlQ29sbGF0aW9uKGRCdW5kbGUuZ2V0TmV4dChtRXJyb3IpLCB0ZW1wU3RyKTsKICAgICAgICAgICAgaWYodGVtcFN0ci5sZW5ndGgoKSE9MCl7CiAgICAgICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwogICAgICAgICAgICAgICAgcHJpbnQgPVRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGVtcFN0ci5yZW1vdmUoKTsKICAgICAgICB9CgogICAgfQogICAgCgkvKndyaXRlU2VudEJya1J1bGVzKHRlbXBTdHIpOwoJaWYoIXRlbXBTdHIuaXNFbXB0eSgpKXsKCQl4bWxTdHJpbmcuYXBwZW5kKHRlbXBTdHIpOwoJCXByaW50ID0gVFJVRTsKCX0KCXRlbXBTdHIucmVtb3ZlKCk7Cgl3cml0ZUxpbmVCcmtSdWxlcyh0ZW1wU3RyKTsKCWlmKCF0ZW1wU3RyLmlzRW1wdHkoKSl7CgkJeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKCQlwcmludCA9IFRSVUU7Cgl9Ki8KCWNob3BJbmRlbnQoKTsKCiAgICBhcmdzWzFdPVVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CglhcmdzWzJdPSIiOwogICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImNvbGxhdGlvbnMiLG1FcnJvciksYXJncywzLHQpKTsKCQoJaWYocHJpbnQpICBwcmludFN0cmluZygmeG1sU3RyaW5nKTsKICAgIG1FcnJvciA9VV9aRVJPX0VSUk9SOwoJCn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlQmFzZShVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewogICAgaWYoYmFzZUNvbGxhdGlvbiAhPSBOVUxMKXsKICAgICAgICBGb3JtYXR0YWJsZSBhcmdzW10gPSB7aW5kZW50T2Zmc2V0LCAiIiwgIiJ9OwogICAgICAgIFVuaWNvZGVTdHJpbmcgdGVtcDsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiYmFzZVN0YXJ0IiwgbUVycm9yKSwgYXJncywgMSwgdGVtcCkpOwogICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgCiAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICBhcmdzWzFdID0gYmFzZUNvbGxhdGlvbjsKICAgICAgICBhcmdzWzJdID0gKGJhc2VUeXBlPT1OVUxMKSA/ICJzdGFuZGFyZCIgOiBiYXNlVHlwZTsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiYWxpYXMiLCBtRXJyb3IpLCBhcmdzLCAzLCB0ZW1wKSk7CgogICAgICAgIGNob3BJbmRlbnQoKTsKCiAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiYmFzZUVuZCIsIG1FcnJvciksIGFyZ3MsIDEsIHRlbXApKTsKICAgIH0KCiAgICBpZihVX0ZBSUxVUkUobUVycm9yKSl7CiAgICAgICAgbUVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgICAgIHhtbFN0cmluZy5yZW1vdmUoKTsKICAgIH0KfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVVQ0FSdWxlcyhVbmljb2RlU3RyaW5nJiBzZXF1ZW5jZSxVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoKICAgIFVuaWNvZGVTdHJpbmcgcnVsZXM7CiAgICBjb25zdCBjaGFyKiBrZXkgPSAiVUNBIjsKCiAgICBVbmljb2RlU3RyaW5nIHQ7CiAgICBpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQlVX1NVQ0NFU1MobUVycm9yKSAmJiAKCQltRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyl7CiAgICAgICAgRm9ybWF0dGFibGUgYXJnc1tdPXtpbmRlbnRPZmZzZXQsIiIsIiIsIiIsIiJ9OwoKCQlVbmljb2RlU3RyaW5nIHN0ciA9ICJ0eXBlPVwiIjsKCQlzdHIuYXBwZW5kKGtleSk7CgkJc3RyLmFwcGVuZCgiXCIiKTsKCQlhcmdzWzJdID0gc3RyOwoKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY29sbGF0aW9uIixtRXJyb3IpLGFyZ3MsMyx0KSk7CgoJCWluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgCiAgICAgICAgLy8gd2lydGUgdGhlIGJhc2UgZWxlbWVudAogICAgICAgIHdyaXRlQmFzZSh0LnJlbW92ZSgpKTsKICAgICAgICBpZih0Lmxlbmd0aCgpICE9IDApewogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHQpOwogICAgICAgIH0KICAgICAgICAKCQlydWxlcyA9IHBhcnNlUnVsZXMoKFVDaGFyKilzZXF1ZW5jZS5nZXRCdWZmZXIoKSxzZXF1ZW5jZS5sZW5ndGgoKSxydWxlcyk7CgkJeG1sU3RyaW5nLmFwcGVuZChydWxlcyk7CiAgICAgICAgc2VxdWVuY2UucmVsZWFzZUJ1ZmZlcigpOwoJCQogICAgICAgIGNob3BJbmRlbnQoKTsKCQlhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCWFyZ3NbMV0gPSAiLyI7CgkJYXJnc1syXSA9IiI7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImNvbGxhdGlvbiIsbUVycm9yKSxhcmdzLDMsdCkpOwogICAgICAgIC8vcHJpbnRTdHJpbmcoJnhtbFN0cmluZyk7CiAgICB9CiAgICBtRXJyb3IgPSBVX1pFUk9fRVJST1I7Cn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlQ29sbGF0aW9uKFJlc291cmNlQnVuZGxlJiBidW5kbGUsVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nLCBVbmljb2RlU3RyaW5nKiBjb2xsS2V5KXsKCiAgICBVbmljb2RlU3RyaW5nIHZlcnNpb247CiAgICBVbmljb2RlU3RyaW5nIG92ZXJpZGU9IkZBTFNFIjsKICAgIFVuaWNvZGVTdHJpbmcgc2VxdWVuY2U7CiAgICBVbmljb2RlU3RyaW5nIHJ1bGVzOwogICAgY29uc3QgY2hhcioga2V5ID0gYnVuZGxlLmdldEtleSgpOwogICAgVW5pY29kZVN0cmluZyB0OwogICAgaWYoc3RyaWNtcChrZXksICJkZWZhdWx0IikgPT0gMCkgewogICAgICAgIEZvcm1hdHRhYmxlIGFyZ3NbXT17aW5kZW50T2Zmc2V0LCIiLCIiLCIiLCIifTsKICAgICAgICAgICAgICAgc2VxdWVuY2UgPSBidW5kbGUuZ2V0U3RyaW5nKG1FcnJvcik7CiAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CiAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBzZXF1ZW5jZTsKICAgICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImRlZmF1bHQiLG1FcnJvciksYXJncywyLHQpKTsKICAgIH1lbHNlIHsKICAgICAgICBpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQkgICAgVV9TVUNDRVNTKG1FcnJvcikgJiYgCgkJICAgIG1FcnJvciE9VV9VU0lOR19GQUxMQkFDS19XQVJOSU5HKXsKICAgICAgICAgICAgRm9ybWF0dGFibGUgYXJnc1tdPXtpbmRlbnRPZmZzZXQsIiIsIiIsIiIsIiJ9OwoKCQkgICAgVW5pY29kZVN0cmluZyBzdHIgPSAidHlwZT1cIiI7CgkJICAgIHN0ci5hcHBlbmQoa2V5KTsKCQkgICAgc3RyLmFwcGVuZCgiXCIiKTsKCQkgICAgYXJnc1syXSA9IHN0cjsKCgkJICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJjb2xsYXRpb24iLG1FcnJvciksYXJncywzLHQpKTsKCgkJICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyB3aXJ0ZSB0aGUgYmFzZSBlbGVtZW50CiAgICAgICAgICAgIHdyaXRlQmFzZSh0LnJlbW92ZSgpKTsKICAgICAgICAgICAgaWYodC5sZW5ndGgoKSAhPSAwKXsKICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQodCk7CiAgICAgICAgICAgIH0KCgkJICAgIHdoaWxlKGJ1bmRsZS5oYXNOZXh0KCkpewogICAgICAgICAgICAgICAgUmVzb3VyY2VCdW5kbGUgZEJ1bmRsZTEgPSBidW5kbGUuZ2V0TmV4dChtRXJyb3IpOwogICAgICAgICAgICAgICAgY29uc3QgY2hhciogbXlrZXk9ZEJ1bmRsZTEuZ2V0S2V5KCk7CiAgICAgICAgICAgICAgICBpZihzdHJpY21wKG15a2V5LCJWZXJzaW9uIik9PTAgJiYgaWdub3JlU3BlY2lhbHM9PUZBTFNFKXsKICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uID0gYnVuZGxlLmdldFN0cmluZ0V4KG15a2V5LG1FcnJvcik7CgkJCSAgICAgICAgVW5pY29kZVN0cmluZyB0ZW1wID0gVW5pY29kZVN0cmluZygiaWN1OnZlcnNpb249XCIiKS5hcHBlbmQodmVyc2lvbik7CgkJCSAgICAgICAgdGVtcC5hcHBlbmQoIlwiIik7CgkJCSAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gbVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInhtbG5zX2ljdSIsbUVycm9yKTsKCQkJICAgICAgICBhcmdzWzJdID0gdGVtcDsKCQkJICAgICAgICBhcmdzWzNdID0gVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKCQkJICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgic3BlY2lhbCIsbUVycm9yKSxhcmdzLDQsdCkpOwogICAgICAgICAgICAgICAgfWVsc2UgaWYoc3RyaWNtcChteWtleSwiU2VxdWVuY2UiKT09MCAmJiBvbmx5U3BlY2lhbHM9PUZBTFNFKXsKICAgICAgICAgICAgICAgICAgICBzZXF1ZW5jZSA9IGJ1bmRsZS5nZXRTdHJpbmdFeChteWtleSxtRXJyb3IpOwoJCQkJICAgIHJ1bGVzID0gcGFyc2VSdWxlcygoVUNoYXIqKXNlcXVlbmNlLmdldEJ1ZmZlcigpLHNlcXVlbmNlLmxlbmd0aCgpLHJ1bGVzKTsKCQkJCSAgICB4bWxTdHJpbmcuYXBwZW5kKHJ1bGVzKTsKICAgICAgICAgICAgICAgICAgICBzZXF1ZW5jZS5yZWxlYXNlQnVmZmVyKCk7CgogICAgICAgICAgICAgICAgfWVsc2UgaWYoc3RyaWNtcChteWtleSwiT3ZlcnJpZGUiKT09MCAmJiBvbmx5U3BlY2lhbHM9PUZBTFNFKXsKICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmlkZSA9ICBidW5kbGUuZ2V0U3RyaW5nRXgobXlrZXksbUVycm9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgY2hvcEluZGVudCgpOwoJCSAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCSAgICBhcmdzWzFdID0gIi8iOwoJCSAgICBhcmdzWzJdID0iIjsKCQkgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImNvbGxhdGlvbiIsbUVycm9yKSxhcmdzLDMsdCkpOwogICAgICAgICAgICAvL3ByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwogICAgICAgIH0KICAgIH0KICAgIG1FcnJvciA9IFVfWkVST19FUlJPUjsKfQpVbmljb2RlU3RyaW5nJiBhcHBlbmRIZXgodWludDMyX3QgbnVtYmVyLAogICAgICAgICAgICBpbnQzMl90IGRpZ2l0cywKICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgdGFyZ2V0KQp7CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgZGlnaXRTdHJpbmdbXSA9IHsKICAgICAgICAweDMwLCAweDMxLCAweDMyLCAweDMzLCAweDM0LCAweDM1LCAweDM2LCAweDM3LCAweDM4LCAweDM5LAogICAgICAgIDB4NDEsIDB4NDIsIDB4NDMsIDB4NDQsIDB4NDUsIDB4NDYsIDAKICAgIH07IC8qICIwMTIzNDU2Nzg5QUJDREVGIiAqLwoKICAgIHN3aXRjaCAoZGlnaXRzKQogICAgewogICAgY2FzZSA4OgogICAgICAgIHRhcmdldCArPSBkaWdpdFN0cmluZ1sobnVtYmVyID4+IDI4KSAmIDB4Rl07CiAgICBjYXNlIDc6CiAgICAgICAgdGFyZ2V0ICs9IGRpZ2l0U3RyaW5nWyhudW1iZXIgPj4gMjQpICYgMHhGXTsKICAgIGNhc2UgNjoKICAgICAgICB0YXJnZXQgKz0gZGlnaXRTdHJpbmdbKG51bWJlciA+PiAyMCkgJiAweEZdOwogICAgY2FzZSA1OgogICAgICAgIHRhcmdldCArPSBkaWdpdFN0cmluZ1sobnVtYmVyID4+IDE2KSAmIDB4Rl07CiAgICBjYXNlIDQ6CiAgICAgICAgdGFyZ2V0ICs9IGRpZ2l0U3RyaW5nWyhudW1iZXIgPj4gMTIpICYgMHhGXTsKICAgIGNhc2UgMzoKICAgICAgICB0YXJnZXQgKz0gZGlnaXRTdHJpbmdbKG51bWJlciA+PiAgOCkgJiAweEZdOwogICAgY2FzZSAyOgogICAgICAgIHRhcmdldCArPSBkaWdpdFN0cmluZ1sobnVtYmVyID4+ICA0KSAmIDB4Rl07CiAgICBjYXNlIDE6CiAgICAgICAgdGFyZ2V0ICs9IGRpZ2l0U3RyaW5nWyhudW1iZXIgPj4gIDApICYgMHhGXTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgdGFyZ2V0ICs9ICIqKiI7CiAgICB9CiAgICByZXR1cm4gdGFyZ2V0Owp9CgoKLy8gUmVwbGFjZSBub25wcmludGFibGUgY2hhcmFjdGVycyB3aXRoIHVuaWNvZGUgZXNjYXBlcwpVbmljb2RlU3RyaW5nJiBwcmV0dGlmeShjb25zdCBVbmljb2RlU3RyaW5nICZzb3VyY2UsVW5pY29kZVN0cmluZyAmdGFyZ2V0KQp7CiAgICBpbnQzMl90IGk7CgogICAgdGFyZ2V0LnJlbW92ZSgpOwogICAgdGFyZ2V0ICs9ICJcIiI7CgogICAgZm9yIChpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGgoKTsgKQogICAgewogICAgICAgIFVDaGFyMzIgY2ggPSBzb3VyY2UuY2hhcjMyQXQoaSk7CiAgICAgICAgaSArPSBVVEZfQ0hBUl9MRU5HVEgoY2gpOwoKICAgICAgICBpZiAoY2ggPCAweDA5IHx8IChjaCA+IDB4MEEgJiYgY2ggPCAweDIwKXx8IGNoID4gMHg3RSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjaCA8PSAweEZGRkYpIHsKICAgICAgICAgICAgICAgIHRhcmdldCArPSAiXFx1IjsKICAgICAgICAgICAgICAgIGFwcGVuZEhleChjaCwgNCwgdGFyZ2V0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRhcmdldCArPSAiXFxVIjsKICAgICAgICAgICAgICAgIGFwcGVuZEhleChjaCwgOCwgdGFyZ2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB0YXJnZXQgKz0gY2g7CiAgICAgICAgfQogICAgfQoKICAgIHRhcmdldCArPSAiXCIiOwoKICAgIHJldHVybiB0YXJnZXQ7Cn0KCiNkZWZpbmUgVUNPTF9UT0tfVU5TRVQgICAgMHhGRkZGRkZGRgojZGVmaW5lIFVDT0xfVE9LX1JFU0VUICAgIDB4REVBREJFRUYKI2RlZmluZSBVQ09MX1RPS19TRVRUSU5HICAweEZGRkZGRkZFCiNkZWZpbmUgVUNPTF9UT0tfT1ZFUlJJREUgMHhGRkZGRkZGRCAKI2RlZmluZSBVQ09MX1RPS19ET05FICAgICAweEZGRkZGRkZDCiNkZWZpbmUgVUNPTF9UT0tfRVhQQU5TSU9OX01BUktFUiAweEZGRkYKClVCb29sIAp1cHJ2X2lzUnVsZVdoaXRlU3BhY2UoVUNoYXIzMiBjKSB7CiAgICAvKiAid2hpdGUgc3BhY2UiIGluIHRoZSBzZW5zZSBvZiBJQ1UgcnVsZSBwYXJzZXJzOiBDZitXaGl0ZV9TcGFjZSAqLwogICAgcmV0dXJuCiAgICAgICAgdV9jaGFyVHlwZShjKT09VV9GT1JNQVRfQ0hBUiB8fAogICAgICAgIHVfaGFzQmluYXJ5UHJvcGVydHkoYywgVUNIQVJfV0hJVEVfU1BBQ0UpOwp9Ci8qCnN0cmVuZ3RoICAJICAgIHByaW1hcnkgKDEpICAgICAgICAgW3N0cmVuZ3RoIDFdIAkgICAgICAgICAgICAgICAgc3RyZW5ndGggPSAicHJpbWFyeSIgCiAgICAgICAgICAgICAgICBzZWNvbmRhcnkgKDIpCiAgICAgICAgICAgICAgICB0ZXJ0aWFyeSAoMykKICAgICAgICAgICAgICAgIHF1YXJ0ZXJuYXJ5ICg0KQogICAgICAgICAgICAgICAgaWRlbnRpY2FsICg1KSAJCgphbHRlcm5hdGUgCSAgICBub24taWdub3JhYmxlICAgICAgIFthbHRlcm5hdGUgbm9uLWlnbm9yYWJsZV0gCSAgICBhbHRlcm5hdGUgPSAibm9uLWlnbm9yYWJsZSIKICAgICAgICAgICAgICAgIHNoaWZ0ZWQgCiAgICAgICAgICAgIApiYWNrd2FyZHMgCSAgICBvbiAgICAgICAgICAgICAgICAgIFtiYWNrd2FyZHMgb25dICAgCSAgICAgICAgICAgIGJhY2t3YXJkcyA9ICJvbiIgCQogICAgICAgICAgICAgICAgb2ZmIAkKCm5vcm1hbGl6YXRpb24gCW9uCiAgICAgICAgICAgICAgICBvZmYgCSAgICAgICAgICAgIFtub3JtYWxpemF0aW9uIG9uXSAgCSAgICAgICAgbm9ybWFsaXphdGlvbiA9ICJvZmYiIAkKCmNhc2VMZXZlbCAJICAgIG9uICAgICAgICAgICAgICAgICAgW2Nhc2VMZXZlbCBvbl0gCSAgICAgICAgICAgICAgICBjYXNlTGV2ZWwgPSAib2ZmIiAJCiAgICAgICAgICAgICAgICBvZmYgCiAgICAgICAgICAgICAgICAKY2FzZUZpcnN0IAkgICAgdXBwZXIgICAgICAgICAgICAgICBbY2FzZUZpcnN0IG9mZl0gCSAgICAgICAgICAgIGNhc2VGaXJzdCA9ICJvZmYiIAogICAgICAgICAgICAgICAgbG93ZXIKICAgICAgICAgICAgICAgIG9mZiAKICAgICAgICAgICAgICAgIApoaXJhZ2FuYVEgCSAgICBvbiAgICAgICAgICAgICAgICAgIFtoaXJhZ2FuYVEgb25dIAkgICAgICAgICAgICAgICAgaGlyYWdhbmGtUXVhcnRlcm5hcnkgPSAib24iIAogICAgICAgICAgICAgICAgb2ZmIAkgICAgICAgIAkKCm51bWVyaWMgCSAgICBvbiAgICAgICAgICAgICAgICAgIFtudW1lcmljIG9uXSAJICAgICAgICAgICAgICAgIG51bWVyaWMgPSAib24iCiAgICAgICAgICAgICAgICBvZmYgCQoqLwoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVTZXR0aW5ncyhVbmljb2RlU3RyaW5nJiBzcmMgLCBVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoJY29uc3QgVUNoYXIqIHNhdmVTdGFydCA9IHNyYy5nZXRCdWZmZXIoKTsKICAgIGNvbnN0IFVDaGFyKiBzdGFydCA9IHNhdmVTdGFydDsKCWNvbnN0IFVDaGFyKiBsaW1pdCA9IHN0YXJ0ICsgc3JjLmxlbmd0aCgpOyAKCWludDMyX3QgdmFsdWVMZW49MCxzZXR0aW5nTGVuID0wOwoJVUJvb2wgaXNWYWx1ZSA9IEZBTFNFOwoJVW5pY29kZVN0cmluZyB0OwogICAgaW50MzJfdCBpbmRleCA9IDA7CiAgICBVbmljb2RlU3RyaW5nIHNldHRpbmcsIHZhbHVlOwogICAgRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwgIiIsICIiIH07CiAgICB3aGlsZShpbmRleCA8IHNyYy5sZW5ndGgoKSl7CiAgICAgICAgaW5kZXggPSBnZXRTZXR0aW5nQW5kVmFsdWUoc3JjLCBpbmRleCwgc2V0dGluZywgdmFsdWUpOwogICAgICAgIGlmKHNldHRpbmcgPT0gInN1cHByZXNzQ29udHJhY3Rpb25zIil7CgkJICAgIGFyZ3NbMV0gPSB2YWx1ZTsKCQkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInN1cHByZXNzQ29udHJhY3Rpb25zIixtRXJyb3IpLGFyZ3MsMix0KSk7CQkJICAgIAogICAgICAgIH1lbHNlIGlmKHNldHRpbmcgPT0ib3B0aW1pemUiKXsKICAgICAgICAgICAgYXJnc1sxXSA9IHZhbHVlOwogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgib3B0aW1pemUiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgaWYoc2V0dGluZyA9PSAic3RyZW5ndGgiKXsKICAgICAgICAgICAgICAgIFVDaGFyIHZhbCA9IHZhbHVlLmNoYXJBdCgwKTsKICAgICAgICAgICAgICAgIHZhbHVlLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgc3dpdGNoICh2YWwpewogICAgICAgICAgICAgICAgICAgIGNhc2UgJzEnOgogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5hcHBlbmQoInByaW1hcnkiKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnMic6CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLmFwcGVuZCgic2Vjb25kYXJ5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJzMnOgogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5hcHBlbmQoInRlcnRpYXJ5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJzQnOgogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5hcHBlbmQoInF1YXRlcm5hcnkiKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnNSc6CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLmFwcGVuZCgiaWRlbnRpY2FsIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIG1FcnJvciA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKICAgICAgICAgICAgICAgICAgICAgICAgZXhpdCAobUVycm9yKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH1lbHNlIGlmKHNldHRpbmcgPT0gImFsdGVybmF0ZSIpewogICAgICAgICAgICB9ZWxzZSBpZihzZXR0aW5nID09ICJiYWNrd2FyZHMiKXsgCQogICAgICAgICAgICAgICAgaWYodmFsdWUgPT0gIjIiKXsKICAgICAgICAgICAgICAgICAgICB2YWx1ZS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICB2YWx1ZS5hcHBlbmQgKCJvbiIpOwogICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbnJlY29nbml6ZWQgdmFsdWUgZm9yIHNldHRpbmcgYmFja3dhcmRzIS4iKTsKICAgICAgICAgICAgICAgICAgICBleGl0KC0xKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfWVsc2UgaWYoc2V0dGluZyA9PSAibm9ybWFsaXphdGlvbiIpeyAKICAgICAgICAgICAgfWVsc2UgaWYoc2V0dGluZyA9PSAiY2FzZUxldmVsIil7ICAJICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgfWVsc2UgaWYoc2V0dGluZyA9PSAiY2FzZWZpcnN0Iil7IAogICAgICAgICAgICAgICAgc2V0dGluZyA9ICJjYXNlRmlyc3QiOwogICAgICAgICAgICB9ZWxzZSBpZihzZXR0aW5nID09ICJoaXJhZ2FuYVEiKXsKICAgICAgICAgICAgICAgIHNldHRpbmcgPSAiaGlyYWdhbmFRdWFydGVybmFyeSI7CiAgICAgICAgICAgIH1lbHNlIGlmKHNldHRpbmcgPT0gIm51bWVyaWMiKXsgIAkgIAogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCJDb3VsZCBub3QgcmVjb2dpemUgc2V0dGluZyEhIik7CiAgICAgICAgICAgICAgICBleGl0KC0xKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBtU2V0dGluZ3MuYXBwZW5kKHNldHRpbmcpOwogICAgICAgICAgICBtU2V0dGluZ3MuYXBwZW5kKCI9XCIiKTsKICAgICAgICAgICAgbVNldHRpbmdzLmFwcGVuZCh2YWx1ZSk7CiAgICAgICAgICAgIG1TZXR0aW5ncy5hcHBlbmQoIlwiICIpOwogICAgICAgIH0KICAgICAgICBzZXR0aW5nLnJlbW92ZSgpOwogICAgICAgIHZhbHVlLnJlbW92ZSgpOwogICAgfQp9CgppbnQzMl90IEdlbmVyYXRlWE1MOjpnZXRTZXR0aW5nQW5kVmFsdWUoVW5pY29kZVN0cmluZyYgc291cmNlLCBpbnQzMl90IGluZGV4LCBVbmljb2RlU3RyaW5nJiBzZXR0aW5nLCBVbmljb2RlU3RyaW5nJiB2YWx1ZSl7CiAgICBjb25zdCBVQ2hhciogc3JjID0gc291cmNlLmdldEJ1ZmZlcigpOwogICAgaW50MzJfdCBzdGFydCA9IGluZGV4OwogICAgaW50MzJfdCBlbmQgPSBzb3VyY2UubGVuZ3RoKCk7CiAgICBpbnQzMl90IG9wZW49MDsKICAgIFVCb29sIHN0YXJ0VmFsPUZBTFNFLCBpbml0aWFsU3BhY2UgPSBUUlVFOwogICAgLyogWyBzZXR0aW5nIHZhbHVlIF0qLwogICAgd2hpbGUoc3RhcnQgPCBlbmQpewogICAgICAgIFVDaGFyIGNoID0gc3JjW3N0YXJ0KytdOwogICAgICAgIHN3aXRjaChjaCl7CiAgICAgICAgICAgIGNhc2UgJ1snOgogICAgICAgICAgICAgICAgb3BlbisrOwogICAgICAgICAgICAgICAgaWYob3BlbiA+IDEgJiYgc3RhcnRWYWw9PVRSVUUpewogICAgICAgICAgICAgICAgICAgIHZhbHVlLmFwcGVuZChjaCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAnXSc6CiAgICAgICAgICAgICAgICBpZihvcGVuID4gMSAmJiBzdGFydFZhbD09VFJVRSl7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUuYXBwZW5kKGNoKTsKICAgICAgICAgICAgICAgIH1lbHNlIGlmKG9wZW4gPT0gMSl7CiAgICAgICAgICAgICAgICAgICAgZ290byBPVVRFUjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG9wZW4tLTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICBjYXNlICcgJzoKICAgICAgICAgICAgICAgIGlmKGluaXRpYWxTcGFjZSl7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdGFydFZhbCA9IFRSVUU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGluaXRpYWxTcGFjZSA9IEZBTFNFOwogICAgICAgICAgICAgICAgaWYoc3RhcnRWYWwgPT0gVFJVRSl7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUuYXBwZW5kKGNoKTsKICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgIHNldHRpbmcuYXBwZW5kKGNoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Ck9VVEVSOgogICAgc291cmNlLnJlbGVhc2VCdWZmZXIoKTsKICAgIHJldHVybiBzdGFydDsKfQp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZVJlc2V0KFVuaWNvZGVTdHJpbmcmIHNyYywgVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKCWNvbnN0IFVDaGFyKiBzdGFydCA9IHNyYy5nZXRCdWZmZXIoKTsKCWNvbnN0IFVDaGFyKiBsaW1pdCA9IHN0YXJ0ICsgc3JjLmxlbmd0aCgpOyAKCVVDaGFyIHNldHRpbmdbMjU2XTsKCVVDaGFyIHZhbHVlWzIwXTsKCVVDaGFyIGNoYXJzWzIwXTsKCVVuaWNvZGVTdHJpbmcgdDsKCWNoYXIqIHRhcmdldDsKCWludDMyX3QgdmFsdWVMZW49MCxzZXR0aW5nTGVuID0wLCBjaGFyc0xlbj0wOwoJVUJvb2wgaXNWYWx1ZSA9IEZBTFNFLCBpc0NoYXJzPUZBTFNFOwoJaWYoc3JjLmluZGV4T2YoInRvcCIpPj0wIHx8IHNyYy5pbmRleE9mKCJsYXN0IHJlZ3VsYXIiKT49MCl7CgkJRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwgbVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImxhc3ROb25JZ25vcmFibGUiLG1FcnJvcil9OwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJyZXNldCIsbUVycm9yKSxhcmdzLDIsdCkpOwoKICAgIH1lbHNlIGlmKHNyYy5pbmRleE9mKCJmaXJzdCBwcmltYXJ5IGlnbm9yYWJsZSIpPj0wKXsKCQlGb3JtYXR0YWJsZSBhcmdzW10gPSB7aW5kZW50T2Zmc2V0LCBtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZmlyc3RQSWdub3JhYmxlIixtRXJyb3IpfTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicmVzZXQiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAKICAgIH1lbHNlIGlmKHNyYy5pbmRleE9mKCJmaXJzdCBzZWNvbmRhcnkgaWdub3JhYmxlIik+PTApewoJCUZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsIG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJmaXJzdFNJZ25vcmFibGUiLG1FcnJvcil9OwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJyZXNldCIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgCiAgICB9ZWxzZSBpZihzcmMuaW5kZXhPZigiZmlyc3QgdGVydGlhcnkgaWdub3JhYmxlIik+PTApewoJCUZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsIG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJmcmlzdFRJZ25vcmFibGUiLG1FcnJvcil9OwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJyZXNldCIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgIAogICAgfWVsc2UgaWYoc3JjLmluZGV4T2YoImxhc3QgcHJpbWFyeSBpZ25vcmFibGUiKT49MCl7CgkJRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwgbVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImxhc3RQSWdub3JhYmxlIixtRXJyb3IpfTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicmVzZXQiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAKICAgIH1lbHNlIGlmKHNyYy5pbmRleE9mKCJsYXN0IHNlY29uZGFyeSBpZ25vcmFibGUiKT49MCl7CgkJRm9ybWF0dGFibGUgYXJnc1tdID0ge2luZGVudE9mZnNldCwgbVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImxhc3RTSWdub3JhYmxlIixtRXJyb3IpfTsKCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicmVzZXQiLG1FcnJvciksYXJncywyLHQpKTsKICAgIAogICAgfWVsc2UgaWYoc3JjLmluZGV4T2YoImxhc3QgdGVydGlhcnkgaWdub3JhYmxlIik+PTApewoJCUZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsIG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJsYXN0VElnbm9yYWJsZSIsbUVycm9yKX07CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInJlc2V0IixtRXJyb3IpLGFyZ3MsMix0KSk7ICAKICAgIH1lbHNlIGlmKHNyYy5pbmRleE9mKCJbIik+PTAgJiYgc3JjLmxlbmd0aCgpID4gMSl7CgkJd2hpbGUoc3RhcnQgPCBsaW1pdCApewoJCQlVQ2hhciBjaCA9ICpzdGFydCsrOwoJCQlpZih1cHJ2X2lzUnVsZVdoaXRlU3BhY2UoY2gpKXsKCQkJCWlmKHNldHRpbmdMZW4+MCl7CgkJCQkJaXNWYWx1ZSA9IFRSVUU7CgkJCQl9ZWxzZSBpZih2YWx1ZUxlbj4wKXsKCQkJCQlpc0NoYXJzID0gVFJVRTsKCQkJCX0KCQkJCWNvbnRpbnVlOyAvL3NraXAgd2hpdGUgc3BhY2VzCgkJCX1lbHNlIGlmKGNoID09IDB4NWIpeyAvLyBza2lwICdbJyAmJiAnXScKCQkJCWNvbnRpbnVlOwogICAgICAgICAgICB9ZWxzZSBpZiggY2ggPT0gMHg1ZCApewogICAgICAgICAgICAgICAgaXNWYWx1ZSA9IEZBTFNFOwogICAgICAgICAgICAgICAgaXNDaGFycyA9IFRSVUU7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoJCQlpZihpc1ZhbHVlKXsKCQkJCXZhbHVlW3ZhbHVlTGVuKytdID0gY2g7CgkJCX1lbHNlIGlmKGlzQ2hhcnMpewoJCQkJY2hhcnNbY2hhcnNMZW4rK10gPWNoOwoJCQl9ZWxzZXsKCQkJCXNldHRpbmdbc2V0dGluZ0xlbisrXSA9IGNoOwoJCQl9CgkJfQoJCXN3aXRjaCh2YWx1ZVswXSl7CgkJY2FzZSAweDMxOgoJCQl0YXJnZXQgPSAicHJpbWFyeSI7CgkJCWJyZWFrOwoJCWNhc2UgMHgzMjoKCQkJdGFyZ2V0ID0gInNlY29uZGFyeSI7CgkJCWJyZWFrOwoJCWNhc2UgMHgzMzoKCQkJdGFyZ2V0ID0gInRlcnRpYXJ5IjsKCQkJYnJlYWs7CgkJY2FzZSAweDM0OgoJCQl0YXJnZXQgPSAicXVhdGVybmFyeSI7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCXRhcmdldCA9ICJ1bmtub3duIjsKCQkJYnJlYWs7CgkJfQoJCUZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsIFVuaWNvZGVTdHJpbmcoc2V0dGluZyxzZXR0aW5nTGVuKSwgVW5pY29kZVN0cmluZyh0YXJnZXQpLCBVbmljb2RlU3RyaW5nKGNoYXJzLGNoYXJzTGVuKX07CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInJlc2V0V2l0aFZhbHVlIixtRXJyb3IpLGFyZ3MsNCx0KSk7Cgl9ZWxzZXsKCQlGb3JtYXR0YWJsZSBhcmdzW10gPSB7aW5kZW50T2Zmc2V0LCBzcmN9OwoJCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJyZXNldCIsbUVycm9yKSxhcmdzLDIsdCkpOwoJfQp9ClVuaWNvZGVTdHJpbmcgR2VuZXJhdGVYTUw6OnBhcnNlUnVsZXMoVUNoYXIqIHJ1bGVzLCBpbnQzMl90IHJ1bGVMZW4sIFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CglUb2tlbiBzcmM7CglzcmMuc3RhcnQgPSBydWxlczsKCXNyYy5jdXJyZW50ID0gcnVsZXM7CglzcmMucHJldkN1cnJlbnQgPSBydWxlczsKCXNyYy5lbmQgPSBydWxlcytydWxlTGVuOwoJc3JjLmNoYXJzPShVQ2hhciopIG1hbGxvYygocnVsZUxlbiArIDEwKSogVV9TSVpFT0ZfVUNIQVIpOwoJc3JjLmNoYXJzQ2FwYWNpdHkgPSBydWxlTGVuKzEwOwoJVW5pY29kZVN0cmluZyBjb2xsU3RyIDsKCXVpbnQzMl90IHByZXZTdHJlbmd0aD1VQ09MX0RFRkFVTFQ7CglpbnQzMl90IGNvdW50ID0gMDsKCVVCb29sIGFwcGVuZGVkUnVsZXMgPSBGQUxTRTsKICAgIFVuaWNvZGVTdHJpbmcgdDsKCVVCb29sIHN0YXJ0T2ZSdWxlcyA9IFRSVUU7CiAgICBVQm9vbCB3cml0dGVuU2V0dGluZ3MgPSBGQUxTRTsKICAgIFVCb29sIGlzVGVtcFN0ckNvbnRyYWN0aW9uID1GQUxTRSwgaXNDb2xsU3RyQ29udHJhY3Rpb24gPSBGQUxTRTsKCglpZihzcmMuc3RhcnQgIT0gc3JjLmVuZCl7CgkJZm9yKDs7KXsKCQkJICAKCQkJICB1aW50MzJfdCBzdHJlbmd0aCA9IHBhcnNlUnVsZXMoJnNyYyxzdGFydE9mUnVsZXMpOwoJCQkgIFVuaWNvZGVTdHJpbmcgdGVtcFN0cjsKCQkJICBzdGFydE9mUnVsZXMgPSBGQUxTRTsKCQkJICB0ZW1wU3RyLmFwcGVuZChzcmMuY2hhcnMsc3JjLmNoYXJzTGVuKTsKICAgICAgICAgICAgICBpZihVX0ZBSUxVUkUobUVycm9yKSl7CiAgICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCJwYXJzZVJ1bGVzIHJldHVybmVkIE5VTEwgZm9yIHN0cmVuZ3RoIS4gRXJyb3I6ICVzIiwgdV9lcnJvck5hbWUobUVycm9yKSk7CiAgICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAvLyAgaW50MzJfdCBpbmRleE9mUGlwZSA9IHRlbXBTdHIuaW5kZXhPZigoVUNoYXIpMHg3Yyk7CgogICAgICAgICAgICAgIGlmKChwcmV2U3RyZW5ndGggPT0gc3RyZW5ndGgpICYmIChwcmV2U3RyZW5ndGggPT0gVUNPTF9UT0tfRE9ORSkpewogICAgICAgICAgICAgICAgICBpZihtU2V0dGluZ3MubGVuZ3RoKCkhPTAgJiYgd3JpdHRlblNldHRpbmdzID09IEZBTFNFKXsKICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdHRhYmxlIGFyZ3NbXT17IGluZGVudE9mZnNldCwgbVNldHRpbmdzfSA7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJzZXR0aW5ncyIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgICAgICAgICAgICAgICB3cml0dGVuU2V0dGluZ3MgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgICAgICBtU2V0dGluZ3MudHJ1bmNhdGUoMCk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgLyogdmVyaWZ5IHRoYXQgdGVtcFN0ciBpcyBhIGNvbnRyYWN0aW9uICovCiAgICAgICAgICAgICAgaXNUZW1wU3RyQ29udHJhY3Rpb24gPSB0ZW1wU3RyLmNvdW50Q2hhcjMyKCk+MTsKICAgICAgICAgICAgICAKCQkJICBpZigocHJldlN0cmVuZ3RoICE9IHN0cmVuZ3RoKSB8fCAKICAgICAgICAgICAgICAgICAgaXNUZW1wU3RyQ29udHJhY3Rpb249PVRSVUUvKiBjb250cmFjdGlvbiAqLyB8fCAKICAgICAgICAgICAgICAgICAgaXNDb2xsU3RyQ29udHJhY3Rpb249PVRSVUUvKiBjb250cmFjdGlvbiAqLyB8fAogICAgICAgICAgICAgICAgICB0ZW1wU3RyLmluZGV4T2YoKFVDaGFyKVVDT0xfVE9LX0VYUEFOU0lPTl9NQVJLRVIpID49MCB8fCAvKiBleHBhbnNpb24gKi8KICAgICAgICAgICAgICAgICAgY29sbFN0ci5pbmRleE9mKChVQ2hhcilVQ09MX1RPS19FWFBBTlNJT05fTUFSS0VSKSA+PTAgfHwvKiBleHBhbnNpb24gKi8KICAgICAgICAgICAgICAgICAgdGVtcFN0ci5pbmRleE9mKChVQ2hhcikweDdjKSA+PTAgfHwgLypjb250ZXh0ICovCiAgICAgICAgICAgICAgICAgIGNvbGxTdHIuaW5kZXhPZigoVUNoYXIpMHg3YykgPj0wIC8qY29udGV4dCovKXsKCgkJCQkJY2hhciogc2luZ2xlS2V5ID0gTlVMTDsKCQkJCQljaGFyKiBzZXFLZXkgPSBOVUxMOwoJCQkJCS8vIGFzc3VtZSB0aGF0IHNldHRpbmdzIGFsd2F5cyBwcmVjZWVkIHJ1bGUgc3RyaW5ncwoKCQkJCQlGb3JtYXR0YWJsZSBhcmdzW10gPSB7aW5kZW50T2Zmc2V0LGNvbGxTdHIsIiJ9OwoJCQkJCWlmKHByZXZTdHJlbmd0aCAhPSBVQ09MX0RFRkFVTFQpewoJCQkJCQlpZihwcmV2U3RyZW5ndGggPT0gVUNPTF9UT0tfU0VUVElORyl7CgkJCQkJCQl3cml0ZVNldHRpbmdzKGNvbGxTdHIseG1sU3RyaW5nKTsKCQkJCQkJfWVsc2UgaWYocHJldlN0cmVuZ3RoPT1VQ09MX1RPS19SRVNFVCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih3cml0dGVuU2V0dGluZ3MgPT0gRkFMU0UgJiYgbVNldHRpbmdzLmxlbmd0aCgpID4gMCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gbVNldHRpbmdzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJzZXR0aW5ncyIsbUVycm9yKSxhcmdzLDIsdCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXR0ZW5TZXR0aW5ncyA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbVNldHRpbmdzLnRydW5jYXRlKDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoJCQkJCQkJaWYoYXBwZW5kZWRSdWxlcyA9PSBGQUxTRSl7CgkJCQkJCQkJYXJnc1swXSA9IGluZGVudE9mZnNldDsKCQkJCQkJCQlhcmdzWzFdID0gIiI7CgkJCQkJCQkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInJ1bGVzIixtRXJyb3IpLGFyZ3MsMix0KSk7CgkJCQkJCQkJaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCQkJCQkJCQlhcHBlbmRlZFJ1bGVzID0gVFJVRTsKCQkJCQkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVzY2FwZShjb2xsU3RyKTsKCQkJCQkJCXdyaXRlUmVzZXQoY29sbFN0cix4bWxTdHJpbmcpOwoJCQkJCQl9ZWxzZSBpZihwcmV2U3RyZW5ndGg9PVVDT0xfVE9LX09WRVJSSURFKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgdGVtcCgiW2JhY2t3YXJkcyBvbl0iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlU2V0dGluZ3ModGVtcCx4bWxTdHJpbmcpOwoJCQkJCQl9ZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHdyaXR0ZW5TZXR0aW5ncyA9PSBGQUxTRSAmJiBtU2V0dGluZ3MubGVuZ3RoKCkgPiAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBtU2V0dGluZ3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInNldHRpbmdzIixtRXJyb3IpLGFyZ3MsMix0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdHRlblNldHRpbmdzID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtU2V0dGluZ3MudHJ1bmNhdGUoMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgkJCQkJCQlpZihhcHBlbmRlZFJ1bGVzID09IEZBTFNFKXsKCQkJCQkJCQlhcmdzWzBdID0gaW5kZW50T2Zmc2V0OwoJCQkJCQkJCWFyZ3NbMV0gPSAiIjsKCQkJCQkJCQl4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicnVsZXMiLG1FcnJvciksYXJncywyLHQpKTsKCQkJCQkJCQlpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwoJCQkJCQkJCWFwcGVuZGVkUnVsZXMgPSBUUlVFOwoJCQkJCQkJfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IGNvbGxTdHI7CgkJCQkJCQlzd2l0Y2gocHJldlN0cmVuZ3RoKXsKCQkJCQkJCWNhc2UgVUNPTF9JREVOVElDQUw6CgkJCQkJCQkJc2luZ2xlS2V5ID0gImlkZW50aWNhbCI7CgkJCQkJCQkJc2VxS2V5ID0gImlkZW50aWNhbFNlcSI7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlIFVDT0xfUFJJTUFSWToKCQkJCQkJCQlzaW5nbGVLZXkgPSAicHJpbWFyeSI7CgkJCQkJCQkJc2VxS2V5ID0gInByaW1hcnlTZXEiOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJY2FzZSBVQ09MX1NFQ09OREFSWToKCQkJCQkJCQlzaW5nbGVLZXkgPSAic2Vjb25kYXJ5IjsKCQkJCQkJCQlzZXFLZXkgPSAic2Vjb25kYXJ5U2VxIjsKCQkJCQkJCQlicmVhazsKCQkJCQkJCWNhc2UgVUNPTF9URVJUSUFSWToKCQkJCQkJCQlzaW5nbGVLZXkgPSAidGVydGlhcnkiOwoJCQkJCQkJCXNlcUtleSA9ICJ0ZXJ0aWFyeVNlcSI7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQljYXNlIFVDT0xfUVVBVEVSTkFSWToKCQkJCQkJCQlzaW5nbGVLZXkgPSAicXVhdGVybmFyeSI7CgkJCQkJCQkJc2VxS2V5ID0gInF1YXRlcm5hcnlTZXEiOwoJCQkJCQkJCWJyZWFrOwoKCQkJCQkJCX0KCQkJCQkJCWlmKGNvdW50IDw9IDEpewoJCQkJCQkJCS8veG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoc2luZ2xlS2V5LG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZUNvbGxhdGlvbihhcmdzWzFdLmdldFN0cmluZygpLHhtbFN0cmluZywgcHJldlN0cmVuZ3RoLCBzaW5nbGVLZXkpOwoKCQkJCQkJCX1lbHNlewoJCQkJCQkJCS8veG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoc2VxS2V5LG1FcnJvciksYXJncywyLHQpKTsKCQkJCQkJCSAgICB3cml0ZUNvbGxhdGlvbihhcmdzWzFdLmdldFN0cmluZygpLHhtbFN0cmluZywgcHJldlN0cmVuZ3RoLCBzZXFLZXkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZihzcmMuY3VycmVudD09IHNyYy5lbmQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgICAgICAgICAgICAKCQkJCQkJfQogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc2V0CgkJCQkJCQogICAgICAgICAgICAgICAgICAgICAgICBjb3VudCA9IDA7CgkJCQkJCWNvbGxTdHIucmVtb3ZlKCk7CgoJCQkJCX0KCQkJICB9CgogICAgICAgICAgICAgIAogICAgICAgICAgICAgIGlzQ29sbFN0ckNvbnRyYWN0aW9uID0gaXNUZW1wU3RyQ29udHJhY3Rpb247CiAgICAgICAgICAgICAgaXNUZW1wU3RyQ29udHJhY3Rpb24gPSBGQUxTRTsKCQkJICBjb2xsU3RyLmFwcGVuZCh0ZW1wU3RyKTsKCiAgICAgICAgICAgICAKCQkJICBjb3VudCsrOwoJCQkgIHByZXZTdHJlbmd0aCA9IHN0cmVuZ3RoOwkJCgoJCX0KCX0KCWlmKGFwcGVuZGVkUnVsZXM9PVRSVUUpewoJCWNob3BJbmRlbnQoKTsKCQlGb3JtYXR0YWJsZSBhcmdzW109IHtpbmRlbnRPZmZzZXQsVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKX07CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInJ1bGVzIixtRXJyb3IpLGFyZ3MsMix0KSk7Cgl9CgoJZnJlZShzcmMuY2hhcnMpOwoJcmV0dXJuIHhtbFN0cmluZzsKfQoKaW50MzJfdCBmaW5kVUNoYXIoY29uc3QgVUNoYXIqIHNyYywgaW50MzJfdCBsZW4sIFVDaGFyIGMpewogICAgaW50MzJfdCBpPTA7CiAgICB3aGlsZShpPGxlbil7CiAgICAgICAgaWYoc3JjW2ldPT1jKXsKICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgfQogICAgICAgIGkrKzsKICAgIH0KICAgIHJldHVybiAtMTsKfQp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUNvbGxhdGlvbihVbmljb2RlU3RyaW5nJiBzcmMsIFVuaWNvZGVTdHJpbmcgJnhtbFN0cmluZyx1aW50MzJfdCBwcmV2U3RyZW5ndGgsIGNvbnN0IGNoYXIqIGtleU5hbWUpewovLyBzdHJlbmd0aCBjb250ZXh0IHN0cmluZyBleHRlbnNpb24KLy8gPDw8PCAgPGNvbnRleHQ+IHwgPHN0cmluZz4gLyA8ZXh0ZW5zaW9uPgogICAgRm9ybWF0dGFibGUgYXJnc1tdID0geyIiICwgIiJ9OwogICAgVW5pY29kZVN0cmluZyBjb250ZXh0LCBzdHJpbmcsIGV4dGVuc2lvbiwgdGVtcDsKICAgIGludDMyX3QgaW5kZXggPSAgc3JjLmluZGV4T2YoKFVDaGFyKSAweDdDKTsKICAgIGludDMyX3QgY29udGV4dE1hcmtlciA9IChpbmRleD4tMSAmJiBzcmMubGVuZ3RoKCkgPiAxKSA/IGluZGV4IDogLTEgOwogICAgaWYoY29udGV4dE1hcmtlciA+PTAgKXsKICAgICAgICBzcmMuZXh0cmFjdCgwLCBjb250ZXh0TWFya2VyLCBjb250ZXh0KTsKICAgICAgICBlc2NhcGUoY29udGV4dCk7CiAgICAgICAgYXJnc1sxXSA9IGNvbnRleHQ7CiAgICAgICAgY29udGV4dCA9IGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY29udGV4dCIsIG1FcnJvciksIGFyZ3MsIDIsIHRlbXApOwogICAgfQogICAgaW50MzJfdCBleHRlbnNpb25NYXJrZXIgPSBzcmMuaW5kZXhPZigoVUNoYXIpIFVDT0xfVE9LX0VYUEFOU0lPTl9NQVJLRVIpOwogICAgaWYoZXh0ZW5zaW9uTWFya2VyID49IDApewogICAgICAgIHNyYy5leHRyYWN0KGV4dGVuc2lvbk1hcmtlcisxIC8qc2tpcCBwYXN0IHRoZSBleHRlbnNpb24gbWFya2VyKi8sCiAgICAgICAgICAgICAgICAgICAgc3JjLmxlbmd0aCgpLCBleHRlbnNpb24pOwogICAgICAgIGVzY2FwZShleHRlbnNpb24pOwogICAgICAgIGFyZ3NbMV0gPSBleHRlbnNpb247CiAgICAgICAgZXh0ZW5zaW9uID0gZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJleHRlbmQiLG1FcnJvciksYXJncywyLHRlbXApOwogICAgfQogICAgaWYoY29udGV4dE1hcmtlciA+PTAgJiYgZXh0ZW5zaW9uTWFya2VyID49MCl7CiAgICAgICAgc3JjLmV4dHJhY3QoY29udGV4dE1hcmtlcisxLCBleHRlbnNpb25NYXJrZXIgLSAoY29udGV4dE1hcmtlcisxKSwgc3RyaW5nKTsKICAgIH1lbHNlIGlmKGNvbnRleHRNYXJrZXIgPj0wKXsKICAgICAgICBzcmMuZXh0cmFjdChjb250ZXh0TWFya2VyKzEsIHNyYy5sZW5ndGgoKS1jb250ZXh0TWFya2VyLCBzdHJpbmcpOwogICAgfWVsc2UgaWYoZXh0ZW5zaW9uTWFya2VyID49MCl7CiAgICAgICAgc3JjLmV4dHJhY3QoMCxleHRlbnNpb25NYXJrZXIsIHN0cmluZyk7CiAgICB9ZWxzZXsKICAgICAgICBzdHJpbmcgPSBzcmM7CiAgICB9CiAgICBlc2NhcGUoc3RyaW5nKTsKICAgIGFyZ3NbMF0gPSAiIjsKICAgIGFyZ3NbMV0gPSBzdHJpbmc7CiAgICBzdHJpbmcgID0gZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KGtleU5hbWUsbUVycm9yKSxhcmdzLDIsdGVtcCk7CiAgICB0ZW1wLnJlbW92ZSgpOwoKICAgIGlmKGNvbnRleHRNYXJrZXI+LTEpewogICAgICAgIHRlbXAuYXBwZW5kKGNvbnRleHQpOwogICAgfQogICAgdGVtcC5hcHBlbmQoc3RyaW5nKTsKICAgIGlmKGV4dGVuc2lvbk1hcmtlcj4tMSl7CiAgICAgICAgdGVtcC5hcHBlbmQoZXh0ZW5zaW9uKTsKICAgIH0KICAgIGlmKGNvbnRleHRNYXJrZXIgPiAtMSB8fCBleHRlbnNpb25NYXJrZXIgPiAtMSl7CiAgICAgICAgdGVtcC5pbnNlcnQoMCwiPHg+Iik7CiAgICAgICAgdGVtcC5hcHBlbmQoIjwveD4iKTsKICAgIH0KICAgIHRlbXAuaW5zZXJ0KDAsIGluZGVudE9mZnNldCk7CiAgICB0ZW1wLmFwcGVuZCgiXG4iKTsKICAgIHhtbFN0cmluZy5hcHBlbmQodGVtcCk7Cn0Kdm9pZCBHZW5lcmF0ZVhNTDo6ZXNjYXBlKFVuaWNvZGVTdHJpbmcmIHN0cil7CglVbmljb2RlU3RyaW5nIHRlbXA7CiAgICBVQ2hhciB0ZXN0WzEwXSA9IHsnXDAnfTsKCUZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsIiJ9OwoJVW5pY29kZVN0cmluZyB0OwoJZm9yKGludCBpPTA7aTxzdHIubGVuZ3RoKCk7aSsrKXsKICAgICAgICBVQ2hhcjMyIGMgPSBzdHIuY2hhcjMyQXQoaSk7CiAgICAgICAgaWYoYyA+MHhGRkZGKXsKICAgICAgICAgICAgaSsrOwogICAgICAgIH0KICAgICAgICBzd2l0Y2goYyl7CiAgICAgICAgY2FzZSAnPCc6CgkJCXRlbXAuYXBwZW5kKCImbHQ7Iik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJz4nOgoJCQl0ZW1wLmFwcGVuZCgiJmd0OyIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICcmJzoKCQkJdGVtcC5hcHBlbmQoIiZhbXA7Iik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJyInOgogICAgICAgICAgICB0ZW1wLmFwcGVuZCgiJnF1b3Q7Iik7CgkJICAgIGJyZWFrOwoJCWNhc2UgMHgwMDoKICAgICAgICBjYXNlIDB4MDE6CiAgICAgICAgY2FzZSAweDAyOgogICAgICAgIGNhc2UgMHgwMzoKICAgICAgICBjYXNlIDB4MDQ6CiAgICAgICAgY2FzZSAweDA1OgogICAgICAgIGNhc2UgMHgwNjoKICAgICAgICBjYXNlIDB4MDc6CiAgICAgICAgY2FzZSAweDA4OgogICAgICAgIGNhc2UgMHgwOToKICAgICAgIC8qIGNhc2UgMHgwQTogKi8KICAgICAgICBjYXNlIDB4MGI6CiAgICAgICAgY2FzZSAweDBjOgogICAgICAgLyogY2FzZSAweDBEOiAqLwogICAgICAgIGNhc2UgMHgwZToKICAgICAgICBjYXNlIDB4MGY6CiAgICAgICAgY2FzZSAweDEwOgogICAgICAgIGNhc2UgMHgxMToKICAgICAgICBjYXNlIDB4MTI6CiAgICAgICAgY2FzZSAweDEzOgogICAgICAgIGNhc2UgMHgxNDoKICAgICAgICBjYXNlIDB4MTU6CiAgICAgICAgY2FzZSAweDE2OgogICAgICAgIGNhc2UgMHgxNzoKICAgICAgICBjYXNlIDB4MTg6CiAgICAgICAgY2FzZSAweDE5OgogICAgICAgIGNhc2UgMHgxQToKICAgICAgICBjYXNlIDB4MWI6CiAgICAgICAgY2FzZSAweDFjOgogICAgICAgIGNhc2UgMHgxZDoKICAgICAgICBjYXNlIDB4MWU6CiAgICAgICAgY2FzZSAweDFmOgogICAgICAgICAgICBpdG91KHRlc3QsYywxNiw0KTsgIAoJCQlhcmdzWzFdID0gVW5pY29kZVN0cmluZyh0ZXN0KTsgCiAgICAgICAgICAgIHRlbXAuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiY3AiLG1FcnJvciksYXJncywyLHQpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKCQkJdGVtcC5hcHBlbmQoYyk7CiAgICAgICAgfQogICAgICAgIAoJfQoJc3RyPXRlbXA7Cn0KCgpzdGF0aWMKaW50MzJfdCB1X3N0cm5jbXBOb0Nhc2UoY29uc3QgVUNoYXIgICAgICpzMSwgCiAgICAgY29uc3QgVUNoYXIgICAgICpzMiwgCiAgICAgaW50MzJfdCAgICAgbikgCnsKICAgIGlmKG4gPiAwKSB7CiAgICAgICAgaW50MzJfdCByYzsKICAgICAgICBmb3IoOzspIHsKICAgICAgICAgICAgcmMgPSAoaW50MzJfdCl1X3RvbG93ZXIoKnMxKSAtIChpbnQzMl90KXVfdG9sb3dlcigqczIpOwogICAgICAgICAgICBpZihyYyAhPSAwIHx8ICpzMSA9PSAwIHx8IC0tbiA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKytzMTsKICAgICAgICAgICAgKytzMjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSAKdm9pZCBzeW50YXhFcnJvcihjb25zdCBVQ2hhciogcnVsZXMsIAogICAgICAgICAgICAgICAgIGludDMyX3QgcG9zLAogICAgICAgICAgICAgICAgIGludDMyX3QgcnVsZXNMZW4sCiAgICAgICAgICAgICAgICAgVVBhcnNlRXJyb3IqIHBhcnNlRXJyb3IpIHsKICAgIHBhcnNlRXJyb3ItPm9mZnNldCA9IHBvczsKICAgIHBhcnNlRXJyb3ItPmxpbmUgPSAwIDsgLyogd2UgYXJlIG5vdCB1c2luZyBsaW5lIG51bWJlcnMgKi8KICAgIAogICAgLy8gZm9yIHByZS1jb250ZXh0CiAgICBpbnQzMl90IHN0YXJ0ID0gKHBvcyA8PVVfUEFSU0VfQ09OVEVYVF9MRU4pPyAwIDogKHBvcyAtIChVX1BBUlNFX0NPTlRFWFRfTEVOLTEpKTsKICAgIGludDMyX3Qgc3RvcCAgPSBwb3M7CiAgICAKICAgIHVfbWVtY3B5KHBhcnNlRXJyb3ItPnByZUNvbnRleHQscnVsZXMrc3RhcnQsc3RvcC1zdGFydCk7CiAgICAvL251bGwgdGVybWluYXRlIHRoZSBidWZmZXIKICAgIHBhcnNlRXJyb3ItPnByZUNvbnRleHRbc3RvcC1zdGFydF0gPSAwOwogICAgCiAgICAvL2ZvciBwb3N0LWNvbnRleHQKICAgIHN0YXJ0ID0gcG9zKzE7CiAgICBzdG9wICA9ICgocG9zK1VfUEFSU0VfQ09OVEVYVF9MRU4pPD0gcnVsZXNMZW4gKT8gKHBvcysoVV9QQVJTRV9DT05URVhUX0xFTi0xKSkgOiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9zdHJsZW4ocnVsZXMpOwoKICAgIHVfbWVtY3B5KHBhcnNlRXJyb3ItPnBvc3RDb250ZXh0LHJ1bGVzK3N0YXJ0LHN0b3Atc3RhcnQpOwogICAgLy9udWxsIHRlcm1pbmF0ZSB0aGUgYnVmZmVyCiAgICBwYXJzZUVycm9yLT5wb3N0Q29udGV4dFtzdG9wLXN0YXJ0XT0gMDsKCiAgICBVbmljb2RlU3RyaW5nIHByZUNvbixwb3N0Q29uOwoJcHJldHRpZnkoVW5pY29kZVN0cmluZyhwYXJzZUVycm9yLT5wcmVDb250ZXh0KSxwcmVDb24pOwoJcHJldHRpZnkocGFyc2VFcnJvci0+cG9zdENvbnRleHQscG9zdENvbik7CgljaGFyIHByZUNoYXJbMjU2XSwgcG9zdENoYXJbMjU2XTsKCXByZUNvbi5leHRyYWN0KDAscHJlQ29uLmxlbmd0aCgpLHByZUNoYXIsc2l6ZW9mKHByZUNoYXIpKTsKCXBvc3RDb24uZXh0cmFjdCgwLHBvc3RDb24ubGVuZ3RoKCkscG9zdENoYXIsc2l6ZW9mKHBvc3RDaGFyKSk7CglwcmludGYoInBhcnNlUnVsZXMoKSBmYWlsZWQuIFByZS1jb250ZXh0OiAlcyBcdCBwb3N0LWNvbnRleHQ6ICVzIFxuIixwcmVDaGFyLCBwb3N0Q2hhcik7CglleGl0KC0xKTsKfQoKI2RlZmluZSB1Y29sX3Rva19pc1NwZWNpYWxDaGFyKGNoKSAgICAgICAgICAgICAgXAogICAgKCgoKChjaCkgPD0gMHgwMDJGKSAmJiAoKGNoKSA+IDB4MDAyMCkpIHx8IFwKICAgICAgKCgoY2gpIDw9IDB4MDAzRikgJiYgKChjaCkgPj0gMHgwMDNBKSkgfHwgXAogICAgICAvKiAoKChjaCkgPD0gMHgwMDYwKSAmJiAoKGNoKSA+PSAweDAwNUIpKSB8fCBcICovIFwKCSAgKCgoY2gpID09IDB4MDA2MCkgfHwgICAgKChjaCkgPT0gMHgwMDVjKSB8fCAoKGNoKSA9PSAweDAwNWUpIHx8ICgoY2gpID09IDB4MDA1ZikgKSB8fCBcCiAgICAgICgoKGNoKSA8PSAweDAwN0UpICYmICgoY2gpID49IDB4MDA3RCkpIHx8IFwKICAgICAgKGNoKSA9PSAweDAwN0IpKQoKCgp2b2lkIEdlbmVyYXRlWE1MOjpncm93QnVmZmVyKFVDaGFyKiBzcmMsIGludDMyX3QgbGVuLCBpbnQzMl90IHNpemUsIGludDMyX3QgcmVxdWlyZWRDYXBhY2l0eSwgVUVycm9yQ29kZSogc3RhdHVzKXsKCVVDaGFyKiB0ZW1wID1OVUxMOwoJCglpZihzdGF0dXMgPT1OVUxMIHx8IFVfRkFJTFVSRSgqc3RhdHVzKSl7CgkJcmV0dXJuOwoJfQoJaWYocmVxdWlyZWRDYXBhY2l0eSA8IGxlbiApewoJCSpzdGF0dXMgPSBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1I7CgkJcmV0dXJuOwoJfQoJdGVtcCA9IChVQ2hhciopIG1hbGxvYyAoIHNpemUgKiByZXF1aXJlZENhcGFjaXR5KTsKCWlmKHRlbXAgPT1OVUxMKXsKCQkqc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKCQlyZXR1cm47Cgl9CgltZW1tb3ZlKHRlbXAsc3JjLGxlbipzaXplKTsKCWZyZWUoc3JjKTsKCXNyYyA9IHRlbXA7Cn0KCi8qCiAqCiAqICAiJgkJYQk8PAkJYmVmZwk8PAkJYwkJPDwJCWQJCTw8CQlkIgogKiAgIF4JCQleCQkJCV4JCQkJCQkJCQkJXgogKiAgIHN0YXJ0CQlwcmV2Q3VycmVudAkJY3VycmVudCAJCQkJCQkJCWVuZAogKi8KCnVpbnQzMl90IEdlbmVyYXRlWE1MOjpwYXJzZVJ1bGVzKFRva2VuKiBzcmMsVUJvb2wgc3RhcnRPZlJ1bGVzKXsKICAvKiBwYXJzaW5nIHBhcnQgKi8KICBVQm9vbCB2YXJpYWJsZVRvcCA9IEZBTFNFOwogIC8vVUJvb2wgdG9wID0gRkFMU0U7CiAgVUJvb2wgaW5DaGFycyA9IFRSVUU7CiAgVUJvb2wgaW5RdW90ZSA9IEZBTFNFOwogIFVCb29sIHdhc0luUXVvdGUgPSBGQUxTRTsKICBVQ2hhciAqb3B0aW9uRW5kID0gTlVMTDsKICB1aW50OF90IGJlZm9yZSA9IDA7CiAgVUJvb2wgaXNFc2NhcGVkID0gRkFMU0U7CiAgVVBhcnNlRXJyb3IgcGFyc2VFcnJvcjsKICB1aW50MzJfdCBuZXdFeHRlbnNpb25MZW4gPSAwOwogIHVpbnQzMl90IGV4dGVuc2lvbk9mZnNldCA9IDA7CiAgdWludDMyX3QgbmV3U3RyZW5ndGggPSBVQ09MX1RPS19VTlNFVDsgCiAgVUJvb2wgaXNTZXR0aW5nID0gRkFMU0U7CiAgY29uc3QgVUNoYXIgdG9wW10gPSB7MHgwMDViLDB4MDA3NCwweDAwNmYsMHgwMDcwLDB4MDA1ZH07CgogIHNyYy0+cHJldkN1cnJlbnQgPSBzcmMtPmN1cnJlbnQ7CiAgc3JjLT5jaGFyc0xlbiA9IDA7CgogIHdoaWxlIChzcmMtPmN1cnJlbnQgPCBzcmMtPmVuZCkgewogICAgVUNoYXIgY2ggPSAqKHNyYy0+Y3VycmVudCk7CgoKICAgIGlmIChpblF1b3RlKSB7CiAgICAgIGlmIChjaCA9PSAweDAwMjcvKidcJycqLykgewogICAgICAgICAgaW5RdW90ZSA9IEZBTFNFOwogICAgICB9ZWxzZXsKCQkgIGlmKHNyYy0+Y2hhcnNMZW4gPj0gKHNyYy0+Y2hhcnNDYXBhY2l0eS0xKSl7CgkJCSAgc3JjLT5jaGFyc0NhcGFjaXR5Kj0yOwoJCQkgZ3Jvd0J1ZmZlcihzcmMtPmNoYXJzLHNyYy0+Y2hhcnNMZW4sVV9TSVpFT0ZfVUNIQVIsIHNyYy0+Y2hhcnNDYXBhY2l0eSwmbUVycm9yKTsKCQkgIH0KCQkgIHNyYy0+Y2hhcnNbc3JjLT5jaGFyc0xlbisrXSA9Y2g7CgkgIH0KICAgIH1lbHNlIGlmKGlzRXNjYXBlZCl7CiAgICAgIGlzRXNjYXBlZCA9RkFMU0U7CiAgICAgIGlmIChuZXdTdHJlbmd0aCA9PSBVQ09MX1RPS19VTlNFVCkgewoJCW1FcnJvciA9IFVfSU5WQUxJRF9GT1JNQVRfRVJST1I7CiAgICAgICAgc3ludGF4RXJyb3Ioc3JjLT5zdGFydCwoaW50MzJfdCkoc3JjLT5jdXJyZW50LXNyYy0+c3RhcnQpLChpbnQzMl90KShzcmMtPmVuZC1zcmMtPnN0YXJ0KSwmcGFyc2VFcnJvcik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgLy8gZW5hYmxpbmcgcnVsZXMgdG8gc3RhcnQgd2l0aCBub24tdG9rZW5zIGEgPCBiCgkJLy8gbmV3U3RyZW5ndGggPSBVQ09MX1RPS19SRVNFVDsKICAgICAgfQoKICAgIH1lbHNlIGlmKGlzU2V0dGluZz09VFJVRSB8fCF1cHJ2X2lzUnVsZVdoaXRlU3BhY2UoY2gpKSB7CiAgICAgICAgLyogU2V0cyB0aGUgc3RyZW5ndGggZm9yIHRoaXMgZW50cnkgKi8KICAgICAgICBzd2l0Y2ggKGNoKSB7CiAgICAgICAgICBjYXNlIDB4MDAzRC8qJz0nKi8gOiAKICAgICAgICAgICAgaWYgKG5ld1N0cmVuZ3RoICE9IFVDT0xfVE9LX1VOU0VUKSB7CiAgICAgICAgICAgICAgZ290byBFbmRPZkxvb3A7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGlmIHdlIHN0YXJ0IHdpdGggc3RyZW5ndGgsIHdlJ2xsIHJlc2V0IHRvIHRvcCAqLwogICAgICAgICAgICBpZihzdGFydE9mUnVsZXMgPT0gVFJVRSkgewogICAgICAgICAgICAgIG5ld1N0cmVuZ3RoID0gVUNPTF9UT0tfUkVTRVQ7CgkJCSAgdV9zdHJjcHkoc3JjLT5jaGFycytzcmMtPmNoYXJzTGVuLHRvcCk7CgkJCSAgc3JjLT5jaGFyc0xlbis9dV9zdHJsZW4odG9wKTsKICAgICAgICAgICAgICBnb3RvIEVuZE9mTG9vcDsKICAgICAgICAgICAgfQogICAgICAgICAgICBuZXdTdHJlbmd0aCA9IFVDT0xfSURFTlRJQ0FMOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBjYXNlIDB4MDAyQy8qJywnKi86ICAKICAgICAgICAgICAgaWYgKG5ld1N0cmVuZ3RoICE9IFVDT0xfVE9LX1VOU0VUKSB7CiAgICAgICAgICAgICAgZ290byBFbmRPZkxvb3A7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGlmIHdlIHN0YXJ0IHdpdGggc3RyZW5ndGgsIHdlJ2xsIHJlc2V0IHRvIHRvcCAqLwogICAgICAgICAgICBpZihzdGFydE9mUnVsZXMgPT0gVFJVRSkgewogICAgICAgICAgICAgIG5ld1N0cmVuZ3RoID0gVUNPTF9UT0tfUkVTRVQ7CgkJCSAgdV9zdHJjcHkoc3JjLT5jaGFycytzcmMtPmNoYXJzTGVuLHRvcCk7CgkJCSAgc3JjLT5jaGFyc0xlbis9dV9zdHJsZW4odG9wKTsKICAgICAgICAgICAgICBnb3RvIEVuZE9mTG9vcDsKICAgICAgICAgICAgfQogICAgICAgICAgICBuZXdTdHJlbmd0aCA9IFVDT0xfVEVSVElBUlk7CiAgICAgICAgICAgIGJyZWFrOwoJCSAgCgkJICBjYXNlIDB4MDAyRDogLyogLSBhZGQgdG8gc3JjLT5jaGFycyBhbmQgY29udGludWUgKi8KCQkJICBpZihzcmMtPmNoYXJzTGVuID49IChzcmMtPmNoYXJzQ2FwYWNpdHktMSkpewoJCQkJc3JjLT5jaGFyc0NhcGFjaXR5Kj0yOwoJCQkJZ3Jvd0J1ZmZlcihzcmMtPmNoYXJzLHNyYy0+Y2hhcnNMZW4sVV9TSVpFT0ZfVUNIQVIsIHNyYy0+Y2hhcnNDYXBhY2l0eSwmbUVycm9yKTsKCQkJICB9CgkJCSAgc3JjLT5jaGFyc1tzcmMtPmNoYXJzTGVuKytdID0gY2g7CgkJCSAgYnJlYWs7CiAgICAgICAgICBjYXNlICAweDAwM0IvKic7JyovOgogICAgICAgICAgICBpZiAobmV3U3RyZW5ndGggIT0gVUNPTF9UT0tfVU5TRVQpIHsKICAgICAgICAgICAgICBnb3RvIEVuZE9mTG9vcDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogaWYgd2Ugc3RhcnQgd2l0aCBzdHJlbmd0aCwgd2UnbGwgcmVzZXQgdG8gdG9wICovCiAgICAgICAgICAgIGlmKHN0YXJ0T2ZSdWxlcyA9PSBUUlVFKSB7CgkJCSAgdV9zdHJjcHkoc3JjLT5jaGFycytzcmMtPmNoYXJzTGVuLHRvcCk7CgkJCSAgc3JjLT5jaGFyc0xlbis9dV9zdHJsZW4odG9wKTsKICAgICAgICAgICAgICBuZXdTdHJlbmd0aCA9IFVDT0xfVE9LX1JFU0VUOwogICAgICAgICAgICAgIGdvdG8gRW5kT2ZMb29wOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG5ld1N0cmVuZ3RoID0gVUNPTF9TRUNPTkRBUlk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgMHgwMDNDLyonPCcqLzogIAogICAgICAgICAgICBpZiAobmV3U3RyZW5ndGggIT0gVUNPTF9UT0tfVU5TRVQpIHsKICAgICAgICAgICAgICBnb3RvIEVuZE9mTG9vcDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogaWYgd2Ugc3RhcnQgd2l0aCBzdHJlbmd0aCwgd2UnbGwgcmVzZXQgdG8gdG9wICovCiAgICAgICAgICAgIGlmKHN0YXJ0T2ZSdWxlcyA9PSBUUlVFKSB7CgkJCSAgdV9zdHJjcHkoc3JjLT5jaGFycytzcmMtPmNoYXJzTGVuLHRvcCk7CgkJCSAgc3JjLT5jaGFyc0xlbis9dV9zdHJsZW4odG9wKTsKICAgICAgICAgICAgICBuZXdTdHJlbmd0aCA9IFVDT0xfVE9LX1JFU0VUOwogICAgICAgICAgICAgIGdvdG8gRW5kT2ZMb29wOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGJlZm9yZSB0aGlzLCBkbyBhIHNjYW4gdG8gdmVyaWZ5IHdoZXRoZXIgdGhpcyBpcyAqLwogICAgICAgICAgICAvKiBhbm90aGVyIHN0cmVuZ3RoICovCiAgICAgICAgICAgIGlmKCooc3JjLT5jdXJyZW50KzEpID09IDB4MDAzQykgewogICAgICAgICAgICAgIHNyYy0+Y3VycmVudCsrOwogICAgICAgICAgICAgIGlmKCooc3JjLT5jdXJyZW50KzEpID09IDB4MDAzQykgewogICAgICAgICAgICAgICAgc3JjLT5jdXJyZW50Kys7IC8qIHRocmVlIGluIGEgcm93ISAqLwogICAgICAgICAgICAgICAgbmV3U3RyZW5ndGggPSBVQ09MX1RFUlRJQVJZOwogICAgICAgICAgICAgIH0gZWxzZSB7IC8qIHR3byBpbiBhIHJvdyAqLwogICAgICAgICAgICAgICAgbmV3U3RyZW5ndGggPSBVQ09MX1NFQ09OREFSWTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7IC8qIGp1c3Qgb25lICovCiAgICAgICAgICAgICAgbmV3U3RyZW5ndGggPSBVQ09MX1BSSU1BUlk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSAweDAwMjYvKicmJyovOiAgCiAgICAgICAgICAgIGlmIChuZXdTdHJlbmd0aCAhPSBVQ09MX1RPS19VTlNFVCkgewogICAgICAgICAgICAgIC8qKi8KICAgICAgICAgICAgICBnb3RvIEVuZE9mTG9vcDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbmV3U3RyZW5ndGggPSBVQ09MX1RPS19SRVNFVDsgLyogUGF0dGVybkVudHJ5OjpSRVNFVCA9IDAgKi8KICAgICAgICAgICAgYnJlYWs7CgoJCSAgY2FzZSAweDAwNUI6CgkJCSAgaWYgKG5ld1N0cmVuZ3RoID09IFVDT0xfVE9LX1VOU0VUKXsKCQkJCSAgbmV3U3RyZW5ndGggPSBVQ09MX1RPS19TRVRUSU5HOwoJCQkgIH0KCQkJICBpZighaW5RdW90ZSl7CgkJCQkgIGlzU2V0dGluZz1UUlVFOwoJCQkgIH0KCQkJICBpZihzcmMtPmNoYXJzTGVuID49IChzcmMtPmNoYXJzQ2FwYWNpdHktMSkpewoJCQkJc3JjLT5jaGFyc0NhcGFjaXR5Kj0yOwoJCQkJZ3Jvd0J1ZmZlcihzcmMtPmNoYXJzLHNyYy0+Y2hhcnNMZW4sVV9TSVpFT0ZfVUNIQVIsIHNyYy0+Y2hhcnNDYXBhY2l0eSwmbUVycm9yKTsKCQkJICB9CgkJCSAgc3JjLT5jaGFyc1tzcmMtPmNoYXJzTGVuKytdID1jaDsKCQkJICBicmVhazsKCQkgIGNhc2UgMHgwMDVEOgoJCQkgIGlmKGlzU2V0dGluZz09VFJVRSl7CgkJCQkgIGlzU2V0dGluZyA9IEZBTFNFOwoJCQkgIH0KCQkJICBpZihzcmMtPmNoYXJzTGVuID49IChzcmMtPmNoYXJzQ2FwYWNpdHktMSkpewoJCQkJc3JjLT5jaGFyc0NhcGFjaXR5Kj0yOwoJCQkJZ3Jvd0J1ZmZlcihzcmMtPmNoYXJzLHNyYy0+Y2hhcnNMZW4sVV9TSVpFT0ZfVUNIQVIsIHNyYy0+Y2hhcnNDYXBhY2l0eSwmbUVycm9yKTsKCQkJICB9CgkJCSAgc3JjLT5jaGFyc1tzcmMtPmNoYXJzTGVuKytdID0gY2g7CgkJCSAgYnJlYWs7CgkJICBjYXNlIDB4MDAyMS8qISBza2lwIGphdmEgdGhhaSBtb2RpZmllciByZW9yZGVyaW5nKi86CgkJCSAgYnJlYWs7IAogICAgICAgICAgY2FzZSAweDAwMkYvKicvJyovOgogICAgICAgICAgICB3YXNJblF1b3RlID0gRkFMU0U7IC8qIGlmIHdlIHdlcmUgY29weWluZyBzb3VyY2UgY2hhcmFjdGVycywgd2Ugd2FudCB0byBzdG9wIG5vdyAqLwogICAgICAgICAgICAvKiBSQU06IGV4cGFuc2lvbiBqdXN0IGFkZCB0aGUgY2hhcmFjdGVyIGJhY2sgKi8KICAgICAgICAgICAgc3JjLT5jaGFyc1tzcmMtPmNoYXJzTGVuKytdID0gVUNPTF9UT0tfRVhQQU5TSU9OX01BUktFUjsKICAgICAgICAgICAgaW5DaGFycyA9IEZBTFNFOyAvKiB3ZSdyZSBub3cgcHJvY2Vzc2luZyBleHBhbnNpb24gKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIDB4MDA1QyAvKiBiYWNrIHNsYXNoIGZvciBlc2NhcGVkIGNoYXJzICovOgogICAgICAgICAgICAgIGlzRXNjYXBlZCA9IFRSVUU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAvKiBmb3VuZCBhIHF1b3RlLCB3ZSdyZSBnb25uYSBzdGFydCBjb3B5aW5nICovCiAgICAgICAgICBjYXNlIDB4MDAyNy8qJ1wnJyovOgogICAgICAgICAgICBpZiAobmV3U3RyZW5ndGggPT0gVUNPTF9UT0tfVU5TRVQpIHsgLyogcXVvdGUgaXMgaWxsZWdhbCB1bnRpbCB3ZSBoYXZlIGEgc3RyZW5ndGggKi8KCQkJICBtRXJyb3IgPSBVX0lOVkFMSURfRk9STUFUX0VSUk9SOwogICAgICAgICAgICAgIHN5bnRheEVycm9yKHNyYy0+c3RhcnQsKGludDMyX3QpKHNyYy0+Y3VycmVudC1zcmMtPnN0YXJ0KSwoaW50MzJfdCkoc3JjLT5lbmQtc3JjLT5zdGFydCksJnBhcnNlRXJyb3IpOwogICAgICAgICAgICAgIHJldHVybiBOVUxMOwoJCQkgIC8vIGVuYWJsaW5nIHJ1bGVzIHRvIHN0YXJ0IHdpdGggYSBub24tdG9rZW4gY2hhcmFjdGVyIGEgPCBiCiAgICAgICAgICAgICAgLy8gbmV3U3RyZW5ndGggPSBVQ09MX1RPS19SRVNFVDsKICAgICAgICAgICAgfQoJCQlpZihpblF1b3RlPT1GQUxTRSl7CgkJCQlpblF1b3RlID0gVFJVRTsKCQkJCXdhc0luUXVvdGUgPSBUUlVFOwoJCQl9ZWxzZXsKCQkJCWluUXVvdGUgPUZBTFNFOwoJCQkJd2FzSW5RdW90ZSA9IEZBTFNFOwoJCQl9CgkJCS8vIHJlbW92ZWQgaW5DaGFycwoKICAgICAgICAgICAgCgogICAgICAgICAgICBjaCA9ICooKysoc3JjLT5jdXJyZW50KSk7IAogICAgICAgICAgICBpZihjaCA9PSAweDAwMjcpIHsgLyogY29weSB0aGUgZG91YmxlIHF1b3RlICovCiAgICAgICAgICAgICAgLy8qc3JjLT5leHRyYUN1cnJlbnQrKyA9IGNoOwoJCQkgIGlmKHNyYy0+Y2hhcnNMZW4gPj0gKHNyYy0+Y2hhcnNDYXBhY2l0eS0xKSl7CgkJCQkgc3JjLT5jaGFyc0NhcGFjaXR5Kj0yOwoJCQkgICAgIGdyb3dCdWZmZXIoc3JjLT5jaGFycyxzcmMtPmNoYXJzTGVuLFVfU0laRU9GX1VDSEFSLCBzcmMtPmNoYXJzQ2FwYWNpdHksJm1FcnJvcik7CgkJCSAgfQoJCQkgIHNyYy0+Y2hhcnNbc3JjLT5jaGFyc0xlbisrXSA9IGNoOwoJCQkgIGlmKCooc3JjLT5jdXJyZW50KzEpIT0weDAwMjcpewoJCQkJaW5RdW90ZSA9IEZBTFNFOwoJCQkgIH0KICAgICAgICAgICAgfWVsc2V7CgkJCQktLXNyYy0+Y3VycmVudDsKCQkJfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAvKiAnQCcgaXMgZnJlbmNoIG9ubHkgaWYgdGhlIHN0cmVuZ3RoIGlzIG5vdCBjdXJyZW50bHkgc2V0ICovCiAgICAgICAgICAvKiBpZiBpdCBpcywgaXQncyBqdXN0IGEgcmVndWxhciBjaGFyYWN0ZXIgaW4gY29sbGF0aW9uIHJ1bGVzICovCiAgICAgICAgICBjYXNlIDB4MDA0MC8qJ0AnKi86CiAgICAgICAgICAgIGlmIChuZXdTdHJlbmd0aCA9PSBVQ09MX1RPS19VTlNFVCkgewogICAgICAgICAgICAgIC8vc3JjLT5vcHRzLT5mcmVuY2hDb2xsYXRpb24gPSBVQ09MX09OOwoJCQkgIC8vZnJlbmNoIHNlY29uZGFyeQoJCQkgIG5ld1N0cmVuZ3RoID0gVUNPTF9UT0tfT1ZFUlJJREU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICBjYXNlIDB4MDA3QyAvKnwqLzogLyogdGhpcyBtZWFucyB3ZSBoYXZlIGFjdHVhbGx5IGJlZW4gcmVhZGluZyBwcmVmaXggcGFydCAqLwogICAgICAgICAgICAvLyB3ZSB3YW50IHRvIHN0b3JlIHJlYWQgY2hhcmFjdGVycyB0byB0aGUgcHJlZml4IHBhcnQgYW5kIGNvbnRpbnVlIHJlYWRpbmcKICAgICAgICAgICAgLy8gdGhlIGNoYXJhY3RlcnMgKHByb3BlciB3YXkgd291bGQgYmUgdG8gcmVzdGFydCByZWFkaW5nIHRoZSBjaGFycywgYnV0IGluCiAgICAgICAgICAgIC8vIHRoYXQgY2FzZSB3ZSB3b3VsZCBoYXZlIHRvIGNvbXBsaWNhdGUgdGhlIHRva2VuIGhhc2hlciwgd2hpY2ggSSBkbyBub3QgCiAgICAgICAgICAgIC8vIGludGVuZCB0byBwbGF5IHdpdGguIEluc3RlYWQsIHdlIHdpbGwgZG8gcHJlZml4ZXMgd2hlbiBwcmVmaXhlcyBhcmUgZHVlCiAgICAgICAgICAgIC8vIChiZWZvcmUgYWRkaW5nIHRoZSBlbGVtZW50cykuCgoJCQkvL3dhc0luUXVvdGUgPSBUUlVFOwoJCQlpZihzcmMtPmNoYXJzTGVuID49IChzcmMtPmNoYXJzQ2FwYWNpdHktMSkpewoJCQkgIHNyYy0+Y2hhcnNDYXBhY2l0eSo9MjsKCQkJICBncm93QnVmZmVyKHNyYy0+Y2hhcnMsc3JjLT5jaGFyc0xlbixVX1NJWkVPRl9VQ0hBUiwgc3JjLT5jaGFyc0NhcGFjaXR5LCZtRXJyb3IpOwoJCQl9CgkJCXNyYy0+Y2hhcnNbc3JjLT5jaGFyc0xlbisrXT1jaDsKICAgICAgICAgICAgLy9jaCA9ICooKysoc3JjLT5jdXJyZW50KSk7IAogICAgICAgICAgICBicmVhazsKICAgICAgICAgIAogICAgICAgICAgICAvL2NoYXJzT2Zmc2V0ID0gMDsKICAgICAgICAgICAgLy9uZXdDaGFyc0xlbiA9IDA7CiAgICAgICAgICAgIC8vYnJlYWs7IC8vIFdlIHdhbnQgdG8gc3RvcmUgdGhlIHdob2xlIHByZWZpeC9jaGFyYWN0ZXIgc2VxdWVuY2UuIElmIHdlIGJyZWFrCiAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSAnfCcgaXMgZ29pbmcgdG8gZ2V0IGxvc3QuCiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBpZiAobmV3U3RyZW5ndGggPT0gVUNPTF9UT0tfVU5TRVQpIHsKCQkJICBtRXJyb3IgPSBVX0lOVkFMSURfRk9STUFUX0VSUk9SOwogICAgICAgICAgICAgIHN5bnRheEVycm9yKHNyYy0+c3RhcnQsKGludDMyX3QpKHNyYy0+Y3VycmVudC1zcmMtPnN0YXJ0KSwoaW50MzJfdCkoc3JjLT5lbmQtc3JjLT5zdGFydCksJnBhcnNlRXJyb3IpOwogICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodWNvbF90b2tfaXNTcGVjaWFsQ2hhcihjaCkgJiYgKGluUXVvdGUgPT0gRkFMU0UpKSB7CiAgICAgICAgICAgICAgbUVycm9yID0gVV9JTlZBTElEX0ZPUk1BVF9FUlJPUjsKICAgICAgICAgICAgICBzeW50YXhFcnJvcihzcmMtPnN0YXJ0LChpbnQzMl90KShzcmMtPmN1cnJlbnQtc3JjLT5zdGFydCksKGludDMyX3QpKHNyYy0+ZW5kLXNyYy0+c3RhcnQpLCZwYXJzZUVycm9yKTsKICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgfQoJCQlpZihzcmMtPmNoYXJzTGVuID49IChzcmMtPmNoYXJzQ2FwYWNpdHktMSkpewoJCQkgc3JjLT5jaGFyc0NhcGFjaXR5Kj0yOwoJCQkgZ3Jvd0J1ZmZlcihzcmMtPmNoYXJzLHNyYy0+Y2hhcnNMZW4sVV9TSVpFT0ZfVUNIQVIsIHNyYy0+Y2hhcnNDYXBhY2l0eSwmbUVycm9yKTsKCgkJCX0KCQkJc3JjLT5jaGFyc1tzcmMtPmNoYXJzTGVuKytdID1jaDsKICAgICAgICAgICAgaWYoY2ggPT0gMHgwMDAwICYmIHNyYy0+Y3VycmVudCsxID09IHNyYy0+ZW5kKSB7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfSAgICAgICAgIAogICAgICAgfQoJICAgc3JjLT5jdXJyZW50Kys7CiAgICB9CgoKCiBFbmRPZkxvb3A6CiAgICBpZihuZXdTdHJlbmd0aCA9PSBVQ09MX1RPS19VTlNFVCAmJiBzcmMtPmN1cnJlbnQgPT0gc3JjLT5lbmQpewogICAgICAgIHJldHVybiBVQ09MX1RPS19ET05FOwogICAgfQogIHdhc0luUXVvdGUgPSBGQUxTRTsKICByZXR1cm4gbmV3U3RyZW5ndGg7Cn0KCnN0YXRpYyBVbmljb2RlU3RyaW5nIHN1cHBJbmRlbnQ7CnZvaWQgR2VuZXJhdGVYTUw6OmFkZEluZGVudChVbmljb2RlU3RyaW5nJiBpbmRlbnQpewogICAgaW5kZW50LmFwcGVuZCgiICAgICIpOwp9CnZvaWQgR2VuZXJhdGVYTUw6OmNob3BJbmRlbnQoVW5pY29kZVN0cmluZyYgaW5kZW50KXsKICAgIGluZGVudC5yZW1vdmUoaW5kZW50Lmxlbmd0aCgpLTQpOwp9Cgp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZVN1cHBsZW1lbnRhbERhdGEoKXsKCUZJTEUqIHNGaWxlPWdldEZpbGVIYW5kbGUoZGVzdERpciwic3VwcGxlbWVudGFsRGF0YSIpOwogICAgVUVycm9yQ29kZSBlcnJvciA9IFVfWkVST19FUlJPUjsKICAgIAogICAgLy8gd3JpdGUgdGhlIHhtbCB2ZXJzaW9uCiAgCVVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nOwoKCVVuaWNvZGVTdHJpbmcgdGVtcCA9IG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJzdXBwbGVtZW50YWxEZWNsYXJhdGlvbiIsZXJyb3IpOwogICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wKTsKCUZvcm1hdHRhYmxlIGFyZ3VtZW50c1tdID0geyIiLCIifTsKCVVuaWNvZGVTdHJpbmcgdGVtcFN0cjsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJzdXBwbGVtZW50YWxEYXRhIixlcnJvciksYXJndW1lbnRzLDEsdGVtcFN0cikpOwoKICAgIC8vIFRPRE86IGNoYW5nZSBsYXRlcgogICAgVVJlc291cmNlQnVuZGxlKiByb290ID0gdXJlc19vcGVuRGlyZWN0KHBhdGgsICJDdXJyZW5jeURhdGEiLCAmZXJyb3IpOwoKICAgIGFkZEluZGVudChzdXBwSW5kZW50KTsKICAgIGFyZ3VtZW50c1swXSA9IHN1cHBJbmRlbnQ7CiAgICBhcmd1bWVudHNbMV0gPSAiIjsKCXhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJjdXJyZW5jeURhdGEiLGVycm9yKSxhcmd1bWVudHMsMix0ZW1wU3RyKSk7CgogICAgdGVtcFN0ci5yZW1vdmUoKTsKICAgIHdyaXRlQ3VycmVuY3lNZXRhKHRlbXBTdHIsIHJvb3QsZXJyb3IpOwogICAgaWYodGVtcFN0ci5sZW5ndGgoKSE9MCl7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wU3RyKTsKICAgIH0KICAgIHRlbXBTdHIucmVtb3ZlKCk7CiAgICB3cml0ZUN1cnJlbmN5TWFwKHRlbXBTdHIsIHJvb3QsIGVycm9yKTsKICAgIGlmKHRlbXBTdHIubGVuZ3RoKCkhPTApewogICAgICAgIHhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CiAgICB9CiAgICBhcmd1bWVudHNbMF0gPSBzdXBwSW5kZW50OwogICAgYXJndW1lbnRzWzFdID0gVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJjdXJyZW5jeURhdGEiLGVycm9yKSxhcmd1bWVudHMsMix0ZW1wU3RyKSk7CiAgICBjaG9wSW5kZW50KHN1cHBJbmRlbnQpOwoJCiAgICBhcmd1bWVudHNbMF0gPSBVbmljb2RlU3RyaW5nKFhNTF9FTkRfU0xBU0gpOwoJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInN1cHBsZW1lbnRhbERhdGEiLGVycm9yKSxhcmd1bWVudHMsMSx0ZW1wU3RyKSk7CglwcmludFN0cmluZygmeG1sU3RyaW5nLCBzRmlsZSk7CgogICAgdXJlc19jbG9zZShyb290KTsKCn0Kdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVDdXJyZW5jeU1hcChVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcsIFVSZXNvdXJjZUJ1bmRsZSogcm9vdCwgVUVycm9yQ29kZSYgZXJyb3IpewogICAgaWYoVV9GQUlMVVJFKGVycm9yKSl7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgVVJlc291cmNlQnVuZGxlKiBjdXJyID0gdXJlc19nZXRCeUtleShyb290LCAiQ3VycmVuY3lNYXAiLCBOVUxMLCAmZXJyb3IpOwogICAgY2hhciBhbHRLZXlbMTAwXSA9IHswfTsKICAgIGNvbnN0IGNoYXIqIHByZUV1cm8gPSAiX1BSRUVVUk8iOwogICAgY29uc3QgY2hhciogZXVybyAgICA9ICJfRVVSTyI7CiAgICBpZihVX1NVQ0NFU1MoZXJyb3IpKXsKICAgICAgICBhZGRJbmRlbnQoc3VwcEluZGVudCk7CiAgICAgICAgd2hpbGUodXJlc19oYXNOZXh0KGN1cnIpKXsKICAgICAgICAgICAgVVJlc291cmNlQnVuZGxlKiBlbGVtZW50ID0gdXJlc19nZXROZXh0UmVzb3VyY2UoY3VycixOVUxMLCAmZXJyb3IpOwogICAgICAgICAgICBjb25zdCBjaGFyKiAgIGNvdW50cnkgID0gIHVyZXNfZ2V0S2V5KGVsZW1lbnQpOwogICAgICAgICAgICBpZihzdHJzdHIoY291bnRyeSwgcHJlRXVybykgIT0gTlVMTCB8fCBzdHJzdHIoY291bnRyeSwgZXVybykhPU5VTEwpewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50MzJfdCBsZW4gPTA7CiAgICAgICAgICAgIGNvbnN0IFVDaGFyKiB0ZW1wID0gdXJlc19nZXRTdHJpbmcoZWxlbWVudCwmbGVuLCAmZXJyb3IpOwogICAgICAgICAgICBVbmljb2RlU3RyaW5nIGN1cnJlbmN5ICh0ZW1wLCBsZW4pOwogICAgICAgICAgICBGb3JtYXR0YWJsZSBhcmdzW10gPSB7c3VwcEluZGVudCwgY291bnRyeSwgIiIgfTsKICAgICAgICAgICAgVW5pY29kZVN0cmluZyB0ZW1wU3RyOwogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicmVnaW9uU3RhcnQiLGVycm9yKSxhcmdzLDIsdGVtcFN0cikpOwogICAgICAgICAgICBhZGRJbmRlbnQoc3VwcEluZGVudCk7CiAgICAgICAgICAgIGFyZ3NbMF0gPSBzdXBwSW5kZW50OwogICAgICAgICAgICBhcmdzWzFdID0gY3VycmVuY3k7CiAgICAgICAgICAgIAogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgic3VwcEN1cnJlbmN5U3RhcnQiLG1FcnJvciksYXJncywzLHRlbXBTdHIpKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGFkZEluZGVudChzdXBwSW5kZW50KTsKICAgICAgICAgICAgc3RyY3B5KGFsdEtleSwgY291bnRyeSk7CiAgICAgICAgICAgIHN0cmNhdChhbHRLZXksIHByZUV1cm8pOwogICAgICAgICAgICBsZW49MDsKICAgICAgICAgICAgdGVtcCA9IHVyZXNfZ2V0U3RyaW5nQnlLZXkoY3VyciwgYWx0S2V5LCAmbGVuLCAmZXJyb3IpOwogICAgICAgICAgICBVbmljb2RlU3RyaW5nIGFsdEN1cnJlbmN5ICh0ZW1wLCBsZW4pOwogICAgICAgICAgICBpZihVX1NVQ0NFU1MoZXJyb3IpKXsKICAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBzdXBwSW5kZW50OwogICAgICAgICAgICAgICAgYXJnc1sxXSA9IGFsdEN1cnJlbmN5OwogICAgICAgICAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImFsdGVybmF0ZSIsZXJyb3IpLGFyZ3MsMix0ZW1wU3RyKSk7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgZXJyb3IgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hvcEluZGVudChzdXBwSW5kZW50KTsKICAgICAgICAgICAKICAgICAgICAgICAgYXJnc1swXSA9IHN1cHBJbmRlbnQ7CiAgICAgICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJzdXBwQ3VycmVuY3lFbmQiLGVycm9yKSxhcmdzLDEsdGVtcFN0cikpOwoKICAgICAgICAgICAgY2hvcEluZGVudChzdXBwSW5kZW50KTsKCiAgICAgICAgICAgIGFyZ3NbMF0gPSBzdXBwSW5kZW50OwogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgicmVnaW9uRW5kIixlcnJvciksYXJncywxLHRlbXBTdHIpKTsKCiAgICAgICAgfQogICAgICAgIGNob3BJbmRlbnQoc3VwcEluZGVudCk7CiAgICB9Cgp9CnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlQ3VycmVuY3lNZXRhKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZywgVVJlc291cmNlQnVuZGxlKiByb290LCBVRXJyb3JDb2RlJiBlcnJvcil7CiAgICBpZihVX0ZBSUxVUkUoZXJyb3IpKXsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBVUmVzb3VyY2VCdW5kbGUqIGN1cnIgPSB1cmVzX2dldEJ5S2V5KHJvb3QsICJDdXJyZW5jeU1ldGEiLCBOVUxMLCAmZXJyb3IpOwogICAgaWYoVV9TVUNDRVNTKGVycm9yKSl7CiAgICAgICAgYWRkSW5kZW50KHN1cHBJbmRlbnQpOwogICAgICAgIEZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtzdXBwSW5kZW50LCAiIiwgIiIsICIifTsKICAgICAgICBGb3JtYXR0YWJsZSBhcmdzMVtdID0geyIifTsKICAgICAgICBVbmljb2RlU3RyaW5nIHRlbXBTdHI7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImZyYWN0aW9ucyIsZXJyb3IpLGFyZ3MsMix0ZW1wU3RyKSk7CiAgICAgICAgCiAgICAgICAgYWRkSW5kZW50KHN1cHBJbmRlbnQpOwogICAgICAgIHdoaWxlKHVyZXNfaGFzTmV4dChjdXJyKSl7CiAgICAgICAgICAgIFVSZXNvdXJjZUJ1bmRsZSogZWxlbWVudCA9IHVyZXNfZ2V0TmV4dFJlc291cmNlKGN1cnIsIE5VTEwsICZlcnJvcik7CiAgICAgICAgICAgIGNvbnN0IGNoYXIqIGtleSA9IHVyZXNfZ2V0S2V5KGVsZW1lbnQpOwogICAgICAgICAgICBpbnQzMl90IGxlbiA9MDsKICAgICAgICAgICAgY29uc3QgaW50MzJfdCogaW50VmVjdG9yID0gdXJlc19nZXRJbnRWZWN0b3IoZWxlbWVudCwmbGVuLCAmZXJyb3IpOwogICAgICAgICAgICB1cmVzX2Nsb3NlKGVsZW1lbnQpOwogICAgICAgICAgICBpZihsZW4gPCAyKXsKICAgICAgICAgICAgICAgIGVycm9yID0gVV9JTlRFUk5BTF9QUk9HUkFNX0VSUk9SOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFVDaGFyIGJ1ZmZlclsxMDBdID0gezB9OwogICAgICAgICAgICBsZW4gPSBpdG91KGJ1ZmZlciwgaW50VmVjdG9yWzBdLCAxMCwgMCk7CiAgICAgICAgICAgICAKICAgICAgICAgICAgYXJnc1swXSA9IHN1cHBJbmRlbnQ7CiAgICAgICAgICAgIGFyZ3NbMV0gPSBrZXk7CiAgICAgICAgICAgIGFyZ3NbMl0gPSBmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoImRpZ2l0cyIsIGVycm9yKSwgVW5pY29kZVN0cmluZyhidWZmZXIsIGxlbiksIHRlbXBTdHIpOwoKICAgICAgICAgICAgaWYoaW50VmVjdG9yIT0wKXsKICAgICAgICAgICAgICAgIGxlbiA9IGl0b3UoYnVmZmVyLCBpbnRWZWN0b3JbMV0sIDEwLCAwKTsKICAgICAgICAgICAgICAgIGFyZ3NbM10gPSBmb3JtYXRTdHJpbmcobVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoInJvdW5kaW5nIiwgZXJyb3IpLCBVbmljb2RlU3RyaW5nKGJ1ZmZlciwgbGVuKSwgdGVtcFN0cik7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgYXJnc1szXSA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiaW5mbyIsbUVycm9yKSxhcmdzLDQsdGVtcFN0cikpOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgY2hvcEluZGVudChzdXBwSW5kZW50KTsKICAgICAgICAKICAgICAgICBhcmdzWzBdID0gc3VwcEluZGVudDsKICAgICAgICBhcmdzWzFdID0gVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiZnJhY3Rpb25zIixtRXJyb3IpLGFyZ3MsMix0ZW1wU3RyKSk7CiAgICAgICAgCiAgICAgICAgY2hvcEluZGVudChzdXBwSW5kZW50KTsKICAgIH0KfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVQYXBlclNpemUoVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKICAgIFJlc291cmNlQnVuZGxlIHBhcGVyU2l6ZSA9IG1Tb3VyY2VCdW5kbGUuZ2V0KCJQYXBlclNpemUiLCBtRXJyb3IpOwogICAgaW50MzJfdCBsZW49MDsKICAgIGNvbnN0IGludDMyX3QqIHNpemVzID0gcGFwZXJTaXplLmdldEludFZlY3RvcihsZW4sbUVycm9yKTsKICAgIFVuaWNvZGVTdHJpbmcgdGVtcFN0cjsKCiAgICBpZiggbUVycm9yIT1VX1VTSU5HX0RFRkFVTFRfV0FSTklORyAmJiAKCQltRXJyb3IhPVVfVVNJTkdfRkFMTEJBQ0tfV0FSTklORyAmJiAKICAgICAgICAgICAgVV9TVUNDRVNTKG1FcnJvcikpewogICAgICAgIEZvcm1hdHRhYmxlIGFyZ3NbXSA9IHtpbmRlbnRPZmZzZXQsICIiLCAiIn07CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcoIG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJwYXBlclNpemUiLCBtRXJyb3IpLCBhcmdzLCAyLCB0ZW1wU3RyKSk7CiAgICAgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCiAgICAgICAgY2hhciBjWzEwXSA9IHswfTsKICAgICAgICBpdG9hKHNpemVzWzBdLCBjLCAxMCk7CiAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICBhcmdzWzFdID0gVW5pY29kZVN0cmluZyhjKTsKICAgICAgICB0ZW1wU3RyLnJlbW92ZSgpOwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKCBtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgiaGVpZ2h0IiwgbUVycm9yKSwgYXJncywgMiwgdGVtcFN0cikpOwogICAgICAgIAogICAgICAgIGNbMF0gPSAwOwogICAgICAgIGl0b2Eoc2l6ZXNbMV0sIGMsIDEwKTsKICAgICAgICBhcmdzWzFdID0gVW5pY29kZVN0cmluZyhjKTsKICAgICAgICB0ZW1wU3RyLnJlbW92ZSgpOwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKCBtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgid2lkdGgiLCBtRXJyb3IpLCBhcmdzLCAyLCB0ZW1wU3RyKSk7CgogICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICB0ZW1wU3RyLnJlbW92ZSgpOwogICAgICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CiAgICAgICAgYXJnc1sxXSA9IFVuaWNvZGVTdHJpbmcoWE1MX0VORF9TTEFTSCk7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcoIG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJwYXBlclNpemUiLCBtRXJyb3IpLCBhcmdzLCAyLCB0ZW1wU3RyKSk7CiAgICAgICAgbUVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIG1FcnJvciA9IFVfWkVST19FUlJPUjsKICAgIHhtbFN0cmluZy5yZW1vdmUoKTsKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVNZWFzdXJlbWVudChVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewogICAgVW5pY29kZVN0cmluZyB0ZW1wU3RyOwogICAgRm9ybWF0dGFibGUgYXJnc1tdID0geyBpbmRlbnRPZmZzZXQsICIiLCAiIiB9OwogICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcoIG1TdHJpbmdzQnVuZGxlLmdldFN0cmluZ0V4KCJtZWFzdXJlbWVudCIsIG1FcnJvciksIGFyZ3MsIDIsIHRlbXBTdHIpKTsKICAgIFVCb29sIHByaW50ID0gRkFMU0U7CgogICAgUmVzb3VyY2VCdW5kbGUgbWVhc3VyZW1lbnRTeXN0ZW0gPSBtU291cmNlQnVuZGxlLmdldCgiTWVhc3VyZW1lbnRTeXN0ZW0iLCBtRXJyb3IpOwogICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKICAgIAogICAgaWYoIG1FcnJvciE9VV9VU0lOR19ERUZBVUxUX1dBUk5JTkcgJiYgCgkJbUVycm9yIT1VX1VTSU5HX0ZBTExCQUNLX1dBUk5JTkcgJiYgCiAgICAgICAgICAgIFVfU1VDQ0VTUyhtRXJyb3IpKXsKCiAgICAgICAgYXJnc1swXSA9IGluZGVudE9mZnNldDsKICAgICAgICBhcmdzWzFdID0gKG1lYXN1cmVtZW50U3lzdGVtLmdldEludChtRXJyb3IpPT0gMCkgPyAibWV0cmljIiA6ICJVUyI7CiAgICAgICAgaWYoVV9TVUNDRVNTKG1FcnJvcikpewogICAgICAgICAgICB0ZW1wU3RyLnJlbW92ZSgpOwogICAgICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyggbVN0cmluZ3NCdW5kbGUuZ2V0U3RyaW5nRXgoIm1lYXN1cmVtZW50U3lzdGVtIiwgbUVycm9yKSwgYXJncywgMiwgdGVtcFN0cikpOwogICAgICAgICAgICBwcmludCA9IFRSVUU7CiAgICAgICAgfQogICAgfQogICAgCiAgICB0ZW1wU3RyLnJlbW92ZSgpOwogICAgd3JpdGVQYXBlclNpemUodGVtcFN0cik7CiAgICBpZih0ZW1wU3RyLmxlbmd0aCgpPjApewogICAgICAgIHhtbFN0cmluZy5hcHBlbmQodGVtcFN0cik7CiAgICAgICAgcHJpbnQgPSBUUlVFOwogICAgfQogICAgdGVtcFN0ci5yZW1vdmUoKTsKICAgIGNob3BJbmRlbnQoKTsKICAgIGFyZ3NbMF0gPSBpbmRlbnRPZmZzZXQ7CiAgICBhcmdzWzFdID0gVW5pY29kZVN0cmluZyhYTUxfRU5EX1NMQVNIKTsKICAgIHhtbFN0cmluZy5hcHBlbmQoZm9ybWF0U3RyaW5nKCBtU3RyaW5nc0J1bmRsZS5nZXRTdHJpbmdFeCgibWVhc3VyZW1lbnQiLCBtRXJyb3IpLCBhcmdzLCAyLCB0ZW1wU3RyKSk7CiAgICBpZihwcmludD09RkFMU0UpewogICAgICAgIHhtbFN0cmluZy5yZW1vdmUoKTsKICAgIH0KICAgIG1FcnJvciA9IFVfWkVST19FUlJPUjsKfQoKLyoKdm9pZCBHZW5lcmF0ZVhNTDo6d3JpdGVQb3NpeENvbXBEYXRhKCl7CiAgICBjaGFyIHRlbXBbNTBdPXsnXDAnfTsKICAgIHN0cmNweSh0ZW1wLGxvY05hbWUpOwogICAgc3RyY2F0KHRlbXAsIl9QQ0QiKTsKICAgIExvY2FsZSBsb2ModGVtcCk7CiAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGUocGF0aCwgbG9jLG1FcnJvcik7CiAgICBpZihtRXJyb3I9PVVfWkVST19FUlJPUil7CiAgICAgICAgVW5pY29kZVN0cmluZyB4bWxTdHJpbmc7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyhQT1NJWF9TVEFSVCksaW5kZW50T2Zmc2V0KSk7CiAgICAgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKICAgICAgICAKICAgICAgICB3cml0ZU1lc3NhZ2VzKGJ1bmRsZSx4bWxTdHJpbmcpOwogICAgICAgIGFkZHJlc3NGb3JtYXQoYnVuZGxlLHhtbFN0cmluZyk7CiAgICAgICAgbmFtZUZvcm1hdChidW5kbGUsIHhtbFN0cmluZyk7CiAgICAgICAgaWRlbnRpdHkoYnVuZGxlLCB4bWxTdHJpbmcpOwogICAgICAgIHRlbGVwaG9uZUZvcm1hdCggYnVuZGxlLCB4bWxTdHJpbmcpOwogICAgICAgIAogICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKGZvcm1hdFN0cmluZyhVbmljb2RlU3RyaW5nKFBPU0lYX0VORCksIGluZGVudE9mZnNldCkpOwogICAgICAgIHByaW50U3RyaW5nKCZ4bWxTdHJpbmcpOwoKICAgIH0KICAgIAogICAgCn0KCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlTWVzc2FnZXMoUmVzb3VyY2VCdW5kbGUmIGJ1bmRsZSwgVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKICAgIFVuaWNvZGVTdHJpbmcgdGVtcCx0ZW1wMTsKICAgIFJlc291cmNlQnVuZGxlIGRCdW5kbGUgPSBidW5kbGUuZ2V0KCJNZXNzYWdlcyIsbUVycm9yKTsKICAgIGlmKFVfU1VDQ0VTUyhtRXJyb3IpKXsKICAgICAgICB0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyhNU0dfU1RBUlQpLGluZGVudE9mZnNldCkpOwogICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJ5ZXNFeHByZXNzaW9uIixkQnVuZGxlLHRlbXAxLFVuaWNvZGVTdHJpbmcoWUVTKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJub0V4cHJlc3Npb24iLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoTk8pKTsKICAgICAgICBpZih0ZW1wMS5sZW5ndGgoKSE9MCl7CiAgICAgICAgICAgIHRlbXAuYXBwZW5kKHRlbXAxKTsKICAgICAgICAgICAgdGVtcC5hcHBlbmQoZm9ybWF0U3RyaW5nKFVuaWNvZGVTdHJpbmcoTVNHX0VORCksaW5kZW50T2Zmc2V0KSk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHRlbXAucmVtb3ZlKCk7CiAgICAgICAgfQogICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXApOwogICAgfQoKfQoKdm9pZCBHZW5lcmF0ZVhNTDo6YWRkcmVzc0Zvcm1hdChSZXNvdXJjZUJ1bmRsZSYgYnVuZGxlLFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CiAgICBVbmljb2RlU3RyaW5nIHRlbXAsdGVtcDE7CiAgICBSZXNvdXJjZUJ1bmRsZSBkQnVuZGxlID0gYnVuZGxlLmdldCgiQWRkcmVzc0Zvcm1hdCIsbUVycm9yKTsKICAgIGlmKFVfU1VDQ0VTUyhtRXJyb3IpKXsKICAgICAgICB0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyhBRERSX1NUQVJUKSxpbmRlbnRPZmZzZXQpKTsKICAgICAgICBpbmRlbnRPZmZzZXQuYXBwZW5kKCJcdCIpOwogICAgICAgIGdldFN0cmluZ1JlcygiUG9zdGFsRm9ybWF0IixkQnVuZGxlLHRlbXAxLFVuaWNvZGVTdHJpbmcoUE9TVEFMKSk7CiAgICAgICAgaWYodGVtcDEubGVuZ3RoKCkhPTApewogICAgICAgICAgICB0ZW1wLmFwcGVuZCh0ZW1wMSk7CiAgICAgICAgICAgIHRlbXAuYXBwZW5kKGZvcm1hdFN0cmluZyhVbmljb2RlU3RyaW5nKEFERFJfRU5EKSxpbmRlbnRPZmZzZXQpKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgdGVtcC5yZW1vdmUoKTsKICAgICAgICB9CiAgICAgICAgY2hvcEluZGVudCgpOwogICAgICAgIHhtbFN0cmluZy5hcHBlbmQodGVtcCk7CiAgICB9Cn0KCnZvaWQgR2VuZXJhdGVYTUw6Om5hbWVGb3JtYXQoUmVzb3VyY2VCdW5kbGUmIGJ1bmRsZSxVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewogICAgVW5pY29kZVN0cmluZyB0ZW1wLHRlbXAxOwogICAgUmVzb3VyY2VCdW5kbGUgZEJ1bmRsZSA9IGJ1bmRsZS5nZXQoIk5hbWVGb3JtYXQiLG1FcnJvcik7CiAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CiAgICAgICAgdGVtcC5hcHBlbmQoZm9ybWF0U3RyaW5nKFVuaWNvZGVTdHJpbmcoTkZfU1RBUlQpLGluZGVudE9mZnNldCkpOwogICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgogICAgICAgIGdldFN0cmluZ1JlcygiTmFtZVBhdHRlcm4iLGRCdW5kbGUsdGVtcDEsVW5pY29kZVN0cmluZyhOQU1FX1BBVCkpOwogICAgICAgIGdldFN0cmluZ1JlcygiR2VuZXJhbFNhbHV0YWlvbiIsZEJ1bmRsZSx0ZW1wMSwgVW5pY29kZVN0cmluZyhHRU5fU0FMVVQpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIlNob3J0U2FsdXRhdGlvbk1yIixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKFNIX1NBTFVUX01SKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJTaG9ydFNhbHV0YXRpb25NaXNzIixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKFNIX1NBTFVUX01TKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJTaG9ydFNhbHV0YXRpb25NcnMiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoU0hfU0FMVVRfTUkpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIkxvbmdTYWx1dGF0aW9uTXIiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoTEdfU0FMVVRfTVIpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIkxvbmdTYWx1dGF0aW9uTWlzcyIsZEJ1bmRsZSx0ZW1wMSwgVW5pY29kZVN0cmluZyhMR19TQUxVVF9NUykpOwogICAgICAgIGdldFN0cmluZ1JlcygiTG9uZ1NhbHV0YXRpb25NcnMiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoTEdfU0FMVVRfTUkpKTsKCiAgICAgICAgaWYodGVtcDEubGVuZ3RoKCkhPTApewogICAgICAgICAgICB0ZW1wLmFwcGVuZCh0ZW1wMSk7CiAgICAgICAgICAgIHRlbXAuYXBwZW5kKGZvcm1hdFN0cmluZyhVbmljb2RlU3RyaW5nKE5GX0VORCksaW5kZW50T2Zmc2V0KSk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHRlbXAucmVtb3ZlKCk7CiAgICAgICAgfQogICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXApOwogICAgfQp9CgkKdm9pZCBHZW5lcmF0ZVhNTDo6aWRlbnRpdHkoUmVzb3VyY2VCdW5kbGUmIGJ1bmRsZSxVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewoJICAgIFVuaWNvZGVTdHJpbmcgdGVtcCx0ZW1wMTsKCSAgICBSZXNvdXJjZUJ1bmRsZSBkQnVuZGxlID0gYnVuZGxlLmdldCgiSWRlbnRpZmljYXRpb24iLG1FcnJvcik7CgkJaWYoVV9TVUNDRVNTKG1FcnJvcikpewoJICAgICAgICB0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyhJRF9TVEFSVCksaW5kZW50T2Zmc2V0KSk7CiAgICAgICAgaW5kZW50T2Zmc2V0LmFwcGVuZCgiXHQiKTsKCiAgICAgICAgZ2V0U3RyaW5nUmVzKCJUaXRsZSIsZEJ1bmRsZSx0ZW1wMSxVbmljb2RlU3RyaW5nKFRJVExFKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJTb3VyY2UiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoU09VUkNFKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJBZGRyZXNzIixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKEFERFJfMSkpOwogICAgICAgLy8gZ2V0U3RyaW5nUmVzKCJDb250YWN0IixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKENPTlRBQ1QpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIkVtYWlsIixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKEVNQUlMKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJUZWxlcGhvbmUiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoVEVMRVBIKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJGYXgiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoRkFYKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJ1IixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKExBTkdfMSkpOwogICAgICAgIGdldFN0cmluZ1JlcygiVGVycml0b3J5IixkQnVuZGxlLHRlbXAxLFVuaWNvZGVTdHJpbmcoVFJUUlkpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIkF1ZGllbmNlIixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKEFVRElFTkNFKSk7CiAgICAgICAgZ2V0U3RyaW5nUmVzKCJBcHBsaWNhdGlvbiIsZEJ1bmRsZSx0ZW1wMSwgVW5pY29kZVN0cmluZyhBUFBMSUMpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIkFiYnJldmlhdGlvbiIsZEJ1bmRsZSx0ZW1wMSwgVW5pY29kZVN0cmluZyhBQkJSXzEpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIlJldmlzaW9uIixkQnVuZGxlLHRlbXAxLCBVbmljb2RlU3RyaW5nKFJFVikpOwogICAgICAgIGdldFN0cmluZ1JlcygiRGF0ZSIsZEJ1bmRsZSx0ZW1wMSwgVW5pY29kZVN0cmluZyhEQVRFXzEpKTsKCiAgICAgICAgaWYodGVtcDEubGVuZ3RoKCkhPTApewogICAgICAgICAgICB0ZW1wLmFwcGVuZCh0ZW1wMSk7CiAgICAgICAgICAgIHRlbXAuYXBwZW5kKGZvcm1hdFN0cmluZyhVbmljb2RlU3RyaW5nKElEX0VORCksaW5kZW50T2Zmc2V0KSk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHRlbXAucmVtb3ZlKCk7CiAgICAgICAgfQogICAgICAgIGNob3BJbmRlbnQoKTsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXApOwogICAgfQp9CgoKdm9pZCBHZW5lcmF0ZVhNTDo6dGVsZXBob25lRm9ybWF0KFJlc291cmNlQnVuZGxlJiBidW5kbGUsVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nKXsKICAgIFVuaWNvZGVTdHJpbmcgdGVtcCx0ZW1wMTsKICAgIFJlc291cmNlQnVuZGxlIGRCdW5kbGUgPSBidW5kbGUuZ2V0KCJUZWxlcGhvbmVGb3JtYXQiLG1FcnJvcik7CiAgICBpZihVX1NVQ0NFU1MobUVycm9yKSl7CiAgICAgICAgdGVtcC5hcHBlbmQoZm9ybWF0U3RyaW5nKFVuaWNvZGVTdHJpbmcoVEZfU1RBUlQpLGluZGVudE9mZnNldCkpOwogICAgICAgIGluZGVudE9mZnNldC5hcHBlbmQoIlx0Iik7CgogICAgICAgIGdldFN0cmluZ1JlcygiSW50ZXJuYXRpb25hbEZvcm1hdCIsZEJ1bmRsZSx0ZW1wMSwgVW5pY29kZVN0cmluZyhJUF9URikpOwogICAgICAgIGdldFN0cmluZ1JlcygiRG9tZXN0aWNGb3JtYXQiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoRFBfVEYpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIkludGVybmF0aW9uYWxEaWFsQ29kZSIsZEJ1bmRsZSx0ZW1wMSwgVW5pY29kZVN0cmluZyhJRENfVEYpKTsKICAgICAgICBnZXRTdHJpbmdSZXMoIkludGVybmF0aW9uYWxQcmVmaXgiLGRCdW5kbGUsdGVtcDEsIFVuaWNvZGVTdHJpbmcoSVBGX1RGKSk7CgogICAgICAgIGlmKHRlbXAxLmxlbmd0aCgpIT0wKXsKICAgICAgICAgICAgdGVtcC5hcHBlbmQodGVtcDEpOwogICAgICAgICAgICB0ZW1wLmFwcGVuZChmb3JtYXRTdHJpbmcoVW5pY29kZVN0cmluZyhURl9FTkQpLGluZGVudE9mZnNldCkpOwogICAgICAgIH1lbHNlewogICAgICAgICAgICB0ZW1wLnJlbW92ZSgpOwogICAgICAgIH0KICAgICAgICBjaG9wSW5kZW50KCk7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wKTsKICAgIH0KfQoKCnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlUG9zaXhBZGRpdGlvbnMoKXsKICAgIFVuaWNvZGVTdHJpbmcgeG1sU3RyaW5nOwogICAgd3JpdGVNZWFzdXJlbWVudCh4bWxTdHJpbmcpOwogICAgd3JpdGVDb3VudHJ5UG9zdCh4bWxTdHJpbmcpOwogICAgd3JpdGVDb3VudHJ5Q2FyKHhtbFN0cmluZyk7CiAgICB3cml0ZUNvdW50cnlJU0JOTnVtYmVyKHhtbFN0cmluZyk7CiAgICB3cml0ZUxhbmd1YWdlTGlicmFyeVVzZSh4bWxTdHJpbmcpOwogICAgd3JpdGVQYXBlclNpemUoeG1sU3RyaW5nKTsKICAgIGlmKHhtbFN0cmluZy5sZW5ndGgoKT4wKXsKICAgICAgICBwcmludFN0cmluZygmeG1sU3RyaW5nKTsKICAgIH0KfQp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUNvdW50cnlQb3N0KFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CiAgICBVbmljb2RlU3RyaW5nIHRlbXA7CiAgICBnZXRTdHJpbmdSZXMoIkNvdW50cnlQb3N0Iix0ZW1wLFVuaWNvZGVTdHJpbmcoUE9TVCkpOwogICAgaWYodGVtcC5sZW5ndGgoKT4wKXsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXApOwogICAgfQp9CnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlQ291bnRyeUNhcihVbmljb2RlU3RyaW5nJiB4bWxTdHJpbmcpewogICAgCiAgICBVbmljb2RlU3RyaW5nIHRlbXA7CiAgICBnZXRTdHJpbmdSZXMoIkNvdW50cnlDYXIiLHRlbXAsVW5pY29kZVN0cmluZyhDTlRSWV9DQVIpKTsKICAgIGlmKHRlbXAubGVuZ3RoKCk+MCl7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wKTsKICAgIH0KfQp2b2lkIEdlbmVyYXRlWE1MOjp3cml0ZUNvdW50cnlJU0JOTnVtYmVyKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CiAgICAKICAgIFVuaWNvZGVTdHJpbmcgdGVtcDsKICAgIGdldFN0cmluZ1JlcygiQ291bnRyeUlTQk4iLHRlbXAsVW5pY29kZVN0cmluZyhJU0JOX05VTSkpOwogICAgaWYodGVtcC5sZW5ndGgoKT4wKXsKICAgICAgICB4bWxTdHJpbmcuYXBwZW5kKHRlbXApOwogICAgfQp9CnZvaWQgR2VuZXJhdGVYTUw6OndyaXRlTGFuZ3VhZ2VMaWJyYXJ5VXNlKFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyl7CiAgICBVbmljb2RlU3RyaW5nIHRlbXA7CiAgICBnZXRTdHJpbmdSZXMoIkxhbmd1YWdlTGliVXNlIix0ZW1wLFVuaWNvZGVTdHJpbmcoTEFOR19MSUIpKTsKICAgIGlmKHRlbXAubGVuZ3RoKCk+MCl7CiAgICAgICAgeG1sU3RyaW5nLmFwcGVuZCh0ZW1wKTsKICAgIH0KfQoKdm9pZCBHZW5lcmF0ZVhNTDo6Z2V0U3RyaW5nUmVzKGNvbnN0IGNoYXIgKmtleSxSZXNvdXJjZUJ1bmRsZSYgYnVuZGxlLFVuaWNvZGVTdHJpbmcmIHhtbFN0cmluZyxVbmljb2RlU3RyaW5nIHBhdHRlcm4pewogICAgUmVzb3VyY2VCdW5kbGUgbXlCdW5kbGUgPSBtU291cmNlQnVuZGxlOwogICAgbVNvdXJjZUJ1bmRsZSA9IGJ1bmRsZTsKICAgIGdldFN0cmluZ1JlcyhrZXkseG1sU3RyaW5nLHBhdHRlcm4pOwogICAgbVNvdXJjZUJ1bmRsZSA9IG15QnVuZGxlOwp9CnZvaWQgR2VuZXJhdGVYTUw6OmdldFN0cmluZ1Jlcyhjb25zdCBjaGFyKiBrZXksVW5pY29kZVN0cmluZyYgeG1sU3RyaW5nLFVuaWNvZGVTdHJpbmcgcGF0dGVybil7CiAgICBVbmljb2RlU3RyaW5nIHRlbXA9bVNvdXJjZUJ1bmRsZS5nZXRTdHJpbmdFeChrZXksbUVycm9yKTsKCUZvcm1hdHRhYmxlIGFyZ3NbXT17aW5kZW50T2Zmc2V0LCIifTsKCWlmKCFVX0ZBSUxVUkUobUVycm9yKSl7CgkJYXJnc1sxXSA9IHRlbXA7CgkJeG1sU3RyaW5nLmFwcGVuZChmb3JtYXRTdHJpbmcocGF0dGVybixhcmdzLDIpKTsKCX0KCW1FcnJvciA9IFVfWkVST19FUlJPUjsKfQoKKi8=