LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0xOTk5LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogRmlsZSB0Ymxjb2xsLmNwcAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMS85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgZGVjbGFyYXRpb25zIG91dCBvZiBmb3IgbG9vcCBpbml0aWFsaXplci4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgTWFjIGNvbXBhdGliaWxpdHkgI2lmZGVmIGZvciBpb3M6Om5vY3JlYXRlLgoqICAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byB1c2UgVGFibGVDb2xsYXRpb25EYXRhIHN1Yi1vYmplY3QgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9sZCBpbnZhcmlhbnQgZGF0YS4KKiAgMi8xMy85NyAgICAgYWxpdSAgICAgICAgTW92ZWQgc2V2ZXJhbCBtZXRob2RzIGludG8gdGhpcyBjbGFzcyBmcm9tIENvbGxhdGlvbi4KKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgYSBwcml2YXRlIFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpIGNvbnN0cnVjdG9yLAoqICAgICAgICAgICAgICAgICAgICAgICAgICB0byBiZSB1c2VkIGJ5IENvbGxhdG9yOjpnZXRJbnN0YW5jZSgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4gIE1hZGUgdXNlIG9mIFVFcnJvckNvZGUgdmFyaWFibGVzIGNvbnNpc3RlbnQuCiogIDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGFuZCBjb3B5CiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIGFuZCBnZXREeW5hbWljQ2xhc3NJRC4KKiAgMy81Lzk3ICAgICAgYWxpdSAgICAgICAgQ2hhbmdlZCBjb21wYWN0aW9uIGN5Y2xlIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuICBXZQoqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2UgdGhlIG1heGltdW0gYWxsb3dhYmxlIHZhbHVlIHdoaWNoIGlzIGtCbG9ja0NvdW50LgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb2RpZmllZCBnZXRSdWxlcygpIHRvIGxvYWQgcnVsZXMgZHluYW1pY2FsbHkuICBDaGFuZ2VkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21GaWxlKCkgY2FsbCB0byBhY2NvbW9kYXRlIHRoaXMgKGFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtZXRlciB0byBzcGVjaWZ5IHdoZXRoZXIgYmluYXJ5IGxvYWRpbmcgaXMgdG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSBwbGFjZSkuCiogMDUvMDYvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIG1lbW9yeSBhbGxvY2F0aW9uIGVycm9yIGNoZWNrLgoqICA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqICA2LzIzLzk3ICAgICBoZWxlbmEgICAgICBBZGRpbmcgY29tbWVudHMgdG8gbWFrZSBjb2RlIG1vcmUgcmVhZGFibGUuCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDA2LzI2Lzk4ICAgICBlcm0gICAgICAgICBDaGFuZ2VzIGZvciBDb2xsYXRpb25LZXlzIHVzaW5nIGJ5dGUgYXJyYXlzLgoqIDA4LzEwLzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgUnVsZUJhc2VkQ29sbGF0b3IuamF2YQoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUKKiAwNi8xNC85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBrUmVzb3VyY2VCdW5kbGVTdWZmaXgKKiAwNi8yMi85OSAgICAgc3RlcGhlbiAgICAgRml4ZWQgbG9naWMgaW4gY29uc3RydWN0RnJvbUZpbGUoKSBzaW5jZSAuY3R4CiogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzIGFyZSBubyBsb25nZXIgdXNlZC4KKiAxMS8wMi85OSAgICAgaGVsZW5hICAgICAgQ29sbGF0b3IgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiAgU3BlY2lhbCBjYXNlCiogICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBOT19PUCBzaXR1YXRpb25zLiAKKiAxMS8xNy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluZWQgc29tZSBpbnRlcm5hbCBmdW5jdGlvbnMuCiogMTIvMTUvOTkgICAgIGFsaXUgICAgICAgIFVwZGF0ZSB0byBzdXBwb3J0IFRoYWkgY29sbGF0aW9uLiAgTW92ZSBOb3JtYWxpemVySXRlcmF0b3IKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gaW1wbGVtZW50YXRpb24gZmlsZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKI2luY2x1ZGUgInVjbXAzMi5oIgojaW5jbHVkZSAidGNvbGRhdGEuaCIKCiNpbmNsdWRlICJ1bmljb2RlL3RibGNvbGwuaCIKCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvbG9jaWQuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pY29kZS5oIgojaW5jbHVkZSAidGFibGVzLmgiCiNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKI2luY2x1ZGUgIm1lcmdlY29sLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Jlc2J1bmQuaCIKI2luY2x1ZGUgImZpbGVzdHJtLmgiCiNpbmNsdWRlICJ1bWVtc3RybS5oIgoKI2lmZGVmIF9ERUJVRwojaW5jbHVkZSAidW5pc3RybS5oIgojZW5kaWYKCiNpbmNsdWRlICJjb21waXRyLmgiCgojaW5jbHVkZSA8c3RyaW5nLmg+CgojaW5jbHVkZSAidW5pY29kZS91c3RyaW5nLmgiCgojaW5jbHVkZSAiY21lbW9yeS5oIgoKCmNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXIKewpwdWJsaWM6CiAgIHN0YXRpYyB2b2lkIHN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgRmlsZVN0cmVhbSogaXMpOwogICBzdGF0aWMgdm9pZCBzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBGaWxlU3RyZWFtKiBvcyk7CiAgIHN0YXRpYyB2b2lkIHN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgVU1lbW9yeVN0cmVhbSogaXMpOwogICBzdGF0aWMgdm9pZCBzdHJlYW1PdXQoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIGNvbGxhdG9yLCBVTWVtb3J5U3RyZWFtKiBvcyk7Cn07CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gIFRoZSBmb2xsb3dpbmcgZGlhZ3JhbSBzaG93cyB0aGUgZGF0YSBzdHJ1Y3R1cmUgb2YgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdC4KLy8gIFN1cHBvc2Ugd2UgaGF2ZSB0aGUgcnVsZSwgd2hlcmUgJ28tdW1sYXV0JyBpcyB0aGUgdW5pY29kZSBjaGFyIDB4MDBGNi4KLy8gICJhLCBBIDwgYiwgQiA8IGMsIEMsIGNoLCBjSCwgQ2gsIENIIDwgZCwgRCAuLi4gPCBvLCBPOyAnby11bWxhdXQnL0UsICdPLXVtbGF1dCcvRSAuLi4iLgovLyAgV2hhdCB0aGUgcnVsZSBzYXlzIGlzLCBzb3J0cyAnY2gnbGlnYXR1cmVzIGFuZCAnYycgb25seSB3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYW5kCi8vICBzb3J0cyAnby11bWxhdXQnIGFzIGlmIGl0J3MgYWx3YXlzIGV4cGFuZGVkIHdpdGggJ2UnLgovLwovLyBtYXBwaW5nIHRhYmxlICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdGluZyBsaXN0ICAgICAgICAgICAgICAgICAgZXhwYW5kaW5nIGxpc3QKLy8gKGNvbnRhaW5zIGFsbCB1bmljb2RlIGNoYXIKLy8gIGVudHJpZXMpICAgICAgICAgICAgICAgICAgICAgICAgIF9fXyAgICAgX19fX19fX19fX19fXyAgICAgICAgIF9fX19fX19fX19fX19fX19fX19fX19fX18KLy8gICBfX19fX19fXyAgICAgICAgICAgICAgICAgICB8PT0+fF8qX3wtLT58J2MnICB8dignYycpIHwgICB8PT0+fHYoJ28nKXx2KCd1bWxhdXQnKXx2KCdlJyl8Ci8vICB8X1x1MDAwMV98LS0+IHYoJ1x1MDAwMScpICAgfCAgIHxfOl98ICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9cdTAwMDJffC0tPiB2KCdcdTAwMDInKSAgIHwgICB8XzpffCAgIHwnY2gnIHx2KCdjaCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX19fOl9fX3wgICAgICAgICAgICAgICAgICB8ICAgfF86X3wgICB8LS0tLS0tLS0tLS0tLXwgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfCdjSCcgfHYoJ2NIJyl8ICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfF9fJ2EnX19ffC0tPiB2KCdhJykgICAgICAgIHwgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tfCAgIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwKLy8gIHxfXydiJ19fX3wtLT4gdignYicpICAgICAgICB8ICAgICAgICAgICB8J0NoJyB8dignQ2gnKXwgICB8ICAgfCAgICAgICAgICAgICA6ICAgICAgICAgICB8Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgfC0tLS0tLS0tLS0tLS18ICAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfAovLyAgfF9fX186X19ffCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIHwnQ0gnIHx2KCdDSCcpfCAgIHwgICB8ICAgICAgICAgICAgIDogICAgICAgICAgIHwKLy8gIHxfX18nYydfX3wtLS0tLS0tLS0tLS0tLS0tLS0tICAgICAgICAgICAgLS0tLS0tLS0tLS0tLSAgICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Ci8vICB8X19fXzpfX198ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwgICAgICAgICAgICAgOiAgICAgICAgICAgfAovLyAgfG8tdW1sYXV0fC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgICB8X19fX19fX19fX19fX19fX19fX19fX19fX3wKLy8gIHxfX19fOl9fX3wKLy8KLy8KLy8gTm90ZWQgYnkgSGVsZW5hIFNoaWggb24gNi8yMy85NyB3aXRoIHBlbmRpbmcgZGVzaWduIGNoYW5nZXMgKHNsaW1taW5nIGNvbGxhdGlvbikuCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNIQVJJTkRFWCA9IDB4NzAwMDAwMDA7ICAgICAgICAgICAgIC8vIG5lZWQgbG9vayB1cCBpbiAuY29tbWl0KCkKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6RVhQQU5EQ0hBUklOREVYID0gMHg3RTAwMDAwMDsgICAgICAgLy8gRXhwYW5kIGluZGV4IGZvbGxvd3MKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Q09OVFJBQ1RDSEFSSU5ERVggPSAweDdGMDAwMDAwOyAgICAgLy8gY29udHJhY3QgaW5kZXhlcyBmb2xsb3dzCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEID0gMHhGRkZGRkZGRjsgICAgICAgICAgICAgIC8vIHVubWFwcGVkIGNoYXJhY3RlciB2YWx1ZXMKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSSU5DUkVNRU5UID0gMHgwMDAxMDAwMDsgLy8gcHJpbWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMTAwOyAvLyBzZWNvbmRhcnkgc3RyZW5ndGggaW5jcmVtZW50CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJJTkNSRU1FTlQgPSAweDAwMDAwMDAxOyAvLyB0ZXJ0aWFyeSBzdHJlbmd0aCBpbmNyZW1lbnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6TUFYSUdOT1JBQkxFID0gMHgwMDAxMDAwMDsgICAgICAgICAgLy8gbWF4aW11bSBpZ25vcmFibGUgY2hhciBvcmRlciB2YWx1ZQpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLID0gMHhmZmZmMDAwMDsgICAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgcHJpbWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUk1BU0sgPSAweDAwMDBmZjAwOyAgICAvLyBtYXNrIG9mZiBhbnl0aGluZyBidXQgc2Vjb25kYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLID0gMHgwMDAwMDBmZjsgICAgIC8vIG1hc2sgb2ZmIGFueXRoaW5nIGJ1dCB0ZXJ0aWFyeSBvcmRlcgpjb25zdCBpbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllSRVNFVE1BU0sgPSAweDAwMDBmZmZmOyAgICAvLyBtYXNrIG9mZiBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OklHTk9SQUJMRU1BU0sgPSAweDAwMDBmZmZmOyAgICAgICAgIC8vIG1hc2sgb2ZmIGlnbm9yYWJsZSBjaGFyIG9yZGVyCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllESUZGRVJFTkNFT05MWSA9IDB4ZmZmZjAwMDA7IC8vIHVzZSBvbmx5IHRoZSBwcmltYXJ5IGRpZmZlcmVuY2UKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFkgPSAweGZmZmZmZjAwOyAgLy8gdXNlIG9ubHkgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSBkaWZmZXJlbmNlCmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUlNISUZUID0gMTY7ICAgICAgICAgICAgIC8vIHByaW1hcnkgb3JkZXIgc2hpZnQKY29uc3QgaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJTSElGVCA9IDg7ICAgICAgICAgICAgLy8gc2Vjb25kYXJ5IG9yZGVyIHNoaWZ0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OlNPUlRLRVlPRkZTRVQgPSAxOyAgICAgICAgICAgICAgICAgIC8vIG1pbmltdW0gc29ydCBrZXkgb2Zmc2V0CmNvbnN0IGludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUk9WRVJGTE9XID0gMHg3RkZGRkZGRjsgIC8vIEluZGljYXRlcyB0aGUgY2hhciBpcyBhIGNvbnRyYWN0IGNoYXIKCmNvbnN0IGludDE2X3QgUnVsZUJhc2VkQ29sbGF0b3I6OkZJTEVJRCA9IDB4NTQ0MzsgICAgICAgICAgICAgICAgICAgIC8vIHVuaXF1ZSBmaWxlIGlkIGZvciBwYXJpdHkgY2hlY2sKY29uc3QgY2hhciogUnVsZUJhc2VkQ29sbGF0b3I6OmtGaWxlbmFtZVN1ZmZpeCA9ICIuY29sIjsgICAgICAgICAgICAgLy8gYmluYXJ5IGNvbGxhdGlvbiBmaWxlIGV4dGVuc2lvbgpjaGFyICBSdWxlQmFzZWRDb2xsYXRvcjo6ZmdDbGFzc0lEID0gMDsgLy8gVmFsdWUgaXMgaXJyZWxldmFudCAgICAgICAvLyBjbGFzcyBpZAoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIE5vcm1hbGl6ZXJJdGVyYXRvcgovLwovLyBUaGlzIGNsYXNzIGlzIGVzc2VudGlhbGx5IGEgZHVwbGljYXRlIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciwKLy8gc3RyaXBwZWQgZG93biBmb3Igc3BlZWQuICBJdCBpcyBkZWNsYXJlZCBoZXJlIHNvIHdlIGNhbiBpbmNvcnBvcmF0ZQovLyBpbnRlcm5hbCBjbGFzc2VzIGFzIHN1Ym9iamVjdHMsIGFzIHdlbGwgYXMganVzdCB0byBoaWRlIGl0IGZyb20gdGhlCi8vIHB1YmxpYyBpbnRlcmZhY2UuCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKLyogSW50ZXJuYWwgY2xhc3MgZm9yIHF1aWNrIGl0ZXJhdGlvbiBvdmVyIHRoZSB0ZXh0LgogICAxMDAlIHB1cmUgaW5saW5lIGNvZGUKKi8KY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yIHsgCnB1YmxpYzoKICAgIE5vcm1hbGl6ZXIgKmN1cnNvcjsKICAgIFZlY3Rvck9mSW50ICpidWZmZXJBbGlhczsKICAgIFZlY3Rvck9mSW50ICpyZW9yZGVyQnVmZmVyOwogICAgVmVjdG9yT2ZJbnQgb3duQnVmZmVyOwogICAgVUNoYXIqICAgICAgdGV4dDsKICAgIGludDMyX3QgICAgIGV4cEluZGV4OwogICAgaW50MzJfdCAgICAgdGV4dExlbjsKICAgIFVUZXh0T2Zmc2V0ICBjdXJyZW50T2Zmc2V0OwogICAgCiAgICBOb3JtYWxpemVySXRlcmF0b3Iodm9pZCk7CiAgICBOb3JtYWxpemVySXRlcmF0b3IoY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIE5vcm1hbGl6ZXI6OkVNb2RlIG1vZGUpOwogICAgfk5vcm1hbGl6ZXJJdGVyYXRvcih2b2lkKTsKICAgIHZvaWQgc2V0VGV4dChjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgIHZvaWQgc2V0TW9kZUFuZFRleHQoTm9ybWFsaXplcjo6RU1vZGUgbW9kZSwgY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBsZW5ndGgsIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAKICAgIFVDaGFyIGN1cnJlbnQodm9pZCkgY29uc3Q7CiAgICBVQ2hhciBuZXh0KHZvaWQpOwogICAgdm9pZCByZXNldCh2b2lkKTsKfTsKCmlubGluZQpOb3JtYWxpemVySXRlcmF0b3I6Ok5vcm1hbGl6ZXJJdGVyYXRvcigpIDoKICAgIGN1cnNvcigwKSwKICAgIGJ1ZmZlckFsaWFzKDApLAogICAgcmVvcmRlckJ1ZmZlcigwKSwKICAgIG93bkJ1ZmZlcigyKSwKICAgIHRleHQoMCksCiAgICB0ZXh0TGVuKDApLAogICAgY3VycmVudE9mZnNldCgwKSwKICAgIGV4cEluZGV4KDApCnsKfQoKaW5saW5lCk5vcm1hbGl6ZXJJdGVyYXRvcjo6Tm9ybWFsaXplckl0ZXJhdG9yKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBOb3JtYWxpemVyOjpFTW9kZSBtb2RlKSA6CiAgICBjdXJzb3IoMCksCiAgICBidWZmZXJBbGlhcygwKSwKICAgIHJlb3JkZXJCdWZmZXIoMCksCiAgICBvd25CdWZmZXIoMiksCiAgICB0ZXh0KDApLAogICAgdGV4dExlbigwKSwKICAgIGN1cnJlbnRPZmZzZXQoMCksCiAgICBleHBJbmRleCgwKQp7CiAgICBpZiAobW9kZSA9PSBOb3JtYWxpemVyOjpOT19PUCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CgogICAgfQp9CgppbmxpbmUKTm9ybWFsaXplckl0ZXJhdG9yOjp+Tm9ybWFsaXplckl0ZXJhdG9yKCkgCnsKICAgIGlmIChjdXJzb3IgIT0gMCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3I7CiAgICAgICAgY3Vyc29yID0gMDsKICAgIH0KICAgIGlmIChyZW9yZGVyQnVmZmVyICE9IDApIHsKICAgICAgICBkZWxldGUgcmVvcmRlckJ1ZmZlcjsKICAgIH0KfQoKaW5saW5lCnZvaWQKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRUZXh0KGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3QgbGVuZ3RoLCBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChjdXJzb3IgPT0gMCkgewogICAgICAgIHRleHQgPSAoVUNoYXIqKXNvdXJjZTsKICAgICAgICB0ZXh0TGVuID0gbGVuZ3RoOwogICAgICAgIGN1cnJlbnRPZmZzZXQgPSAwOwoKICAgIH0gZWxzZSB7CiAgICAgICAgdGV4dCA9IDA7CiAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgfQogICAgYnVmZmVyQWxpYXMgPSAwOwogICAgY3VycmVudE9mZnNldCA9IDA7Cn0KCi8qIFlvdSBjYW4gb25seSBzZXQgbW9kZSBhZnRlciB0aGUgY29tcGFyaXNpb24gb2YgdHdvIHN0cmluZ3MgaXMgY29tcGxldGVkLgogICBTZXR0aW5nIHRoZSBtb2RlIGluIHRoZSBtaWRkbGUgb2YgYSBjb21wYXJpc29uIGlzIG5vdCBhbGxvd2VkLgogICAqLwppbmxpbmUKdm9pZAoKTm9ybWFsaXplckl0ZXJhdG9yOjpzZXRNb2RlQW5kVGV4dChOb3JtYWxpemVyOjpFTW9kZSBtb2RlLCBjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IGxlbmd0aCwgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICBpZihtb2RlICE9IE5vcm1hbGl6ZXI6Ok5PX09QKQogICAgewogICAgICAgIC8qIERPIGhhdmUgYSBtb2RlIC0gIHdpbGwgbmVlZCBhIG5vcm1hbGl6ZXIgb2JqZWN0ICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICAvKiBKdXN0IG1vZGlmeSB0aGUgZXhpc3RpbmcgY3Vyc29yICovCiAgICAgICAgICAgIGN1cnNvci0+c2V0TW9kZShtb2RlKTsKICAgICAgICAgICAgY3Vyc29yLT5zZXRUZXh0KHNvdXJjZSwgbGVuZ3RoLCBzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjdXJzb3IgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIGxlbmd0aCwgbW9kZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBSRVNFVCB0aGUgb2xkIGRhdGEgKi8KICAgICAgICB0ZXh0ID0gMDsKICAgICAgICB0ZXh0TGVuID0gMDsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogTk9fT1AgbW9kZS4uICovCiAgICAgICAgaWYoY3Vyc29yICE9IE5VTEwpCiAgICAgICAgeyAvKiBnZXQgcmlkIG9mIHRoZSBvbGQgY3Vyc29yICovCiAgICAgICAgICAgIGRlbGV0ZSBjdXJzb3I7IAogICAgICAgICAgICBjdXJzb3IgPSAwOwogICAgICAgIH0KCiAgICAgICAgdGV4dCA9IChVQ2hhciopc291cmNlOwogICAgICAgIHRleHRMZW4gPSBsZW5ndGg7CiAgICB9CiAgICBjdXJyZW50T2Zmc2V0ID0gMDsgLyogYWx3YXlzICovCiAgIAogICAgYnVmZmVyQWxpYXMgPSAwOwp9CgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpjdXJyZW50KHZvaWQpIGNvbnN0CnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICBpZihjdXJyZW50T2Zmc2V0ID49IHRleHRMZW4pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTm9ybWFsaXplcjo6RE9ORTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRleHRbY3VycmVudE9mZnNldF07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAoVUNoYXIpY3Vyc29yLT5jdXJyZW50KCk7Cn0KCgppbmxpbmUKVUNoYXIKTm9ybWFsaXplckl0ZXJhdG9yOjpuZXh0KHZvaWQpCnsKICAgIGlmICh0ZXh0ICE9IDApIHsKICAgICAgICByZXR1cm4gKChjdXJyZW50T2Zmc2V0IDwgdGV4dExlbikgPyB0ZXh0WysrY3VycmVudE9mZnNldF0gOiBOb3JtYWxpemVyOjpET05FKTsKICAgIH0KICAgIHJldHVybiAoVUNoYXIpY3Vyc29yLT5uZXh0KCk7Cn0KCmlubGluZQp2b2lkCk5vcm1hbGl6ZXJJdGVyYXRvcjo6cmVzZXQodm9pZCkKewogICAgY3VycmVudE9mZnNldCA9IDA7CiAgICBpZihjdXJzb3IpCiAgICB7CiAgICAgICAgY3Vyc29yLT5yZXNldCgpOwogICAgfQp9CgovLz09PT09PT09PT09PT09PT0gU29tZSBpbmxpbmUgZGVmaW5pdGlvbnMgb2YgaW1wbGVtZW50YXRpb24gZnVuY3Rpb25zLi4uLi4uLi4gPT09PT09PT0KLyoqCiAqIEEgY2xvbmUgb2YgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjptYWtlUmVvcmRlcmVkQnVmZmVyLCB0cmltbWVkIGRvd24KICogdG8gb25seSBoYW5kbGUgZm9yd2FyZC4KICovCmlubGluZSBWZWN0b3JPZkludCoKUnVsZUJhc2VkQ29sbGF0b3I6Om1ha2VSZW9yZGVyZWRCdWZmZXIoTm9ybWFsaXplckl0ZXJhdG9yKiBjdXJzb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNvbEZpcnN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxhc3RWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yT2ZJbnQqIGxhc3RFeHBhbnNpb24pIGNvbnN0IHsKICAgIFZlY3Rvck9mSW50KiByZXN1bHQ7CgogICAgaW50MzJfdCBmaXJzdFZhbHVlID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjb2xGaXJzdCk7CiAgICBpZiAoZmlyc3RWYWx1ZSA+PSBDT05UUkFDVENIQVJJTkRFWCkgewogICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICAgIGZpcnN0VmFsdWUgPSBuZXh0Q29udHJhY3RDaGFyKGN1cnNvciwgY29sRmlyc3QsIHN0YXR1cyk7CiAgICB9CgogICAgVmVjdG9yT2ZJbnQqIGZpcnN0RXhwYW5zaW9uID0gTlVMTDsKICAgIGlmIChmaXJzdFZhbHVlID49IEVYUEFORENIQVJJTkRFWCkgewogICAgICAgIGZpcnN0RXhwYW5zaW9uID0gZ2V0RXhwYW5kVmFsdWVMaXN0KGZpcnN0VmFsdWUpOwogICAgfQoKICAgIGlmIChmaXJzdEV4cGFuc2lvbiA9PSBOVUxMICYmIGxhc3RFeHBhbnNpb24gPT0gTlVMTCkgewogICAgICAgIGN1cnNvci0+b3duQnVmZmVyLmF0KDApID0gZmlyc3RWYWx1ZTsKICAgICAgICBjdXJzb3ItPm93bkJ1ZmZlci5hdCgxKSA9IGxhc3RWYWx1ZTsKICAgICAgICByZXN1bHQgPSAmY3Vyc29yLT5vd25CdWZmZXI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpbnQzMl90IGZpcnN0TGVuZ3RoID0gZmlyc3RFeHBhbnNpb249PU5VTEw/IDEgOiBmaXJzdEV4cGFuc2lvbi0+c2l6ZSgpOwogICAgICAgIGludDMyX3QgbGFzdExlbmd0aCA9IGxhc3RFeHBhbnNpb249PU5VTEw/IDEgOiBsYXN0RXhwYW5zaW9uLT5zaXplKCk7CiAgICAgICAgaWYgKGN1cnNvci0+cmVvcmRlckJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgICAgIGN1cnNvci0+cmVvcmRlckJ1ZmZlciA9IG5ldyBWZWN0b3JPZkludChmaXJzdExlbmd0aCtsYXN0TGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgLy8gcmVvcmRlcmRCdWZmZXIgZ2V0cyByZXVzZWQgZm9yIHRoZSBsaWZlIG9mIHRoaXMgb2JqZWN0LgogICAgICAgIC8vIFNpbmNlIGl0cyBpbnRlcm5hbCBidWZmZXIgb25seSBncm93cywgdGhlcmUgaXMgYSBkYW5nZXIKICAgICAgICAvLyB0aGF0IGl0IHdpbGwgZ2V0IHJlYWxseSwgcmVhbGx5IGJpZywgYW5kIG5ldmVyIHNocmluay4gIElmCiAgICAgICAgLy8gdGhpcyBpcyBhY3R1YWxseSBoYXBwZW5pbmcsIGluc2VydCBjb2RlIGhlcmUgdG8gY2hlY2sgZm9yCiAgICAgICAgLy8gdGhlIGNvbmRpdGlvbi4gIFNvbWV0aGluZyBhbG9uZyB0aGUgbGluZXMgb2Y6CiAgICAgICAgLy8hIGVsc2UgaWYgKHJlb3JkZXJCdWZmZXItPnNpemUoKSA+PSAyNTYgJiYKICAgICAgICAvLyEgICAgICAgICAgKGZpcnN0TGVuZ3RoK2xhc3RMZW5ndGgpIDwgMTYpIHsKICAgICAgICAvLyEgICAgIGRlbGV0ZSByZW9yZGVyQnVmZmVyOwogICAgICAgIC8vISAgICAgcmVvcmRlckJ1ZmZlciA9IG5ldyBWZWN0b3JPZkludChmaXJzdExlbmd0aCtsYXN0TGVuZ3RoKTsKICAgICAgICAvLyEgfQogICAgICAgIC8vIFRoZSBzcGVjaWZpYyBudW1lcmljIHZhbHVlcyBuZWVkIHRvIGJlIGRldGVybWluZWQKICAgICAgICAvLyBlbXBpcmljYWxseS4gW2FsaXVdCiAgICAgICAgcmVzdWx0ID0gY3Vyc29yLT5yZW9yZGVyQnVmZmVyOwoKICAgICAgICBpZiAoZmlyc3RFeHBhbnNpb24gPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQtPmF0UHV0KDAsIGZpcnN0VmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gU3lzdGVtLmFycmF5Y29weShmaXJzdEV4cGFuc2lvbiwgMCwgcmVzdWx0LCAwLCBmaXJzdExlbmd0aCk7CiAgICAgICAgICAgICpyZXN1bHQgPSAqZmlyc3RFeHBhbnNpb247CiAgICAgICAgfQoKICAgICAgICBpZiAobGFzdEV4cGFuc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJlc3VsdC0+YXRQdXQoZmlyc3RMZW5ndGgsIGxhc3RWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyBTeXN0ZW0uYXJyYXljb3B5KGxhc3RFeHBhbnNpb24sIDAsIHJlc3VsdCwgZmlyc3RMZW5ndGgsIGxhc3RMZW5ndGgpOwogICAgICAgICAgICBmb3IgKGludDMyX3QgaT0wOyBpPGxhc3RMZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgcmVzdWx0LT5hdFB1dChmaXJzdExlbmd0aCArIGksIGxhc3RFeHBhbnNpb24tPmF0KGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXN1bHQtPnNldFNpemUoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKCgoKCmlubGluZSBpbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpzdHJlbmd0aE9yZGVyKGludDMyX3QgdmFsdWUpIGNvbnN0CnsKICAgIGlmIChnZXRTdHJlbmd0aCgpID09IFBSSU1BUlkpCiAgICB7CiAgICAgICAgcmV0dXJuICh2YWx1ZSAmIFBSSU1BUllESUZGRVJFTkNFT05MWSk7CiAgICB9IGVsc2UgaWYgKGdldFN0cmVuZ3RoKCkgPT0gU0VDT05EQVJZKQogICAgewogICAgICAgIHJldHVybiAodmFsdWUgJiBTRUNPTkRBUllESUZGRVJFTkNFT05MWSk7CiAgICB9CiAgICByZXR1cm4gdmFsdWU7Cn0KCgppbmxpbmUgaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U3RyZW5ndGhPcmRlcihOb3JtYWxpemVySXRlcmF0b3IqIGN1cnNvciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgc3RhdHVzKSBjb25zdAp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSOwogICAgfQoKICAgIGlmIChjdXJzb3ItPmJ1ZmZlckFsaWFzICE9IE5VTEwpCiAgICB7CiAgICAgICAgLy8gYnVmZmVyQWxpYXMgbmVlZHMgYSBiaXQgb2YgYW4gZXhwbGFuYXRpb24uCiAgICAgICAgLy8gV2hlbiB3ZSBoaXQgYW4gZXhwYW5kaW5nIGNoYXJhY3RlciBpbiB0aGUgdGV4dCwgd2UgY2FsbCB0aGUgb3JkZXIncwogICAgICAgIC8vIGdldEV4cGFuZFZhbHVlcyBtZXRob2QgdG8gcmV0cmlldmUgYW4gYXJyYXkgb2YgdGhlIG9yZGVyaW5ncyBmb3IgYWxsCiAgICAgICAgLy8gb2YgdGhlIGNoYXJhY3RlcnMgaW4gdGhlIGV4cGFuc2lvbiAoc2VlIHRoZSBlbmQgb2YgdGhpcyBtZXRob2QpLgogICAgICAgIC8vIFRoZSBmaXJzdCBvcmRlcmluZyBpcyByZXR1cm5lZCwgYW5kIGFuIGFsaWFzIHRvIHRoZSBvcmRlcmluZ3MgYXJyYXkKICAgICAgICAvLyBpcyBzYXZlZCBzbyB0aGF0IHRoZSByZW1haW5pbmcgb3JkZXJpbmdzIGNhbiBiZSByZXR1cm5lZCBvbiBzdWJzZXF1ZW50CiAgICAgICAgLy8gY2FsbHMgdG8gbmV4dC4gIFNvLCBpZiB0aGUgZXhwYW5kaW5nIGJ1ZmZlciBpcyBub3QgZXhoYXVzdGVkLCAKICAgICAgICAvLyBhbGwgd2UgaGF2ZSB0byBkbyBoZXJlIGlzIHJldHVybiB0aGUgbmV4dCBvcmRlcmluZyBpbiB0aGUgYnVmZmVyLiAgCiAgICAgICAgaWYgKGN1cnNvci0+ZXhwSW5kZXggPCBjdXJzb3ItPmJ1ZmZlckFsaWFzLT5zaXplKCkpCiAgICAgICAgewogICAgICAgICAgICAvL19MKChzdGRlcnIsICJuZXh0IGZyb20gWyUwOFhdIGZyb20gYnVmZmVyQWxpYXNcbiIsIHRoaXMpKTsKICAgICAgICAgICAgcmV0dXJuIHN0cmVuZ3RoT3JkZXIoY3Vyc29yLT5idWZmZXJBbGlhcy0+YXQoY3Vyc29yLT5leHBJbmRleCsrKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGN1cnNvci0+YnVmZmVyQWxpYXMgPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBVQ2hhciBjaCA9IGN1cnNvci0+Y3VycmVudCgpOwogICAgY3Vyc29yLT5uZXh0KCk7CgogICAgLy9fTCgoc3RkZXJyLCAiTmV4dCBmcm9tIFslMDhYXSA9IFslMDRYXSwgWyVjXVxuIiwgY3Vyc29yLCAoaW50KWNoICYgMHhGRkZGLCAoY2hhcikoY2ggJiAweEZGKSkpOwogICAgCiAgICBpZiAoY2ggPT0gTm9ybWFsaXplcjo6RE9ORSkgewogICAgICAgIHJldHVybiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUjsKICAgIH0KICAgIC8vIEFzayB0aGUgY29sbGF0b3IgZm9yIHRoaXMgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuCiAgICBpbnQzMl90IHZhbHVlID0gdWNtcDMyX2dldChkYXRhLT5tYXBwaW5nLCBjaCk7CgogICAgaWYgKHZhbHVlID09IFVOTUFQUEVEKQogICAgewogICAgICAgIC8vIFJldHVybmVkIGFuICJ1bm1hcHBlZCIgZmxhZyBhbmQgc2F2ZSB0aGUgY2hhcmFjdGVyIHNvIGl0IGNhbiBiZSAKICAgICAgICAvLyByZXR1cm5lZCBuZXh0IHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkLgogICAgICAgIGlmIChjaCA9PSAweDAwMDApIHJldHVybiBjaDsgLy8gXHUwMDAwIGlzIG5vdCB2YWxpZCBpbiBDKysncyBVbmljb2RlU3RyaW5nCiAgICAgICAgY3Vyc29yLT5vd25CdWZmZXIuYXQoMCkgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OlVOTUFQUEVEQ0hBUlZBTFVFOwogICAgICAgIGN1cnNvci0+b3duQnVmZmVyLmF0KDEpID0gY2ggPDwgMTY7CiAgICAgICAgY3Vyc29yLT5idWZmZXJBbGlhcyA9ICZjdXJzb3ItPm93bkJ1ZmZlcjsKCiAgICB9IGVsc2UgewogICAgICAgIAogICAgICAgIGlmICh2YWx1ZSA+PSBDT05UUkFDVENIQVJJTkRFWCkKICAgICAgICB7CiAgICAgICAgICAgIHZhbHVlID0gbmV4dENvbnRyYWN0Q2hhcihjdXJzb3IsIGNoLCBzdGF0dXMpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAodmFsdWUgPj0gRVhQQU5EQ0hBUklOREVYKSB7CiAgICAgICAgICAgIGN1cnNvci0+YnVmZmVyQWxpYXMgPSBnZXRFeHBhbmRWYWx1ZUxpc3QodmFsdWUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc1RoYWlQcmVWb3dlbChjaCkpIHsKICAgICAgICAgICAgVUNoYXIgY29uc29uYW50ID0gY3Vyc29yLT5jdXJyZW50KCk7CiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmlzVGhhaUJhc2VDb25zb25hbnQoY29uc29uYW50KSkgewogICAgICAgICAgICAgICAgY3Vyc29yLT5uZXh0KCk7CiAgICAgICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzID0gbWFrZVJlb3JkZXJlZEJ1ZmZlcihjdXJzb3IsIGNvbnNvbmFudCwgdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJzb3ItPmJ1ZmZlckFsaWFzKTsgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKGN1cnNvci0+YnVmZmVyQWxpYXMgIT0gTlVMTCkgewogICAgICAgIGN1cnNvci0+ZXhwSW5kZXggPSAxOwogICAgICAgIHZhbHVlID0gY3Vyc29yLT5idWZmZXJBbGlhcy0+YXQoMCk7CiAgICB9CgogICAgcmV0dXJuIHN0cmVuZ3RoT3JkZXIodmFsdWUpOwp9CgovLyA9PT09PT09PT09PT09PT09PT09PSBFbmQgaW5saW5lcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKCkKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YSgwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBSdWxlQmFzZWRDb2xsYXRvciYgIHRoYXQpCiAgICA6IENvbGxhdG9yKHRoYXQpLAogICAgICBpc092ZXJJZ25vcmUodGhhdC5pc092ZXJJZ25vcmUpLAogICAgICBtUGF0dGVybigwKSwKICAgICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIC8vdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgICBkYXRhSXNPd25lZChGQUxTRSksCiAgICAgIGRhdGEodGhhdC5kYXRhKSAvLyBBbGlhcyB0aGUgZGF0YSBwb2ludGVyCnsKfQoKVUJvb2wKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIHRoYXQpIGNvbnN0CnsKICAgIGlmICh0aGlzID09ICZ0aGF0KQogICAgewogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIGlmICh0aGlzLT5nZXREeW5hbWljQ2xhc3NJRCgpICE9IHRoYXQuZ2V0RHluYW1pY0NsYXNzSUQoKSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7ICAvLyBub3QgdGhlIHNhbWUgY2xhc3MKICAgIH0KCiAgICBpZiAoIUNvbGxhdG9yOjpvcGVyYXRvcj09KHRoYXQpKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdEFsaWFzID0gKFJ1bGVCYXNlZENvbGxhdG9yJil0aGF0OwoKICAgIGlmIChpc092ZXJJZ25vcmUgIT0gdGhhdEFsaWFzLmlzT3Zlcklnbm9yZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGRhdGEgIT0gdGhhdEFsaWFzLmRhdGEpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgpSdWxlQmFzZWRDb2xsYXRvciYKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPShjb25zdCAgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXQpCnsKICAgIGlmICh0aGlzICE9ICZ0aGF0KQogICAgewogICAgICAgIENvbGxhdG9yOjpvcGVyYXRvcj0odGhhdCk7CiAgICAgICAgaXNPdmVySWdub3JlID0gdGhhdC5pc092ZXJJZ25vcmU7CgogICAgICAgIGlmIChkYXRhSXNPd25lZCkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIH0KCiAgICAgICAgZGF0YSA9IDA7CiAgICAgICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgICAgIG1QYXR0ZXJuID0gMDsKICAgICAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwogICAgICAgIGRhdGEgPSB0aGF0LmRhdGE7CiAgICB9CgogICAgcmV0dXJuICp0aGlzOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogICAgOiBDb2xsYXRvcigpLAogICAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgICBtUGF0dGVybigwKSwKICAgICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIC8vLyAgICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YSgwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKICA6IENvbGxhdG9yKGNvbGxhdGlvblN0cmVuZ3RoLCBOb3JtYWxpemVyOjpOT19PUCksCiAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgbVBhdHRlcm4oMCksCiAgICAvLyAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAvLyAgICB0YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICBkYXRhKDApLAogICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihURVJUSUFSWSwgZGVjb21wb3NpdGlvbk1vZGUpLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgc291cmNlQ3Vyc29yKDApLAogICAgLy8gICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgZGF0YSgwKSwKICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICByZXR1cm47CiAgICB9CiAgCiAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihjb2xsYXRpb25TdHJlbmd0aCwgZGVjb21wb3NpdGlvbk1vZGUpLAogICAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgICBtUGF0dGVybigwKSwKICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGEoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbVJ1bGVzKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBDb25zdHJ1Y3QgdGhpcyBjb2xsYXRvcidzIHJ1bGVzZXQgZnJvbSBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChydWxlcy5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKCiAgICBkYXRhID0gbmV3IFRhYmxlQ29sbGF0aW9uRGF0YTsKICAgIGlmIChkYXRhLT5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgdXNpbmcgdGhlIGJ1aWxkIG1ldGhvZCwgc28gd2Ugb3duIGl0LgogICAgZGF0YUlzT3duZWQgPSBUUlVFOwoKICAgIC8vIE5vdyB0aGF0IHdlJ3ZlIGdvdCBhbGwgdGhlIGJ1ZmZlcnMgYWxsb2NhdGVkLCBkbyB0aGUgYWN0dWFsIHdvcmsKICAgIG1QYXR0ZXJuID0gMDsKICAgIGJ1aWxkKHJ1bGVzLCBzdGF0dXMpOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tRmlsZShjb25zdCBjaGFyKiBmaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gVGhpcyBtZXRob2QgdHJpZXMgdG8gcmVhZCBpbiBhIGZsYXR0ZW5lZCBSdWxlQmFzZWRDb2xsYXRvciB0aGF0CiAgICAvLyBoYXMgYmVlbiBwcmV2aW91c2x5IHN0cmVhbWVkIG91dCB1c2luZyB0aGUgc3RyZWFtT3V0KCkgbWV0aG9kLgogICAgLy8gVGhlICdmaWxlTmFtZScgcGFyYW1ldGVyIHNob3VsZCBjb250YWluIGEgZnVsbCBwYXRobmFtZSB2YWxpZCBvbgogICAgLy8gdGhlIGxvY2FsIGVudmlyb25tZW50LgoKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKICAgIG1QYXR0ZXJuID0gMDsKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsgLy8gVGhpcyBpcyB0aGUgZGVmYXVsdCBzdHJlbmd0aAoKICAgIEZpbGVTdHJlYW0qIGlmcyA9IFRfRmlsZVN0cmVhbV9vcGVuKGZpbGVOYW1lLCAicmIiKTsKICAgIGlmIChpZnMgPT0gMCkgewogICAgICAgIHN0YXR1cyA9IFVfRklMRV9BQ0NFU1NfRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIFRoZSBzdHJlYW1JbiBmdW5jdGlvbiBkb2VzIHRoZSBhY3R1YWwgd29yayBoZXJlLi4uCiAgICBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1Jbih0aGlzLCBpZnMpOwoKICAgIGlmICghVF9GaWxlU3RyZWFtX2Vycm9yKGlmcykpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgfQogICAgZWxzZSBpZiAoZGF0YSAmJiBkYXRhLT5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CgojaWZkZWYgQ09MTERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgImJpbmFyeSByZWFkICVzIHNpemUgJWQsICVzXG4iLCBmaWxlTmFtZSwgVF9GaWxlU3RyZWFtX3NpemUoaWZzKSwgdV9lcnJvck5hbWUoc3RhdHVzKSk7CiNlbmRpZgoKICAgIC8vIFdlIGNvbnN0cnVjdGVkIHRoZSBkYXRhIHdoZW4gc3RyZWFtaW5nIGl0IGluLCBzbyB3ZSBvd24gaXQKICAgIGRhdGFJc093bmVkID0gVFJVRTsKCiAgICBUX0ZpbGVTdHJlYW1fY2xvc2UoaWZzKTsKfQoKY29uc3QgY2hhciAqClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tQnVuZGxlKGNvbnN0IExvY2FsZSAmIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAvLyBUaGlzIG1ldGhvZCB0cmllcyB0byBsb2NhdGUgYmluYXJ5IGNvbGxhdGlvbiBkYXRhIHdoaWNoIGhhcyBiZWVuIAogIC8vIHByZXZpb3VzbHkgc3RyZWFtZWQgdG8gYSBiaW5hcnkgb2JqZWN0ICIlJUNvbGxhdGlvbiIgaW4gYSAKICAvLyByZXNvdXJjZSBidW5kbGUuIElmIHRoZSBkYXRhIGlzIGZvdW5kLCBpdCBpcyBjYWNoZWQuCiAgLy8gY2FjaGUgaXMgY2hlY2tlZCBiZWZvcmUgYWN0dWFsbHkgc3RyZWFtaW5nIGluIGRhdGEKICAvLyByZXNvdXJjZSBidW5kbGUgZmFsbGJhY2sgbWVjaGFuaXNtIGlzIHVzZWQuCgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KICAgIGNvbnN0IGNoYXIqIHJlYWxOYW1lID0gMDsKCiAgICBtUGF0dGVybiA9IDA7CiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7IC8vIFRoaXMgaXMgdGhlIGRlZmF1bHQgc3RyZW5ndGgKCiAgICBSZXNvdXJjZUJ1bmRsZSByYigoY2hhciAqKTAsIG5hbWUsIHN0YXR1cyk7CiAgICBpZihVX1NVQ0NFU1Moc3RhdHVzKSkgewogICAgICBSZXNvdXJjZUJ1bmRsZSBiaW5hcnkgPSByYi5nZXQoIiUlQ29sbGF0aW9uIiwgc3RhdHVzKTsgLy9UaGlzIGlzIHRoZSBidW5kbGUgdGhhdCBhY3R1YWxseSBjb250YWlucyB0aGUgY29sbGF0aW9uIGRhdGEKICAgICAgcmVhbE5hbWUgPSBiaW5hcnkuZ2V0TmFtZSgpOwogICAgICBpZihVX1NVQ0NFU1Moc3RhdHVzKSkgewoJVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7Cgljb25zdHJ1Y3RGcm9tQ2FjaGUocmVhbE5hbWUsIGludFN0YXR1cyk7IC8vIGNoZWNrIHdoZXRoZXIgd2UgYWxyZWFkeSBoYXZlIHRoaXMgZGF0YSBpbiBjYWNoZQoJaWYoVV9TVUNDRVNTKGludFN0YXR1cykpIHsKCSAgcmV0dXJuIHJlYWxOYW1lOwoJfQoJaW50MzJfdCBpbkRhdGFMZW4gPSAwOwoJY29uc3QgdWludDhfdCAqaW5EYXRhID0gYmluYXJ5LmdldEJpbmFyeShpbkRhdGFMZW4sIHN0YXR1cyk7IC8vVGhpcyBnb3QgdXMgdGhlIHJlYWwgYmluYXJ5IGRhdGEKCQoJVU1lbW9yeVN0cmVhbSAqaWZzID0gdXBydl9tc3RybV9vcGVuQnVmZmVyKGluRGF0YSwgaW5EYXRhTGVuKTsKCQoJaWYgKGlmcyA9PSAwKSB7CgkgIHN0YXR1cyA9IFVfRklMRV9BQ0NFU1NfRVJST1I7CgkgIHJldHVybiAwOwoJfQoKCS8vIFRoZSBzdHJlYW1JbiBmdW5jdGlvbiBkb2VzIHRoZSBhY3R1YWwgd29yayBoZXJlLi4uCglSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1Jbih0aGlzLCBpZnMpOwoKCWlmICghdXBydl9tc3RybV9lcnJvcihpZnMpKSB7Cgl9CgllbHNlIGlmIChkYXRhICYmIGRhdGEtPmlzQm9ndXMoKSkgewoJICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwoJICBkZWxldGUgZGF0YTsKCSAgZGF0YSA9IDA7Cgl9IGVsc2UgewoJICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CgkgIGRlbGV0ZSBkYXRhOwoJICBkYXRhID0gMDsKCX0KCgkvLyBXZSBjb25zdHJ1Y3RlZCB0aGUgZGF0YSB3aGVuIHN0cmVhbWluZyBpdCBpbiwgc28gd2Ugb3duIGl0CglkYXRhSXNPd25lZCA9IFRSVUU7CgoJdXBydl9tc3RybV9jbG9zZShpZnMpOwoJYWRkVG9DYWNoZShyZWFsTmFtZSk7IC8vIGFkZCB0aGUgbmV3bHkgY29uc3RydWN0ZWQgZGF0YSB0byBjYWNoZQoJcmV0dXJuIHJlYWxOYW1lOwogICAgICB9IGVsc2UgewoJc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwoJcmV0dXJuIDA7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvciggICBjb25zdCBMb2NhbGUmIGRlc2lyZWRMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQogICAgOiBDb2xsYXRvcigpLAogICAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgICBkYXRhSXNPd25lZChGQUxTRSksCiAgICAgIGRhdGEoMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgbVBhdHRlcm4oMCkKewoKCiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICByZXR1cm47CiAgfQogIAogIC8vIFRyeSB0byBsb2FkLCBpbiBvcmRlcjoKICAvLyAxLiBUaGUgZGVzaXJlZCBsb2NhbGUncyBjb2xsYXRpb24uCiAgLy8gMi4gQSBmYWxsYmFjayBvZiB0aGUgZGVzaXJlZCBsb2NhbGUuCiAgLy8gMy4gVGhlIGRlZmF1bHQgbG9jYWxlJ3MgY29sbGF0aW9uLgogIC8vIDQuIEEgZmFsbGJhY2sgb2YgdGhlIGRlZmF1bHQgbG9jYWxlLgogIC8vIDUuIFRoZSBkZWZhdWx0IGNvbGxhdGlvbiBydWxlcywgd2hpY2ggY29udGFpbnMgZW5fVVMgY29sbGF0aW9uIHJ1bGVzLgoKICAvLyBUbyByZWl0ZXJhdGUsIHdlIHRyeToKICAvLyBTcGVjaWZpYzoKICAvLyAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkKICAvLyAgbGFuZ3VhZ2UKICAvLyBEZWZhdWx0OgogIC8vICBsYW5ndWFnZStjb3VudHJ5K3ZhcmlhbnQKICAvLyAgbGFuZ3VhZ2UrY291bnRyeQogIC8vICBsYW5ndWFnZQogIC8vIFJvb3Q6IChha2EgREVGQVVMVFJVTEVTKQogIC8vIHN0ZXBzIDEtNSBhcmUgaGFuZGxlZCBieSByZXNvdXJjZSBidW5kbGUgZmFsbGJhY2sgbWVjaGFuaXNtLiAKICAvLyBob3dldmVyLCBpbiBhIHZlcnkgdW5wcm9iYWJsZSBzaXR1YXRpb24gdGhhdCBubyByZXNvdXJjZSBidW5kbGUKICAvLyBkYXRhIGV4aXN0cywgc3RlcCA1IGlzIHJlcGVhdGVkIHdpdGggaGFyZGNvZGVkIGRlZmF1bHQgcnVsZXMuCgogIGNvbnN0IGNoYXIgKmxvY05hbWUgPSBjb25zdHJ1Y3RGcm9tQnVuZGxlKGRlc2lyZWRMb2NhbGUsIHN0YXR1cyk7ICAvKiEqLwogIGRhdGEtPmRlc2lyZWRMb2NhbGUgPSBkZXNpcmVkTG9jYWxlOwogIAogIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkgewogICAgZGF0YS0+cmVhbExvY2FsZU5hbWUgPSBsb2NOYW1lOwogICAgaWYoc3RhdHVzICE9IFVfVVNJTkdfREVGQVVMVF9FUlJPUikgewogICAgICBzZXREZWNvbXBvc2l0aW9uKE5vcm1hbGl6ZXI6Ok5PX09QKTsKICAgIH0KICB9IGVsc2UgewogICAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBjb25zdHJ1Y3RGcm9tQ2FjaGUoUmVzb3VyY2VCdW5kbGU6OmtEZWZhdWx0RmlsZW5hbWUsIGludFN0YXR1cyk7CiAgICBpZihVX0ZBSUxVUkUoaW50U3RhdHVzKSkgewogICAgICBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgIGNvbnN0cnVjdEZyb21SdWxlcyhSdWxlQmFzZWRDb2xsYXRvcjo6REVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwogICAgICBpZiAoaW50U3RhdHVzID09IFVfWkVST19FUlJPUikgewoJc3RhdHVzID0gVV9VU0lOR19ERUZBVUxUX0VSUk9SOwogICAgICB9IGVsc2UgewoJc3RhdHVzID0gaW50U3RhdHVzOyAgICAgLy8gYnViYmxlIGJhY2sKICAgICAgfQogICAgCiAgICAgIGlmIChzdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikgewoJcmV0dXJuOwogICAgICB9CiAgICB9CiAgICBkYXRhLT5yZWFsTG9jYWxlTmFtZSA9IFJlc291cmNlQnVuZGxlOjprRGVmYXVsdEZpbGVuYW1lOwogICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpOT19PUCk7CiAgICBhZGRUb0NhY2hlKFJlc291cmNlQnVuZGxlOjprRGVmYXVsdEZpbGVuYW1lKTsKICB9CiAgcmV0dXJuOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tRmlsZSggICBjb25zdCBMb2NhbGUmICAgICAgICAgICBsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIGxvY2FsZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCAgICAgICAgICAgICAgICAgIHRyeUJpbmFyeUZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgICAgICAgICBzdGF0dXMpCnsKICAvLyBjb25zdHJ1Y3RGcm9tRmlsZSBjcmVhdGVzIGEgY29sbGF0aW9uIG9iamVjdCBieSByZWFkaW5nIGZyb20gYQogIC8vIGZpbGUuICBJdCBkb2VzIG5vdCBlbXBsb3kgdGhlIHVzdWFsIEZJTEUgc2VhcmNoIG1lY2hhbmlzbSB3aXRoCiAgLy8gbG9jYWxlcywgZGVmYXVsdCBsb2NhbGVzLCBhbmQgYmFzZSBsb2NhbGVzLiAgSW5zdGVhZCwgaXQgdHJpZXMgdG8KICAvLyBsb29rIG9ubHkgaW4gZmlsZXMgd2l0aCB0aGUgZ2l2ZW4gbG9jYWxGaWxlTmFtZS4gIEl0IGRvZXMsCiAgLy8gaG93ZXZlciwgZW1wbG95IHRoZSBMT0NBTEUgc2VhcmNoIG1lY2hhbmlzbS4KICAKICAvLyBUaGlzIG1ldGhvZCBtYWludGFpbnMgdGhlIGJpbmFyeSBjb2xsYXRpb24gZmlsZXMuICBJZiBhIGNvbGxhdGlvbgogIC8vIGlzIG5vdCBwcmVzZW50IGluIGJpbmFyeSBmb3JtLCBidXQgaXMgcHJlc2VudCBpbiB0ZXh0IGZvcm0gKGluIGEKICAvLyByZXNvdXJjZSBidW5kbGUgZmlsZSksIGl0IHdpbGwgYmUgbG9hZGVkIGluIHRleHQgZm9ybSwgYW5kIHRoZW4KICAvLyB3cml0dGVuIHRvIGRpc2suCiAgCiAgLy8gSWYgdHJ5QmluYXJ5RmlsZSBpcyB0cnVlLCB0aGVuIHRyeSB0byBsb2FkIGZyb20gdGhlIGJpbmFyeSBmaWxlIGZpcnN0LgoKICBpZihVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuOwogIH0KICAKICBpZihkYXRhSXNPd25lZCkgewogICAgZGVsZXRlIGRhdGE7CiAgICBkYXRhID0gMDsKICB9CiAgCiAgICBpZih0cnlCaW5hcnlGaWxlKSB7CiAgICAgIGNoYXIgKmJpbmFyeUZpbGVQYXRoID0gY3JlYXRlUGF0aE5hbWUoVW5pY29kZVN0cmluZyh1X2dldERhdGFEaXJlY3RvcnkoKSwiIiksIAoJCQkJCSAgICBsb2NhbGVGaWxlTmFtZSwgVW5pY29kZVN0cmluZyhrRmlsZW5hbWVTdWZmaXgsIiIpKTsKICAKICAgICAgICAvLyBUcnkgdG8gbG9hZCB1cCB0aGUgY29sbGF0aW9uIGZyb20gYSBiaW5hcnkgZmlsZSBmaXJzdAogICAgICAgIGNvbnN0cnVjdEZyb21GaWxlKGJpbmFyeUZpbGVQYXRoLCBzdGF0dXMpOwogICAgICAgICNpZmRlZiBDT0xMREVCVUcKICAgICAgICAgICAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSAgPDwga0ZpbGVuYW1lU3VmZml4IDw8ICIgYmluYXJ5IGxvYWQgIiA8PCB1X2Vycm9yTmFtZShzdGF0dXMpIDw8IGVuZGw7CiAgICAgICAgI2VuZGlmCiAgICAgICAgaWYoVV9TVUNDRVNTKHN0YXR1cykgfHwgc3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpIHsKICAgICAgICAgICAgZGVsZXRlIFtdIGJpbmFyeUZpbGVQYXRoOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGlmKHN0YXR1cyA9PSBVX0ZJTEVfQUNDRVNTX0VSUk9SKSB7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICB9CiAgICAgICAgZGVsZXRlIFtdIGJpbmFyeUZpbGVQYXRoOwogICAgfQoKICAvLyBOb3cgdHJ5IHRvIGxvYWQgaXQgdXAgZnJvbSBhIHJlc291cmNlIGJ1bmRsZSB0ZXh0IHNvdXJjZSBmaWxlCiAgVW5pY29kZVN0cmluZyBkYXRhRGlyID0gVW5pY29kZVN0cmluZyh1X2dldERhdGFEaXJlY3RvcnkoKSwiIik7CgogICAgY2hhciAqY2g7CiAgICBjaCA9IG5ldyBjaGFyW2xvY2FsZUZpbGVOYW1lLnNpemUoKSArIDFdOwogICAgY2hbbG9jYWxlRmlsZU5hbWUuZXh0cmFjdCgwLCAweDdmZmZmZmZmLCBjaCwgIiIpXSA9IDA7CiAgICBSZXNvdXJjZUJ1bmRsZSBidW5kbGUoZGF0YURpciwgY2gsIHN0YXR1cyk7CiAgCiAgICBkZWxldGUgW10gY2g7CiAgCiAgLy8gaWYgdGhlcmUgaXMgbm8gcmVzb3VyY2UgYnVuZGxlIGZpbGUgZm9yIHRoZSBnaXZlIGxvY2FsZSwgYnJlYWsgb3V0CiAgaWYoVV9GQUlMVVJFKHN0YXR1cykpCiAgewogICAgICByZXR1cm47CiAgfQoKICAgICNpZmRlZiBDT0xMREVCVUcKICAgICAgICBjZXJyIDw8IGxvY2FsZUZpbGVOYW1lIDw8ICIgYXNjaWkgbG9hZCAiIDw8IHVfZXJyb3JOYW1lKHN0YXR1cykgPDwgZW5kbDsKICAgICNlbmRpZgoKICAgIC8vIGNoZWNrIGFuZCBzZWUgaWYgdGhpcyByZXNvdXJjZSBidW5kbGUgY29udGFpbnMgY29sbGF0aW9uIGRhdGEKICAKICAgIFVuaWNvZGVTdHJpbmcgY29sU3RyaW5nOwogICAgVUVycm9yQ29kZSBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CgogICAgUmVzb3VyY2VCdW5kbGUgY29sRWxlbXMgPSBidW5kbGUuZ2V0KCJDb2xsYXRpb25FbGVtZW50cyIsIGludFN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKGludFN0YXR1cykpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNvbFN0cmluZyA9IGNvbEVsZW1zLmdldFN0cmluZ0V4KCJTZXF1ZW5jZSIsIGludFN0YXR1cyk7CgogICAgaWYoVV9GQUlMVVJFKGludFN0YXR1cykpIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmKGNvbFN0cmluZy5pc0JvZ3VzKCkpIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgLy8gSGF2aW5nIGxvYWRlZCB0aGUgY29sbGF0aW9uIGZyb20gdGhlIHJlc291cmNlIGJ1bmRsZSB0ZXh0IGZpbGUsCiAgLy8gbm93IHJldHJpZXZlIHRoZSBDb2xsYXRpb25FbGVtZW50cyB0YWdnZWQgZGF0YSwgbWVyZ2VkIHdpdGggdGhlCiAgLy8gZGVmYXVsdCBydWxlcy4gIElmIHRoYXQgZmFpbHMsIHVzZSB0aGUgZGVmYXVsdCBydWxlcyBhbG9uZS4KCiAgY29sU3RyaW5nLmluc2VydCgwLCBERUZBVUxUUlVMRVMpOwogIGlmKGNvbFN0cmluZy5pc0JvZ3VzKCkpIHsKICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICByZXR1cm47CiAgfQogICAgCiAgY29uc3RydWN0RnJvbVJ1bGVzKGNvbFN0cmluZywgaW50U3RhdHVzKTsKICBpZihpbnRTdGF0dXMgPT0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUikgewogICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgIHJldHVybjsKICB9CiAgCiAgaWYoaW50U3RhdHVzICE9IFVfWkVST19FUlJPUikgIHsKICAgIHN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgICAgCiAgICAvLyBwcmVkZWZpbmVkIHRhYmxlcyBzaG91bGQgY29udGFpbiBjb3JyZWN0IGdyYW1tYXIKICAgIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhERUZBVUxUUlVMRVMsIGludFN0YXR1cyk7CiAgICBpZihpbnRTdGF0dXMgIT0gVV9aRVJPX0VSUk9SKSB7CiAgICAgIHN0YXR1cyA9IGludFN0YXR1czsKICAgIH0KICB9IAogIAojaWZkZWYgQ09MTERFQlVHCiAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSA8PCAiIGFzY2lpIGxvYWQgIiA8PCAoVV9TVUNDRVNTKHN0YXR1cykgPyAiT0siIDogIkZhaWxlZCIpIDw8ICIgLSB0cnk9ICIgPDwgKHRyeUJpbmFyeUZpbGU/InRydWUiOiJmYWxzZSIpIDw8IGVuZGw7CiNlbmRpZgoKfQoKUnVsZUJhc2VkQ29sbGF0b3I6On5SdWxlQmFzZWRDb2xsYXRvcigpCnsKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgIH0KCiAgICBkYXRhID0gMDsKCiAgICAvLyAgICBkZWxldGUgc291cmNlQ3Vyc29yOwogICAgLy8gICAgc291cmNlQ3Vyc29yID0gMDsKCiAgICAvLyAgICBkZWxldGUgdGFyZ2V0Q3Vyc29yOwogICAgLy8gICAgdGFyZ2V0Q3Vyc29yID0gMDsKCiAgICBpZiAoY3Vyc29yMSAhPSBOVUxMKSB7CiAgICAgICAgZGVsZXRlIGN1cnNvcjE7CiAgICAgICAgY3Vyc29yMSA9IDA7CiAgICB9CiAgICBpZiAoY3Vyc29yMiAhPSBOVUxMKSB7CiAgICAgICAgZGVsZXRlIGN1cnNvcjI7CiAgICAgICAgY3Vyc29yMiA9IDA7CiAgICB9CgogICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgbVBhdHRlcm4gPSAwOwp9CgpDb2xsYXRvcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lKCkgY29uc3QKewogICAgcmV0dXJuIG5ldyBSdWxlQmFzZWRDb2xsYXRvcigqdGhpcyk7Cn0KCi8vIENyZWF0ZSBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBvYmplY3QgdGhhdCB3aWxsIGl0ZXJhdG9yIG92ZXIgdGhlIGVsZW1lbnRzCi8vIGluIGEgc3RyaW5nLCB1c2luZyB0aGUgY29sbGF0aW9uIHJ1bGVzIGRlZmluZWQgaW4gdGhpcyBSdWxlQmFzZWRDb2xsYXRvcgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlKSBjb25zdAp7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqbmV3Q3Vyc29yID0gMDsKCiAgICBuZXdDdXJzb3IgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywgc3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbmV3Q3Vyc29yOwp9CgovLyBDcmVhdGUgYSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igb2JqZWN0IHRoYXQgd2lsbCBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cwovLyBpbiBhIHN0cmluZywgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyBkZWZpbmVkIGluIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UpIGNvbnN0CnsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yICpuZXdDdXJzb3IgPSAwOwoKICAgIG5ld0N1cnNvciA9IG5ldyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Ioc291cmNlLCB0aGlzLCBzdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJldHVybiBuZXdDdXJzb3I7Cn0KCi8vIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGNvbGxhdG9yJ3MgcnVsZXMuCi8vIFRoZSBzdHJpbmcgY2FuIGxhdGVyIGJlIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3IgdGhhdCB0YWtlcyBhCi8vIFVuaWNvZGVTdHJpbmcgYXJndW1lbnQsIHdoaWNoIHdpbGwgY29uc3RydWN0IGEgY29sbGF0b3IgdGhhdCdzCi8vIGZ1bmN0aW9uYWxseSBpZGVudGljYWwgdG8gdGhpcyBvbmUuCi8vIFlvdSBjYW4gYWxzbyBhbGxvdyB1c2VycyB0byBlZGl0IHRoZSBzdHJpbmcgaW4gb3JkZXIgdG8gY2hhbmdlCi8vIHRoZSBjb2xsYXRpb24gZGF0YSwgb3IgeW91IGNhbiBwcmludCBpdCBvdXQgZm9yIGluc3BlY3Rpb24sIG9yIHdoYXRldmVyLgoKY29uc3QgVW5pY29kZVN0cmluZyYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldFJ1bGVzKCkgY29uc3QKewogICAgaWYgKG1QYXR0ZXJuICE9IDApCiAgICB7CiAgICAgICAgTWVyZ2VDb2xsYXRpb24qJiBub25Db25zdE1QYXR0ZXJuID0gKihNZXJnZUNvbGxhdGlvbioqKSZtUGF0dGVybjsKICAgICAgICBtUGF0dGVybi0+ZW1pdFBhdHRlcm4oZGF0YS0+cnVsZVRhYmxlKTsKICAgICAgICBkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CiAgICAgICAgZGVsZXRlIG5vbkNvbnN0TVBhdHRlcm47CiAgICAgICAgbm9uQ29uc3RNUGF0dGVybiA9IDA7CiAgICB9CiAgICBlbHNlIGlmICghZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQpCiAgICB7CiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCB0aGUgY2FsbGVyIHdhbnRzIHRoZSBydWxlcywgYnV0IHRoZSBydWxlIHRhYmxlIGRhdGEKICAgICAgICAvLyBpcyBub3QgbG9hZGVkLiAgRnVydGhlcm1vcmUsIHRoZXJlIGlzIG5vIG1QYXR0ZXJuIG9iamVjdCB0byBsb2FkCiAgICAgICAgLy8gdGhlIHJ1bGVzIGZyb20uICBUaGVyZWZvcmUsIHdlIGZldGNoIHRoZSBydWxlcyBvZmYgdGhlIGRpc2suCiAgICAgICAgLy8gTm90aWNlIHRoYXQgd2UgcGFzcyBpbiBhIHRyeUJpbmFyeUZpbGUgdmFsdWUgb2YgRkFMU0UsIHNpbmNlCiAgICAgICAgLy8gYnkgZGVzaWduIHRoZSBiaW5hcnkgZmlsZSBoYXMgTk8gcnVsZXMgaW4gaXQhCiAgICAgICAgLy9VRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICAvL1J1bGVCYXNlZENvbGxhdG9yIHRlbXAoZGF0YS0+cmVhbExvY2FsZU5hbWUsIHN0YXR1cyk7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgdGVtcDsKICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAgICB0ZW1wLmNvbnN0cnVjdEZyb21GaWxlKGRhdGEtPmRlc2lyZWRMb2NhbGUsIGRhdGEtPnJlYWxMb2NhbGVOYW1lLCBGQUxTRSwgc3RhdHVzKTsKCiAgICAgICAgLy8gV2UgbXVzdCBjaGVjayB0aGF0IG1QYXR0ZXJuIGlzIG5vbnplcm8gaGVyZSwgb3Igd2UgcnVuIHRoZSByaXNrCiAgICAgICAgLy8gb2YgYW4gaW5maW5pdGUgbG9vcC4KICAgICAgICBpZiAoVV9TVUNDRVNTKHN0YXR1cykgJiYgdGVtcC5tUGF0dGVybiAhPSAwKQogICAgICAgIHsKICAgICAgICAgICAgZGF0YS0+cnVsZVRhYmxlID0gdGVtcC5nZXRSdWxlcygpOwogICAgICAgICAgICBkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CiNpZmRlZiBfREVCVUcKLy8gICAgICAgICAgICAgIC8vIHRoZSBmb2xsb3dpbmcgaXMgdXNlZnVsIGZvciBzcGVjaWZpYyBkZWJ1Z2dpbmcgcHVycG9zZXMKLy8gICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIG5hbWU7Ci8vICAgICAgICAgICAgICAgY2VyciA8PCAiVGFibGUgY29sbGF0aW9uIHJ1bGVzIGxvYWRlZCBkeW5hbWljYWxseSBmb3IgIgovLyAgICAgICAgICAgICAgICAgICA8PCBkYXRhLT5kZXNpcmVkTG9jYWxlLmdldE5hbWUobmFtZSkKLy8gICAgICAgICAgICAgICAgICAgPDwgIiBhdCAiCi8vICAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPnJlYWxMb2NhbGVOYW1lCi8vICAgICAgICAgICAgICAgICAgIDw8ICIsICIgPDwgZGVjIDw8IGRhdGEtPnJ1bGVUYWJsZS5zaXplKCkgPDwgIiBjaGFyYWN0ZXJzIgovLyAgICAgICAgICAgICAgICAgICA8PCBlbmRsOwojZW5kaWYKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKI2lmZGVmIF9ERUJVRwovLyAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBuYW1lOwovLyAgICAgICAgICAgICAgY2VyciA8PCAiVW5hYmxlIHRvIGxvYWQgdGFibGUgY29sbGF0aW9uIHJ1bGVzIGR5bmFtaWNhbGx5IGZvciAiCi8vICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+ZGVzaXJlZExvY2FsZS5nZXROYW1lKG5hbWUpCi8vICAgICAgICAgICAgICAgICAgPDwgIiBhdCAiCi8vICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+cmVhbExvY2FsZU5hbWUKLy8gICAgICAgICAgICAgICAgICA8PCBlbmRsOwovLyAgICAgICAgICAgICAgY2VyciA8PCAiU3RhdHVzICIgPDwgdV9lcnJvck5hbWUoc3RhdHVzKSA8PCAiLCBtUGF0dGVybiAiIDw8IHRlbXAubVBhdHRlcm4gPDwgZW5kbDsKI2VuZGlmCgkgICAgLyogU1JMIGhhdmUgdG8gYWRkIHRoaXMgYmVjYXVzZSB3ZSBub3cgaGF2ZSB0aGUgc2l0dWF0aW9uIHdoZXJlCgkgICAgICAgREVGQVVMVCBpcyBsb2FkZWQgZnJvbSBhIGJpbmFyeSBmaWxlIHcvIG5vIHJ1bGVzLiAqLwoJICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwoJICAgIHRlbXAuY29uc3RydWN0RnJvbVJ1bGVzKFJ1bGVCYXNlZENvbGxhdG9yOjpERUZBVUxUUlVMRVMsIGludFN0YXR1cyk7CgkgICAgCgkgICAgaWYoVV9TVUNDRVNTKGludFN0YXR1cykgJiYgKHRlbXAubVBhdHRlcm4gIT0gMCkpCgkgICAgICB7CgkJZGF0YS0+cnVsZVRhYmxlID0gdGVtcC5nZXRSdWxlcygpOwoJCWRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkID0gVFJVRTsKCSAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGRhdGEtPnJ1bGVUYWJsZTsKfQoKCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZSggY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgpIGNvbnN0CnsKICAgIFVuaWNvZGVTdHJpbmcgc291cmNlX3RvZ287CiAgICBVbmljb2RlU3RyaW5nIHRhcmdldF90b2dvOwogICAgVVRleHRPZmZzZXQgYmVnaW49MDsKCiAgICBzb3VyY2UuZXh0cmFjdChiZWdpbiwgdXBydl9taW4obGVuZ3RoLHNvdXJjZS5sZW5ndGgoKSksIHNvdXJjZV90b2dvKTsKICAgIHRhcmdldC5leHRyYWN0KGJlZ2luLCB1cHJ2X21pbihsZW5ndGgsdGFyZ2V0Lmxlbmd0aCgpKSwgdGFyZ2V0X3RvZ28pOwogICAgcmV0dXJuIChSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShzb3VyY2VfdG9nbywgdGFyZ2V0X3RvZ28pKTsKfQoKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0ICAgClJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKGNvbnN0ICAgVUNoYXIqIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVUNoYXIqICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRhcmdldExlbmd0aCkgY29uc3QKewogICAgLy8gY2hlY2sgaWYgc291cmNlIGFuZCB0YXJnZXQgYXJlIHZhbGlkIHN0cmluZ3MKICAgIGlmICgoKHNvdXJjZSA9PSAwKSAmJiAodGFyZ2V0ID09IDApKSB8fAogICAgICAgICgoc291cmNlTGVuZ3RoID09IDApICYmICh0YXJnZXRMZW5ndGggPT0gMCkpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICB9CgogICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IENvbGxhdG9yOjpFUVVBTDsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIGlmIChjdXJzb3IxID09IE5VTEwpCiAgICB7CiAgICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IxID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcihzb3VyY2UsIHNvdXJjZUxlbmd0aCwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjdXJzb3IxLT5zZXRNb2RlQW5kVGV4dChnZXREZWNvbXBvc2l0aW9uKCksIHNvdXJjZSwgc291cmNlTGVuZ3RoLCBzdGF0dXMpOwogICAgfQoKICAgIGlmICggLypjdXJzb3IxLT5jdXJzb3IgPT0gTlVMTCB8fCovIFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICB9CgogICAgaWYgKGN1cnNvcjIgPT0gTlVMTCkKICAgIHsKICAgICAgICAoKFJ1bGVCYXNlZENvbGxhdG9yICopdGhpcyktPmN1cnNvcjIgPSBuZXcgTm9ybWFsaXplckl0ZXJhdG9yKHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBnZXREZWNvbXBvc2l0aW9uKCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGN1cnNvcjItPnNldE1vZGVBbmRUZXh0KGdldERlY29tcG9zaXRpb24oKSwgdGFyZ2V0LCB0YXJnZXRMZW5ndGgsIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKC8qY3Vyc29yMiA9PSBOVUxMIHx8Ki8gVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgIH0KCiAgICBpbnQzMl90IHNPcmRlciwgdE9yZGVyOwogICAgLy8gICAgaW50MzJfdCBzT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUiwgdE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVI7CiAgICBVQm9vbCBnZXRzID0gVFJVRSwgZ2V0dCA9IFRSVUU7CiAgICBVQm9vbCBpbml0aWFsQ2hlY2tTZWNUZXIgPSBnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpTRUNPTkRBUlk7CiAgICBVQm9vbCBjaGVja1NlY1RlciA9IGluaXRpYWxDaGVja1NlY1RlcjsKICAgIFVCb29sIGNoZWNrVGVydGlhcnkgPSBnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpURVJUSUFSWTsKICAgIFVCb29sIGlzRnJlbmNoU2VjID0gZGF0YS0+aXNGcmVuY2hTZWM7CiAgICB1aW50MzJfdCBwU09yZGVyLCBwVE9yZGVyOwoKICAgIHdoaWxlKFRSVUUpCiAgICB7CiAgICAgICAgLy8gR2V0IHRoZSBuZXh0IGNvbGxhdGlvbiBlbGVtZW50IGluIGVhY2ggb2YgdGhlIHN0cmluZ3MsIHVubGVzcwogICAgICAgIC8vIHdlJ3ZlIGJlZW4gcmVxdWVzdGVkIHRvIHNraXAgaXQuCiAgICAgICAgaWYgKGdldHMpCiAgICAgICAgewogICAgICAgICAgICBzT3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cyk7CgogICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGdldHMgPSBUUlVFOwoKICAgICAgICBpZiAoZ2V0dCkKICAgICAgICB7CiAgICAgICAgICAgIHRPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoKE5vcm1hbGl6ZXJJdGVyYXRvciopY3Vyc29yMiwgc3RhdHVzKTsKCiAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpFUVVBTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBnZXR0ID0gVFJVRTsKCiAgICAgICAgLy8gSWYgd2UndmUgaGl0IHRoZSBlbmQgb2Ygb25lIG9mIHRoZSBzdHJpbmdzLCBqdW1wIG91dCBvZiB0aGUgbG9vcAogICAgICAgIGlmICgoc09yZGVyID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKXx8CiAgICAgICAgICAgICh0T3JkZXIgPT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvLyBJZiB0aGVyZSdzIG5vIGRpZmZlcmVuY2UgYXQgdGhpcyBwb3NpdGlvbiwgd2UgY2FuIHNraXAgdG8gdGhlCiAgICAgICAgLy8gbmV4dCBvbmUuCiAgICAgICAgcFNPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHNPcmRlcik7CiAgICAgICAgcFRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHRPcmRlcik7CiAgICAgICAgaWYgKHNPcmRlciA9PSB0T3JkZXIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoaXNGcmVuY2hTZWMgJiYgcFNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIGluIGZyZW5jaCwgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZSBtb3JlIHRvIHRoZSByaWdodCBpcyBzdHJvbmdlciwKICAgICAgICAgICAgICAgICAgICAvLyBzbyBhY2NlbnRzIGhhdmUgdG8gYmUgY2hlY2tlZCB3aXRoIGVhY2ggYmFzZSBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBpbml0aWFsQ2hlY2tTZWNUZXI7CgogICAgICAgICAgICAgICAgICAgIC8vIGJ1dCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhcmUgbGVzcyBpbXBvcnRhbnQgdGhhbiB0aGUgZmlyc3QgCiAgICAgICAgICAgICAgICAgICAgLy8gc2Vjb25kYXJ5IGRpZmZlcmVuY2UsIHNvIGNoZWNraW5nIHRlcnRpYXJ5IHJlbWFpbnMgZGlzYWJsZWQKICAgICAgICAgICAgICAgICAgICBjaGVja1RlcnRpYXJ5ID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29tcGFyZSBwcmltYXJ5IGRpZmZlcmVuY2VzIGZpcnN0LgogICAgICAgIGlmIChwU09yZGVyICE9IHBUT3JkZXIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc09yZGVyID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBlbnRpcmUgc291cmNlIGVsZW1lbnQgaXMgaWdub3JhYmxlLgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCBzb3VyY2UgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgdGFyZ2V0IGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXR0ID0gRkFMU0U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBnZXRzID0gRkFMU0U7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVGhlIHNvdXJjZSBhbmQgdGFyZ2V0IGVsZW1lbnRzIGFyZW4ndCBpZ25vcmFibGUsIGJ1dCBpdCdzIHN0aWxsIHBvc3NpYmxlCiAgICAgICAgICAgIC8vIGZvciB0aGUgcHJpbWFyeSBjb21wb25lbnQgb2Ygb25lIG9mIHRoZSBlbGVtZW50cyB0byBiZSBpZ25vcmFibGUuLi4uCiAgICAgICAgICAgIGlmIChwU09yZGVyID09IDApICAvLyBwcmltYXJ5IG9yZGVyIGluIHNvdXJjZSBpcyBpZ25vcmFibGUKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gVGhlIHNvdXJjZSdzIHByaW1hcnkgaXMgaWdub3JhYmxlLCBidXQgdGhlIHRhcmdldCdzIGlzbid0LiAgV2UgdHJlYXQgaWdub3JhYmxlcwogICAgICAgICAgICAgICAgLy8gYXMgYSBzZWNvbmRhcnkgZGlmZmVyZW5jZSwgc28gcmVtZW1iZXIgdGhhdCB3ZSBmb3VuZCBvbmUuCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCBzb3VyY2UgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgdGFyZ2V0IGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXR0ID0gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocFRPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyByZWNvcmQgZGlmZmVyZW5jZXMgLSBzZWUgdGhlIGNvbW1lbnQgYWJvdmUuCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkxFU1M7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gU2tpcCB0byB0aGUgbmV4dCB0YXJnZXQgZWxlbWVudCwgYnV0IGRvbid0IGZldGNoIGFub3RoZXIgc291cmNlIGVsZW1lbnQuCiAgICAgICAgICAgICAgICBnZXRzID0gRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBOZWl0aGVyIG9mIHRoZSBvcmRlcnMgaXMgaWdub3JhYmxlLCBhbmQgd2UgYWxyZWFkeSBrbm93IHRoYXQgdGhlIHByaW1hcnkKICAgICAgICAgICAgICAgIC8vIG9yZGVycyBhcmUgZGlmZmVyZW50IGJlY2F1c2Ugb2YgdGhlIChwU09yZGVyICE9IHBUT3JkZXIpIHRlc3QgYWJvdmUuCiAgICAgICAgICAgICAgICAvLyBSZWNvcmQgdGhlIGRpZmZlcmVuY2UgYW5kIHN0b3AgdGhlIGNvbXBhcmlzb24uCiAgICAgICAgICAgICAgICBpZiAocFNPcmRlciA8IHBUT3JkZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsgLy8gZWxzZSBvZiBpZiAoIHBTT3JkZXIgIT0gcFRPcmRlciApCiAgICAgICAgICAgIC8vIHByaW1hcnkgb3JkZXIgaXMgdGhlIHNhbWUsIGJ1dCBjb21wbGV0ZSBvcmRlciBpcyBkaWZmZXJlbnQuIFNvIHRoZXJlCiAgICAgICAgICAgIC8vIGFyZSBubyBiYXNlIGVsZW1lbnRzIGF0IHRoaXMgcG9pbnQsIG9ubHkgaWdub3JhYmxlcyAoU2luY2UgdGhlIHN0cmluZ3MgYXJlCiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZWQpCgogICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5IGRpZmZlcmVuY2UgbWF5IHN0aWxsIG1hdHRlcgogICAgICAgICAgICAgICAgdWludDMyX3Qgc2VjU09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihzT3JkZXIpOwogICAgICAgICAgICAgICAgdWludDMyX3Qgc2VjVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcih0T3JkZXIpOwoKICAgICAgICAgICAgICAgIGlmIChzZWNTT3JkZXIgIT0gc2VjVE9yZGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAoc2VjU09yZGVyIDwgc2VjVE9yZGVyKSA/IENvbGxhdG9yOjpMRVNTIDogQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOyAKICAgICAgICAgICAgICAgICAgICAvLyAoZXZlbiBpbiBmcmVuY2gsIG9ubHkgdGhlIGZpcnN0IHNlY29uZGFyeSBkaWZmZXJlbmNlIHdpdGhpbgogICAgICAgICAgICAgICAgICAgIC8vICBhIGJhc2UgY2hhcmFjdGVyIG1hdHRlcnMpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrVGVydGlhcnkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBhIHRlcnRpYXJ5IGRpZmZlcmVuY2UgbWF5IHN0aWxsIG1hdHRlcgogICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCB0ZXJTT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIoc09yZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdGVyVE9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKHRPcmRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVyU09yZGVyICE9IHRlclRPcmRlcikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgYSB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSAodGVyU09yZGVyIDwgdGVyVE9yZGVyKSA/IENvbGxhdG9yOjpMRVNTIDogQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHN0cmVuZ3RoIGlzIFRFUlRJQVJZKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tUZXJ0aWFyeSA9IEZBTFNFOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IC8vIGlmIChjaGVja1NlY1RlcikKCiAgICAgICAgfSAgLy8gaWYgKCBwU09yZGVyICE9IHBUT3JkZXIgKQogICAgfSAvLyB3aGlsZSgpCgogICAgaWYgKHNPcmRlciAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikKICAgIHsKICAgICAgICAvLyAodE9yZGVyIG11c3QgYmUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIsCiAgICAgICAgLy8gIHNpbmNlIHRoaXMgcG9pbnQgaXMgb25seSByZWFjaGVkIHdoZW4gc09yZGVyIG9yIHRPcmRlciBpcyBOVUxMT1JERVIuKQogICAgICAgIC8vIFRoZSBzb3VyY2Ugc3RyaW5nIGhhcyBtb3JlIGVsZW1lbnRzLCBidXQgdGhlIHRhcmdldCBzdHJpbmcgaGFzbid0LgogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoc09yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhbiBhZGRpdGlvbmFsIG5vbi1pZ25vcmFibGUgYmFzZSBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcHJpbWFyeSBkaWZmZXJlbmNlLCBzbyB0aGUgc291cmNlIGlzIGdyZWF0ZXIKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHNPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBzZWNvbmRhcnkgZWxlbWVudHMgbWVhbiB0aGUgc291cmNlIHN0cmluZyBpcyBncmVhdGVyCiAgICAgICAgICAgICAgICBpZiAoY2hlY2tTZWNUZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7ICAvLyAoc3RyZW5ndGggaXMgU0VDT05EQVJZKQogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gCiAgICAgICAgfQogICAgICAgIHdoaWxlICgoc09yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcihjdXJzb3IxLCBzdGF0dXMpKSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUik7CiAgICB9CiAgICBlbHNlIGlmICh0T3JkZXIgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgLy8gVGhlIHRhcmdldCBzdHJpbmcgaGFzIG1vcmUgZWxlbWVudHMsIGJ1dCB0aGUgc291cmNlIHN0cmluZyBoYXNuJ3QuCiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcih0T3JkZXIpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFdlIGZvdW5kIGFuIGFkZGl0aW9uYWwgbm9uLWlnbm9yYWJsZSBiYXNlIGNoYXJhY3RlciBpbiB0aGUgdGFyZ2V0IHN0cmluZy4KICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBwcmltYXJ5IGRpZmZlcmVuY2UsIHNvIHRoZSBzb3VyY2UgaXMgbGVzcwogICAgICAgICAgICAgICAgcmV0dXJuIENvbGxhdG9yOjpMRVNTOyAvLyAoc3RyZW5ndGggaXMgUFJJTUFSWSkKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIodE9yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIHNlY29uZGFyeSBlbGVtZW50cyBpbiB0aGUgdGFyZ2V0IG1lYW4gdGhlIHNvdXJjZSBzdHJpbmcgaXMgbGVzcwogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHRPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoY3Vyc29yMiwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQoKCiAgICAvLyBGb3IgSURFTlRJQ0FMIGNvbXBhcmlzb25zLCB3ZSB1c2UgYSBiaXR3aXNlIGNoYXJhY3RlciBjb21wYXJpc29uCiAgICAvLyBhcyBhIHRpZWJyZWFrZXIgaWYgYWxsIGVsc2UgaXMgZXF1YWwKICAgIC8vIE5PVEU6IFRoZSBqYXZhIGNvZGUgY29tcGFyZXMgcmVzdWx0IHdpdGggMCwgYW5kIAogICAgLy8gcHV0cyB0aGUgcmVzdWx0IG9mIHRoZSBzdHJpbmcgY29tcGFyaXNvbiBkaXJlY3RseSBpbnRvIHJlc3VsdAogICAgaWYgKHJlc3VsdCA9PSBDb2xsYXRvcjo6RVFVQUwgJiYgZ2V0U3RyZW5ndGgoKSA9PSBJREVOVElDQUwpCiAgICB7CiNpZiAwCiAgICAgIC8vICoqKioqKioqIGZvciB0aGUgIFVDaGFyIG5vcm1hbGl6YXRpb24gaW50ZXJmYWNlLgogICAgICAvLyBJdCBkb2Vzbid0IHdvcmsgbXVjaCBmYXN0ZXIsIGFuZCB0aGUgY29kZSB3YXMgYnJva2VuCiAgICAgIC8vIHNvIGl0J3MgY29tbWVudGVkIG91dC4gLS1zcmwKLy8gICAgICAgICAgVUNoYXIgc291cmNlRGVjb21wWzEwMjRdLCB0YXJnZXREZWNvbXBbMTAyNF07Ci8vICAJaW50MzJfdCBzb3VyY2VEZWNvbXBMZW5ndGggPSAxMDI0OwovLyAgCWludDMyX3QgdGFyZ2V0RGVjb21wTGVuZ3RoID0gMTAyNDsKCQovLyAgICAgICAgICBpbnQ4X3QgY29tcGFyaXNvbjsKLy8gIAlOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBNb2RlID0gZ2V0RGVjb21wb3NpdGlvbigpOwogICAgICAgIAovLyAgCWlmIChkZWNvbXBNb2RlICE9IE5vcm1hbGl6ZXI6Ok5PX09QKQovLyAgCSAgewovLyAgCSAgICBOb3JtYWxpemVyOjpub3JtYWxpemUoc291cmNlLCBzb3VyY2VMZW5ndGgsIGRlY29tcE1vZGUsCi8vICAJCQkJICAwLCBzb3VyY2VEZWNvbXAsIHNvdXJjZURlY29tcExlbmd0aCwgc3RhdHVzKTsKCSAgICAKLy8gIAkgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBkZWNvbXBNb2RlLAovLyAgCQkJCSAgMCwgdGFyZ2V0RGVjb21wLCB0YXJnZXREZWNvbXBMZW5ndGgsIHN0YXR1cyk7CgkgICAgCi8vICAJICAgIGNvbXBhcmlzb24gPSB1X3N0cmNtcChzb3VyY2VEZWNvbXAsdGFyZ2V0RGVjb21wKTsKLy8gIAkgIH0KLy8gIAllbHNlCi8vICAJICB7Ci8vICAJICAgIGNvbXBhcmlzb24gPSB1X3N0cmNtcChzb3VyY2UsIHRhcmdldCk7IC8qICEgKi8KLy8gIAkgIH0KCiNlbHNlCgoJVW5pY29kZVN0cmluZyBzb3VyY2VEZWNvbXAsIHRhcmdldERlY29tcDsKCiAgICAgICAgaW50OF90IGNvbXBhcmlzb247CiAgICAgICAgCiAgICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHNvdXJjZSwgZ2V0RGVjb21wb3NpdGlvbigpLCAKICAgICAgICAgICAgICAgICAgICAgIDAsIHNvdXJjZURlY29tcCwgIHN0YXR1cyk7CgogICAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZSh0YXJnZXQsIGdldERlY29tcG9zaXRpb24oKSwgCiAgICAgICAgICAgICAgICAgICAgICAwLCB0YXJnZXREZWNvbXAsICBzdGF0dXMpOwogICAgICAgIAogICAgICAgIGNvbXBhcmlzb24gPSBzb3VyY2VEZWNvbXAuY29tcGFyZSh0YXJnZXREZWNvbXApOwojZW5kaWYKCiAgICAgICAgaWYgKGNvbXBhcmlzb24gPCAwKQogICAgICAgIHsKICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkxFU1M7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGNvbXBhcmlzb24gPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpFUVVBTDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmVzdWx0ID0gQ29sbGF0b3I6OkdSRUFURVI7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCgppbnQzMl90ClJ1bGVCYXNlZENvbGxhdG9yOjpuZXh0Q29udHJhY3RDaGFyKE5vcm1hbGl6ZXJJdGVyYXRvciAqY3Vyc29yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QKewogICAgLy8gRmlyc3QgZ2V0IHRoZSBvcmRlcmluZyBvZiB0aGlzIHNpbmdsZSBjaGFyYWN0ZXIKICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICpsaXN0ID0gZ2V0Q29udHJhY3RWYWx1ZXMoY2gpOwogICAgRW50cnlQYWlyICpwYWlyID0gKEVudHJ5UGFpciAqKWxpc3QtPmF0KDApOwogICAgaW50MzJfdCBvcmRlciA9IHBhaXItPnZhbHVlOwoKICAgIC8vIE5vdyBpdGVyYXRlIHRocm91Z2ggdGhlIGNoYXJzIGZvbGxvd2luZyBpdCBhbmQKICAgIC8vIGxvb2sgZm9yIHRoZSBsb25nZXN0IG1hdGNoCiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkucmVtb3ZlKCk7CiAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkgKz0gY2g7CgogICAgd2hpbGUgKChjaCA9IGN1cnNvci0+Y3VycmVudCgpKSAhPSBOb3JtYWxpemVyOjpET05FKQogICAgewogICAgICAgICgoVW5pY29kZVN0cmluZyYpa2V5KSArPSBjaDsKCiAgICAgICAgaW50MzJfdCBuID0gZ2V0RW50cnkobGlzdCwga2V5LCBUUlVFKTsKCiAgICAgICAgaWYgKG4gPT0gVU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY3Vyc29yLT5uZXh0KCk7CgogICAgICAgIHBhaXIgPSAoRW50cnlQYWlyICopbGlzdC0+YXQobik7CiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KCi8vIENvbXBhcmUgdHdvIHN0cmluZ3MgdXNpbmcgdGhpcyBjb2xsYXRvcgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0CnsKICAgIHJldHVybiBjb21wYXJlKHNvdXJjZS5nZXRVQ2hhcnMoKSwgc291cmNlLmxlbmd0aCgpLCB0YXJnZXQuZ2V0VUNoYXJzKCksIHRhcmdldC5sZW5ndGgoKSk7Cn0KCi8vIFJldHJpZXZlIGEgY29sbGF0aW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzdHJpbmcKLy8gVGhlIGtleSBjYW4gYmUgY29tcGFyZWQgd2l0aCBvdGhlciBjb2xsYXRpb24ga2V5cyB1c2luZyBhIGJpdHdpc2UgY29tcGFyaXNvbgovLyAoZS5nLiBtZW1jbXApIHRvIGZpbmQgdGhlIG9yZGVyaW5nIG9mIHRoZWlyIHJlc3BlY3RpdmUgc291cmNlIHN0cmluZ3MuCi8vIFRoaXMgaXMgaGFuZHkgd2hlbiBkb2luZyBhIHNvcnQsIHdoZXJlIGVhY2ggc29ydCBrZXkgbXVzdCBiZSBjb21wYXJlZAovLyBtYW55IHRpbWVzLgovLwovLyBUaGUgYmFzaWMgYWxnb3JpdGhtIGhlcmUgaXMgdG8gZmluZCBhbGwgb2YgdGhlIGNvbGxhdGlvbiBlbGVtZW50cyBmb3IgZWFjaAovLyBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcsIGNvbnZlcnQgdGhlbSB0byBhbiBBU0NJSSByZXByZXNlbnRhdGlvbiwKLy8gYW5kIHB1dCB0aGVtIGludG8gdGhlIGNvbGxhdGlvbiBrZXkuICBCdXQgaXQncyB0cmlja2llciB0aGFuIHRoYXQuCi8vIEVhY2ggY29sbGF0aW9uIGVsZW1lbnQgaW4gYSBzdHJpbmcgaGFzIHRocmVlIGNvbXBvbmVudHM6IHByaW1hcnkgKCdBJyB2cyAnQicpLAovLyBzZWNvbmRhcnkgKCd1JyB2cyAn/CcpLCBhbmQgdGVydGlhcnkgKCdBJyB2cyAnYScpLCBhbmQgYSBwcmltYXJ5IGRpZmZlcmVuY2UKLy8gYXQgdGhlIGVuZCBvZiBhIHN0cmluZyB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgYSBzZWNvbmRhcnkgb3IgdGVydGlhcnkKLy8gZGlmZmVyZW5jZSBlYXJsaWVyIGluIHRoZSBzdHJpbmcuCi8vCi8vIFRvIGFjY291bnQgZm9yIHRoaXMsIHdlIHB1dCBhbGwgb2YgdGhlIHByaW1hcnkgb3JkZXJzIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlCi8vIHN0cmluZywgZm9sbG93ZWQgYnkgdGhlIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgb3JkZXJzLiBFYWNoIHNldCBvZiBvcmRlcnMgaXMKLy8gdGVybWluYXRlZCBieSBudWxscyBzbyB0aGF0IGEga2V5IGZvciBhIHN0cmluZyB3aGljaCBpcyBhIGluaXRpYWwgc3Vic3RyaW5nIG9mCi8vIGFub3RoZXIga2V5IHdpbGwgY29tcGFyZSBsZXNzIHdpdGhvdXQgYW55IHNwZWNpYWwgY2FzZS4KLy8KLy8gSGVyZSdzIGEgaHlwb3RoZXRpY2FsIGV4YW1wbGUsIHdpdGggdGhlIGNvbGxhdGlvbiBlbGVtZW50IHJlcHJlc2VudGVkIGFzCi8vIGEgdGhyZWUtZGlnaXQgbnVtYmVyLCBvbmUgZGlnaXQgZm9yIHByaW1hcnksIG9uZSBmb3Igc2Vjb25kYXJ5LCBldGMuCi8vCi8vIFN0cmluZzogICAgICAgICAgICAgIEEgICAgIGEgICAgIEIgICAgyQovLyBDb2xsYXRpb24gRWxlbWVudHM6IDEwMSAgIDEwMCAgIDIwMSAgNTExCi8vIENvbGxhdGlvbiBLZXk6ICAgICAgMTEyNTxudWxsPjAwMDE8bnVsbD4xMDExPG51bGw+Ci8vCi8vIFRvIG1ha2UgdGhpbmdzIGV2ZW4gdHJpY2tpZXIsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyAoYWNjZW50IG1hcmtzKSBhcmUgY29tcGFyZWQKLy8gc3RhcnRpbmcgYXQgdGhlICplbmQqIG9mIHRoZSBzdHJpbmcgaW4gbGFuZ3VhZ2VzIHdpdGggRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZy4KLy8gQnV0IHdoZW4gY29tcGFyaW5nIHRoZSBhY2NlbnQgbWFya3Mgb24gYSBzaW5nbGUgYmFzZSBjaGFyYWN0ZXIsIHRoZXkgYXJlIGNvbXBhcmVkCi8vIGZyb20gdGhlIGJlZ2lubmluZy4gIFRvIGhhbmRsZSB0aGlzLCB3ZSByZXZlcnNlIGFsbCBvZiB0aGUgYWNjZW50cyB0aGF0IGJlbG9uZwovLyB0byBlYWNoIGJhc2UgY2hhcmFjdGVyLCB0aGVuIHdlIHJldmVyc2UgdGhlIGVudGlyZSBzdHJpbmcgb2Ygc2Vjb25kYXJ5IG9yZGVyaW5ncwovLyBhdCB0aGUgZW5kLgovLwpDb2xsYXRpb25LZXkmClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiAgIHNvcnRrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKSBjb25zdAp7CiAgICByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleShzb3VyY2UuZ2V0VUNoYXJzKCksIHNvdXJjZS5sZW5ndGgoKSwgc29ydGtleSwgc3RhdHVzKTsKfQoKQ29sbGF0aW9uS2V5JgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KCBjb25zdCAgIFVDaGFyKiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiAgIHNvcnRrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKSBjb25zdAp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SOwogICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgIH0KICAgIAogICAgaWYgKCghc291cmNlKSB8fCAoc291cmNlTGVuID09IDApKQogICAgewogICAgICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CiAgICB9CgogICAgaWYgKGN1cnNvcjEgPT0gTlVMTCkKICAgIHsKICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IxID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcihzb3VyY2UsIHNvdXJjZUxlbiwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgY3Vyc29yMS0+c2V0TW9kZUFuZFRleHQoZ2V0RGVjb21wb3NpdGlvbigpLCBzb3VyY2Usc291cmNlTGVuLCBzdGF0dXMpOwogICAgfQoKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICB9CgogICAgVUJvb2wgIGNvbXBhcmVTZWMgICA9IChnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpTRUNPTkRBUlkpOwogICAgVUJvb2wgIGNvbXBhcmVUZXIgICA9IChnZXRTdHJlbmd0aCgpID49IENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICBVQm9vbCAgY29tcGFyZUlkZW50ID0gKGdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3I6OklERU5USUNBTCk7CiAgICBpbnQzMl90IG9yZGVyICAgICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsUHJpbWFyeSA9IDA7CiAgICBpbnQzMl90IHRvdGFsU2VjICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsVGVyICAgICA9IDA7CiAgICBpbnQzMl90IHRvdGFsSWRlbnQgICAgID0gMDsKICAgIFVuaWNvZGVTdHJpbmcgZGVjb21wOwoKICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgc291cmNlLCBjb3VudGluZyBwcmltYXJ5LCBzZWNvbmRhcnksIGFuZCB0ZXJ0aWFyeSBlbnRyaWVzCiAgICB3aGlsZSgob3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cykpICE9CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGludDMyX3Qgc2VjT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHRlck9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKG9yZGVyKTsKCiAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgICAgIH0KCiAgICAgICAgaWYgKCEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShvcmRlcikpCiAgICAgICAgewogICAgICAgICAgICB0b3RhbFByaW1hcnkgKz0gMTsKCiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxUZXIgKz0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29tcGFyZVNlYyAmJiBzZWNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlciAmJiB0ZXJPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0b3RhbFRlciArPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGNvdW50IHRoZSBudWxsIGJ5dGVzIGFmdGVyIHRoZSBlbnRpcmVzCiAgICB0b3RhbFByaW1hcnkgKz0gMTsKCiAgICBpZiAoY29tcGFyZVNlYykKICAgIHsKICAgICAgICB0b3RhbFNlYyArPSAxOwogICAgfQoKICAgIGlmIChjb21wYXJlVGVyKQogICAgewogICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICB9CgogICAgaWYgKGNvbXBhcmVJZGVudCkKICAgIHsKICAgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHNvdXJjZSwgZ2V0RGVjb21wb3NpdGlvbigpLCAvLyBTUkw6ID8/CiAgICAgICAgICAgICAgICAwLCBkZWNvbXAsIHN0YXR1cyk7CgogICAgICAgIGlmIChVX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHRvdGFsSWRlbnQgPSBkZWNvbXAubGVuZ3RoKCkgKyAxOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBDb21wdXRlIHRvdGFsIG51bWJlciBvZiBieXRlcyB0byBob2xkIHRoZSBlbnRyaWVzCiAgICAvLyBhbmQgbWFrZSBzdXJlIHRoZSBrZXkgY2FuIGhvbGQgdGhlbQogICAgdWludDMyX3Qgc2l6ZSAgID0gMiAqICh0b3RhbFByaW1hcnkgKyB0b3RhbFNlYyArIHRvdGFsVGVyICsgdG90YWxJZGVudCk7CgogICAgc29ydGtleS5lbnN1cmVDYXBhY2l0eShzaXplKTsKCiAgICBpZiAoc29ydGtleS5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm4gc29ydGtleTsKICAgIH0KCiAgICBpbnQzMl90IHByaW1hcnlDdXJzb3IgPSAwOwogICAgaW50MzJfdCBzZWNDdXJzb3IgICAgID0gMiAqIHRvdGFsUHJpbWFyeTsKICAgIGludDMyX3Qgc2VjQmFzZSAgICAgICA9IHNlY0N1cnNvcjsKICAgIGludDMyX3QgcHJlU2VjSWdub3JlICA9IHNlY0Jhc2U7CiAgICBpbnQzMl90IHRlckN1cnNvciAgICAgPSBzZWNDdXJzb3IgKyAoMiAqIHRvdGFsU2VjKTsKICAgIGludDMyX3QgaWRlbnRDdXJzb3IgICAgICA9IHRlckN1cnNvciArICgyICogdG90YWxUZXIpOwoKICAgIC8vIHJlc2V0IHNvdXJjZSB0byB0aGUgYmVnaW5uaW5nCiAgICBjdXJzb3IxLT5yZXNldCgpOwoKICAgIC8vIG5vdyBpdGVyYXRlIG92ZXIgdGhlIHNvdXJjZSBjb21wdXRpbmcgdGhlIGFjdHVhbCBlbnRyaWVzCiAgICB3aGlsZSgob3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjEsIHN0YXR1cykpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzb3J0a2V5LnJlc2V0KCk7CiAgICAgICAgfQoKICAgICAgICBpbnQzMl90IHByaW1hcnlPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHNlY09yZGVyICAgICA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIob3JkZXIpOwogICAgICAgIGludDMyX3QgdGVyT3JkZXIgICAgID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKG9yZGVyKTsKCiAgICAgICAgaWYgKCEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShvcmRlcikpCiAgICAgICAgewogICAgICAgICAgICBwcmltYXJ5Q3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHByaW1hcnlDdXJzb3IsIHByaW1hcnlPcmRlciArIFNPUlRLRVlPRkZTRVQpOwoKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChkYXRhLT5pc0ZyZW5jaFNlYyAmJiAocHJlU2VjSWdub3JlIDwgc2VjQ3Vyc29yKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzb3J0a2V5LnJldmVyc2VCeXRlcyhwcmVTZWNJZ25vcmUsIHNlY0N1cnNvcik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgc2VjQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHNlY0N1cnNvciwgc2VjT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKCiAgICAgICAgICAgICAgICBwcmVTZWNJZ25vcmUgPSBzZWNDdXJzb3I7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZXJDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXModGVyQ3Vyc29yLCB0ZXJPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjICYmIHNlY09yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNlY0N1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIHNlY09yZGVyICsgZGF0YS0+bWF4U2VjT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIgJiYgdGVyT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVyQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHRlckN1cnNvciwgdGVyT3JkZXIgKyBkYXRhLT5tYXhUZXJPcmRlciArIFNPUlRLRVlPRkZTRVQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIGFwcGVuZCAwIGF0IHRoZSBlbmQgb2YgZWFjaCBwb3J0aW9uLgogICAgc29ydGtleS5zdG9yZUJ5dGVzKHByaW1hcnlDdXJzb3IsIDApOwoKICAgIGlmIChjb21wYXJlU2VjKQogICAgewogICAgICAgIGlmIChkYXRhLT5pc0ZyZW5jaFNlYykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwcmVTZWNJZ25vcmUgPCBzZWNDdXJzb3IpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHByZVNlY0lnbm9yZSwgc2VjQ3Vyc29yKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc29ydGtleS5yZXZlcnNlQnl0ZXMoc2VjQmFzZSwgc2VjQ3Vyc29yKTsKICAgICAgICB9CgogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlVGVyKQogICAgewogICAgICAgIHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIDApOwogICAgfQoKICAgIGlmIChjb21wYXJlSWRlbnQpCiAgICB7CiAgICAgICAgc29ydGtleS5zdG9yZVVuaWNvZGVTdHJpbmcoaWRlbnRDdXJzb3IsIGRlY29tcCk7CiAgICB9CgogICAgLy8gICAgRGVidWdnaW5nIC0gcHJpbnQgb3V0IHRoZSBzb3J0a2V5IFstLXNybF0KLy8gICAgICB7Ci8vICAgICAgICBjb25zdCB1aW50OF90ICpieXRlczsKLy8gICAgICAgIGludDMyX3QgeGNvdW50OwovLyAgICAgICAgYnl0ZXMgPSBzb3J0a2V5LmdldEJ5dGVBcnJheSh4Y291bnQpOwovLyAgICAgICAgLy8gICAgICBmcHJpbnRmKHN0ZGVyciwgIlxuXG4tICBbJTAyWF0gWyUwMlhdXG5cbiIsIChpbnQpKGJ5dGVzWzBdJjB4RkYpLCAoaW50KShieXRlc1sxXSYweEZGKSApOwovLyAgICAgIH0KCiAgICByZXR1cm4gc29ydGtleTsKfQoKCi8vIEJ1aWxkIHRoaXMgY29sbGF0b3IncyBydWxlIHRhYmxlcyBiYXNlZCBvbiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcnVsZXMKLy8gU2VlIHRoZSBiaWcgZGlhZ3JhbSBhdCB0aGUgdG9wIG9mIHRoaXMgZmlsZSBmb3IgYW4gb3ZlcnZpZXcgb2YgaG93IHRoZSB0YWJsZXMKLy8gYXJlIG9yZ2FuaXplZC4Kdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YnVpbGQoY29uc3QgVW5pY29kZVN0cmluZyYgICBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gVGhpcyBhcnJheSBtYXBzIFVuaWNvZGUgY2hhcmFjdGVycyB0byB0aGVpciBjb2xsYXRpb24gb3JkZXJpbmcKICAgIGRhdGEtPm1hcHBpbmcgPSB1Y21wMzJfb3BlbihVTk1BUFBFRCk7CgogICAgaWYgKGRhdGEtPm1hcHBpbmctPmZCb2d1cykKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGFTdHJlbmd0aCA9IENvbGxhdG9yOjpJREVOVElDQUw7CiAgICBVQm9vbCBpc1NvdXJjZSA9IFRSVUU7CiAgICBpbnQzMl90IGkgPSAwOwogICAgVW5pY29kZVN0cmluZyBsYXN0R3JvdXBDaGFyczsKICAgIFVuaWNvZGVTdHJpbmcgZXhwQ2hhcnM7CiAgICBVbmljb2RlU3RyaW5nIGdyb3VwQ2hhcnM7CgogICAgaWYgKHBhdHRlcm4ubGVuZ3RoKCkgPT0gMCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX0lOVkFMSURfRk9STUFUX0VSUk9SOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBCdWlsZCB0aGUgbWVyZ2VkIGNvbGxhdGlvbiBlbnRyaWVzCiAgICAvLyBTaW5jZSBydWxlcyBjYW4gYmUgc3BlY2lmaWVkIGluIGFueSBvcmRlciBpbiB0aGUgc3RyaW5nCiAgICAvLyAoZS5nLiAiYyAsIEMgPCBkICwgRCA8IGUgLCBFIC4uLi4gQyA8IENIIikKICAgIC8vIHRoaXMgc3BsaXRzIGFsbCBvZiB0aGUgcnVsZXMgaW4gdGhlIHN0cmluZyBvdXQgaW50byBzZXBhcmF0ZQogICAgLy8gb2JqZWN0cyBhbmQgdGhlbiBzb3J0cyB0aGVtLiAgSW4gdGhlIGFib3ZlIGV4YW1wbGUsIGl0IG1lcmdlcyB0aGUKICAgIC8vICJDIDwgQ0giIHJ1bGUgaW4ganVzdCBiZWZvcmUgdGhlICJDIDwgRCIgcnVsZS4KCiAgICBtUGF0dGVybiA9IG5ldyBNZXJnZUNvbGxhdGlvbihwYXR0ZXJuLCBnZXREZWNvbXBvc2l0aW9uKCksIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgdWNtcDMyX2Nsb3NlKGRhdGEtPm1hcHBpbmcpOwogICAgICAgIGRhdGEtPm1hcHBpbmcgPSAwOwogICAgICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgICAgICBtUGF0dGVybiA9IDA7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGludDMyX3Qgb3JkZXIgPSAwOwoKICAgIC8vIFdhbGsgdGhyb3VnaCBlYWNoIGVudHJ5CiAgICBmb3IgKGkgPSAwOyBpIDwgbVBhdHRlcm4tPmdldENvdW50KCk7ICsraSkKICAgIHsKICAgICAgICBjb25zdCBQYXR0ZXJuRW50cnkqIGVudHJ5ID0gbVBhdHRlcm4tPmdldEl0ZW1BdChpKTsKICAgICAgICBncm91cENoYXJzLnJlbW92ZSgpOwogICAgICAgIGV4cENoYXJzLnJlbW92ZSgpOwoKICAgICAgICAvLyBpZiBlbnRyeSBpcyB2YWxpZAogICAgICAgIGlmIChlbnRyeSAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgZW50cnktPmdldENoYXJzKGdyb3VwQ2hhcnMpOwoKICAgICAgICAgICAgLy8gY2hlY2sgaWYgZnJlbmNoIHNlY29uZGFyeSBuZWVkcyB0byBiZSB0dXJuZWQgb24KICAgICAgICAgICAgaWYgKChncm91cENoYXJzLmxlbmd0aCgpID4gMSkgJiYKICAgICAgICAgICAgICAgIChncm91cENoYXJzW2dyb3VwQ2hhcnMubGVuZ3RoKCktMV0gPT0gMHgwMDQwKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YS0+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/ICIsIE9LIiA6ICIsIEZBSUwiKSk7CiNlbmRpZgoKICAgIFVCb29sIGVyciA9IHVwcnZfbXN0cm1fZXJyb3Iob2ZzKSA9PSAwOwoKICAgIHVwcnZfbXN0cm1fY2xvc2Uob2ZzKTsKCiAgICByZXR1cm4gZXJyOwp9CiovCgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjphZGRUb0NhY2hlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSkKewogICAgLy8gVGhpcyBtZXRob2QgZG9lc24ndCBhZGQgdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGl0c2VsZiB0byB0aGUgY2FjaGUuICBJbnN0ZWFkLAogICAgLy8gaXQgYWRkcyB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3IncyBkYXRhIG9iamVjdCB0byB0aGUgVGFibGVDb2xsYXRpb25EYXRhCiAgICAvLyBjYWNoZSwgYW5kIG1hcmtzIGl0IGFzIG5vbi1vd25lZCBpbiB0aGUgZ2l2ZW4gUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0LgogICAgVGFibGVDb2xsYXRpb25EYXRhOjphZGRUb0NhY2hlKGtleSwgZGF0YSk7CiAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tQ2FjaGUoY29uc3QgVW5pY29kZVN0cmluZyYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gQXR0ZW1wdCB0byBjb25zdHJ1Y3QgdGhpcyBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgZnJvbSBjYWNoZWQgVGFibGVDb2xsYXRpb25EYXRhLgogICAgLy8gSWYgbm8gc3VjaCBkYXRhIGlzIGluIHRoZSBjYWNoZSwgcmV0dXJuIGZhbHNlLgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IE5VTEw7CiAgICB9CgogICAgaXNPdmVySWdub3JlID0gRkFMU0U7CiAgICBsYXN0Q2hhciA9IDA7CiAgICBtUGF0dGVybiA9IDA7CiAgICBzZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwoKICAgIGRhdGFJc093bmVkID0gRkFMU0U7CiAgICBkYXRhID0gVGFibGVDb2xsYXRpb25EYXRhOjpmaW5kSW5DYWNoZShrZXkpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICB9Cn0KCmNoYXIqClJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVQYXRoTmFtZSggIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHByZWZpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIHN1ZmZpeCkKewogICAgLy8gQ29uY2F0ZW5hdGUgdGhyZWUgZWxlbWVudHMgdG8gZm9ybSBhIGZpbGUgbmFtZSwgYW5kIHJldHVybiBpdC4KCiAgICBVbmljb2RlU3RyaW5nICAgd29ya2luZ05hbWUocHJlZml4KTsKICAgIGludDMyX3QgICAgICAgICBzaXplOwogICAgY2hhciogICAgICAgICAgIHJldHVyblZhbDsKCiAgICB3b3JraW5nTmFtZSArPSBuYW1lOwogICAgd29ya2luZ05hbWUgKz0gc3VmZml4OwoKICAgIHNpemUgPSB3b3JraW5nTmFtZS5sZW5ndGgoKTsKICAgIHJldHVyblZhbCA9IG5ldyBjaGFyW3NpemUgKyAxXTsKICAgIHdvcmtpbmdOYW1lLmV4dHJhY3QoMCwgc2l6ZSwgcmV0dXJuVmFsLCAiIik7CiAgICByZXR1cm5WYWxbc2l6ZV0gPSAwOwoKICAgIHJldHVybiByZXR1cm5WYWw7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNob3BMb2NhbGUoVW5pY29kZVN0cmluZyYgbG9jYWxlTmFtZSkKewogICAgLy8gY2hvcExvY2FsZSByZW1vdmVzIHRoZSBmaW5hbCBlbGVtZW50IGZyb20gYSBsb2NhbGUgc3RyaW5nLgogICAgLy8gRm9yIGluc3RhbmNlLCAiZGVfQ0giIGJlY29tZXMgImRlIiwgYW5kICJkZSIgYmVjb21lcyAiIi4KICAgIC8vICIiIHJlbWFpbnMgIiIuCgogICAgaW50MzJfdCAgICAgc2l6ZSA9IGxvY2FsZU5hbWUubGVuZ3RoKCk7CiAgICBpbnQzMl90ICAgICBpOwoKICAgIGZvciAoaSA9IHNpemUgLSAxOyBpID4gMDsgaS0tKQogICAgewogICAgICAgIGlmIChsb2NhbGVOYW1lW2ldID09IDB4MDA1RikKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoaSA8IDApCiAgICB7CiAgICAgICBpID0gMDsKICAgIH0KCiAgICBsb2NhbGVOYW1lLnJlbW92ZShpLCBzaXplIC0gaSk7Cn0KCgp1aW50OF90ICoKUnVsZUJhc2VkQ29sbGF0b3I6OmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLCBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICBVTWVtb3J5U3RyZWFtICptZW1kYXRhID0gMDsKICB1aW50OF90ICpkYXRhID0gMDsKCiAgaWYoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgICAgIG1lbWRhdGEgPSB1cHJ2X21zdHJtX29wZW5OZXcoMCk7CgogICAgICBpZiAobWVtZGF0YSAhPSAwKSB7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtT3V0KHRoaXMsIG1lbWRhdGEpOwogICAgICB9CgogICAgICBVQm9vbCBlcnIgPSB1cHJ2X21zdHJtX2Vycm9yKG1lbWRhdGEpID09IDA7CgoKICAgIGRhdGEgPSAodWludDhfdCAqKXVwcnZfbWFsbG9jKG1lbWRhdGEtPmZQb3MpOwogICAgaWYoZGF0YSA9PSAwKSB7CiAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgIHVwcnZfbXN0cm1fY2xvc2UobWVtZGF0YSk7CiAgICAgIGxlbmd0aCA9IDA7CiAgICAgIHJldHVybiAwOwogICAgfSBlbHNlIHsKICAgICAgdXBydl9tZW1jcHkoZGF0YSwgbWVtZGF0YS0+ZlN0YXJ0LCBtZW1kYXRhLT5mUG9zKTsKICAgICAgbGVuZ3RoID0gbWVtZGF0YS0+ZlBvczsKICAgICAgdXBydl9tc3RybV9jbG9zZShtZW1kYXRhKTsKICAgICAgcmV0dXJuIGRhdGE7CiAgICB9Cn0KCgovL2VvZgo=