LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0xOTk5LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSB0Ymxjb2xsLmNwcAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMS85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgZGVjbGFyYXRpb25zIG91dCBvZiBmb3IgbG9vcCBpbml0aWFsaXplci4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgTWFjIGNvbXBhdGliaWxpdHkgI2lmZGVmIGZvciBpb3M6Om5vY3JlYXRlLgoqICAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byB1c2UgVGFibGVDb2xsYXRpb25EYXRhIHN1Yi1vYmplY3QgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZCBpbnZhcmlhbnQgZGF0YS4KKiAgMi8xMy85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgc2V2ZXJhbCBtZXRob2RzIGludG8gdGhpcyBjbGFzcyBmcm9tIENvbGxhdGlvbi4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgYSBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpIGNvbnN0cnVjdG9yLAoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZSB1c2VkIGJ5IENvbGxhdG9yOjpnZXRJbnN0YW5jZSgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4gIE1hZGUgdXNlIG9mIFVFcnJvckNvZGUgdmFyaWFibGVzIGNvbnNpc3RlbnQuCiogIDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGFuZCBjb3B5CiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIGFuZCBnZXREeW5hbWljQ2xhc3NJRC4KKiAgMy81Lzk3ICAgICAgYWxpdSAgICAgICAgQ2hhbmdlZCBjb21wYWN0aW9uIGN5Y2xlIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuICBXZQoqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgdGhlIG1heGltdW0gYWxsb3dhYmxlIHZhbHVlIHdoaWNoIGlzIGtCbG9ja0NvdW50LgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllZCBnZXRSdWxlcygpIHRvIGxvYWQgcnVsZXMgZHluYW1pY2FsbHkuICBDaGFuZ2VkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21GaWxlKCkgY2FsbCB0byBhY2NvbW9kYXRlIHRoaXMgKGFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciB0byBzcGVjaWZ5IHdoZXRoZXIgYmluYXJ5IGxvYWRpbmcgaXMgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSBwbGFjZSkuCiogMDUvMDYvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIG1lbW9yeSBhbGxvY2F0aW9uIGVycm9yIGNoZWNrLgoqICA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqICA2LzIzLzk3ICAgICBoZWxlbmEgICAgICBBZGRpbmcgY29tbWVudHMgdG8gbWFrZSBjb2RlIG1vcmUgcmVhZGFibGUuCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDA2LzI2Lzk4ICAgICBlcm0gICAgICAgICBDaGFuZ2VzIGZvciBDb2xsYXRpb25LZXlzIHVzaW5nIGJ5dGUgYXJyYXlzLgoqIDA4LzEwLzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgUnVsZUJhc2VkQ29sbGF0b3IuamF2YQoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUKKiAwNi8xNC85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBrUmVzb3VyY2VCdW5kbGVTdWZmaXgKKiAwNi8yMi85OSAgICAgc3RlcGhlbiAgICAgRml4ZWQgbG9naWMgaW4gY29uc3RydWN0RnJvbUZpbGUoKSBzaW5jZSAuY3R4CiogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzIGFyZSBubyBsb25nZXIgdXNlZC4KKiAxMS8wMi85OSAgICAgaGVsZW5hICAgICAgQ29sbGF0b3IgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiAgU3BlY2lhbCBjYXNlCiogICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBOT19PUCBzaXR1YXRpb25zLiAKKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKI2luY2x1ZGUgInVjbXAzMi5oIgojaW5jbHVkZSAidGNvbGRhdGEuaCIKCiNpbmNsdWRlICJ1bmljb2RlL3RibGNvbGwuaCIKCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvbG9jaWQuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pY29kZS5oIgojaW5jbHVkZSAidGFibGVzLmgiCiNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKI2luY2x1ZGUgIm1lcmdlY29sLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Jlc2J1bmQuaCIKI2luY2x1ZGUgImZpbGVzdHJtLmgiCiNpbmNsdWRlICJ1bWVtc3RybS5oIgoKI2lmZGVmIF9ERUJVRwojaW5jbHVkZSAidW5pc3RybS5oIgojZW5kaWYKCiNpbmNsdWRlICJjb21waXRyLmgiCgojaW5jbHVkZSA8c3RyaW5nLmg+CgojaW5jbHVkZSAidW5pY29kZS91c3RyaW5nLmgiCgojaW5jbHVkZSAiY21lbW9yeS5oIgoKCmNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXIKewpwdWJsaWM6CiAgIHN0YXRpYyB2b2lkIHN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgRmlsZVN0cmVhbSogaXMpOwogICBzdGF0aWMgdm9pZCBzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBvcyk7CiAgIHN0YXRpYyB2b2lkIHN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgVU1lbW9yeVN0cmVhbSogaXMpOwogICBzdGF0aWMgdm9pZCBzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBVTWVtb3J5U3RyZWFtKiBvcyk7Cn07CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gIFRoZSBmb2xsb3dpbmcgZGlhZ3JhbSBzaG93cyB0aGUgZGF0YSBzdHJ1Y3R1cmUgb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdC4KLy8gIFN1cHBvc2Ugd2UgaGF2ZSB0aGUgcnVsZSwgd2hlcmUgJ28tdW1sYXV0JyBpcyB0aGUgdW5pY29kZSBjaGFyIDB4MDBGNi4KLy8gICJhLCBBIDwgYiwgQiA8IGMsIEMsIGNoLCBjSCwgQ2gsIENIIDwgZCwgRCAuLi4gPCBvLCBPOyAnby11bWxhdXQnL0UsICdPLXVtbGF1dCcvRSAuLi4iLgovLyAgV2hhdCB0aGUgcnVsZSBzYXlzIGlzLCBzb3J0cyAnY2gnbGlnYXR1cmVzIGFuZCAnYycgb25seSB3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYW5kCi8vICBzb3J0cyAnby11bWxhdXQnIGFzIGlmIGl0J3MgYWx3YXlzIGV4cGFuZGVkIHdpdGggJ2UnLgovLwovLyBtYXBwaW5nIHRhYmxlICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdGluZyBsaXN0ICAgICAgICAgICAgICAgICAgZXhwYW5kaW5nIGxpc3QKLy8gKGNvbnRhaW5zIGFsbCB1bmljb2RlIGNoYXIKLy8gIGVudHJpZXMpICAgICAgICAgICAgICAgICAgICAgICAgIF9fXyAgICAgX19fX19fX19fX19fXyAgICAgICAgIF9fX19fX19fX19fX19fX19fX19fX19fX18KLy8gICBfX19fX19fXyAgICAgICAgICAgICAgICAgICB8PT0+fF8qX3wtLT58J2MnICB8dignYycpIHwgICB8PT0+fHYoJ28nKXx2KCd1bWxhdXQnKXx2KCdlJyl8Ci8vICB8X1x1MDAwMV98LS0+IHYoJ1x1MDAwMScpICAgfCAgIHxfOl98ICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9cdTAwMDJffC0tPiB2KCdcdTAwMDInKSAgIHwgICB8XzpffCAgIHwnY2gnIHx2KCdjaCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgfF86X3wgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfCdjSCcgfHYoJ2NIJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fJ2EnX19ffC0tPiB2KCdhJykgICAgICAgIHwgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfXydiJ19fX3wtLT4gdignYicpICAgICAgICB8ICAgICAgICAgICB8J0NoJyB8dignQ2gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwnQ0gnIHx2KCdDSCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX18nYydfX3wtLS0tLS0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgLS0tLS0tLS0tLS0tLSAgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfG8tdW1sYXV0fC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICB8X19fX19fX19fX19fX19fX19fX19fX19fX3wKLy8gIHxfX19fOl9fX3wKLy8KLy8KLy8gTm90ZWQgYnkgSGVsZW5hIFNoaWggb24gNi8yMy85NyB3aXRoIHBlbmRpbmcgZGVzaWduIGNoYW5nZXMgKHNsaW1taW5nIGNvbGxhdGlvbikuCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNIQVJJTkRFWCA9IDB4NzAwMDAwMDA7ICAgICAgICAgICAgIC8vIG5lZWQgbG9vayB1cCBpbiAuY29tbWl0KCkKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6RVhQQU5EQ0hBUklOREVYID0gMHg3RTAwMDAwMDsgICAgICAgLy8gRXhwYW5kIGluZGV4IGZvbGxvd3MKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09OVFJBQ1RDSEFSSU5ERVggPSAweDdGMDAwMDAwOyAgICAgLy8gY29udHJhY3QgaW5kZXhlcyBmb2xsb3dzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEID0gMHhGRkZGRkZGRjsgICAgICAgICAgICAgIC8vIHVubWFwcGVkIGNoYXJhY3RlciB2YWx1ZXMKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAxMDAwMDsgLy8gcHJpbWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMTAwOyAvLyBzZWNvbmRhcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMDAxOyAvLyB0ZXJ0aWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6TUFYSUdOT1JBQkxFID0gMHgwMDAxMDAwMDsgICAgICAgICAgLy8gbWF4aW11bSBpZ25vcmFibGUgY2hhciBvcmRlciB2YWx1ZQpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLID0gMHhmZmZmMDAwMDsgICAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgcHJpbWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUk1BU0sgPSAweDAwMDBmZjAwOyAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgc2Vjb25kYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLID0gMHgwMDAwMDBmZjsgICAgIC8vIG1hc2sgb2ZmIGFueXRoaW5nIGJ1dCB0ZXJ0aWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllSRVNFVE1BU0sgPSAweDAwMDBmZmZmOyAgICAvLyBtYXNrIG9mZiBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OklHTk9SQUJMRU1BU0sgPSAweDAwMDBmZmZmOyAgICAgICAgIC8vIG1hc2sgb2ZmIGlnbm9yYWJsZSBjaGFyIG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllESUZGRVJFTkNFT05MWSA9IDB4ZmZmZjAwMDA7IC8vIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGRpZmZlcmVuY2UKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmZmZjAwOyAgLy8gdXNlIG9ubHkgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBkaWZmZXJlbmNlCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUlNISUZUID0gMTY7ICAgICAgICAgICAgIC8vIHByaW1hcnkgb3JkZXIgc2hpZnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJTSElGVCA9IDg7ICAgICAgICAgICAgLy8gc2Vjb25kYXJ5IG9yZGVyIHNoaWZ0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNPUlRLRVlPRkZTRVQgPSAxOyAgICAgICAgICAgICAgICAgIC8vIG1pbmltdW0gc29ydCBrZXkgb2Zmc2V0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUk9WRVJGTE9XID0gMHg3RkZGRkZGRjsgIC8vIEluZGljYXRlcyB0aGUgY2hhciBpcyBhIGNvbnRyYWN0IGNoYXIKCmNvbnN0IGludDE2X3QgUnVsZUJhc2VkQ29sbGF0b3I6OkZJTEVJRCA9IDB4NTQ0MzsgICAgICAgICAgICAgICAgICAgIC8vIHVuaXF1ZSBmaWxlIGlkIGZvciBwYXJpdHkgY2hlY2sKY29uc3QgY2hhciogUnVsZUJhc2VkQ29sbGF0b3I6OmtGaWxlbmFtZVN1ZmZpeCA9ICIuY29sIjsgICAgICAgICAgICAgLy8gYmluYXJ5IGNvbGxhdGlvbiBmaWxlIGV4dGVuc2lvbgpjaGFyICBSdWxlQmFzZWRDb2xsYXRvcjo6ZmdDbGFzc0lEID0gMDsgLy8gVmFsdWUgaXMgaXJyZWxldmFudCAgICAgICAvLyBjbGFzcyBpZAoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIE5vcm1hbGl6ZXJJdGVyYXRvcgovLwovLyBUaGlzIGNsYXNzIGlzIGVzc2VudGlhbGx5IGEgZHVwbGljYXRlIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwKLy8gc3RyaXBwZWQgZG93biBmb3Igc3BlZWQuICBJdCBpcyBkZWNsYXJlZCBoZXJlIHNvIHdlIGNhbiBpbmNvcnBvcmF0ZQovLyBpbnRlcm5hbCBjbGFzc2VzIGFzIHN1Ym9iamVjdHMsIGFzIHdlbGwgYXMganVzdCB0byBoaWRlIGl0IGZyb20gdGhlCi8vIHB1YmxpYyBpbnRlcmZhY2UuCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKLyogSW50ZXJuYWwgY2xhc3MgZm9yIHF1aWNrIGl0ZXJhdGlvbiBvdmVyIHRoZSB0ZXh0LgogICAxMDAlIHB1cmUgaW5saW5lIGNvZGUKKi8KY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yIHsgCnB1YmxpYzoKICAgIE5vcm1hbGl6ZXIgKmN1cnNvcjsKICAgIFZlY3Rvck9mSW50ICpidWZmZXJBbGlhczsKICAgIFZlY3Rvck9mSW50ICpyZW9yZGVyQnVmZmVyOwogICAgVmVjdG9yT2ZJbnQgb3duQnVmZmVyOwogICAgVUNoYXIqICAgICAgdGV4dDsKICAgIGludDMyX3QgICAgIGV4cEluZGV4OwogICAgaW50MzJfdCAgICAgdGV4dExlbjsKICAgIFVUZXh0T2Zmc2V0ICBjdXJyZW50T2Zmc2V0OwogICAgCiAgICBOb3JtYWxpemVySXRlcmF0b3Iodm9pZCk7CiAgICBOb3JtYWxpemVySXRlcmF0b3IoY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIE5vcm1hbGl6ZXI6OkVNb2RlIG1vZGUpOwogICAgfk5vcm1hbGl6ZXJJdGVyYXRvcih2b2lkKTsKICAgIHZvaWQgc2V0VGV4dChjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgIHZvaWQgc2V0TW9kZUFuZFRleHQoTm9ybWFsaXplcjo6RU1vZGUgbW9kZSwgY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAKICAgIFVDaGFyIGN1cnJlbnQodm9pZCkgY29uc3Q7CiAgICBVQ2hhciBuZXh0KHZvaWQpOwogICAgdm9pZCByZXNldCh2b2lkKTsKfTsKCmlubGluZQpOb3JtYWxpemVySXRlcmF0b3I6Ok5vcm1hbGl6ZXJJdGVyYXRvcigpIDoKICAgIGN1cnNvcigwKSwKICAgIGJ1ZmZlckFsaWFzKDApLAogICAgcmVvcmRlckJ1ZmZlcigwKSwKICAgIG93bkJ1ZmZlcigyKSwKICAgIHRleHQoMCksCiAgICB0ZXh0TGVuKDApLAogICAgY3VycmVudE9mZnNldCgwKSwKICAgIGV4cEluZGV4KDApCnsKfQoKaW5saW5lCk5vcm1hbGl6ZXJJdGVyYXRvcjo6Tm9ybWFsaXplckl0ZXJhdG9yKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBOb3JtYWxpemVyOjpFTW9kZSBtb2RlKSA6CiAgICBjdXJzb3IoMCksCiAgICBidWZmZXJBbGlhcygwKSwKICAgIHJlb3JkZXJCdWZmZXIoMCksCiAgICBvd25CdWZmZXIoMiksCiAgICB0ZXh0KDApLAogICAgdGV4dExlbigwKSwKICAgIGN1cnJlbnRPZmZzZXQoMCksCiAgICBleHBJbmRleCgwKQp7CiAgICBpZiAobW9kZSA9PSBOb3JtYWxpemVyOjpOT19PUCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CgogICAgfQp9CgppbmxpbmUKTm9ybWFsaXplckl0ZXJhdG9yOjp+Tm9ybWFsaXplckl0ZXJhdG9yKCkgCnsKICAgIGlmIChjdXJzb3IgIT0gMCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3I7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KICAgIGlmIChyZW9yZGVyQnVmZmVyICE9IDApIHsKICAgICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgIH0KfQoKaW5saW5lCnZvaWQKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRUZXh0KGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChjdXJzb3IgPT0gMCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwoKICAgIH0gZWxzZSB7CiAgICAgICAgdGV4dCA9IDA7CiAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgfQogICAgYnVmZmVyQWxpYXMgPSAwOwogICAgY3VycmVudE9mZnNldCA9IDA7Cn0KCi8qIFlvdSBjYW4gb25seSBzZXQgbW9kZSBhZnRlciB0aGUgY29tcGFyaXNpb24gb2YgdHdvIHN0cmluZ3MgaXMgY29tcGxldGVkLgogICBTZXR0aW5nIHRoZSBtb2RlIGluIHRoZSBtaWRkbGUgb2YgYSBjb21wYXJpc29uIGlzIG5vdCBhbGxvd2VkLgogICAqLwppbmxpbmUKdm9pZAoKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRNb2RlQW5kVGV4dChOb3JtYWxpemVyOjpFTW9kZSBtb2RlLCBjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZihtb2RlICE9IE5vcm1hbGl6ZXI6Ok5PX09QKQogICAgewogICAgICAgIC8qIERPIGhhdmUgYSBtb2RlIC0gIHdpbGwgbmVlZCBhIG5vcm1hbGl6ZXIgb2JqZWN0ICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICAvKiBKdXN0IG1vZGlmeSB0aGUgZXhpc3RpbmcgY3Vyc29yICovCiAgICAgICAgICAgIGN1cnNvci0+c2V0TW9kZShtb2RlKTsKICAgICAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBSRVNFVCB0aGUgb2xkIGRhdGEgKi8KICAgICAgICB0ZXh0ID0gMDsKICAgICAgICB0ZXh0TGVuID0gMDsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogTk9fT1AgbW9kZS4uICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgeyAvKiBnZXQgcmlkIG9mIHRoZSBvbGQgY3Vyc29yICovCiAgICAgICAgICAgIGRlbGV0ZSBjdXJzb3I7IAogICAgICAgICAgICBjdXJzb3IgPSAwOwogICAgICAgIH0KCiAgICAgICAgdGV4dCA9IChVQ2hhciopc291cmNlOwogICAgICAgIHRleHRMZW4gPSBsZW5ndGg7CiAgICB9CiAgICBjdXJyZW50T2Zmc2V0ID0gMDsgLyogYWx3YXlzICovCiAgIAogICAgYnVmZmVyQWxpYXMgPSAwOwp9CgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpjdXJyZW50KHZvaWQpIGNvbnN0CnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICBpZihjdXJyZW50T2Zmc2V0ID49IHRleHRMZW4pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTm9ybWFsaXplcjo6RE9ORTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRleHRbY3VycmVudE9mZnNldF07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAoVUNoYXIpY3Vyc29yLT5jdXJyZW50KCk7Cn0KCgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpuZXh0KHZvaWQpCnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICByZXR1cm4gKFVDaGFyKSgoY3VycmVudE9mZnNldCA8IHRleHRMZW4pID8gdGV4dFsrK2N1cnJlbnRPZmZzZXRdIDogTm9ybWFsaXplcjo6RE9ORSk7CiAgICB9CiAgICByZXR1cm4gKFVDaGFyKWN1cnNvci0+bmV4dCgpOwp9CgppbmxpbmUKdm9pZApOb3JtYWxpemVySXRlcmF0b3I6OnJlc2V0KHZvaWQpCnsKICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgaWYoY3Vyc29yKQogICAgewogICAgICAgIGN1cnNvci0+cmVzZXQoKTsKICAgIH0KfQoKLy89PT09PT09PT09PT09PT09IFNvbWUgaW5saW5lIGRlZmluaXRpb25zIG9mIGltcGxlbWVudGF0aW9uIGZ1bmN0aW9ucy4uLi4uLi4uID09PT09PT09Ci8qKgogKiBBIGNsb25lIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bWFrZVJlb3JkZXJlZEJ1ZmZlciwgdHJpbW1lZCBkb3duCiAqIHRvIG9ubHkgaGFuZGxlIGZvcndhcmQuCiAqLwppbmxpbmUgVmVjdG9yT2ZJbnQqClJ1bGVCYXNlZENvbGxhdG9yOjptYWtlUmVvcmRlcmVkQnVmZmVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ2hhciBjb2xGaXJzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsYXN0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mSW50KiBsYXN0RXhwYW5zaW9uKSBjb25zdCB7CiAgICBWZWN0b3JPZkludCogcmVzdWx0OwoKICAgIGludDMyX3QgZmlyc3RWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY29sRmlyc3QpOwogICAgaWYgKGZpcnN0VmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpIHsKICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICBmaXJzdFZhbHVlID0gbmV4dENvbnRyYWN0Q2hhcihjdXJzb3IsIGNvbEZpcnN0LCBzdGF0dXMpOwogICAgfQoKICAgIFZlY3Rvck9mSW50KiBmaXJzdEV4cGFuc2lvbiA9IE5VTEw7CiAgICBpZiAoZmlyc3RWYWx1ZSA+PSBFWFBBTkRDSEFSSU5ERVgpIHsKICAgICAgICBmaXJzdEV4cGFuc2lvbiA9IGdldEV4cGFuZFZhbHVlTGlzdChmaXJzdFZhbHVlKTsKICAgIH0KCiAgICBpZiAoZmlyc3RFeHBhbnNpb24gPT0gTlVMTCAmJiBsYXN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgwKSA9IGZpcnN0VmFsdWU7CiAgICAgICAgY3Vyc29yLT5vd25CdWZmZXIuYXQoMSkgPSBsYXN0VmFsdWU7CiAgICAgICAgcmVzdWx0ID0gJmN1cnNvci0+b3duQnVmZmVyOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgaW50MzJfdCBmaXJzdExlbmd0aCA9IGZpcnN0RXhwYW5zaW9uPT1OVUxMPyAxIDogZmlyc3RFeHBhbnNpb24tPnNpemUoKTsKICAgICAgICBpbnQzMl90IGxhc3RMZW5ndGggPSBsYXN0RXhwYW5zaW9uPT1OVUxMPyAxIDogbGFzdEV4cGFuc2lvbi0+c2l6ZSgpOwogICAgICAgIGlmIChjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgICBjdXJzb3ItPnJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgfQogICAgICAgIC8vIHJlb3JkZXJkQnVmZmVyIGdldHMgcmV1c2VkIGZvciB0aGUgbGlmZSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAvLyBTaW5jZSBpdHMgaW50ZXJuYWwgYnVmZmVyIG9ubHkgZ3Jvd3MsIHRoZXJlIGlzIGEgZGFuZ2VyCiAgICAgICAgLy8gdGhhdCBpdCB3aWxsIGdldCByZWFsbHksIHJlYWxseSBiaWcsIGFuZCBuZXZlciBzaHJpbmsuICBJZgogICAgICAgIC8vIHRoaXMgaXMgYWN0dWFsbHkgaGFwcGVuaW5nLCBpbnNlcnQgY29kZSBoZXJlIHRvIGNoZWNrIGZvcgogICAgICAgIC8vIHRoZSBjb25kaXRpb24uICBTb21ldGhpbmcgYWxvbmcgdGhlIGxpbmVzIG9mOgogICAgICAgIC8vISBlbHNlIGlmIChyZW9yZGVyQnVmZmVyLT5zaXplKCkgPj0gMjU2ICYmCiAgICAgICAgLy8hICAgICAgICAgIChmaXJzdExlbmd0aCtsYXN0TGVuZ3RoKSA8IDE2KSB7CiAgICAgICAgLy8hICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgICAgICAvLyEgICAgIHJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICAgICAgLy8hIH0KICAgICAgICAvLyBUaGUgc3BlY2lmaWMgbnVtZXJpYyB2YWx1ZXMgbmVlZCB0byBiZSBkZXRlcm1pbmVkCiAgICAgICAgLy8gZW1waXJpY2FsbHkuIFthbGl1XQogICAgICAgIHJlc3VsdCA9IGN1cnNvci0+cmVvcmRlckJ1ZmZlcjsKCiAgICAgICAgaWYgKGZpcnN0RXhwYW5zaW9uID09IE5VTEwpIHsKICAgICAgICAgICAgcmVzdWx0LT5hdFB1dCgwLCBmaXJzdFZhbHVlKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8vIFN5c3RlbS5hcnJheWNvcHkoZmlyc3RFeHBhbnNpb24sIDAsIHJlc3VsdCwgMCwgZmlyc3RMZW5ndGgpOwogICAgICAgICAgICAqcmVzdWx0ID0gKmZpcnN0RXhwYW5zaW9uOwogICAgICAgIH0KCiAgICAgICAgaWYgKGxhc3RFeHBhbnNpb24gPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQtPmF0UHV0KGZpcnN0TGVuZ3RoLCBsYXN0VmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gU3lzdGVtLmFycmF5Y29weShsYXN0RXhwYW5zaW9uLCAwLCByZXN1bHQsIGZpcnN0TGVuZ3RoLCBsYXN0TGVuZ3RoKTsKICAgICAgICAgICAgZm9yIChpbnQzMl90IGk9MDsgaTxsYXN0TGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC0+YXRQdXQoZmlyc3RMZW5ndGggKyBpLCBsYXN0RXhwYW5zaW9uLT5hdChpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVzdWx0LT5zZXRTaXplKGZpcnN0TGVuZ3RoK2xhc3RMZW5ndGgpOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCgoKCgppbmxpbmUgaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6c3RyZW5ndGhPcmRlcihpbnQzMl90IHZhbHVlKSBjb25zdAp7CiAgICBpZiAoZ2V0U3RyZW5ndGgoKSA9PSBQUklNQVJZKQogICAgewogICAgICAgIHJldHVybiAodmFsdWUgJiBQUklNQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfSBlbHNlIGlmIChnZXRTdHJlbmd0aCgpID09IFNFQ09OREFSWSkKICAgIHsKICAgICAgICByZXR1cm4gKHZhbHVlICYgU0VDT05EQVJZRElGRkVSRU5DRU9OTFkpOwogICAgfQogICAgcmV0dXJuIHZhbHVlOwp9CgoKaW5saW5lIGludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0cmVuZ3RoT3JkZXIoTm9ybWFsaXplckl0ZXJhdG9yKiBjdXJzb3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUjsKICAgIH0KCiAgICBpZiAoY3Vyc29yLT5idWZmZXJBbGlhcyAhPSBOVUxMKQogICAgewogICAgICAgIC8vIGJ1ZmZlckFsaWFzIG5lZWRzIGEgYml0IG9mIGFuIGV4cGxhbmF0aW9uLgogICAgICAgIC8vIFdoZW4gd2UgaGl0IGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIgaW4gdGhlIHRleHQsIHdlIGNhbGwgdGhlIG9yZGVyJ3MKICAgICAgICAvLyBnZXRFeHBhbmRWYWx1ZXMgbWV0aG9kIHRvIHJldHJpZXZlIGFuIGFycmF5IG9mIHRoZSBvcmRlcmluZ3MgZm9yIGFsbAogICAgICAgIC8vIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBleHBhbnNpb24gKHNlZSB0aGUgZW5kIG9mIHRoaXMgbWV0aG9kKS4KICAgICAgICAvLyBUaGUgZmlyc3Qgb3JkZXJpbmcgaXMgcmV0dXJuZWQsIGFuZCBhbiBhbGlhcyB0byB0aGUgb3JkZXJpbmdzIGFycmF5CiAgICAgICAgLy8gaXMgc2F2ZWQgc28gdGhhdCB0aGUgcmVtYWluaW5nIG9yZGVyaW5ncyBjYW4gYmUgcmV0dXJuZWQgb24gc3Vic2VxdWVudAogICAgICAgIC8vIGNhbGxzIHRvIG5leHQuICBTbywgaWYgdGhlIGV4cGFuZGluZyBidWZmZXIgaXMgbm90IGV4aGF1c3RlZCwgCiAgICAgICAgLy8gYWxsIHdlIGhhdmUgdG8gZG8gaGVyZSBpcyByZXR1cm4gdGhlIG5leHQgb3JkZXJpbmcgaW4gdGhlIGJ1ZmZlci4gIAogICAgICAgIGlmIChjdXJzb3ItPmV4cEluZGV4IDwgY3Vyc29yLT5idWZmZXJBbGlhcy0+c2l6ZSgpKQogICAgICAgIHsKICAgICAgICAgICAgLy9fTCgoc3RkZXJyLCAibmV4dCBmcm9tIFslMDhYXSBmcm9tIGJ1ZmZlckFsaWFzXG4iLCB0aGlzKSk7CiAgICAgICAgICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KGN1cnNvci0+ZXhwSW5kZXgrKykpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgVUNoYXIgY2ggPSBjdXJzb3ItPmN1cnJlbnQoKTsKICAgIGN1cnNvci0+bmV4dCgpOwoKICAgIC8vX0woKHN0ZGVyciwgIk5leHQgZnJvbSBbJTA4WF0gPSBbJTA0WF0sIFslY11cbiIsIGN1cnNvciwgKGludCljaCAmIDB4RkZGRiwgKGNoYXIpKGNoICYgMHhGRikpKTsKICAgIAogICAgaWYgKGNoID09IE5vcm1hbGl6ZXI6OkRPTkUpIHsKICAgICAgICByZXR1cm4gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVI7CiAgICB9CiAgICAvLyBBc2sgdGhlIGNvbGxhdG9yIGZvciB0aGlzIGNoYXJhY3RlcidzIG9yZGVyaW5nLgogICAgaW50MzJfdCB2YWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgIGlmICh2YWx1ZSA9PSBVTk1BUFBFRCkKICAgIHsKICAgICAgICAvLyBSZXR1cm5lZCBhbiAidW5tYXBwZWQiIGZsYWcgYW5kIHNhdmUgdGhlIGNoYXJhY3RlciBzbyBpdCBjYW4gYmUgCiAgICAgICAgLy8gcmV0dXJuZWQgbmV4dCB0aW1lIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4KICAgICAgICBpZiAoY2ggPT0gMHgwMDAwKSByZXR1cm4gY2g7IC8vIFx1MDAwMCBpcyBub3QgdmFsaWQgaW4gQysrJ3MgVW5pY29kZVN0cmluZwogICAgICAgIGN1cnNvci0+b3duQnVmZmVyLmF0KDApID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpVTk1BUFBFRENIQVJWQUxVRTsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgxKSA9IGNoIDw8IDE2OwogICAgICAgIGN1cnNvci0+YnVmZmVyQWxpYXMgPSAmY3Vyc29yLT5vd25CdWZmZXI7CgogICAgfSBlbHNlIHsKICAgICAgICAKICAgICAgICBpZiAodmFsdWUgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICAgICAgewogICAgICAgICAgICB2YWx1ZSA9IG5leHRDb250cmFjdENoYXIoY3Vyc29yLCBjaCwgc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKHZhbHVlID49IEVYUEFORENIQVJJTkRFWCkgewogICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gZ2V0RXhwYW5kVmFsdWVMaXN0KHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNUaGFpUHJlVm93ZWwoY2gpKSB7CiAgICAgICAgICAgIFVDaGFyIGNvbnNvbmFudCA9IGN1cnNvci0+Y3VycmVudCgpOwogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc1RoYWlCYXNlQ29uc29uYW50KGNvbnNvbmFudCkpIHsKICAgICAgICAgICAgICAgIGN1cnNvci0+bmV4dCgpOwogICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyA9IG1ha2VSZW9yZGVyZWRCdWZmZXIoY3Vyc29yLCBjb25zb25hbnQsIHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyk7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjdXJzb3ItPmJ1ZmZlckFsaWFzICE9IE5VTEwpIHsKICAgICAgICBjdXJzb3ItPmV4cEluZGV4ID0gMTsKICAgICAgICB2YWx1ZSA9IGN1cnNvci0+YnVmZmVyQWxpYXMtPmF0KDApOwogICAgfQoKICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKHZhbHVlKTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT0gRW5kIGlubGluZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcigpCiAgICA6IENvbGxhdG9yKCksCiAgICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICAgIG1QYXR0ZXJuKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGEoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKQp7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgUnVsZUJhc2VkQ29sbGF0b3ImICB0aGF0KQogICAgOiBDb2xsYXRvcih0aGF0KSwKICAgICAgaXNPdmVySWdub3JlKHRoYXQuaXNPdmVySWdub3JlKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKHRoYXQuZGF0YSkgLy8gQWxpYXMgdGhlIGRhdGEgcG9pbnRlcgp7Cn0KClVCb29sClJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiB0aGF0KSBjb25zdAp7CiAgICBpZiAodGhpcyA9PSAmdGhhdCkKICAgIHsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICBpZiAodGhpcy0+Z2V0RHluYW1pY0NsYXNzSUQoKSAhPSB0aGF0LmdldER5bmFtaWNDbGFzc0lEKCkpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOyAgLy8gbm90IHRoZSBzYW1lIGNsYXNzCiAgICB9CgogICAgaWYgKCFDb2xsYXRvcjo6b3BlcmF0b3I9PSh0aGF0KSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXRBbGlhcyA9IChSdWxlQmFzZWRDb2xsYXRvciYpdGhhdDsKCiAgICBpZiAoaXNPdmVySWdub3JlICE9IHRoYXRBbGlhcy5pc092ZXJJZ25vcmUpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChkYXRhICE9IHRoYXRBbGlhcy5kYXRhKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKUnVsZUJhc2VkQ29sbGF0b3ImClJ1bGVCYXNlZENvbGxhdG9yOjpvcGVyYXRvcj0oY29uc3QgIFJ1bGVCYXNlZENvbGxhdG9yJiB0aGF0KQp7CiAgICBpZiAodGhpcyAhPSAmdGhhdCkKICAgIHsKICAgICAgICBDb2xsYXRvcjo6b3BlcmF0b3I9KHRoYXQpOwogICAgICAgIGlzT3Zlcklnbm9yZSA9IHRoYXQuaXNPdmVySWdub3JlOwoKICAgICAgICBpZiAoZGF0YUlzT3duZWQpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICB9CgogICAgICAgIGRhdGEgPSAwOwogICAgICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgICAgICBtUGF0dGVybiA9IDA7CiAgICAgICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKICAgICAgICBkYXRhID0gdGhhdC5kYXRhOwogICAgfQoKICAgIHJldHVybiAqdGhpczsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvLy8gICAgICB0YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGEoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihjb2xsYXRpb25TdHJlbmd0aCwgTm9ybWFsaXplcjo6Tk9fT1ApLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgc291cmNlQ3Vyc29yKDApLAogICAgLy8gICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgZGF0YSgwKSwKICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogIDogQ29sbGF0b3IoVEVSVElBUlksIGRlY29tcG9zaXRpb25Nb2RlKSwKICAgIGlzT3Zlcklnbm9yZShGQUxTRSksCiAgICBtUGF0dGVybigwKSwKICAgIC8vICAgIHNvdXJjZUN1cnNvcigwKSwKICAgIC8vICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgIGRhdGEoMCksCiAgICBkYXRhSXNPd25lZChGQUxTRSkKewogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgcmV0dXJuOwogICAgfQogIAogIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgIEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogIDogQ29sbGF0b3IoY29sbGF0aW9uU3RyZW5ndGgsIGRlY29tcG9zaXRpb25Nb2RlKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgIC8vdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgICBkYXRhKDApLAogICAgICBkYXRhSXNPd25lZChGQUxTRSkKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21SdWxlcyhjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gQ29uc3RydWN0IHRoaXMgY29sbGF0b3IncyBydWxlc2V0IGZyb20gaXRzIHN0cmluZyByZXByZXNlbnRhdGlvbgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAocnVsZXMuaXNCb2d1cygpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KCiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CgogICAgZGF0YSA9IG5ldyBUYWJsZUNvbGxhdGlvbkRhdGE7CiAgICBpZiAoZGF0YS0+aXNCb2d1cygpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIFdlIGNvbnN0cnVjdGVkIHRoZSBkYXRhIHVzaW5nIHRoZSBidWlsZCBtZXRob2QsIHNvIHdlIG93biBpdC4KICAgIGRhdGFJc093bmVkID0gVFJVRTsKCiAgICAvLyBOb3cgdGhhdCB3ZSd2ZSBnb3QgYWxsIHRoZSBidWZmZXJzIGFsbG9jYXRlZCwgZG8gdGhlIGFjdHVhbCB3b3JrCiAgICBtUGF0dGVybiA9IDA7CiAgICBidWlsZChydWxlcywgc3RhdHVzKTsKfQoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbUZpbGUoY29uc3QgY2hhciogZmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIC8vIFRoaXMgbWV0aG9kIHRyaWVzIHRvIHJlYWQgaW4gYSBmbGF0dGVuZWQgUnVsZUJhc2VkQ29sbGF0b3IgdGhhdAogICAgLy8gaGFzIGJlZW4gcHJldmlvdXNseSBzdHJlYW1lZCBvdXQgdXNpbmcgdGhlIHN0cmVhbU91dCgpIG1ldGhvZC4KICAgIC8vIFRoZSAnZmlsZU5hbWUnIHBhcmFtZXRlciBzaG91bGQgY29udGFpbiBhIGZ1bGwgcGF0aG5hbWUgdmFsaWQgb24KICAgIC8vIHRoZSBsb2NhbCBlbnZpcm9ubWVudC4KCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KCiAgICBtUGF0dGVybiA9IDA7CiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7IC8vIFRoaXMgaXMgdGhlIGRlZmF1bHQgc3RyZW5ndGgKCiAgICBGaWxlU3RyZWFtKiBpZnMgPSBUX0ZpbGVTdHJlYW1fb3BlbihmaWxlTmFtZSwgInJiIik7CiAgICBpZiAoaWZzID09IDApIHsKICAgICAgICBzdGF0dXMgPSBVX0ZJTEVfQUNDRVNTX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBUaGUgc3RyZWFtSW4gZnVuY3Rpb24gZG9lcyB0aGUgYWN0dWFsIHdvcmsgaGVyZS4uLgogICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4odGhpcywgaWZzKTsKCiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihpZnMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIH0KICAgIGVsc2UgaWYgKGRhdGEgJiYgZGF0YS0+aXNCb2d1cygpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgcmVhZCAlcyBzaXplICVkLCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKGlmcyksIHVfZXJyb3JOYW1lKHN0YXR1cykpOwojZW5kaWYKCiAgICAvLyBXZSBjb25zdHJ1Y3RlZCB0aGUgZGF0YSB3aGVuIHN0cmVhbWluZyBpdCBpbiwgc28gd2Ugb3duIGl0CiAgICBkYXRhSXNPd25lZCA9IFRSVUU7CgogICAgVF9GaWxlU3RyZWFtX2Nsb3NlKGlmcyk7Cn0KCmNvbnN0IGNoYXIgKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbUJ1bmRsZShjb25zdCBMb2NhbGUgJiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgLy8gVGhpcyBtZXRob2QgdHJpZXMgdG8gbG9jYXRlIGJpbmFyeSBjb2xsYXRpb24gZGF0YSB3aGljaCBoYXMgYmVlbiAKICAvLyBwcmV2aW91c2x5IHN0cmVhbWVkIHRvIGEgYmluYXJ5IG9iamVjdCAiJSVDb2xsYXRpb24iIGluIGEgCiAgLy8gcmVzb3VyY2UgYnVuZGxlLiBJZiB0aGUgZGF0YSBpcyBmb3VuZCwgaXQgaXMgY2FjaGVkLgogIC8vIGNhY2hlIGlzIGNoZWNrZWQgYmVmb3JlIGFjdHVhbGx5IHN0cmVhbWluZyBpbiBkYXRhCiAgLy8gcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbSBpcyB1c2VkLgoKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CiAgICBjb25zdCBjaGFyKiByZWFsTmFtZSA9IDA7CgogICAgbVBhdHRlcm4gPSAwOwogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOyAvLyBUaGlzIGlzIHRoZSBkZWZhdWx0IHN0cmVuZ3RoCgogICAgUmVzb3VyY2VCdW5kbGUgcmIoKGNoYXIgKikwLCBuYW1lLCBzdGF0dXMpOwogICAgaWYoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgICAgUmVzb3VyY2VCdW5kbGUgYmluYXJ5ID0gcmIuZ2V0KCIlJUNvbGxhdGlvbiIsIHN0YXR1cyk7IC8vVGhpcyBpcyB0aGUgYnVuZGxlIHRoYXQgYWN0dWFsbHkgY29udGFpbnMgdGhlIGNvbGxhdGlvbiBkYXRhCiAgICAgIHJlYWxOYW1lID0gYmluYXJ5LmdldE5hbWUoKTsKICAgICAgaWYoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgICAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICBjb25zdHJ1Y3RGcm9tQ2FjaGUocmVhbE5hbWUsIGludFN0YXR1cyk7IC8vIGNoZWNrIHdoZXRoZXIgd2UgYWxyZWFkeSBoYXZlIHRoaXMgZGF0YSBpbiBjYWNoZQogICAgICAgIGlmKFVfU1VDQ0VTUyhpbnRTdGF0dXMpKSB7CiAgICAgICAgICByZXR1cm4gcmVhbE5hbWU7CiAgICAgICAgfQogICAgICAgIGludDMyX3QgaW5EYXRhTGVuID0gMDsKICAgICAgICBjb25zdCB1aW50OF90ICppbkRhdGEgPSBiaW5hcnkuZ2V0QmluYXJ5KGluRGF0YUxlbiwgc3RhdHVzKTsgLy9UaGlzIGdvdCB1cyB0aGUgcmVhbCBiaW5hcnkgZGF0YQoKICAgICAgICBVTWVtb3J5U3RyZWFtICppZnMgPSB1cHJ2X21zdHJtX29wZW5CdWZmZXIoaW5EYXRhLCBpbkRhdGFMZW4pOwoKICAgICAgICBpZiAoaWZzID09IDApIHsKICAgICAgICAgIHN0YXR1cyA9IFVfRklMRV9BQ0NFU1NfRVJST1I7CiAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8vIFRoZSBzdHJlYW1JbiBmdW5jdGlvbiBkb2VzIHRoZSBhY3R1YWwgd29yayBoZXJlLi4uCiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4odGhpcywgaWZzKTsKCiAgICAgICAgaWYgKCF1cHJ2X21zdHJtX2Vycm9yKGlmcykpIHsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZGF0YSAmJiBkYXRhLT5pc0JvZ3VzKCkpIHsKICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICAgIGRhdGEgPSAwOwogICAgICAgIH0KCiAgICAgICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgd2hlbiBzdHJlYW1pbmcgaXQgaW4sIHNvIHdlIG93biBpdAogICAgICAgIGRhdGFJc093bmVkID0gVFJVRTsKCiAgICAgICAgdXBydl9tc3RybV9jbG9zZShpZnMpOwogICAgICAgIGFkZFRvQ2FjaGUocmVhbE5hbWUpOyAvLyBhZGQgdGhlIG5ld2x5IGNvbnN0cnVjdGVkIGRhdGEgdG8gY2FjaGUKICAgICAgICByZXR1cm4gcmVhbE5hbWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAwOwogICAgfQp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoICAgY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIG1QYXR0ZXJuKDApCnsKCgogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuOwogIH0KICAKICAvLyBUcnkgdG8gbG9hZCwgaW4gb3JkZXI6CiAgLy8gMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogIC8vIDIuIEEgZmFsbGJhY2sgb2YgdGhlIGRlc2lyZWQgbG9jYWxlLgogIC8vIDMuIFRoZSBkZWZhdWx0IGxvY2FsZSdzIGNvbGxhdGlvbi4KICAvLyA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAvLyA1LiBUaGUgZGVmYXVsdCBjb2xsYXRpb24gcnVsZXMsIHdoaWNoIGNvbnRhaW5zIGVuX1VTIGNvbGxhdGlvbiBydWxlcy4KCiAgLy8gVG8gcmVpdGVyYXRlLCB3ZSB0cnk6CiAgLy8gU3BlY2lmaWM6CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkrdmFyaWFudAogIC8vICBsYW5ndWFnZStjb3VudHJ5CiAgLy8gIGxhbmd1YWdlCiAgLy8gRGVmYXVsdDoKICAvLyAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkKICAvLyAgbGFuZ3VhZ2UKICAvLyBSb290OiAoYWthIERFRkFVTFRSVUxFUykKICAvLyBzdGVwcyAxLTUgYXJlIGhhbmRsZWQgYnkgcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbS4gCiAgLy8gaG93ZXZlciwgaW4gYSB2ZXJ5IHVucHJvYmFibGUgc2l0dWF0aW9uIHRoYXQgbm8gcmVzb3VyY2UgYnVuZGxlCiAgLy8gZGF0YSBleGlzdHMsIHN0ZXAgNSBpcyByZXBlYXRlZCB3aXRoIGhhcmRjb2RlZCBkZWZhdWx0IHJ1bGVzLgoKICBjb25zdCBjaGFyICpsb2NOYW1lID0gY29uc3RydWN0RnJvbUJ1bmRsZShkZXNpcmVkTG9jYWxlLCBzdGF0dXMpOyAgLyohKi8KICBkYXRhLT5kZXNpcmVkTG9jYWxlID0gZGVzaXJlZExvY2FsZTsKICAKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgIGRhdGEtPnJlYWxMb2NhbGVOYW1lID0gbG9jTmFtZTsKICAgIGlmKHN0YXR1cyAhPSBVX1VTSU5HX0RFRkFVTFRfRVJST1IpIHsKICAgICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpOT19PUCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgY29uc3RydWN0RnJvbUNhY2hlKFJlc291cmNlQnVuZGxlOjprRGVmYXVsdEZpbGVuYW1lLCBpbnRTdGF0dXMpOwogICAgaWYoVV9GQUlMVVJFKGludFN0YXR1cykpIHsKICAgICAgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICBjb25zdHJ1Y3RGcm9tUnVsZXMoUnVsZUJhc2VkQ29sbGF0b3I6OkRFRkFVTFRSVUxFUywgaW50U3RhdHVzKTsKICAgICAgaWYgKGludFN0YXR1cyA9PSBVX1pFUk9fRVJST1IpIHsKICAgICAgICBzdGF0dXMgPSBVX1VTSU5HX0RFRkFVTFRfRVJST1I7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RhdHVzID0gaW50U3RhdHVzOyAgICAgLy8gYnViYmxlIGJhY2sKICAgICAgfQoKICAgICAgaWYgKHN0YXR1cyA9PSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICB9CiAgICBkYXRhLT5yZWFsTG9jYWxlTmFtZSA9IFJlc291cmNlQnVuZGxlOjprRGVmYXVsdEZpbGVuYW1lOwogICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpOT19PUCk7CiAgICBhZGRUb0NhY2hlKFJlc291cmNlQnVuZGxlOjprRGVmYXVsdEZpbGVuYW1lKTsKICB9CiAgcmV0dXJuOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tRmlsZSggICBjb25zdCBMb2NhbGUmICAgICAgICAgICBsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIGxvY2FsZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCAgICAgICAgICAgICAgICAgIHRyeUJpbmFyeUZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgICAgICAgICBzdGF0dXMpCnsKICAvLyBjb25zdHJ1Y3RGcm9tRmlsZSBjcmVhdGVzIGEgY29sbGF0aW9uIG9iamVjdCBieSByZWFkaW5nIGZyb20gYQogIC8vIGZpbGUuICBJdCBkb2VzIG5vdCBlbXBsb3kgdGhlIHVzdWFsIEZJTEUgc2VhcmNoIG1lY2hhbmlzbSB3aXRoCiAgLy8gbG9jYWxlcywgZGVmYXVsdCBsb2NhbGVzLCBhbmQgYmFzZSBsb2NhbGVzLiAgSW5zdGVhZCwgaXQgdHJpZXMgdG8KICAvLyBsb29rIG9ubHkgaW4gZmlsZXMgd2l0aCB0aGUgZ2l2ZW4gbG9jYWxGaWxlTmFtZS4gIEl0IGRvZXMsCiAgLy8gaG93ZXZlciwgZW1wbG95IHRoZSBMT0NBTEUgc2VhcmNoIG1lY2hhbmlzbS4KICAKICAvLyBUaGlzIG1ldGhvZCBtYWludGFpbnMgdGhlIGJpbmFyeSBjb2xsYXRpb24gZmlsZXMuICBJZiBhIGNvbGxhdGlvbgogIC8vIGlzIG5vdCBwcmVzZW50IGluIGJpbmFyeSBmb3JtLCBidXQgaXMgcHJlc2VudCBpbiB0ZXh0IGZvcm0gKGluIGEKICAvLyByZXNvdXJjZSBidW5kbGUgZmlsZSksIGl0IHdpbGwgYmUgbG9hZGVkIGluIHRleHQgZm9ybSwgYW5kIHRoZW4KICAvLyB3cml0dGVuIHRvIGRpc2suCiAgCiAgLy8gSWYgdHJ5QmluYXJ5RmlsZSBpcyB0cnVlLCB0aGVuIHRyeSB0byBsb2FkIGZyb20gdGhlIGJpbmFyeSBmaWxlIGZpcnN0LgoKICBpZihVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuOwogIH0KICAKICBpZihkYXRhSXNPd25lZCkgewogICAgZGVsZXRlIGRhdGE7CiAgICBkYXRhID0gMDsKICB9CgogICAgaWYodHJ5QmluYXJ5RmlsZSkgewogICAgICBjaGFyICpiaW5hcnlGaWxlUGF0aCA9IGNyZWF0ZVBhdGhOYW1lKFVuaWNvZGVTdHJpbmcodV9nZXREYXRhRGlyZWN0b3J5KCksIiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcoa0ZpbGVuYW1lU3VmZml4LCIiKSk7CgogICAgICAgIC8vIFRyeSB0byBsb2FkIHVwIHRoZSBjb2xsYXRpb24gZnJvbSBhIGJpbmFyeSBmaWxlIGZpcnN0CiAgICAgICAgY29uc3RydWN0RnJvbUZpbGUoYmluYXJ5RmlsZVBhdGgsIHN0YXR1cyk7CiAgICAgICAgI2lmZGVmIENPTExERUJVRwogICAgICAgICAgICBjZXJyIDw8IGxvY2FsZUZpbGVOYW1lICA8PCBrRmlsZW5hbWVTdWZmaXggPDwgIiBiaW5hcnkgbG9hZCAiIDw8IHVfZXJyb3JOYW1lKHN0YXR1cykgPDwgZW5kbDsKICAgICAgICAjZW5kaWYKICAgICAgICBpZihVX1NVQ0NFU1Moc3RhdHVzKSB8fCBzdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikgewogICAgICAgICAgICBkZWxldGUgW10gYmluYXJ5RmlsZVBhdGg7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYoc3RhdHVzID09IFVfRklMRV9BQ0NFU1NfRVJST1IpIHsKICAgICAgICAgICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICAgIH0KICAgICAgICBkZWxldGUgW10gYmluYXJ5RmlsZVBhdGg7CiAgICB9CgogIC8vIE5vdyB0cnkgdG8gbG9hZCBpdCB1cCBmcm9tIGEgcmVzb3VyY2UgYnVuZGxlIHRleHQgc291cmNlIGZpbGUKICBVbmljb2RlU3RyaW5nIGRhdGFEaXIgPSBVbmljb2RlU3RyaW5nKHVfZ2V0RGF0YURpcmVjdG9yeSgpLCIiKTsKCiAgICBjaGFyICpjaDsKICAgIGNoID0gbmV3IGNoYXJbbG9jYWxlRmlsZU5hbWUuc2l6ZSgpICsgMV07CiAgICBjaFtsb2NhbGVGaWxlTmFtZS5leHRyYWN0KDAsIDB4N2ZmZmZmZmYsIGNoLCAiIildID0gMDsKICAgIFJlc291cmNlQnVuZGxlIGJ1bmRsZShkYXRhRGlyLCBjaCwgc3RhdHVzKTsKICAKICAgIGRlbGV0ZSBbXSBjaDsKICAKICAvLyBpZiB0aGVyZSBpcyBubyByZXNvdXJjZSBidW5kbGUgZmlsZSBmb3IgdGhlIGdpdmUgbG9jYWxlLCBicmVhayBvdXQKICBpZihVX0ZBSUxVUkUoc3RhdHVzKSkKICB7CiAgICAgIHJldHVybjsKICB9CgogICAgI2lmZGVmIENPTExERUJVRwogICAgICAgIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgPDwgIiBhc2NpaSBsb2FkICIgPDwgdV9lcnJvck5hbWUoc3RhdHVzKSA8PCBlbmRsOwogICAgI2VuZGlmCgogICAgLy8gY2hlY2sgYW5kIHNlZSBpZiB0aGlzIHJlc291cmNlIGJ1bmRsZSBjb250YWlucyBjb2xsYXRpb24gZGF0YQogIAogICAgVW5pY29kZVN0cmluZyBjb2xTdHJpbmc7CiAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICBSZXNvdXJjZUJ1bmRsZSBjb2xFbGVtcyA9IGJ1bmRsZS5nZXQoIkNvbGxhdGlvbkVsZW1lbnRzIiwgaW50U3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoaW50U3RhdHVzKSkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29sU3RyaW5nID0gY29sRWxlbXMuZ2V0U3RyaW5nRXgoIlNlcXVlbmNlIiwgaW50U3RhdHVzKTsKCiAgICBpZihVX0ZBSUxVUkUoaW50U3RhdHVzKSkgewogICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYoY29sU3RyaW5nLmlzQm9ndXMoKSkgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAvLyBIYXZpbmcgbG9hZGVkIHRoZSBjb2xsYXRpb24gZnJvbSB0aGUgcmVzb3VyY2UgYnVuZGxlIHRleHQgZmlsZSwKICAvLyBub3cgcmV0cmlldmUgdGhlIENvbGxhdGlvbkVsZW1lbnRzIHRhZ2dlZCBkYXRhLCBtZXJnZWQgd2l0aCB0aGUKICAvLyBkZWZhdWx0IHJ1bGVzLiAgSWYgdGhhdCBmYWlscywgdXNlIHRoZSBkZWZhdWx0IHJ1bGVzIGFsb25lLgoKICBjb2xTdHJpbmcuaW5zZXJ0KDAsIERFRkFVTFRSVUxFUyk7CiAgaWYoY29sU3RyaW5nLmlzQm9ndXMoKSkgewogICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgIHJldHVybjsKICB9CiAgICAKICBjb25zdHJ1Y3RGcm9tUnVsZXMoY29sU3RyaW5nLCBpbnRTdGF0dXMpOwogIGlmKGludFN0YXR1cyA9PSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSB7CiAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgcmV0dXJuOwogIH0KICAKICBpZihpbnRTdGF0dXMgIT0gVV9aRVJPX0VSUk9SKSAgewogICAgc3RhdHVzID0gVV9VU0lOR19ERUZBVUxUX0VSUk9SOwogICAgICAKICAgIC8vIHByZWRlZmluZWQgdGFibGVzIHNob3VsZCBjb250YWluIGNvcnJlY3QgZ3JhbW1hcgogICAgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgY29uc3RydWN0RnJvbVJ1bGVzKERFRkFVTFRSVUxFUywgaW50U3RhdHVzKTsKICAgIGlmKGludFN0YXR1cyAhPSBVX1pFUk9fRVJST1IpIHsKICAgICAgc3RhdHVzID0gaW50U3RhdHVzOwogICAgfQogIH0gCiAgCiNpZmRlZiBDT0xMREVCVUcKICBjZXJyIDw8IGxvY2FsZUZpbGVOYW1lIDw8ICIgYXNjaWkgbG9hZCAiIDw8IChVX1NVQ0NFU1Moc3RhdHVzKSA/ICJPSyIgOiAiRmFpbGVkIikgPDwgIiAtIHRyeT0gIiA8PCAodHJ5QmluYXJ5RmlsZT8idHJ1ZSI6ImZhbHNlIikgPDwgZW5kbDsKI2VuZGlmCgp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6flJ1bGVCYXNlZENvbGxhdG9yKCkKewogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgfQoKICAgIGRhdGEgPSAwOwoKICAgIC8vICAgIGRlbGV0ZSBzb3VyY2VDdXJzb3I7CiAgICAvLyAgICBzb3VyY2VDdXJzb3IgPSAwOwoKICAgIC8vICAgIGRlbGV0ZSB0YXJnZXRDdXJzb3I7CiAgICAvLyAgICB0YXJnZXRDdXJzb3IgPSAwOwoKICAgIGlmIChjdXJzb3IxICE9IE5VTEwpIHsKICAgICAgICBkZWxldGUgY3Vyc29yMTsKICAgICAgICBjdXJzb3IxID0gMDsKICAgIH0KICAgIGlmIChjdXJzb3IyICE9IE5VTEwpIHsKICAgICAgICBkZWxldGUgY3Vyc29yMjsKICAgICAgICBjdXJzb3IyID0gMDsKICAgIH0KCiAgICBkZWxldGUgbVBhdHRlcm47CiAgICBtUGF0dGVybiA9IDA7Cn0KCkNvbGxhdG9yKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y2xvbmUoKSBjb25zdAp7CiAgICByZXR1cm4gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKCp0aGlzKTsKfQoKLy8gQ3JlYXRlIGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG9iamVjdCB0aGF0IHdpbGwgaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMKLy8gaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UpIGNvbnN0CnsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpuZXdDdXJzb3IgPSAwOwoKICAgIG5ld0N1cnNvciA9IG5ldyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlLCB0aGlzLCBzdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiBuZXdDdXJzb3I7Cn0KCi8vIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzCi8vIGluIGEgc3RyaW5nLCB1c2luZyB0aGUgY29sbGF0aW9uIHJ1bGVzIGRlZmluZWQgaW4gdGhpcyBSdWxlQmFzZWRDb2xsYXRvcgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZSkgY29uc3QKewogICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgKm5ld0N1cnNvciA9IDA7CgogICAgbmV3Q3Vyc29yID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIG5ld0N1cnNvcjsKfQoKLy8gUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgY29sbGF0b3IncyBydWxlcy4KLy8gVGhlIHN0cmluZyBjYW4gbGF0ZXIgYmUgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGEKLy8gVW5pY29kZVN0cmluZyBhcmd1bWVudCwgd2hpY2ggd2lsbCBjb25zdHJ1Y3QgYSBjb2xsYXRvciB0aGF0J3MKLy8gZnVuY3Rpb25hbGx5IGlkZW50aWNhbCB0byB0aGlzIG9uZS4KLy8gWW91IGNhbiBhbHNvIGFsbG93IHVzZXJzIHRvIGVkaXQgdGhlIHN0cmluZyBpbiBvcmRlciB0byBjaGFuZ2UKLy8gdGhlIGNvbGxhdGlvbiBkYXRhLCBvciB5b3UgY2FuIHByaW50IGl0IG91dCBmb3IgaW5zcGVjdGlvbiwgb3Igd2hhdGV2ZXIuCgpjb25zdCBVbmljb2RlU3RyaW5nJgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0UnVsZXMoKSBjb25zdAp7CiAgICBpZiAobVBhdHRlcm4gIT0gMCkKICAgIHsKICAgICAgICBNZXJnZUNvbGxhdGlvbiomIG5vbkNvbnN0TVBhdHRlcm4gPSAqKE1lcmdlQ29sbGF0aW9uKiopJm1QYXR0ZXJuOwogICAgICAgIG1QYXR0ZXJuLT5lbWl0UGF0dGVybihkYXRhLT5ydWxlVGFibGUpOwogICAgICAgIGRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkID0gVFJVRTsKICAgICAgICBkZWxldGUgbm9uQ29uc3RNUGF0dGVybjsKICAgICAgICBub25Db25zdE1QYXR0ZXJuID0gMDsKICAgIH0KICAgIGVsc2UgaWYgKCFkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCkKICAgIHsKICAgICAgICAvLyBBdCB0aGlzIHBvaW50IHRoZSBjYWxsZXIgd2FudHMgdGhlIHJ1bGVzLCBidXQgdGhlIHJ1bGUgdGFibGUgZGF0YQogICAgICAgIC8vIGlzIG5vdCBsb2FkZWQuICBGdXJ0aGVybW9yZSwgdGhlcmUgaXMgbm8gbVBhdHRlcm4gb2JqZWN0IHRvIGxvYWQKICAgICAgICAvLyB0aGUgcnVsZXMgZnJvbS4gIFRoZXJlZm9yZSwgd2UgZmV0Y2ggdGhlIHJ1bGVzIG9mZiB0aGUgZGlzay4KICAgICAgICAvLyBOb3RpY2UgdGhhdCB3ZSBwYXNzIGluIGEgdHJ5QmluYXJ5RmlsZSB2YWx1ZSBvZiBGQUxTRSwgc2luY2UKICAgICAgICAvLyBieSBkZXNpZ24gdGhlIGJpbmFyeSBmaWxlIGhhcyBOTyBydWxlcyBpbiBpdCEKICAgICAgICAvL1VFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICAgIC8vUnVsZUJhc2VkQ29sbGF0b3IgdGVtcChkYXRhLT5yZWFsTG9jYWxlTmFtZSwgc3RhdHVzKTsKICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciB0ZW1wOwogICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICAgIHRlbXAuY29uc3RydWN0RnJvbUZpbGUoZGF0YS0+ZGVzaXJlZExvY2FsZSwgZGF0YS0+cmVhbExvY2FsZU5hbWUsIEZBTFNFLCBzdGF0dXMpOwoKICAgICAgICAvLyBXZSBtdXN0IGNoZWNrIHRoYXQgbVBhdHRlcm4gaXMgbm9uemVybyBoZXJlLCBvciB3ZSBydW4gdGhlIHJpc2sKICAgICAgICAvLyBvZiBhbiBpbmZpbml0ZSBsb29wLgogICAgICAgIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSAmJiB0ZW1wLm1QYXR0ZXJuICE9IDApCiAgICAgICAgewogICAgICAgICAgICBkYXRhLT5ydWxlVGFibGUgPSB0ZW1wLmdldFJ1bGVzKCk7CiAgICAgICAgICAgIGRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkID0gVFJVRTsKI2lmZGVmIF9ERUJVRwovLyAgICAgICAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBpcyB1c2VmdWwgZm9yIHNwZWNpZmljIGRlYnVnZ2luZyBwdXJwb3NlcwovLyAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgbmFtZTsKLy8gICAgICAgICAgICAgICBjZXJyIDw8ICJUYWJsZSBjb2xsYXRpb24gcnVsZXMgbG9hZGVkIGR5bmFtaWNhbGx5IGZvciAiCi8vICAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPmRlc2lyZWRMb2NhbGUuZ2V0TmFtZShuYW1lKQovLyAgICAgICAgICAgICAgICAgICA8PCAiIGF0ICIKLy8gICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+cmVhbExvY2FsZU5hbWUKLy8gICAgICAgICAgICAgICAgICAgPDwgIiwgIiA8PCBkZWMgPDwgZGF0YS0+cnVsZVRhYmxlLnNpemUoKSA8PCAiIGNoYXJhY3RlcnMiCi8vICAgICAgICAgICAgICAgICAgIDw8IGVuZGw7CiNlbmRpZgogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewojaWZkZWYgX0RFQlVHCi8vICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIG5hbWU7Ci8vICAgICAgICAgICAgICBjZXJyIDw8ICJVbmFibGUgdG8gbG9hZCB0YWJsZSBjb2xsYXRpb24gcnVsZXMgZHluYW1pY2FsbHkgZm9yICIKLy8gICAgICAgICAgICAgICAgICA8PCBkYXRhLT5kZXNpcmVkTG9jYWxlLmdldE5hbWUobmFtZSkKLy8gICAgICAgICAgICAgICAgICA8PCAiIGF0ICIKLy8gICAgICAgICAgICAgICAgICA8PCBkYXRhLT5yZWFsTG9jYWxlTmFtZQovLyAgICAgICAgICAgICAgICAgIDw8IGVuZGw7Ci8vICAgICAgICAgICAgICBjZXJyIDw8ICJTdGF0dXMgIiA8PCB1X2Vycm9yTmFtZShzdGF0dXMpIDw8ICIsIG1QYXR0ZXJuICIgPDwgdGVtcC5tUGF0dGVybiA8PCBlbmRsOwojZW5kaWYKICAgICAgICAgICAgLyogU1JMIGhhdmUgdG8gYWRkIHRoaXMgYmVjYXVzZSB3ZSBub3cgaGF2ZSB0aGUgc2l0dWF0aW9uIHdoZXJlCiAgICAgICAgICAgICAgIERFRkFVTFQgaXMgbG9hZGVkIGZyb20gYSBiaW5hcnkgZmlsZSB3LyBubyBydWxlcy4gKi8KICAgICAgICAgICAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgICAgIHRlbXAuY29uc3RydWN0RnJvbVJ1bGVzKFJ1bGVCYXNlZENvbGxhdG9yOjpERUZBVUxUUlVMRVMsIGludFN0YXR1cyk7CgogICAgICAgICAgICBpZihVX1NVQ0NFU1MoaW50U3RhdHVzKSAmJiAodGVtcC5tUGF0dGVybiAhPSAwKSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkYXRhLT5ydWxlVGFibGUgPSB0ZW1wLmdldFJ1bGVzKCk7CiAgICAgICAgICAgICAgICBkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CiAgICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZGF0YS0+cnVsZVRhYmxlOwp9CgoKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0ClJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKCBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3QKewogICAgVW5pY29kZVN0cmluZyBzb3VyY2VfdG9nbzsKICAgIFVuaWNvZGVTdHJpbmcgdGFyZ2V0X3RvZ287CiAgICBVVGV4dE9mZnNldCBiZWdpbj0wOwoKICAgIHNvdXJjZS5leHRyYWN0KGJlZ2luLCB1cHJ2X21pbihsZW5ndGgsc291cmNlLmxlbmd0aCgpKSwgc291cmNlX3RvZ28pOwogICAgdGFyZ2V0LmV4dHJhY3QoYmVnaW4sIHVwcnZfbWluKGxlbmd0aCx0YXJnZXQubGVuZ3RoKCkpLCB0YXJnZXRfdG9nbyk7CiAgICByZXR1cm4gKFJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKHNvdXJjZV90b2dvLCB0YXJnZXRfdG9nbykpOwp9CgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgICAKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoY29uc3QgICBVQ2hhciogc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVQ2hhciogIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGFyZ2V0TGVuZ3RoKSBjb25zdAp7CiAgICAvLyBjaGVjayBpZiBzb3VyY2UgYW5kIHRhcmdldCBhcmUgdmFsaWQgc3RyaW5ncwogICAgaWYgKCgoc291cmNlID09IDApICYmICh0YXJnZXQgPT0gMCkpIHx8CiAgICAgICAgKChzb3VyY2VMZW5ndGggPT0gMCkgJiYgKHRhcmdldExlbmd0aCA9PSAwKSkpCiAgICB7CiAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgIH0KCiAgICBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gQ29sbGF0b3I6OkVRVUFMOwogICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CgogICAgaWYgKGN1cnNvcjEgPT0gTlVMTCkKICAgIHsKICAgICAgICAoKFJ1bGVCYXNlZENvbGxhdG9yICopdGhpcyktPmN1cnNvcjEgPSBuZXcgTm9ybWFsaXplckl0ZXJhdG9yKHNvdXJjZSwgc291cmNlTGVuZ3RoLCBnZXREZWNvbXBvc2l0aW9uKCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGN1cnNvcjEtPnNldE1vZGVBbmRUZXh0KGdldERlY29tcG9zaXRpb24oKSwgc291cmNlLCBzb3VyY2VMZW5ndGgsIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKCAvKmN1cnNvcjEtPmN1cnNvciA9PSBOVUxMIHx8Ki8gVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgIH0KCiAgICBpZiAoY3Vyc29yMiA9PSBOVUxMKQogICAgewogICAgICAgICgoUnVsZUJhc2VkQ29sbGF0b3IgKil0aGlzKS0+Y3Vyc29yMiA9IG5ldyBOb3JtYWxpemVySXRlcmF0b3IodGFyZ2V0LCB0YXJnZXRMZW5ndGgsIGdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgY3Vyc29yMi0+c2V0TW9kZUFuZFRleHQoZ2V0RGVjb21wb3NpdGlvbigpLCB0YXJnZXQsIHRhcmdldExlbmd0aCwgc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoLypjdXJzb3IyID09IE5VTEwgfHwqLyBVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIGludDMyX3Qgc09yZGVyLCB0T3JkZXI7CiAgICAvLyAgICBpbnQzMl90IHNPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSLCB0T3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUjsKICAgIFVCb29sIGdldHMgPSBUUlVFLCBnZXR0ID0gVFJVRTsKICAgIFVCb29sIGluaXRpYWxDaGVja1NlY1RlciA9IGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlNFQ09OREFSWTsKICAgIFVCb29sIGNoZWNrU2VjVGVyID0gaW5pdGlhbENoZWNrU2VjVGVyOwogICAgVUJvb2wgY2hlY2tUZXJ0aWFyeSA9IGdldFN0cmVuZ3RoKCkgPj0gQ29sbGF0b3I6OlRFUlRJQVJZOwogICAgVUJvb2wgaXNGcmVuY2hTZWMgPSBkYXRhLT5pc0ZyZW5jaFNlYzsKICAgIHVpbnQzMl90IHBTT3JkZXIsIHBUT3JkZXI7CgogICAgZm9yKDs7KQogICAgewogICAgICAgIC8vIEdldCB0aGUgbmV4dCBjb2xsYXRpb24gZWxlbWVudCBpbiBlYWNoIG9mIHRoZSBzdHJpbmdzLCB1bmxlc3MKICAgICAgICAvLyB3ZSd2ZSBiZWVuIHJlcXVlc3RlZCB0byBza2lwIGl0LgogICAgICAgIGlmIChnZXRzKQogICAgICAgIHsKICAgICAgICAgICAgc09yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcigoTm9ybWFsaXplckl0ZXJhdG9yKiljdXJzb3IxLCBzdGF0dXMpOwoKICAgICAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBnZXRzID0gVFJVRTsKCiAgICAgICAgaWYgKGdldHQpCiAgICAgICAgewogICAgICAgICAgICB0T3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjIsIHN0YXR1cyk7CgogICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZ2V0dCA9IFRSVUU7CgogICAgICAgIC8vIElmIHdlJ3ZlIGhpdCB0aGUgZW5kIG9mIG9uZSBvZiB0aGUgc3RyaW5ncywganVtcCBvdXQgb2YgdGhlIGxvb3AKICAgICAgICBpZiAoKHNPcmRlciA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUil8fAogICAgICAgICAgICAodE9yZGVyID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKSkKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgdGhlcmUncyBubyBkaWZmZXJlbmNlIGF0IHRoaXMgcG9zaXRpb24sIHdlIGNhbiBza2lwIHRvIHRoZQogICAgICAgIC8vIG5leHQgb25lLgogICAgICAgIHBTT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcihzT3JkZXIpOwogICAgICAgIHBUT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcih0T3JkZXIpOwogICAgICAgIGlmIChzT3JkZXIgPT0gdE9yZGVyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlzRnJlbmNoU2VjICYmIHBTT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBpbiBmcmVuY2gsIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UgbW9yZSB0byB0aGUgcmlnaHQgaXMgc3Ryb25nZXIsCiAgICAgICAgICAgICAgICAgICAgLy8gc28gYWNjZW50cyBoYXZlIHRvIGJlIGNoZWNrZWQgd2l0aCBlYWNoIGJhc2UgZWxlbWVudAogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gaW5pdGlhbENoZWNrU2VjVGVyOwoKICAgICAgICAgICAgICAgICAgICAvLyBidXQgdGVydGlhcnkgZGlmZmVyZW5jZXMgYXJlIGxlc3MgaW1wb3J0YW50IHRoYW4gdGhlIGZpcnN0IAogICAgICAgICAgICAgICAgICAgIC8vIHNlY29uZGFyeSBkaWZmZXJlbmNlLCBzbyBjaGVja2luZyB0ZXJ0aWFyeSByZW1haW5zIGRpc2FibGVkCiAgICAgICAgICAgICAgICAgICAgY2hlY2tUZXJ0aWFyeSA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIC8vIENvbXBhcmUgcHJpbWFyeSBkaWZmZXJlbmNlcyBmaXJzdC4KICAgICAgICBpZiAocFNPcmRlciAhPSBwVE9yZGVyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHNPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBUaGUgZW50aXJlIHNvdXJjZSBlbGVtZW50IGlzIGlnbm9yYWJsZS4KICAgICAgICAgICAgICAgIC8vIFNraXAgdG8gdGhlIG5leHQgc291cmNlIGVsZW1lbnQsIGJ1dCBkb24ndCBmZXRjaCBhbm90aGVyIHRhcmdldCBlbGVtZW50LgogICAgICAgICAgICAgICAgZ2V0dCA9IEZBTFNFOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0T3JkZXIgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ2V0cyA9IEZBTFNFOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRoZSBzb3VyY2UgYW5kIHRhcmdldCBlbGVtZW50cyBhcmVuJ3QgaWdub3JhYmxlLCBidXQgaXQncyBzdGlsbCBwb3NzaWJsZQogICAgICAgICAgICAvLyBmb3IgdGhlIHByaW1hcnkgY29tcG9uZW50IG9mIG9uZSBvZiB0aGUgZWxlbWVudHMgdG8gYmUgaWdub3JhYmxlLi4uLgogICAgICAgICAgICBpZiAocFNPcmRlciA9PSAwKSAgLy8gcHJpbWFyeSBvcmRlciBpbiBzb3VyY2UgaXMgaWdub3JhYmxlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBzb3VyY2UncyBwcmltYXJ5IGlzIGlnbm9yYWJsZSwgYnV0IHRoZSB0YXJnZXQncyBpc24ndC4gIFdlIHRyZWF0IGlnbm9yYWJsZXMKICAgICAgICAgICAgICAgIC8vIGFzIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UsIHNvIHJlbWVtYmVyIHRoYXQgd2UgZm91bmQgb25lLgogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFNraXAgdG8gdGhlIG5leHQgc291cmNlIGVsZW1lbnQsIGJ1dCBkb24ndCBmZXRjaCBhbm90aGVyIHRhcmdldCBlbGVtZW50LgogICAgICAgICAgICAgICAgZ2V0dCA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHBUT3JkZXIgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gcmVjb3JkIGRpZmZlcmVuY2VzIC0gc2VlIHRoZSBjb21tZW50IGFib3ZlLgogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFNraXAgdG8gdGhlIG5leHQgdGFyZ2V0IGVsZW1lbnQsIGJ1dCBkb24ndCBmZXRjaCBhbm90aGVyIHNvdXJjZSBlbGVtZW50LgogICAgICAgICAgICAgICAgZ2V0cyA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gTmVpdGhlciBvZiB0aGUgb3JkZXJzIGlzIGlnbm9yYWJsZSwgYW5kIHdlIGFscmVhZHkga25vdyB0aGF0IHRoZSBwcmltYXJ5CiAgICAgICAgICAgICAgICAvLyBvcmRlcnMgYXJlIGRpZmZlcmVudCBiZWNhdXNlIG9mIHRoZSAocFNPcmRlciAhPSBwVE9yZGVyKSB0ZXN0IGFib3ZlLgogICAgICAgICAgICAgICAgLy8gUmVjb3JkIHRoZSBkaWZmZXJlbmNlIGFuZCBzdG9wIHRoZSBjb21wYXJpc29uLgogICAgICAgICAgICAgICAgaWYgKHBTT3JkZXIgPCBwVE9yZGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6TEVTUzsgIC8vIChzdHJlbmd0aCBpcyBQUklNQVJZKQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsgIC8vIChzdHJlbmd0aCBpcyBQUklNQVJZKQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7IC8vIGVsc2Ugb2YgaWYgKCBwU09yZGVyICE9IHBUT3JkZXIgKQogICAgICAgICAgICAvLyBwcmltYXJ5IG9yZGVyIGlzIHRoZSBzYW1lLCBidXQgY29tcGxldGUgb3JkZXIgaXMgZGlmZmVyZW50LiBTbyB0aGVyZQogICAgICAgICAgICAvLyBhcmUgbm8gYmFzZSBlbGVtZW50cyBhdCB0aGlzIHBvaW50LCBvbmx5IGlnbm9yYWJsZXMgKFNpbmNlIHRoZSBzdHJpbmdzIGFyZQogICAgICAgICAgICAvLyBub3JtYWxpemVkKQoKICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBhIHNlY29uZGFyeSBvciB0ZXJ0aWFyeSBkaWZmZXJlbmNlIG1heSBzdGlsbCBtYXR0ZXIKICAgICAgICAgICAgICAgIHVpbnQzMl90IHNlY1NPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIoc09yZGVyKTsKICAgICAgICAgICAgICAgIHVpbnQzMl90IHNlY1RPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIodE9yZGVyKTsKCiAgICAgICAgICAgICAgICBpZiAoc2VjU09yZGVyICE9IHNlY1RPcmRlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBpcyBhIHNlY29uZGFyeSBkaWZmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHNlY1NPcmRlciA8IHNlY1RPcmRlcikgPyBDb2xsYXRvcjo6TEVTUyA6IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsgCiAgICAgICAgICAgICAgICAgICAgLy8gKGV2ZW4gaW4gZnJlbmNoLCBvbmx5IHRoZSBmaXJzdCBzZWNvbmRhcnkgZGlmZmVyZW5jZSB3aXRoaW4KICAgICAgICAgICAgICAgICAgICAvLyAgYSBiYXNlIGNoYXJhY3RlciBtYXR0ZXJzKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjaGVja1RlcnRpYXJ5KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIG1heSBzdGlsbCBtYXR0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdGVyU09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKHNPcmRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHRlclRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcih0T3JkZXIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlclNPcmRlciAhPSB0ZXJUT3JkZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIGEgdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHRlclNPcmRlciA8IHRlclRPcmRlcikgPyBDb2xsYXRvcjo6TEVTUyA6IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIChzdHJlbmd0aCBpcyBURVJUSUFSWSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrVGVydGlhcnkgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAvLyBpZiAoY2hlY2tTZWNUZXIpCgogICAgICAgIH0gIC8vIGlmICggcFNPcmRlciAhPSBwVE9yZGVyICkKICAgIH0gLy8gd2hpbGUoKQoKICAgIGlmIChzT3JkZXIgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgLy8gKHRPcmRlciBtdXN0IGJlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSLAogICAgICAgIC8vICBzaW5jZSB0aGlzIHBvaW50IGlzIG9ubHkgcmVhY2hlZCB3aGVuIHNPcmRlciBvciB0T3JkZXIgaXMgTlVMTE9SREVSLikKICAgICAgICAvLyBUaGUgc291cmNlIHN0cmluZyBoYXMgbW9yZSBlbGVtZW50cywgYnV0IHRoZSB0YXJnZXQgc3RyaW5nIGhhc24ndC4KICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHNPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gV2UgZm91bmQgYW4gYWRkaXRpb25hbCBub24taWdub3JhYmxlIGJhc2UgY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHByaW1hcnkgZGlmZmVyZW5jZSwgc28gdGhlIHNvdXJjZSBpcyBncmVhdGVyCiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkdSRUFURVI7IC8vIChzdHJlbmd0aCBpcyBQUklNQVJZKQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihzT3JkZXIpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEFkZGl0aW9uYWwgc2Vjb25kYXJ5IGVsZW1lbnRzIG1lYW4gdGhlIHNvdXJjZSBzdHJpbmcgaXMgZ3JlYXRlcgogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHNPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoY3Vyc29yMSwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQogICAgZWxzZSBpZiAodE9yZGVyICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIC8vIFRoZSB0YXJnZXQgc3RyaW5nIGhhcyBtb3JlIGVsZW1lbnRzLCBidXQgdGhlIHNvdXJjZSBzdHJpbmcgaGFzbid0LgogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIodE9yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhbiBhZGRpdGlvbmFsIG5vbi1pZ25vcmFibGUgYmFzZSBjaGFyYWN0ZXIgaW4gdGhlIHRhcmdldCBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcHJpbWFyeSBkaWZmZXJlbmNlLCBzbyB0aGUgc291cmNlIGlzIGxlc3MKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6TEVTUzsgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHRPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBzZWNvbmRhcnkgZWxlbWVudHMgaW4gdGhlIHRhcmdldCBtZWFuIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGxlc3MKICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6TEVTUzsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAKICAgICAgICB9CiAgICAgICAgd2hpbGUgKCh0T3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKGN1cnNvcjIsIHN0YXR1cykpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKTsKICAgIH0KCgogICAgLy8gRm9yIElERU5USUNBTCBjb21wYXJpc29ucywgd2UgdXNlIGEgYml0d2lzZSBjaGFyYWN0ZXIgY29tcGFyaXNvbgogICAgLy8gYXMgYSB0aWVicmVha2VyIGlmIGFsbCBlbHNlIGlzIGVxdWFsCiAgICAvLyBOT1RFOiBUaGUgamF2YSBjb2RlIGNvbXBhcmVzIHJlc3VsdCB3aXRoIDAsIGFuZCAKICAgIC8vIHB1dHMgdGhlIHJlc3VsdCBvZiB0aGUgc3RyaW5nIGNvbXBhcmlzb24gZGlyZWN0bHkgaW50byByZXN1bHQKICAgIGlmIChyZXN1bHQgPT0gQ29sbGF0b3I6OkVRVUFMICYmIGdldFN0cmVuZ3RoKCkgPT0gSURFTlRJQ0FMKQogICAgewojaWYgMAogICAgICAvLyAqKioqKioqKiBmb3IgdGhlICBVQ2hhciBub3JtYWxpemF0aW9uIGludGVyZmFjZS4KICAgICAgLy8gSXQgZG9lc24ndCB3b3JrIG11Y2ggZmFzdGVyLCBhbmQgdGhlIGNvZGUgd2FzIGJyb2tlbgogICAgICAvLyBzbyBpdCdzIGNvbW1lbnRlZCBvdXQuIC0tc3JsCi8vICAgICAgICAgIFVDaGFyIHNvdXJjZURlY29tcFsxMDI0XSwgdGFyZ2V0RGVjb21wWzEwMjRdOwovLyAgICAgICAgICBpbnQzMl90IHNvdXJjZURlY29tcExlbmd0aCA9IDEwMjQ7Ci8vICAgICAgICAgIGludDMyX3QgdGFyZ2V0RGVjb21wTGVuZ3RoID0gMTAyNDsKCi8vICAgICAgICAgIGludDhfdCBjb21wYXJpc29uOwovLyAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBNb2RlID0gZ2V0RGVjb21wb3NpdGlvbigpOwoKLy8gICAgICAgICAgaWYgKGRlY29tcE1vZGUgIT0gTm9ybWFsaXplcjo6Tk9fT1ApCi8vICAgICAgICAgICAgewovLyAgICAgICAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHNvdXJjZSwgc291cmNlTGVuZ3RoLCBkZWNvbXBNb2RlLAovLyAgICAgICAgICAgICAgICAgICAgICAgIDAsIHNvdXJjZURlY29tcCwgc291cmNlRGVjb21wTGVuZ3RoLCBzdGF0dXMpOwoKLy8gICAgICAgICAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZSh0YXJnZXQsIHRhcmdldExlbmd0aCwgZGVjb21wTW9kZSwKLy8gICAgICAgICAgICAgICAgICAgICAgICAwLCB0YXJnZXREZWNvbXAsIHRhcmdldERlY29tcExlbmd0aCwgc3RhdHVzKTsKCi8vICAgICAgICAgICAgICBjb21wYXJpc29uID0gdV9zdHJjbXAoc291cmNlRGVjb21wLHRhcmdldERlY29tcCk7Ci8vICAgICAgICAgICAgfQovLyAgICAgICAgICBlbHNlCi8vICAgICAgICAgICAgewovLyAgICAgICAgICAgICAgY29tcGFyaXNvbiA9IHVfc3RyY21wKHNvdXJjZSwgdGFyZ2V0KTsgLyogISAqLwovLyAgICAgICAgICAgIH0KCiNlbHNlCgogICAgICAgIFVuaWNvZGVTdHJpbmcgc291cmNlRGVjb21wLCB0YXJnZXREZWNvbXA7CgogICAgICAgIGludDhfdCBjb21wYXJpc29uOwogICAgICAgIAogICAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZShzb3VyY2UsIGdldERlY29tcG9zaXRpb24oKSwgCiAgICAgICAgICAgICAgICAgICAgICAwLCBzb3VyY2VEZWNvbXAsICBzdGF0dXMpOwoKICAgICAgICBOb3JtYWxpemVyOjpub3JtYWxpemUodGFyZ2V0LCBnZXREZWNvbXBvc2l0aW9uKCksIAogICAgICAgICAgICAgICAgICAgICAgMCwgdGFyZ2V0RGVjb21wLCAgc3RhdHVzKTsKICAgICAgICAKICAgICAgICBjb21wYXJpc29uID0gc291cmNlRGVjb21wLmNvbXBhcmUodGFyZ2V0RGVjb21wKTsKI2VuZGlmCgogICAgICAgIGlmIChjb21wYXJpc29uIDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChjb21wYXJpc29uID09IDApCiAgICAgICAgewogICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgoKaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6bmV4dENvbnRyYWN0Q2hhcihOb3JtYWxpemVySXRlcmF0b3IgKmN1cnNvciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0CnsKICAgIC8vIEZpcnN0IGdldCB0aGUgb3JkZXJpbmcgb2YgdGhpcyBzaW5nbGUgY2hhcmFjdGVyCiAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqbGlzdCA9IGdldENvbnRyYWN0VmFsdWVzKGNoKTsKICAgIEVudHJ5UGFpciAqcGFpciA9IChFbnRyeVBhaXIgKilsaXN0LT5hdCgwKTsKICAgIGludDMyX3Qgb3JkZXIgPSBwYWlyLT52YWx1ZTsKCiAgICAvLyBOb3cgaXRlcmF0ZSB0aHJvdWdoIHRoZSBjaGFycyBmb2xsb3dpbmcgaXQgYW5kCiAgICAvLyBsb29rIGZvciB0aGUgbG9uZ2VzdCBtYXRjaAogICAgKChVbmljb2RlU3RyaW5nJilrZXkpLnJlbW92ZSgpOwogICAgKChVbmljb2RlU3RyaW5nJilrZXkpICs9IGNoOwoKICAgIHdoaWxlICgoY2ggPSBjdXJzb3ItPmN1cnJlbnQoKSkgIT0gTm9ybWFsaXplcjo6RE9ORSkKICAgIHsKICAgICAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkgKz0gY2g7CgogICAgICAgIGludDMyX3QgbiA9IGdldEVudHJ5KGxpc3QsIGtleSwgVFJVRSk7CgogICAgICAgIGlmIChuID09IFVOTUFQUEVEKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGN1cnNvci0+bmV4dCgpOwoKICAgICAgICBwYWlyID0gKEVudHJ5UGFpciAqKWxpc3QtPmF0KG4pOwogICAgICAgIG9yZGVyID0gcGFpci0+dmFsdWU7CiAgICB9CgogICAgcmV0dXJuIG9yZGVyOwp9CgovLyBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoaXMgY29sbGF0b3IKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0ClJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdAp7CiAgICByZXR1cm4gY29tcGFyZShzb3VyY2UuZ2V0VUNoYXJzKCksIHNvdXJjZS5sZW5ndGgoKSwgdGFyZ2V0LmdldFVDaGFycygpLCB0YXJnZXQubGVuZ3RoKCkpOwp9CgovLyBSZXRyaWV2ZSBhIGNvbGxhdGlvbiBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgc3RyaW5nCi8vIFRoZSBrZXkgY2FuIGJlIGNvbXBhcmVkIHdpdGggb3RoZXIgY29sbGF0aW9uIGtleXMgdXNpbmcgYSBiaXR3aXNlIGNvbXBhcmlzb24KLy8gKGUuZy4gbWVtY21wKSB0byBmaW5kIHRoZSBvcmRlcmluZyBvZiB0aGVpciByZXNwZWN0aXZlIHNvdXJjZSBzdHJpbmdzLgovLyBUaGlzIGlzIGhhbmR5IHdoZW4gZG9pbmcgYSBzb3J0LCB3aGVyZSBlYWNoIHNvcnQga2V5IG11c3QgYmUgY29tcGFyZWQKLy8gbWFueSB0aW1lcy4KLy8KLy8gVGhlIGJhc2ljIGFsZ29yaXRobSBoZXJlIGlzIHRvIGZpbmQgYWxsIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgZm9yIGVhY2gKLy8gY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLCBjb252ZXJ0IHRoZW0gdG8gYW4gQVNDSUkgcmVwcmVzZW50YXRpb24sCi8vIGFuZCBwdXQgdGhlbSBpbnRvIHRoZSBjb2xsYXRpb24ga2V5LiAgQnV0IGl0J3MgdHJpY2tpZXIgdGhhbiB0aGF0LgovLyBFYWNoIGNvbGxhdGlvbiBlbGVtZW50IGluIGEgc3RyaW5nIGhhcyB0aHJlZSBjb21wb25lbnRzOiBwcmltYXJ5ICgnQScgdnMgJ0InKSwKLy8gc2Vjb25kYXJ5ICgndScgdnMgJ/wnKSwgYW5kIHRlcnRpYXJ5ICgnQScgdnMgJ2EnKSwgYW5kIGEgcHJpbWFyeSBkaWZmZXJlbmNlCi8vIGF0IHRoZSBlbmQgb2YgYSBzdHJpbmcgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5Ci8vIGRpZmZlcmVuY2UgZWFybGllciBpbiB0aGUgc3RyaW5nLgovLwovLyBUbyBhY2NvdW50IGZvciB0aGlzLCB3ZSBwdXQgYWxsIG9mIHRoZSBwcmltYXJ5IG9yZGVycyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZQovLyBzdHJpbmcsIGZvbGxvd2VkIGJ5IHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVycy4gRWFjaCBzZXQgb2Ygb3JkZXJzIGlzCi8vIHRlcm1pbmF0ZWQgYnkgbnVsbHMgc28gdGhhdCBhIGtleSBmb3IgYSBzdHJpbmcgd2hpY2ggaXMgYSBpbml0aWFsIHN1YnN0cmluZyBvZgovLyBhbm90aGVyIGtleSB3aWxsIGNvbXBhcmUgbGVzcyB3aXRob3V0IGFueSBzcGVjaWFsIGNhc2UuCi8vCi8vIEhlcmUncyBhIGh5cG90aGV0aWNhbCBleGFtcGxlLCB3aXRoIHRoZSBjb2xsYXRpb24gZWxlbWVudCByZXByZXNlbnRlZCBhcwovLyBhIHRocmVlLWRpZ2l0IG51bWJlciwgb25lIGRpZ2l0IGZvciBwcmltYXJ5LCBvbmUgZm9yIHNlY29uZGFyeSwgZXRjLgovLwovLyBTdHJpbmc6ICAgICAgICAgICAgICBBICAgICBhICAgICBCICAgIMkKLy8gQ29sbGF0aW9uIEVsZW1lbnRzOiAxMDEgICAxMDAgICAyMDEgIDUxMQovLyBDb2xsYXRpb24gS2V5OiAgICAgIDExMjU8bnVsbD4wMDAxPG51bGw+MTAxMTxudWxsPgovLwovLyBUbyBtYWtlIHRoaW5ncyBldmVuIHRyaWNraWVyLCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMgKGFjY2VudCBtYXJrcykgYXJlIGNvbXBhcmVkCi8vIHN0YXJ0aW5nIGF0IHRoZSAqZW5kKiBvZiB0aGUgc3RyaW5nIGluIGxhbmd1YWdlcyB3aXRoIEZyZW5jaCBzZWNvbmRhcnkgb3JkZXJpbmcuCi8vIEJ1dCB3aGVuIGNvbXBhcmluZyB0aGUgYWNjZW50IG1hcmtzIG9uIGEgc2luZ2xlIGJhc2UgY2hhcmFjdGVyLCB0aGV5IGFyZSBjb21wYXJlZAovLyBmcm9tIHRoZSBiZWdpbm5pbmcuICBUbyBoYW5kbGUgdGhpcywgd2UgcmV2ZXJzZSBhbGwgb2YgdGhlIGFjY2VudHMgdGhhdCBiZWxvbmcKLy8gdG8gZWFjaCBiYXNlIGNoYXJhY3RlciwgdGhlbiB3ZSByZXZlcnNlIHRoZSBlbnRpcmUgc3RyaW5nIG9mIHNlY29uZGFyeSBvcmRlcmluZ3MKLy8gYXQgdGhlIGVuZC4KLy8KQ29sbGF0aW9uS2V5JgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KCBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QKewogICAgcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoc291cmNlLmdldFVDaGFycygpLCBzb3VyY2UubGVuZ3RoKCksIHNvcnRrZXksIHN0YXR1cyk7Cn0KCkNvbGxhdGlvbktleSYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSggY29uc3QgICBVQ2hhciogIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICB9CiAgICAKICAgIGlmICgoIXNvdXJjZSkgfHwgKHNvdXJjZUxlbiA9PSAwKSkKICAgIHsKICAgICAgICByZXR1cm4gc29ydGtleS5yZXNldCgpOwogICAgfQoKICAgIGlmIChjdXJzb3IxID09IE5VTEwpCiAgICB7CiAgICAgICgoUnVsZUJhc2VkQ29sbGF0b3IgKil0aGlzKS0+Y3Vyc29yMSA9IG5ldyBOb3JtYWxpemVySXRlcmF0b3Ioc291cmNlLCBzb3VyY2VMZW4sIGdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIGN1cnNvcjEtPnNldE1vZGVBbmRUZXh0KGdldERlY29tcG9zaXRpb24oKSwgc291cmNlLHNvdXJjZUxlbiwgc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgfQoKICAgIFVCb29sICBjb21wYXJlU2VjICAgPSAoZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6U0VDT05EQVJZKTsKICAgIFVCb29sICBjb21wYXJlVGVyICAgPSAoZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6VEVSVElBUlkpOwogICAgVUJvb2wgIGNvbXBhcmVJZGVudCA9IChnZXRTdHJlbmd0aCgpID09IENvbGxhdG9yOjpJREVOVElDQUwpOwogICAgaW50MzJfdCBvcmRlciAgICAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbFByaW1hcnkgPSAwOwogICAgaW50MzJfdCB0b3RhbFNlYyAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbFRlciAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbElkZW50ICAgICA9IDA7CiAgICBVbmljb2RlU3RyaW5nIGRlY29tcDsKCiAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIHNvdXJjZSwgY291bnRpbmcgcHJpbWFyeSwgc2Vjb25kYXJ5LCBhbmQgdGVydGlhcnkgZW50cmllcwogICAgd2hpbGUoKG9yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcigoTm9ybWFsaXplckl0ZXJhdG9yKiljdXJzb3IxLCBzdGF0dXMpKSAhPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGludDMyX3Qgc2VjT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHRlck9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKG9yZGVyKTsKCiAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShvcmRlcikpCiAgICAgICAgewogICAgICAgICAgICB0b3RhbFByaW1hcnkgKz0gMTsKCiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxUZXIgKz0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29tcGFyZVNlYyAmJiBzZWNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlciAmJiB0ZXJPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFRlciArPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGNvdW50IHRoZSBudWxsIGJ5dGVzIGFmdGVyIHRoZSBlbnRpcmVzCiAgICB0b3RhbFByaW1hcnkgKz0gMTsKCiAgICBpZiAoY29tcGFyZVNlYykKICAgIHsKICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgfQoKICAgIGlmIChjb21wYXJlVGVyKQogICAgewogICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICB9CgogICAgaWYgKGNvbXBhcmVJZGVudCkKICAgIHsKICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHNvdXJjZSwgZ2V0RGVjb21wb3NpdGlvbigpLCAvLyBTUkw6ID8/CiAgICAgICAgICAgICAgICAwLCBkZWNvbXAsIHN0YXR1cyk7CgogICAgICAgIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHRvdGFsSWRlbnQgPSBkZWNvbXAubGVuZ3RoKCkgKyAxOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBDb21wdXRlIHRvdGFsIG51bWJlciBvZiBieXRlcyB0byBob2xkIHRoZSBlbnRyaWVzCiAgICAvLyBhbmQgbWFrZSBzdXJlIHRoZSBrZXkgY2FuIGhvbGQgdGhlbQogICAgdWludDMyX3Qgc2l6ZSAgID0gMiAqICh0b3RhbFByaW1hcnkgKyB0b3RhbFNlYyArIHRvdGFsVGVyICsgdG90YWxJZGVudCk7CgogICAgc29ydGtleS5lbnN1cmVDYXBhY2l0eShzaXplKTsKCiAgICBpZiAoc29ydGtleS5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm4gc29ydGtleTsKICAgIH0KCiAgICBpbnQzMl90IHByaW1hcnlDdXJzb3IgPSAwOwogICAgaW50MzJfdCBzZWNDdXJzb3IgICAgID0gMiAqIHRvdGFsUHJpbWFyeTsKICAgIGludDMyX3Qgc2VjQmFzZSAgICAgICA9IHNlY0N1cnNvcjsKICAgIGludDMyX3QgcHJlU2VjSWdub3JlICA9IHNlY0Jhc2U7CiAgICBpbnQzMl90IHRlckN1cnNvciAgICAgPSBzZWNDdXJzb3IgKyAoMiAqIHRvdGFsU2VjKTsKICAgIGludDMyX3QgaWRlbnRDdXJzb3IgICAgICA9IHRlckN1cnNvciArICgyICogdG90YWxUZXIpOwoKICAgIC8vIHJlc2V0IHNvdXJjZSB0byB0aGUgYmVnaW5uaW5nCiAgICBjdXJzb3IxLT5yZXNldCgpOwoKICAgIC8vIG5vdyBpdGVyYXRlIG92ZXIgdGhlIHNvdXJjZSBjb21wdXRpbmcgdGhlIGFjdHVhbCBlbnRyaWVzCiAgICB3aGlsZSgob3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cykpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CiAgICAgICAgfQoKICAgICAgICBpbnQzMl90IHByaW1hcnlPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHNlY09yZGVyICAgICA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIob3JkZXIpOwogICAgICAgIGludDMyX3QgdGVyT3JkZXIgICAgID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKG9yZGVyKTsKCiAgICAgICAgaWYgKCEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShvcmRlcikpCiAgICAgICAgewogICAgICAgICAgICBwcmltYXJ5Q3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHByaW1hcnlDdXJzb3IsIHByaW1hcnlPcmRlciArIFNPUlRLRVlPRkZTRVQpOwoKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChkYXRhLT5pc0ZyZW5jaFNlYyAmJiAocHJlU2VjSWdub3JlIDwgc2VjQ3Vyc29yKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzb3J0a2V5LnJldmVyc2VCeXRlcyhwcmVTZWNJZ25vcmUsIHNlY0N1cnNvcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgc2VjQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHNlY0N1cnNvciwgc2VjT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKCiAgICAgICAgICAgICAgICBwcmVTZWNJZ25vcmUgPSBzZWNDdXJzb3I7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZXJDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXModGVyQ3Vyc29yLCB0ZXJPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjICYmIHNlY09yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNlY0N1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIHNlY09yZGVyICsgZGF0YS0+bWF4U2VjT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIgJiYgdGVyT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVyQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHRlckN1cnNvciwgdGVyT3JkZXIgKyBkYXRhLT5tYXhUZXJPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGFwcGVuZCAwIGF0IHRoZSBlbmQgb2YgZWFjaCBwb3J0aW9uLgogICAgc29ydGtleS5zdG9yZUJ5dGVzKHByaW1hcnlDdXJzb3IsIDApOwoKICAgIGlmIChjb21wYXJlU2VjKQogICAgewogICAgICAgIGlmIChkYXRhLT5pc0ZyZW5jaFNlYykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmVTZWNJZ25vcmUgPCBzZWNDdXJzb3IpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHByZVNlY0lnbm9yZSwgc2VjQ3Vyc29yKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc29ydGtleS5yZXZlcnNlQnl0ZXMoc2VjQmFzZSwgc2VjQ3Vyc29yKTsKICAgICAgICB9CgogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlVGVyKQogICAgewogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlSWRlbnQpCiAgICB7CiAgICAgICAgc29ydGtleS5zdG9yZVVuaWNvZGVTdHJpbmcoaWRlbnRDdXJzb3IsIGRlY29tcCk7CiAgICB9CgogICAgLy8gICAgRGVidWdnaW5nIC0gcHJpbnQgb3V0IHRoZSBzb3J0a2V5IFstLXNybF0KLy8gICAgICB7Ci8vICAgICAgICBjb25zdCB1aW50OF90ICpieXRlczsKLy8gICAgICAgIGludDMyX3QgeGNvdW50OwovLyAgICAgICAgYnl0ZXMgPSBzb3J0a2V5LmdldEJ5dGVBcnJheSh4Y291bnQpOwovLyAgICAgICAgLy8gICAgICBmcHJpbnRmKHN0ZGVyciwgIlxuXG4tICBbJTAyWF0gWyUwMlhdXG5cbiIsIChpbnQpKGJ5dGVzWzBdJjB4RkYpLCAoaW50KShieXRlc1sxXSYweEZGKSApOwovLyAgICAgIH0KCiAgICByZXR1cm4gc29ydGtleTsKfQoKCi8vIEJ1aWxkIHRoaXMgY29sbGF0b3IncyBydWxlIHRhYmxlcyBiYXNlZCBvbiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcnVsZXMKLy8gU2VlIHRoZSBiaWcgZGlhZ3JhbSBhdCB0aGUgdG9wIG9mIHRoaXMgZmlsZSBmb3IgYW4gb3ZlcnZpZXcgb2YgaG93IHRoZSB0YWJsZXMKLy8gYXJlIG9yZ2FuaXplZC4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YnVpbGQoY29uc3QgVW5pY29kZVN0cmluZyYgICBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVGhpcyBhcnJheSBtYXBzIFVuaWNvZGUgY2hhcmFjdGVycyB0byB0aGVpciBjb2xsYXRpb24gb3JkZXJpbmcKICAgIGRhdGEtPm1hcHBpbmcgPSB1Y21wMzJfb3BlbihVTk1BUFBFRCk7CgogICAgaWYgKGRhdGEtPm1hcHBpbmctPmZCb2d1cykKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpbnQzMl90IGkgPSAwOwogICAgVW5pY29kZVN0cmluZyBsYXN0R3JvdXBDaGFyczsKICAgIFVuaWNvZGVTdHJpbmcgZXhwQ2hhcnM7CiAgICBVbmljb2RlU3RyaW5nIGdyb3VwQ2hhcnM7CgogICAgaWYgKHBhdHRlcm4ubGVuZ3RoKCkgPT0gMCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX0lOVkFMSURfRk9STUFUX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBCdWlsZCB0aGUgbWVyZ2VkIGNvbGxhdGlvbiBlbnRyaWVzCiAgICAvLyBTaW5jZSBydWxlcyBjYW4gYmUgc3BlY2lmaWVkIGluIGFueSBvcmRlciBpbiB0aGUgc3RyaW5nCiAgICAvLyAoZS5nLiAiYyAsIEMgPCBkICwgRCA8IGUgLCBFIC4uLi4gQyA8IENIIikKICAgIC8vIHRoaXMgc3BsaXRzIGFsbCBvZiB0aGUgcnVsZXMgaW4gdGhlIHN0cmluZyBvdXQgaW50byBzZXBhcmF0ZQogICAgLy8gb2JqZWN0cyBhbmQgdGhlbiBzb3J0cyB0aGVtLiAgSW4gdGhlIGFib3ZlIGV4YW1wbGUsIGl0IG1lcmdlcyB0aGUKICAgIC8vICJDIDwgQ0giIHJ1bGUgaW4ganVzdCBiZWZvcmUgdGhlICJDIDwgRCIgcnVsZS4KCiAgICBtUGF0dGVybiA9IG5ldyBNZXJnZUNvbGxhdGlvbihwYXR0ZXJuLCBnZXREZWNvbXBvc2l0aW9uKCksIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgdWNtcDMyX2Nsb3NlKGRhdGEtPm1hcHBpbmcpOwogICAgICAgIGRhdGEtPm1hcHBpbmcgPSAwOwogICAgICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgICAgICBtUGF0dGVybiA9IDA7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGludDMyX3Qgb3JkZXIgPSAwOwoKICAgIC8vIFdhbGsgdGhyb3VnaCBlYWNoIGVudHJ5CiAgICBmb3IgKGkgPSAwOyBpIDwgbVBhdHRlcm4tPmdldENvdW50KCk7ICsraSkKICAgIHsKICAgICAgICBjb25zdCBQYXR0ZXJuRW50cnkqIGVudHJ5ID0gbVBhdHRlcm4tPmdldEl0ZW1BdChpKTsKICAgICAgICBncm91cENoYXJzLnJlbW92ZSgpOwogICAgICAgIGV4cENoYXJzLnJlbW92ZSgpOwoKICAgICAgICAvLyBpZiBlbnRyeSBpcyB2YWxpZAogICAgICAgIGlmIChlbnRyeSAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgZW50cnktPmdldENoYXJzKGdyb3VwQ2hhcnMpOwoKICAgICAgICAgICAgLy8gY2hlY2sgaWYgZnJlbmNoIHNlY29uZGFyeSBuZWVkcyB0byBiZSB0dXJuZWQgb24KICAgICAgICAgICAgaWYgKChncm91cENoYXJzLmxlbmd0aCgpID4gMSkgJiYKICAgICAgICAgICAgICAgIChncm91cENoYXJzW2dyb3VwQ2hhcnMubGVuZ3RoKCktMV0gPT0gMHgwMDQwKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YS0+aXNGcmVuY2hTZWMgPSBUUlVFOwogICAgICAgICAgICAgICAgZ3JvdXBDaGFycy5yZW1vdmUoZ3JvdXBDaGFycy5sZW5ndGgoKS0xKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgb3JkZXIgPSBpbmNyZW1lbnQoKENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGgpZW50cnktPmdldFN0cmVuZ3RoKCksIG9yZGVyKTsKCiAgICAgICAgICAgIGlmIChlbnRyeS0+Z2V0RXh0ZW5zaW9uKGV4cENoYXJzKS5sZW5ndGgoKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhbiBleHBhbmRpbmcgY2hhcmFjdGVyLCB3aGVyZSBvbmUgY2hhcmFjdGVyIG9uIGlucHV0CiAgICAgICAgICAgICAgICAvLyBleHBhbmRzIHRvIHNldmVyYWwgc29ydCBlbGVtZW50cyAoZS5nLiAn9icgLS0+ICdvJyAnZScpCiAgICAgICAgICAgICAgICBhZGRFeHBhbmRPcmRlcihncm91cENoYXJzLCBleHBDaGFycywgb3JkZXIsIHN0YXR1cyk7CiAgICAgICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGdyb3VwQ2hhcnMubGVuZ3RoKCkgPiAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBlbmNvdW50ZXJlZCBhIGNvbnRyYWN0aW5nIGNoYXJhY3Rlciwgd2hlcmUgc2V2ZXJhbCBjaGFyYWN0ZXJzIG9uIGlucHV0CiAgICAgICAgICAgICAgICAvLyBjb250cmFjdCBpbnRvIG9uZSBzb3J0IG9yZGVyLiAgRm9yIGV4YW1wbGUsICJjaCIgaXMgdHJlYXRlZCBhcyBhIHNpbmdsZQogICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyIGluIHRyYWRpdGlvbmFsIFNwYW5pc2ggc29ydGluZy4KICAgICAgICAgICAgICAgIGFkZENvbnRyYWN0T3JkZXIoZ3JvdXBDaGFycywgb3JkZXIsIHN0YXR1cyk7CiAgICAgICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gTm90aGluZyBvdXQgb2YgdGhlIG9yZGluYXJ5IC0tIG9uZSBjaGFyYWN0ZXIgbWFwcyB0byBvbmUgc29ydCBvcmRlcgogICAgICAgICAgICAgICAgYWRkT3JkZXIoZ3JvdXBDaGFyc1swXSwgb3JkZXIsIHN0YXR1cyk7CiAgICAgICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGFkZCBleHBhbmRpbmcgZW50cmllcyBmb3IgcHJlLWNvbXBvc2VkIGNoYXJhY3RlcnMKICAgIGFkZENvbXBvc2VkQ2hhcnMoKTsKCiAgICAvLyBGaWxsIGluIGFsbCB0aGUgZXhwYW5kaW5nIGNoYXJzIHZhbHVlcwogICAgY29tbWl0KCk7CgogICAgLy8gQ29tcGFjdCB0aGUgZGF0YSBtYXBwaW5nIHRhYmxlCiAgICB1Y21wMzJfY29tcGFjdChkYXRhLT5tYXBwaW5nLCAxKTsKfQoKLyoqCiAqIEFkZCBleHBhbmRpbmcgZW50cmllcyBmb3IgcHJlLWNvbXBvc2VkIHVuaWNvZGUgY2hhcmFjdGVycyBzbyB0aGF0IHRoaXMKICogY29sbGF0b3IgY2FuIGJlIHVzZWQgcmVhc29uYWJseSB3ZWxsIHdpdGggZGVjb21wb3NpdGlvbiB0dXJuZWQgb2ZmLgogKi8KIHZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OmFkZENvbXBvc2VkQ2hhcnMoKQogewogICAgVW5pY29kZVN0cmluZyBidWY7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIG9mIHRoZSBwcmUtY29tcG9zZWQgY2hhcmFjdGVycyBpbiBVbmljb2RlCiAgICBDb21wb3NlZENoYXJJdGVyIGl0ZXI7CiAgICBVbmljb2RlU3RyaW5nIGRlY29tcDsKCiAgICB3aGlsZSAoaXRlci5oYXNOZXh0KCkpCiAgICB7CiAgICAgICAgVUNoYXIgYyA9IGl0ZXIubmV4dCgpOwogICAgICAgIAogICAgICAgIGlmIChnZXRDaGFyT3JkZXIoYykgPT0gVU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICAvLyAKICAgICAgICAgICAgLy8gV2UgZG9uJ3QgYWxyZWFkeSBoYXZlIGFuIG9yZGVyaW5nIGZvciB0aGlzIHByZS1jb21wb3NlZCBjaGFyYWN0ZXIuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIEZpcnN0LCBzZWUgaWYgdGhlIGRlY29tcG9zZWQgc3RyaW5nIGlzIGFscmVhZHkgaW4gb3VyCiAgICAgICAgICAgIC8vIHRhYmxlcyBhcyBhIHNpbmdsZSBjb250cmFjdGluZy1zdHJpbmcgb3JkZXJpbmcuCiAgICAgICAgICAgIC8vIElmIHNvLCBqdXN0IG1hcCB0aGUgcHJlY29tcG9zZWQgY2hhcmFjdGVyIHRvIHRoYXQgb3JkZXIuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIFRPRE86IFdoYXQgd2Ugc2hvdWxkIHJlYWxseSBiZSBkb2luZyBoZXJlIGlzIHRyeWluZyB0byBmaW5kIHRoZQogICAgICAgICAgICAvLyBsb25nZXN0IGluaXRpYWwgc3Vic3RyaW5nIG9mIHRoZSBkZWNvbXBvc2l0aW9uIHRoYXQgaXMgcHJlc2VudAogICAgICAgICAgICAvLyBpbiB0aGUgdGFibGVzIGFzIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyIHNlcXVlbmNlLCBhbmQgZmluZCBpdHMKICAgICAgICAgICAgLy8gb3JkZXJpbmcuICBUaGVuIGRvIHRoaXMgcmVjdXJzaXZlbHkgd2l0aCB0aGUgcmVtYWluaW5nIGNoYXJzCiAgICAgICAgICAgIC8vIHNvIHRoYXQgd2UgYnVpbGQgYSBsaXN0IG9mIG9yZGVyaW5ncywgYW5kIGFkZCB0aGF0IGxpc3QgdG8KICAgICAgICAgICAgLy8gdGhlIGV4cGFuc2lvbiB0YWJsZS4gCiAgICAgICAgICAgIC8vIFRoYXQgd291bGQgYmUgbW9yZSBjb3JyZWN0IGJ1dCBhbHNvIHNpZ25pZmljYW50bHkgc2xvd2VyLCBzbwogICAgICAgICAgICAvLyBJJ20gbm90IHRvdGFsbHkgc3VyZSBpdCdzIHdvcnRoIGRvaW5nLgogICAgICAgICAgICAvLwogICAgICAgICAgICBpdGVyLmdldERlY29tcG9zaXRpb24oZGVjb21wKTsKICAgICAgICAgICAgaW50IGNvbnRyYWN0T3JkZXIgPSBnZXRDb250cmFjdE9yZGVyKGRlY29tcCk7CgogICAgICAgICAgICBpZiAoY29udHJhY3RPcmRlciAhPSBVTk1BUFBFRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWRkT3JkZXIoYywgY29udHJhY3RPcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCBoYXZlIGEgY29udHJhY3Rpbmcgb3JkZXJpbmcgZm9yIHRoZSBlbnRpcmUgc3RyaW5nCiAgICAgICAgICAgICAgICAvLyB0aGF0IHJlc3VsdHMgZnJvbSB0aGUgZGVjb21wb3NpdGlvbiwgYnV0IGlmIHdlIGhhdmUgb3JkZXJzCiAgICAgICAgICAgICAgICAvLyBmb3IgZWFjaCBpbmRpdmlkdWFsIGNoYXJhY3Rlciwgd2UgY2FuIGFkZCBhbiBleHBhbmRpbmcKICAgICAgICAgICAgICAgIC8vIHRhYmxlIGVudHJ5IGZvciB0aGUgcHJlLWNvbXBvc2VkIGNoYXJhY3RlciAKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICBVQm9vbCBhbGxUaGVyZSA9IFRSVUU7CiAgICAgICAgICAgICAgICBpbnQzMl90IGk7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGRlY29tcC5sZW5ndGgoKTsgaSArPSAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChnZXRDaGFyT3JkZXIoZGVjb21wW2ldKSA9PSBVTk1BUFBFRCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbFRoZXJlID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoYWxsVGhlcmUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYnVmLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgICAgIGJ1ZiArPSBjOwogICAgICAgICAgICAgICAgICAgIGFkZEV4cGFuZE9yZGVyKGJ1ZiwgZGVjb21wLCBVTk1BUFBFRCwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQogICAgCi8vIFdoZW4gdGhlIGV4cGFuZGluZyBjaGFyYWN0ZXIgdGFibGVzIGFyZSBidWlsdCBieSBhZGRFeHBhbmRPcmRlciwKLy8gaXQgZG9lc24ndCBrbm93IHdoYXQgdGhlIGZpbmFsIG9yZGVyaW5nIG9mIGVhY2ggY2hhcmFjdGVyCi8vIGluIHRoZSBleHBhbnNpb24gd2lsbCBiZS4gIEluc3RlYWQsIGl0IGp1c3QgcHV0cyB0aGUgcmF3IGNoYXJhY3RlcgovLyBjb2RlIGludG8gdGhlIHRhYmxlLCBhZGRpbmcgQ0hBUklOREVYIGFzIGEgZmxhZy4gIE5vdyB0aGF0IHdlJ3ZlCi8vIGZpbmlzaGVkIGJ1aWxkaW5nIHRoZSBtYXBwaW5nIHRhYmxlLCB3ZSBjYW4gZ28gYmFjayBhbmQgbG9vayB1cAovLyB0aGF0IGNoYXJhY3RlciB0byBzZWUgd2hhdCBpdHMgcmVhbCBjb2xsYXRpb24gb3JkZXIgaXMgYW5kCi8vIHN0aWNrIHRoYXQgaW50byB0aGUgZXhwYW5zaW9uIHRhYmxlLiAgVGhhdCBsZXRzIHVzIGF2b2lkIGRvaW5nCi8vIGEgdHdvLXN0YWdlIGxvb2t1cCBsYXRlci4KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbW1pdCgpCnsKICAgIC8vIGlmIHRoZXJlIGFyZSBhbnkgZXhwYW5kaW5nIGNoYXJhY3RlcnMKICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSAhPSBOVUxMKQogICAgewogICAgICAgIGludDMyX3QgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgVmVjdG9yT2ZJbnQqIHZhbHVlTGlzdCA9IGRhdGEtPmV4cGFuZFRhYmxlLT5hdChpKTsKICAgICAgICAgICAgaW50MzJfdCBqOwogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgdmFsdWVMaXN0LT5zaXplKCk7IGorKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gZm91bmQgYSBleHBhbmRpbmcgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAvLyB0aGUgZXhwYW5kaW5nIGNoYXIgdmFsdWUgaXMgbm90IGZpbGxlZCBpbiB5ZXQKICAgICAgICAgICAgICAgIGlmICgodmFsdWVMaXN0LT5hdChqKSA8IEVYUEFORENIQVJJTkRFWCkgJiYKICAgICAgICAgICAgICAgICAgICAodmFsdWVMaXN0LT5hdChqKSA+IENIQVJJTkRFWCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHRoZSByZWFsIHZhbHVlcyBmb3IgdGhlIG5vbi1maWxsZWQgZW50cnkKICAgICAgICAgICAgICAgICAgICBVQ2hhciBjaCA9IChVQ2hhcikodmFsdWVMaXN0LT5hdChqKSAtIENIQVJJTkRFWCk7CiAgICAgICAgICAgICAgICAgICAgaW50MzJfdCByZWFsVmFsdWUgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWxWYWx1ZSA9PSBVTk1BUFBFRCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSByZWFsIHZhbHVlIGlzIHN0aWxsIHVubWFwcGVkLCBtYXliZSBpdCdzaWdub3JhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaiwgSUdOT1JBQkxFTUFTSyAmIGNoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gZmlsbCBpbiB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUxpc3QtPmF0UHV0KGosIHJlYWxWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogfQoKLyoqCiAqICBJbmNyZW1lbnQgb2YgdGhlIGxhc3Qgb3JkZXIgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gbGV2ZWwuCiAqLwppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjppbmNyZW1lbnQoQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBhU3RyZW5ndGgsIGludDMyX3QgbGFzdFZhbHVlKQp7CiAgICBzd2l0Y2goYVN0cmVuZ3RoKQogICAgewogICAgY2FzZSBDb2xsYXRvcjo6UFJJTUFSWToKICAgICAgICAvLyBpbmNyZW1lbnQgcHJpYW1yeSBvcmRlciAgYW5kIG1hc2sgb2ZmIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGxhc3RWYWx1ZSArPSBQUklNQVJZT1JERVJJTkNSRU1FTlQ7CiAgICAgICAgbGFzdFZhbHVlICY9IFBSSU1BUllPUkRFUk1BU0s7CiAgICAgICAgaXNPdmVySWdub3JlID0gVFJVRTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIENvbGxhdG9yOjpTRUNPTkRBUlk6CiAgICAgICAgLy8gaW5jcmVtZW50IHNlY29uZGFyeSBvcmRlciBhbmQgbWFzayBvZmYgdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGxhc3RWYWx1ZSArPSBTRUNPTkRBUllPUkRFUklOQ1JFTUVOVDsKICAgICAgICBsYXN0VmFsdWUgJj0gU0VDT05EQVJZRElGRkVSRU5DRU9OTFk7CgogICAgICAgIC8vIHJlY29yZCBtYXggIyBvZiBpZ25vcmFibGUgY2hhcnMgd2l0aCBzZWNvbmRhcnkgZGlmZmVyZW5jZQogICAgICAgIGlmIChpc092ZXJJZ25vcmUgPT0gRkFMU0UpCiAgICAgICAgewogICAgICAgICAgICBkYXRhLT5tYXhTZWNPcmRlciArPSAxOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIENvbGxhdG9yOjpURVJUSUFSWToKICAgICAgICAvLyBpbmNyZW1lbnQgdGVydGlhcnkgb3JkZXIKICAgICAgICBsYXN0VmFsdWUgKz0gVEVSVElBUllPUkRFUklOQ1JFTUVOVDsKCiAgICAgICAgLy8gcmVjb3JkIG1heCAjIG9mIGlnbm9yYWJsZSBjaGFycyB3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgICAgICBpZiAoaXNPdmVySWdub3JlID09IEZBTFNFKQogICAgICAgIHsKICAgICAgICAgICAgZGF0YS0+bWF4VGVyT3JkZXIgKz0gMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogIC8vIGNhc2UgSURFTlRJQ0FMPyAgCiAgICB9CgogICAgcmV0dXJuIGxhc3RWYWx1ZTsKfQoKLy8gQWRkcyBhIGNoYXJhY3RlciBhbmQgaXRzIGRlc2lnbmF0ZWQgb3JkZXIgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLgovLyBUaGlzIGlzIHRoZSBzaW1wbGUgY2FzZSwgd2l0aCBubyBleHBhbnNpb24gb3IgY29udHJhY3Rpb24Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkT3JkZXIoVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gdHJ5IHRvIGZpbmQgdGhlIG9yZGVyIG9mIHRoZSBjaGFyIGluIHRoZSBtYXBwaW5nIHRhYmxlCiAgICBpbnQzMl90IG9yZGVyID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CgogICAgaWYgKG9yZGVyID49IENPTlRSQUNUQ0hBUklOREVYKQogICAgewogICAgICAgIC8vIFRoZXJlJ3MgYWxyZWFkeSBhbiBlbnRyeSBmb3IgdGhpcyBjaGFyYWN0ZXIgdGhhdCBwb2ludHMgdG8gYSBjb250cmFjdGluZwogICAgICAgIC8vIGNoYXJhY3RlciB0YWJsZS4gIEluc3RlYWQgb2YgYWRkaW5nIHRoZSBjaGFyYWN0ZXIgZGlyZWN0bHkgdG8gdGhlIG1hcHBpbmcKICAgICAgICAvLyB0YWJsZSwgd2UgbXVzdCBhZGQgaXQgdG8gdGhlIGNvbnRyYWN0IHRhYmxlIGluc3RlYWQuCiAgICAgICAga2V5LnJlbW92ZSgpOwogICAgICAgIGtleSArPSBjaDsKICAgICAgICBpZiAoa2V5LmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGFkZENvbnRyYWN0T3JkZXIoa2V5LCBhbk9yZGVyLCBzdGF0dXMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vIGFkZCB0aGUgZW50cnkgdG8gdGhlIG1hcHBpbmcgdGFibGUsIHRoZSBzYW1lIGxhdGVyIGVudHJ5IHJlcGxhY2VzIHRoZSBwcmV2aW91cyBvbmUKICAgICAgICB1Y21wMzJfc2V0KGRhdGEtPm1hcHBpbmcsIGNoLCBhbk9yZGVyKTsKICAgIH0KfQoKLy8gQWRkIGFuIGV4cGFuZGluZy1jaGFyYWN0ZXIgZW50cnkgdG8gdGhlIHRhYmxlLgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRFeHBhbmRPcmRlciggIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgY29udHJhY3RDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIGV4cGFuZENoYXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gQ3JlYXRlIGFuIGV4cGFuc2lvbiB0YWJsZSBlbnRyeQogICAgaW50MzJfdCB0YWJsZUluZGV4ID0gYWRkRXhwYW5zaW9uKGFuT3JkZXIsIGV4cGFuZENoYXJzKTsKICAgIAogICAgLy8gQW5kIGFkZCBpdHMgaW5kZXggaW50byB0aGUgbWFpbiBtYXBwaW5nIHRhYmxlCiAgICBpZiAoY29udHJhY3RDaGFycy5sZW5ndGgoKSA+IDEpCiAgICB7CiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihjb250cmFjdENoYXJzLCB0YWJsZUluZGV4LCBzdGF0dXMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGFkZE9yZGVyKGNvbnRyYWN0Q2hhcnNbMF0sIHRhYmxlSW5kZXgsIHN0YXR1cyk7CiAgICB9Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmFkZEV4cGFuc2lvbihpbnQzMl90IGFuT3JkZXIsIGNvbnN0IFVuaWNvZGVTdHJpbmcgJmV4cGFuZENoYXJzKQp7CiAgICBpZiAoZGF0YS0+ZXhwYW5kVGFibGUgPT0gTlVMTCkKICAgIHsKICAgICAgICBkYXRhLT5leHBhbmRUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0V4cGFuZFRhYmxlKCk7CgogICAgICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSA9PSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvLyBJZiBhbk9yZGVyIGlzIHZhbGlkLCB3ZSB3YW50IHRvIGFkZCBpdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0CiAgICBpbnQzMl90IG9mZnNldCA9IChhbk9yZGVyID09IFVOTUFQUEVEKSA/IDAgOiAxOwogICAgCiAgICBWZWN0b3JPZkludCAqdmFsdWVMaXN0ID0gbmV3IFZlY3Rvck9mSW50KGV4cGFuZENoYXJzLmxlbmd0aCgpICsgb2Zmc2V0KTsKCiAgICBpZiAob2Zmc2V0ID09IDEpCiAgICB7CiAgICAgICAgdmFsdWVMaXN0LT5hdFB1dCgwLCBhbk9yZGVyKTsKICAgIH0KCiAgICBpbnQzMl90IGk7CiAgICBmb3IgKGkgPSAwOyBpIDwgZXhwYW5kQ2hhcnMubGVuZ3RoKCk7IGkgKz0gMSkKICAgIHsKICAgICAgICBVQ2hhciBjaCA9IGV4cGFuZENoYXJzW2ldOwogICAgICAgIGludDMyX3QgbWFwVmFsdWUgPSBnZXRDaGFyT3JkZXIoY2gpOwogICAgICAgIAogICAgICAgIGlmIChtYXBWYWx1ZSAhPSBVTk1BUFBFRCkKICAgICAgICB7CiAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaSArIG9mZnNldCwgbWFwVmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvLyBjYW4ndCBmaW5kIGl0IGluIHRoZSB0YWJsZSwgd2lsbCBiZSBmaWxsZWQgaW4gYnkgY29tbWl0KCkuCiAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaSArIG9mZnNldCwgQ0hBUklOREVYICsgKGludDMyX3QpY2gpOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBBZGQgdGhlIGV4cGFuZGluZyBjaGFyIGxpc3QgaW50byB0aGUgZXhwYW5zaW9uIHRhYmxlLgogICAgaW50MzJfdCB0YWJsZUluZGV4ID0gRVhQQU5EQ0hBUklOREVYICsgZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKTsKICAgIGRhdGEtPmV4cGFuZFRhYmxlLT5hdFB1dChkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpLCB2YWx1ZUxpc3QpOwogICAgCiAgICByZXR1cm4gdGFibGVJbmRleDsKfQoKLy8gQWRkIGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMgdGhhdCBjb250cmFjdHMgaW50byBhIHNpbmdsZSBvcmRlcmluZy4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29udHJhY3RPcmRlcihjb25zdCAgIFVuaWNvZGVTdHJpbmcmIGdyb3VwQ2hhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wgZndkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUgPT0gTlVMTCkKICAgIHsKICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gbmV3IFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZSgpOwogICAgICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgLy8gU2VlIGlmIHRoZSBpbml0aWFsIGNoYXJhY3RlciBvZiB0aGUgc3RyaW5nIGFscmVhZHkgaGFzIGEgY29udHJhY3QgdGFibGUuCiAgICAvLyBlLmcuIGZvciAiY2giLCBsb29rIGZvciAnYycuCiAgICBpbnQzMl90IGVudHJ5ID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBncm91cENoYXJzWzBdKTsKICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICplbnRyeVRhYmxlID0gZ2V0Q29udHJhY3RWYWx1ZXMoZW50cnkgLSBDT05UUkFDVENIQVJJTkRFWCk7CgogICAgaWYgKGVudHJ5VGFibGUgPT0gTlVMTCkKICAgIHsKICAgICAgICAvLyBXZSBuZWVkIHRvIGNyZWF0ZSBhIG5ldyB0YWJsZSBvZiBjb250cmFjdCBlbnRyaWVzIGZvciB0aGlzIGJhc2UgY2hhcgogICAgICAgIGludDMyX3QgdGFibGVJbmRleCA9IENPTlRSQUNUQ0hBUklOREVYICsgZGF0YS0+Y29udHJhY3RUYWJsZS0+c2l6ZSgpOwogICAgICAgIEVudHJ5UGFpciAqcGFpciA9IE5VTEw7CiAgICAgICAgVW5pY29kZVN0cmluZyBzdWJzdHJpbmc7CgogICAgICAgIGVudHJ5VGFibGUgPSBuZXcgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQoKTsKICAgICAgICBpZiAoZW50cnlUYWJsZS0+aXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZS0+YXRQdXQoZGF0YS0+Y29udHJhY3RUYWJsZS0+c2l6ZSgpLCBlbnRyeVRhYmxlKTsKICAgICAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZS0+aXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAgICAgCgogICAgICAgIC8vIEFkZCB0aGUgaW5pdGlhbCBjaGFyYWN0ZXIncyBjdXJyZW50IG9yZGVyaW5nIGZpcnN0LiB0aGVuCiAgICAgICAgLy8gdXBkYXRlIGl0cyBtYXBwaW5nIHRvIHBvaW50IHRvIHRoaXMgY29udHJhY3QgdGFibGUKICAgICAgICBncm91cENoYXJzLmV4dHJhY3QoMCwgMSwgc3Vic3RyaW5nKTsKICAgICAgICBpZiAoc3Vic3RyaW5nLmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHBhaXIgPSBuZXcgRW50cnlQYWlyKHN1YnN0cmluZywgZW50cnkpOwoKICAgICAgICBlbnRyeVRhYmxlLT5hdFB1dCgwLCBwYWlyKTsKICAgICAgICBpZiAoZW50cnlUYWJsZS0+aXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdWNtcDMyX3NldChkYXRhLT5tYXBwaW5nLCBncm91cENoYXJzWzBdLCB0YWJsZUluZGV4KTsKICAgIH0KCiAgICAvLyBOb3cgYWRkIChvciByZXBsYWNlKSB0aGlzIHN0cmluZyBpbiB0aGUgdGFibGUKICAgIGludDMyX3QgaW5kZXggPSBnZXRFbnRyeShlbnRyeVRhYmxlLCBncm91cENoYXJzLCBmd2QpOwoKICAgIGlmIChpbmRleCAhPSBVTk1BUFBFRCkKICAgIHsKICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSAoRW50cnlQYWlyICopIGVudHJ5VGFibGUtPmF0KGluZGV4KTsKICAgICAgICBwYWlyLT52YWx1ZSA9IGFuT3JkZXI7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gbmV3IEVudHJ5UGFpcihncm91cENoYXJzLCBhbk9yZGVyLCBmd2QpOwoKICAgICAgICBlbnRyeVRhYmxlLT5hdFB1dChlbnRyeVRhYmxlLT5zaXplKCksIHBhaXIpOwogICAgfQogICAgCiAgICAvLyBJZiB0aGlzIHdhcyBhIGZvcndhcmQgbWFwcGluZyBmb3IgYSBjb250cmFjdGluZyBzdHJpbmcsIGFsc28gYWRkIGEKICAgIC8vIHJldmVyc2UgbWFwcGluZyBmb3IgaXQsIHNvIHRoYXQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cwogICAgLy8gY2FuIHdvcmsgcmlnaHQKICAgIGlmIChmd2QpCiAgICB7CiAgICAgICAgVW5pY29kZVN0cmluZyByZXZlcnNlKGdyb3VwQ2hhcnMpOwoKICAgICAgICBpZiAocmV2ZXJzZS5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBhZGRDb250cmFjdE9yZGVyKHJldmVyc2UucmV2ZXJzZSgpLCBhbk9yZGVyLCBGQUxTRSwgc3RhdHVzKTsKICAgIH0KfQoKLyoqCiAqIElmIHRoZSBnaXZlbiBzdHJpbmcgaGFzIGJlZW4gc3BlY2lmaWVkIGFzIGEgY29udHJhY3Rpbmcgc3RyaW5nCiAqIGluIHRoaXMgY29sbGF0aW9uIHRhYmxlLCByZXR1cm4gaXRzIG9yZGVyaW5nLgogKiBPdGhlcndpc2UgcmV0dXJuIFVOTUFQUEVELgogKi8KIGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbnRyYWN0T3JkZXIoY29uc3QgVW5pY29kZVN0cmluZyAmZ3JvdXBDaGFycykgY29uc3QKewogICAgaW50MzJfdCByZXN1bHQgPSBVTk1BUFBFRDsKCiAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZSAhPSBOVUxMKQogICAgewogICAgICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICplbnRyeVRhYmxlID0gZ2V0Q29udHJhY3RWYWx1ZXMoZ3JvdXBDaGFyc1swXSk7CgogICAgICAgIGlmIChlbnRyeVRhYmxlICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBpbnQzMl90IGluZGV4ID0gZ2V0RW50cnkoZW50cnlUYWJsZSwgZ3JvdXBDaGFycywgVFJVRSk7CgogICAgICAgICAgICBpZiAoaW5kZXggIT0gVU5NQVBQRUQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEVudHJ5UGFpciAqcGFpciA9IGVudHJ5VGFibGUtPmF0KGluZGV4KTsKCiAgICAgICAgICAgICAgICByZXN1bHQgPSBwYWlyLT52YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDaGFyT3JkZXIoVUNoYXIgY2gpIGNvbnN0CnsKICAgIGludDMyX3Qgb3JkZXIgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKICAgIAogICAgaWYgKG9yZGVyID49IENPTlRSQUNUQ0hBUklOREVYKQogICAgewogICAgICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICpncm91cExpc3QgPSBnZXRDb250cmFjdFZhbHVlcyhvcmRlciAtIENPTlRSQUNUQ0hBUklOREVYKTsKICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBncm91cExpc3QtPmF0KDApOwoKICAgICAgICBvcmRlciA9IHBhaXItPnZhbHVlOwogICAgfQoKICAgIHJldHVybiBvcmRlcjsKfQogICAgCi8vIENyZWF0ZSBhIGhhc2ggY29kZSBmb3IgdGhpcyBjb2xsYXRpb24uICBKdXN0IGhhc2ggdGhlIG1haW4gcnVsZSB0YWJsZSAtLQovLyB0aGF0IHNob3VsZCBiZSBnb29kIGVub3VnaCBmb3IgYWxtb3N0IGFueSB1c2UuCmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6Omhhc2hDb2RlKCkgY29uc3QKewogICAgaW50MzJfdCAgICAgICAgIHZhbHVlID0gMDsKICAgIGludDMyX3QgICAgICAgICBjOwogICAgaW50MzJfdCAgICAgICAgIGNvdW50ID0gZ2V0UnVsZXMoKS5sZW5ndGgoKTsKICAgIFVUZXh0T2Zmc2V0ICAgICAgcG9zID0gY291bnQgLSAxOwoKICAgIGlmIChjb3VudCA+IDY0KQogICAgewogICAgICAgIGNvdW50ID0gNjQ7IC8vIG9ubHkgaGFzaCB1cHRvIGxpbWl0CiAgICB9CgogICAgaW50MTZfdCBpID0gMDsKCiAgICB3aGlsZSAoaSA8IGNvdW50KQogICAgewogICAgICAgIGMgPSBkYXRhLT5ydWxlVGFibGVbcG9zXTsKICAgICAgICB2YWx1ZSA9ICgodmFsdWUgPDwgKGMgJiAweDBmKSkgXiAoYyA8PCA4KSkgKyAoYyBeIHZhbHVlKTsKICAgICAgICBpICs9IDE7CiAgICAgICAgcG9zIC09IDE7CiAgICB9CgogICAgaWYgKHZhbHVlID09IDApCiAgICB7CiAgICAgICAgdmFsdWUgPSAxOwogICAgfQoKICAgIHJldHVybiB2YWx1ZTsKfQoKLy8gZmluZCB0aGUgY29udHJhY3RpbmcgY2hhciBlbnRyeSBpbiB0aGUgbGlzdAppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFbnRyeShWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCBmd2QpCnsKICAgIGludDMyX3QgaTsKCiAgICBpZiAobGlzdCAhPSBOVUxMKQogICAgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0LT5zaXplKCk7IGkgKz0gMSkKICAgICAgICB7CiAgICAgICAgICAgIEVudHJ5UGFpciAqcGFpciA9IGxpc3QtPmF0KGkpOwoKICAgICAgICAgICAgaWYgKChwYWlyICE9IE5VTEwpICYmIChwYWlyLT5md2QgPT0gZndkKSAmJiAocGFpci0+ZW50cnlOYW1lID09IG5hbWUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEOwp9CgovLyBsb29rIGZvciB0aGUgY29udHJhY3RpbmcgbGlzdCBlbnRyeSB3aXRoIHRoZSBiZWdpbm5pbmcgY2hhcgpWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCoKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbnRyYWN0VmFsdWVzKFVDaGFyIGNoKSBjb25zdAp7CiAgICBpbnQzMl90IGluZGV4ID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CiAgICByZXR1cm4gZ2V0Q29udHJhY3RWYWx1ZXMoaW5kZXggLSBDT05UUkFDVENIQVJJTkRFWCk7Cn0KCi8vIGxvb2sgZm9yIHRoZSBjb250cmFjdGluZyBsaXN0IGVudHJ5IHdpdGggdGhlIGluZGV4ClZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29udHJhY3RWYWx1ZXMoaW50MzJfdCAgICBpbmRleCkgY29uc3QKewogICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICBpZiAoaW5kZXggPj0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBkYXRhLT5jb250cmFjdFRhYmxlLT5hdChpbmRleCk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKgogICogUmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlcyB0aGF0IGVuZAogICogd2l0aCB0aGUgc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAgKgogICogQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgKiBAcmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNldWVuY2VzIGVuZGluZwogICogICAgICAgICB3aXRoIHRoZSBzcGVjaWZpZWQgb3JkZXIuCiAgKgogICogQHNlZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IjZ2V0TWF4RXhwYW5zaW9uCiAgKi8KaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICAgIGludDMyX3QgcmVzdWx0ID0gMTsKICAgIAogICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgLy8gUmlnaHQgbm93IHRoaXMgZG9lcyBhIGxpbmVhciBzZWFyY2ggdGhyb3VnaCB0aGUgZW50aXJlCiAgICAgICAgLy8gZXhwYW5kc2lvbiB0YWJsZS4gIElmIGEgY29sbGF0b3IgaGFkIGEgbGFyZ2UgbnVtYmVyIG9mIGV4cGFuc2lvbnMsCiAgICAgICAgLy8gdGhpcyBjb3VsZCBjYXVzZSBhIHBlcmZvcm1hbmNlIHByb2JsZW0sIGJ1dCBpbiBwcmFjdGljZSB0aGF0CiAgICAgICAgLy8gcmFyZWx5IGhhcHBlbnMKICAgICAgICBpbnQzMl90IGk7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGRhdGEtPmV4cGFuZFRhYmxlLT5zaXplKCk7IGkgKz0gMSkKICAgICAgICB7CiAgICAgICAgICAgIFZlY3Rvck9mSW50ICp2YWx1ZUxpc3QgPSBkYXRhLT5leHBhbmRUYWJsZS0+YXQoaSk7CiAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoID0gdmFsdWVMaXN0LT5zaXplKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAobGVuZ3RoID4gcmVzdWx0ICYmIHZhbHVlTGlzdC0+YXQobGVuZ3RoLTEpID09IG9yZGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBsZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQogICAgCi8qKgogKiAgR2V0IHRoZSBlbnRyeSBvZiBoYXNoIHRhYmxlIG9mIHRoZSBleHBhbmRpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICogIHRhYmxlLgogKiAgQHBhcmFtIG9mZnNldCB0aGUgaW5kZXggb2YgdGhlIGV4cGFuZGluZyBzdHJpbmcgdmFsdWUgbGlzdAogKi8KVmVjdG9yT2ZJbnQgKlJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFeHBhbmRWYWx1ZUxpc3QoaW50MzJfdCBvcmRlcikgY29uc3QKewogICAgcmV0dXJuIGRhdGEtPmV4cGFuZFRhYmxlLT5hdChvcmRlciAtIEVYUEFORENIQVJJTkRFWCk7Cn0KCgoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1JbihSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIFVNZW1vcnlTdHJlYW0qIGlzKQp7CiAgICBpZiAoIXVwcnZfbXN0cm1fZXJyb3IoaXMpKQogICAgewogICAgICAgIC8vIENoZWNrIHRoYXQgdGhpcyBpcyB0aGUgY29ycmVjdCBmaWxlIHR5cGUKICAgICAgICBpbnQxNl90IGlkOwoKICAgICAgICB1cHJ2X21zdHJtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICB1cHJ2X21zdHJtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gU3RyZWFtIGluIGxhcmdlIG9iamVjdHMKICAgICAgICBjaGFyIGlzTnVsbDsKCiAgICAgICAgdXBydl9tc3RybV9yZWFkKGlzLCAmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CiAgICAgICAgaWYgKGlzTnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBjb2xsYXRvci0+ZGF0YTsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29sbGF0b3ItPmRhdGEgPT0gTlVMTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEgPSBuZXcgVGFibGVDb2xsYXRpb25EYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtSW4oaXMpOwogICAgICAgICAgICBpZiAoY29sbGF0b3ItPmRhdGEtPmlzQm9ndXMoKSkgewogICAgICAgICAgICAgICAgdXBydl9tc3RybV9zZXRFcnJvcihpcyk7IC8vIGZvcmNlIHRoZSBzdHJlYW0gdG8gc2V0IGl0cyBlcnJvciBmbGFnCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBlbmQgbWFya2VyIGlzIHByZXNlbnQKICAgICAgICB1cHJ2X21zdHJtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICB1cHJ2X21zdHJtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gUmVzZXQgb3RoZXIgZGF0YSBtZW1iZXJzCiAgICAgICAgY29sbGF0b3ItPmlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgICAgIGNvbGxhdG9yLT5sYXN0Q2hhciA9IDA7CiAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5tUGF0dGVybjsKICAgICAgICBjb2xsYXRvci0+bVBhdHRlcm4gPSAwOwogICAgICAgIGNvbGxhdG9yLT5rZXkucmVtb3ZlKCk7CiAgICAgICAgY29sbGF0b3ItPmRhdGFJc093bmVkID0gVFJVRTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBVTWVtb3J5U3RyZWFtKiBvcykKewogICAgaWYgKCF1cHJ2X21zdHJtX2Vycm9yKG9zKSkKICAgIHsKICAgICAgICAvLyBXZSB1c2UgYSAxNi1iaXQgSUQgY29kZSB0byBpZGVudGlmeSB0aGlzIGZpbGUuCiAgICAgICAgaW50MTZfdCBpZCA9IGNvbGxhdG9yLT5GSUxFSUQ7CiAgICAgICAgdXBydl9tc3RybV93cml0ZShvcywgKHVpbnQ4X3QgKikmaWQsIHNpemVvZihpZCkpOwoKICAgICAgICAvLyBTdHJlYW0gb3V0IHRoZSBkYXRhCiAgICAgICAgY2hhciBpc051bGw7CiAgICAgICAgaXNOdWxsID0gKGNvbGxhdG9yLT5kYXRhID09IDApOwogICAgICAgIHVwcnZfbXN0cm1fd3JpdGUob3MsICh1aW50OF90KikmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CgogICAgICAgIGlmICghaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEtPnN0cmVhbU91dChvcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBXcml0ZSBvdXQgdGhlIElEIHRvIGluZGljYXRlIHRoZSBlbmQKICAgICAgICB1cHJ2X21zdHJtX3dyaXRlKG9zLCAodWludDhfdCAqKSZpZCwgc2l6ZW9mKGlkKSk7CiAgICB9Cn0KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4oUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBpcykKewogICAgaWYgKCFUX0ZpbGVTdHJlYW1fZXJyb3IoaXMpKQogICAgewogICAgICAgIC8vIENoZWNrIHRoYXQgdGhpcyBpcyB0aGUgY29ycmVjdCBmaWxlIHR5cGUKICAgICAgICBpbnQxNl90IGlkOwoKICAgICAgICBUX0ZpbGVTdHJlYW1fcmVhZChpcywgJmlkLCBzaXplb2YoaWQpKTsKICAgICAgICBpZiAoaWQgIT0gY29sbGF0b3ItPkZJTEVJRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRoaXMgaXNuJ3QgdGhlIHJpZ2h0IHR5cGUgb2YgZmlsZS4gIE1hcmsgdGhlIGlvcwogICAgICAgICAgICAvLyBhcyBmYWlsaW5nIGFuZCByZXR1cm4uCiAgICAgICAgICAgIFRfRmlsZVN0cmVhbV9zZXRFcnJvcihpcyk7IC8vIGZvcmNlIHRoZSBzdHJlYW0gdG8gc2V0IGl0cyBlcnJvciBmbGFnCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8vIFN0cmVhbSBpbiBsYXJnZSBvYmplY3RzCiAgICAgICAgY2hhciBpc051bGw7CgogICAgICAgIFRfRmlsZVN0cmVhbV9yZWFkKGlzLCAmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CiAgICAgICAgaWYgKGlzTnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBjb2xsYXRvci0+ZGF0YTsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29sbGF0b3ItPmRhdGEgPT0gTlVMTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEgPSBuZXcgVGFibGVDb2xsYXRpb25EYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtSW4oaXMpOwogICAgICAgICAgICBpZiAoY29sbGF0b3ItPmRhdGEtPmlzQm9ndXMoKSkgewogICAgICAgICAgICAgICAgVF9GaWxlU3RyZWFtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGVuZCBtYXJrZXIgaXMgcHJlc2VudAogICAgICAgIFRfRmlsZVN0cmVhbV9yZWFkKGlzLCAmaWQsIHNpemVvZihpZCkpOwogICAgICAgIGlmIChpZCAhPSBjb2xsYXRvci0+RklMRUlEKQogICAgICAgIHsKICAgICAgICAgICAgLy8gVGhpcyBpc24ndCB0aGUgcmlnaHQgdHlwZSBvZiBmaWxlLiAgTWFyayB0aGUgaW9zCiAgICAgICAgICAgIC8vIGFzIGZhaWxpbmcgYW5kIHJldHVybi4KICAgICAgICAgICAgVF9GaWxlU3RyZWFtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gUmVzZXQgb3RoZXIgZGF0YSBtZW1iZXJzCiAgICAgICAgY29sbGF0b3ItPmlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgICAgIGNvbGxhdG9yLT5sYXN0Q2hhciA9IDA7CiAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5tUGF0dGVybjsKICAgICAgICBjb2xsYXRvci0+bVBhdHRlcm4gPSAwOwogICAgICAgIGNvbGxhdG9yLT5rZXkucmVtb3ZlKCk7CiAgICAgICAgY29sbGF0b3ItPmRhdGFJc093bmVkID0gVFJVRTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBvcykKewogICAgaWYgKCFUX0ZpbGVTdHJlYW1fZXJyb3Iob3MpKQogICAgewogICAgICAgIC8vIFdlIHVzZSBhIDE2LWJpdCBJRCBjb2RlIHRvIGlkZW50aWZ5IHRoaXMgZmlsZS4KICAgICAgICBpbnQxNl90IGlkID0gY29sbGF0b3ItPkZJTEVJRDsKICAgICAgICBUX0ZpbGVTdHJlYW1fd3JpdGUob3MsICZpZCwgc2l6ZW9mKGlkKSk7CgogICAgICAgIC8vIFN0cmVhbSBvdXQgdGhlIGRhdGEKICAgICAgICBjaGFyIGlzTnVsbDsKICAgICAgICBpc051bGwgPSAoY29sbGF0b3ItPmRhdGEgPT0gMCk7CiAgICAgICAgVF9GaWxlU3RyZWFtX3dyaXRlKG9zLCAmaXNOdWxsLCBzaXplb2YoaXNOdWxsKSk7CgogICAgICAgIGlmICghaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgY29sbGF0b3ItPmRhdGEtPnN0cmVhbU91dChvcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBXcml0ZSBvdXQgdGhlIElEIHRvIGluZGljYXRlIHRoZSBlbmQKICAgICAgICBUX0ZpbGVTdHJlYW1fd3JpdGUob3MsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICB9Cn0KClVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjp3cml0ZVRvRmlsZShjb25zdCBjaGFyKiBmaWxlTmFtZSkgY29uc3QKewogICAgRmlsZVN0cmVhbSogb2ZzID0gVF9GaWxlU3RyZWFtX29wZW4oZmlsZU5hbWUsICJ3YiIpOwogICAgaWYgKG9mcyAhPSAwKQogICAgewogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dCh0aGlzLCBvZnMpOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgd3JpdGUgJXMgc2l6ZSAlZCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKG9mcyksCiAgICAgICAgKCFUX0ZpbGVTdHJlYW1fZXJyb3Iob2ZzKSA/ICIsIE9LIiA6ICIsIEZBSUwiKSk7CiNlbmRpZgoKICAgIFVCb29sIGVyciA9IFRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID09IDA7CgogICAgVF9GaWxlU3RyZWFtX2Nsb3NlKG9mcyk7CiAgICByZXR1cm4gZXJyOwp9Ci8qClVCb29sIFJ1bGVCYXNlZENvbGxhdG9yOjpwcmVwYXJlRm9yQnVuZGxlKCkgY29uc3QKewogICAgVU1lbW9yeVN0cmVhbSogb2ZzID0gdXBydl9tc3RybV9vcGVuTmV3KDApOwogICAgaWYgKG9mcyAhPSAwKQogICAgewogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dCh0aGlzLCBvZnMpOwogICAgfQoKI2lmZGVmIENPTExERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJiaW5hcnkgd3JpdGUgJXMgc2l6ZSAlZCAlc1xuIiwgZmlsZU5hbWUsIFRfRmlsZVN0cmVhbV9zaXplKG9mcyksCiAgICAgICAgKCFUX0ZpbGVTdHJlYW1fZXJyb3Iob2ZzKSA/ICIsIE9LIiA6ICIsIEZBSUwiKSk7CiNlbmRpZgoKICAgIFVCb29sIGVyciA9IHVwcnZfbXN0cm1fZXJyb3Iob2ZzKSA9PSAwOwoKICAgIHVwcnZfbXN0cm1fY2xvc2Uob2ZzKTsKCiAgICByZXR1cm4gZXJyOwp9CiovCgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjphZGRUb0NhY2hlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSkKewogICAgLy8gVGhpcyBtZXRob2QgZG9lc24ndCBhZGQgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGl0c2VsZiB0byB0aGUgY2FjaGUuICBJbnN0ZWFkLAogICAgLy8gaXQgYWRkcyB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3IncyBkYXRhIG9iamVjdCB0byB0aGUgVGFibGVDb2xsYXRpb25EYXRhCiAgICAvLyBjYWNoZSwgYW5kIG1hcmtzIGl0IGFzIG5vbi1vd25lZCBpbiB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0LgogICAgVGFibGVDb2xsYXRpb25EYXRhOjphZGRUb0NhY2hlKGtleSwgZGF0YSk7CiAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tQ2FjaGUoY29uc3QgVW5pY29kZVN0cmluZyYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gQXR0ZW1wdCB0byBjb25zdHJ1Y3QgdGhpcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbSBjYWNoZWQgVGFibGVDb2xsYXRpb25EYXRhLgogICAgLy8gSWYgbm8gc3VjaCBkYXRhIGlzIGluIHRoZSBjYWNoZSwgcmV0dXJuIGZhbHNlLgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IE5VTEw7CiAgICB9CgogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBsYXN0Q2hhciA9IDA7CiAgICBtUGF0dGVybiA9IDA7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwoKICAgIGRhdGFJc093bmVkID0gRkFMU0U7CiAgICBkYXRhID0gVGFibGVDb2xsYXRpb25EYXRhOjpmaW5kSW5DYWNoZShrZXkpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICB9Cn0KCmNoYXIqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVQYXRoTmFtZSggIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHByZWZpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHN1ZmZpeCkKewogICAgLy8gQ29uY2F0ZW5hdGUgdGhyZWUgZWxlbWVudHMgdG8gZm9ybSBhIGZpbGUgbmFtZSwgYW5kIHJldHVybiBpdC4KCiAgICBVbmljb2RlU3RyaW5nICAgd29ya2luZ05hbWUocHJlZml4KTsKICAgIGludDMyX3QgICAgICAgICBzaXplOwogICAgY2hhciogICAgICAgICAgIHJldHVyblZhbDsKCiAgICB3b3JraW5nTmFtZSArPSBuYW1lOwogICAgd29ya2luZ05hbWUgKz0gc3VmZml4OwoKICAgIHNpemUgPSB3b3JraW5nTmFtZS5sZW5ndGgoKTsKICAgIHJldHVyblZhbCA9IG5ldyBjaGFyW3NpemUgKyAxXTsKICAgIHdvcmtpbmdOYW1lLmV4dHJhY3QoMCwgc2l6ZSwgcmV0dXJuVmFsLCAiIik7CiAgICByZXR1cm5WYWxbc2l6ZV0gPSAwOwoKICAgIHJldHVybiByZXR1cm5WYWw7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNob3BMb2NhbGUoVW5pY29kZVN0cmluZyYgbG9jYWxlTmFtZSkKewogICAgLy8gY2hvcExvY2FsZSByZW1vdmVzIHRoZSBmaW5hbCBlbGVtZW50IGZyb20gYSBsb2NhbGUgc3RyaW5nLgogICAgLy8gRm9yIGluc3RhbmNlLCAiZGVfQ0giIGJlY29tZXMgImRlIiwgYW5kICJkZSIgYmVjb21lcyAiIi4KICAgIC8vICIiIHJlbWFpbnMgIiIuCgogICAgaW50MzJfdCAgICAgc2l6ZSA9IGxvY2FsZU5hbWUubGVuZ3RoKCk7CiAgICBpbnQzMl90ICAgICBpOwoKICAgIGZvciAoaSA9IHNpemUgLSAxOyBpID4gMDsgaS0tKQogICAgewogICAgICAgIGlmIChsb2NhbGVOYW1lW2ldID09IDB4MDA1RikKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaSA8IDApCiAgICB7CiAgICAgICBpID0gMDsKICAgIH0KCiAgICBsb2NhbGVOYW1lLnJlbW92ZShpLCBzaXplIC0gaSk7Cn0KCgp1aW50OF90ICoKUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLCBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICAgIFVNZW1vcnlTdHJlYW0gKm1lbWRhdGEgPSAwOwogICAgdWludDhfdCAqZGF0YSA9IDA7CgogICAgaWYoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBtZW1kYXRhID0gdXBydl9tc3RybV9vcGVuTmV3KDApOwoKICAgIGlmIChtZW1kYXRhICE9IDApIHsKICAgICAgICBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1PdXQodGhpcywgbWVtZGF0YSk7CiAgICB9CgogICAgVUJvb2wgZXJyID0gdXBydl9tc3RybV9lcnJvcihtZW1kYXRhKSA9PSAwOwoKCiAgICBkYXRhID0gKHVpbnQ4X3QgKil1cHJ2X21hbGxvYyhtZW1kYXRhLT5mUG9zKTsKICAgIGlmKGRhdGEgPT0gMCkgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgdXBydl9tc3RybV9jbG9zZShtZW1kYXRhKTsKICAgICAgICBsZW5ndGggPSAwOwogICAgICAgIHJldHVybiAwOwogICAgfSBlbHNlIHsKICAgICAgICB1cHJ2X21lbWNweShkYXRhLCBtZW1kYXRhLT5mU3RhcnQsIG1lbWRhdGEtPmZQb3MpOwogICAgICAgIGxlbmd0aCA9IG1lbWRhdGEtPmZQb3M7CiAgICAgICAgdXBydl9tc3RybV9jbG9zZShtZW1kYXRhKTsKICAgICAgICByZXR1cm4gZGF0YTsKICAgIH0KfQoKCi8vZW9mCg==