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+YXQoMCk7CiAgICB9CgogICAgcmV0dXJuIHN0cmVuZ3RoT3JkZXIodmFsdWUpOwp9CgovLyA9PT09PT09PT09PT09PT09PT09PSBFbmQgaW5saW5lcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKCkKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgbVBhdHRlcm4oMCksCiAgICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgICAvL3RhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YSgwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKfQoKUnVsZUJhc2VkQ29sbGF0b3I6OlJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0ICBSdWxlQmFzZWRDb2xsYXRvciYgIHRoYXQpCiAgICA6IENvbGxhdG9yKHRoYXQpLAogICAgICBpc092ZXJJZ25vcmUodGhhdC5pc092ZXJJZ25vcmUpLAogICAgICBtUGF0dGVybigwKSwKICAgICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIC8vdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgICBkYXRhSXNPd25lZChGQUxTRSksCiAgICAgIGRhdGEodGhhdC5kYXRhKSAvLyBBbGlhcyB0aGUgZGF0YSBwb2ludGVyCnsKfQoKVUJvb2wKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIHRoYXQpIGNvbnN0CnsKICAgIGlmICh0aGlzID09ICZ0aGF0KQogICAgewogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIGlmICh0aGlzLT5nZXREeW5hbWljQ2xhc3NJRCgpICE9IHRoYXQuZ2V0RHluYW1pY0NsYXNzSUQoKSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7ICAvLyBub3QgdGhlIHNhbWUgY2xhc3MKICAgIH0KCiAgICBpZiAoIUNvbGxhdG9yOjpvcGVyYXRvcj09KHRoYXQpKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBSdWxlQmFzZWRDb2xsYXRvciYgdGhhdEFsaWFzID0gKFJ1bGVCYXNlZENvbGxhdG9yJil0aGF0OwoKICAgIGlmIChpc092ZXJJZ25vcmUgIT0gdGhhdEFsaWFzLmlzT3Zlcklnbm9yZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGRhdGEgIT0gdGhhdEFsaWFzLmRhdGEpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgpSdWxlQmFzZWRDb2xsYXRvciYKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yPShjb25zdCAgUnVsZUJhc2VkQ29sbGF0b3ImIHRoYXQpCnsKICAgIGlmICh0aGlzICE9ICZ0aGF0KQogICAgewogICAgICAgIENvbGxhdG9yOjpvcGVyYXRvcj0odGhhdCk7CiAgICAgICAgaXNPdmVySWdub3JlID0gdGhhdC5pc092ZXJJZ25vcmU7CgogICAgICAgIGlmIChkYXRhSXNPd25lZCkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIH0KCiAgICAgICAgZGF0YSA9IDA7CiAgICAgICAgZGVsZXRlIG1QYXR0ZXJuOwogICAgICAgIG1QYXR0ZXJuID0gMDsKICAgICAgICBkYXRhSXNPd25lZCA9IEZBTFNFOwogICAgICAgIGRhdGEgPSB0aGF0LmRhdGE7CiAgICB9CgogICAgcmV0dXJuICp0aGlzOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQogICAgOiBDb2xsYXRvcigpLAogICAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgICBtUGF0dGVybigwKSwKICAgICAgLy8gICAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAgIC8vLyAgICAgIHRhcmdldEN1cnNvcigwKSwKICAgICAgY3Vyc29yMSgwKSwKICAgICAgY3Vyc29yMigwKSwKICAgICAgZGF0YSgwKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKICA6IENvbGxhdG9yKGNvbGxhdGlvblN0cmVuZ3RoLCBOb3JtYWxpemVyOjpOT19PUCksCiAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgbVBhdHRlcm4oMCksCiAgICAvLyAgICBzb3VyY2VDdXJzb3IoMCksCiAgICAvLyAgICB0YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICBkYXRhKDApLAogICAgZGF0YUlzT3duZWQoRkFMU0UpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMocnVsZXMsIHN0YXR1cyk7Cn0KClJ1bGVCYXNlZENvbGxhdG9yOjpSdWxlQmFzZWRDb2xsYXRvcihjb25zdCAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihURVJUSUFSWSwgZGVjb21wb3NpdGlvbk1vZGUpLAogICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgIG1QYXR0ZXJuKDApLAogICAgLy8gICAgc291cmNlQ3Vyc29yKDApLAogICAgLy8gICAgdGFyZ2V0Q3Vyc29yKDApLAogICAgICBjdXJzb3IxKDApLAogICAgICBjdXJzb3IyKDApLAogICAgZGF0YSgwKSwKICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICByZXR1cm47CiAgICB9CiAgCiAgY29uc3RydWN0RnJvbVJ1bGVzKHJ1bGVzLCBzdGF0dXMpOwp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgICAgRUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSwKICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCiAgOiBDb2xsYXRvcihjb2xsYXRpb25TdHJlbmd0aCwgZGVjb21wb3NpdGlvbk1vZGUpLAogICAgICBpc092ZXJJZ25vcmUoRkFMU0UpLAogICAgICBtUGF0dGVybigwKSwKICAgIC8vICAgICAgc291cmNlQ3Vyc29yKDApLAogICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIGRhdGEoMCksCiAgICAgIGRhdGFJc093bmVkKEZBTFNFKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGNvbnN0cnVjdEZyb21SdWxlcyhydWxlcywgc3RhdHVzKTsKfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbVJ1bGVzKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBDb25zdHJ1Y3QgdGhpcyBjb2xsYXRvcidzIHJ1bGVzZXQgZnJvbSBpdHMgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChydWxlcy5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKCiAgICBkYXRhID0gbmV3IFRhYmxlQ29sbGF0aW9uRGF0YTsKICAgIGlmIChkYXRhLT5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgdXNpbmcgdGhlIGJ1aWxkIG1ldGhvZCwgc28gd2Ugb3duIGl0LgogICAgZGF0YUlzT3duZWQgPSBUUlVFOwoKICAgIC8vIE5vdyB0aGF0IHdlJ3ZlIGdvdCBhbGwgdGhlIGJ1ZmZlcnMgYWxsb2NhdGVkLCBkbyB0aGUgYWN0dWFsIHdvcmsKICAgIG1QYXR0ZXJuID0gMDsKICAgIGJ1aWxkKHJ1bGVzLCBzdGF0dXMpOwp9Cgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tRmlsZShjb25zdCBjaGFyKiBmaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gVGhpcyBtZXRob2QgdHJpZXMgdG8gcmVhZCBpbiBhIGZsYXR0ZW5lZCBSdWxlQmFzZWRDb2xsYXRvciB0aGF0CiAgICAvLyBoYXMgYmVlbiBwcmV2aW91c2x5IHN0cmVhbWVkIG91dCB1c2luZyB0aGUgc3RyZWFtT3V0KCkgbWV0aG9kLgogICAgLy8gVGhlICdmaWxlTmFtZScgcGFyYW1ldGVyIHNob3VsZCBjb250YWluIGEgZnVsbCBwYXRobmFtZSB2YWxpZCBvbgogICAgLy8gdGhlIGxvY2FsIGVudmlyb25tZW50LgoKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRhdGFJc093bmVkKQogICAgewogICAgICAgIGRlbGV0ZSBkYXRhOwogICAgICAgIGRhdGEgPSAwOwogICAgfQoKICAgIG1QYXR0ZXJuID0gMDsKICAgIGlzT3Zlcklnbm9yZSA9IEZBTFNFOwogICAgc2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsgLy8gVGhpcyBpcyB0aGUgZGVmYXVsdCBzdHJlbmd0aAoKICAgIEZpbGVTdHJlYW0qIGlmcyA9IFRfRmlsZVN0cmVhbV9vcGVuKGZpbGVOYW1lLCAicmIiKTsKICAgIGlmIChpZnMgPT0gMCkgewogICAgICAgIHN0YXR1cyA9IFVfRklMRV9BQ0NFU1NfRVJST1I7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIFRoZSBzdHJlYW1JbiBmdW5jdGlvbiBkb2VzIHRoZSBhY3R1YWwgd29yayBoZXJlLi4uCiAgICBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1Jbih0aGlzLCBpZnMpOwoKICAgIGlmICghVF9GaWxlU3RyZWFtX2Vycm9yKGlmcykpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgfQogICAgZWxzZSBpZiAoZGF0YSAmJiBkYXRhLT5pc0JvZ3VzKCkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzdGF0dXMgPSBVX01JU1NJTkdfUkVTT1VSQ0VfRVJST1I7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICAgICAgZGF0YSA9IDA7CiAgICB9CgojaWZkZWYgQ09MTERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgImJpbmFyeSByZWFkICVzIHNpemUgJWQsICVzXG4iLCBmaWxlTmFtZSwgVF9GaWxlU3RyZWFtX3NpemUoaWZzKSwgdV9lcnJvck5hbWUoc3RhdHVzKSk7CiNlbmRpZgoKICAgIC8vIFdlIGNvbnN0cnVjdGVkIHRoZSBkYXRhIHdoZW4gc3RyZWFtaW5nIGl0IGluLCBzbyB3ZSBvd24gaXQKICAgIGRhdGFJc093bmVkID0gVFJVRTsKCiAgICBUX0ZpbGVTdHJlYW1fY2xvc2UoaWZzKTsKfQoKY29uc3QgY2hhciAqClJ1bGVCYXNlZENvbGxhdG9yOjpjb25zdHJ1Y3RGcm9tQnVuZGxlKGNvbnN0IExvY2FsZSAmIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAvLyBUaGlzIG1ldGhvZCB0cmllcyB0byBsb2NhdGUgYmluYXJ5IGNvbGxhdGlvbiBkYXRhIHdoaWNoIGhhcyBiZWVuIAogIC8vIHByZXZpb3VzbHkgc3RyZWFtZWQgdG8gYSBiaW5hcnkgb2JqZWN0ICIlJUNvbGxhdGlvbiIgaW4gYSAKICAvLyByZXNvdXJjZSBidW5kbGUuIElmIHRoZSBkYXRhIGlzIGZvdW5kLCBpdCBpcyBjYWNoZWQuCiAgLy8gY2FjaGUgaXMgY2hlY2tlZCBiZWZvcmUgYWN0dWFsbHkgc3RyZWFtaW5nIGluIGRhdGEKICAvLyByZXNvdXJjZSBidW5kbGUgZmFsbGJhY2sgbWVjaGFuaXNtIGlzIHVzZWQuCgogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gMDsKICAgIH0KICAgIGNvbnN0IGNoYXIqIHJlYWxOYW1lID0gMDsKCiAgICBtUGF0dGVybiA9IDA7CiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7IC8vIFRoaXMgaXMgdGhlIGRlZmF1bHQgc3RyZW5ndGgKCiAgICBSZXNvdXJjZUJ1bmRsZSByYigwLCBuYW1lLCBzdGF0dXMpOwogICAgaWYoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgICAgUmVzb3VyY2VCdW5kbGUgYmluYXJ5ID0gcmIuZ2V0KCIlJUNvbGxhdGlvbiIsIHN0YXR1cyk7IC8vVGhpcyBpcyB0aGUgYnVuZGxlIHRoYXQgYWN0dWFsbHkgY29udGFpbnMgdGhlIGNvbGxhdGlvbiBkYXRhCiAgICAgIHJlYWxOYW1lID0gYmluYXJ5LmdldE5hbWUoKTsKICAgICAgaWYoVV9TVUNDRVNTKHN0YXR1cykpIHsKCVVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwoJY29uc3RydWN0RnJvbUNhY2hlKHJlYWxOYW1lLCBpbnRTdGF0dXMpOyAvLyBjaGVjayB3aGV0aGVyIHdlIGFscmVhZHkgaGF2ZSB0aGlzIGRhdGEgaW4gY2FjaGUKCWlmKFVfU1VDQ0VTUyhpbnRTdGF0dXMpKSB7CgkgIHJldHVybiByZWFsTmFtZTsKCX0KCWludDMyX3QgaW5EYXRhTGVuID0gMDsKCWNvbnN0IHVpbnQ4X3QgKmluRGF0YSA9IGJpbmFyeS5nZXRCaW5hcnkoaW5EYXRhTGVuLCBzdGF0dXMpOyAvL1RoaXMgZ290IHVzIHRoZSByZWFsIGJpbmFyeSBkYXRhCgkKCVVNZW1vcnlTdHJlYW0gKmlmcyA9IHVwcnZfbXN0cm1fb3BlbkJ1ZmZlcihpbkRhdGEsIGluRGF0YUxlbik7CgkKCWlmIChpZnMgPT0gMCkgewoJICBzdGF0dXMgPSBVX0ZJTEVfQUNDRVNTX0VSUk9SOwoJICByZXR1cm4gMDsKCX0KCgkvLyBUaGUgc3RyZWFtSW4gZnVuY3Rpb24gZG9lcyB0aGUgYWN0dWFsIHdvcmsgaGVyZS4uLgoJUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtSW4odGhpcywgaWZzKTsKCglpZiAoIXVwcnZfbXN0cm1fZXJyb3IoaWZzKSkgewoJfQoJZWxzZSBpZiAoZGF0YSAmJiBkYXRhLT5pc0JvZ3VzKCkpIHsKCSAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKCSAgZGVsZXRlIGRhdGE7CgkgIGRhdGEgPSAwOwoJfSBlbHNlIHsKCSAgc3RhdHVzID0gVV9NSVNTSU5HX1JFU09VUkNFX0VSUk9SOwoJICBkZWxldGUgZGF0YTsKCSAgZGF0YSA9IDA7Cgl9CgoJLy8gV2UgY29uc3RydWN0ZWQgdGhlIGRhdGEgd2hlbiBzdHJlYW1pbmcgaXQgaW4sIHNvIHdlIG93biBpdAoJZGF0YUlzT3duZWQgPSBUUlVFOwoKCXVwcnZfbXN0cm1fY2xvc2UoaWZzKTsKCWFkZFRvQ2FjaGUocmVhbE5hbWUpOyAvLyBhZGQgdGhlIG5ld2x5IGNvbnN0cnVjdGVkIGRhdGEgdG8gY2FjaGUKCXJldHVybiByZWFsTmFtZTsKICAgICAgfSBlbHNlIHsKCXN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKCXJldHVybiAwOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAwOwogICAgfQp9CgpSdWxlQmFzZWRDb2xsYXRvcjo6UnVsZUJhc2VkQ29sbGF0b3IoICAgY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKICAgIDogQ29sbGF0b3IoKSwKICAgICAgaXNPdmVySWdub3JlKEZBTFNFKSwKICAgICAgZGF0YUlzT3duZWQoRkFMU0UpLAogICAgICBkYXRhKDApLAogICAgICAvLyAgICAgIHNvdXJjZUN1cnNvcigwKSwKICAgICAgLy90YXJnZXRDdXJzb3IoMCksCiAgICAgIGN1cnNvcjEoMCksCiAgICAgIGN1cnNvcjIoMCksCiAgICAgIG1QYXR0ZXJuKDApCnsKCgogIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuOwogIH0KICAKICAvLyBUcnkgdG8gbG9hZCwgaW4gb3JkZXI6CiAgLy8gMS4gVGhlIGRlc2lyZWQgbG9jYWxlJ3MgY29sbGF0aW9uLgogIC8vIDIuIEEgZmFsbGJhY2sgb2YgdGhlIGRlc2lyZWQgbG9jYWxlLgogIC8vIDMuIFRoZSBkZWZhdWx0IGxvY2FsZSdzIGNvbGxhdGlvbi4KICAvLyA0LiBBIGZhbGxiYWNrIG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4KICAvLyA1LiBUaGUgZGVmYXVsdCBjb2xsYXRpb24gcnVsZXMsIHdoaWNoIGNvbnRhaW5zIGVuX1VTIGNvbGxhdGlvbiBydWxlcy4KCiAgLy8gVG8gcmVpdGVyYXRlLCB3ZSB0cnk6CiAgLy8gU3BlY2lmaWM6CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkrdmFyaWFudAogIC8vICBsYW5ndWFnZStjb3VudHJ5CiAgLy8gIGxhbmd1YWdlCiAgLy8gRGVmYXVsdDoKICAvLyAgbGFuZ3VhZ2UrY291bnRyeSt2YXJpYW50CiAgLy8gIGxhbmd1YWdlK2NvdW50cnkKICAvLyAgbGFuZ3VhZ2UKICAvLyBSb290OiAoYWthIERFRkFVTFRSVUxFUykKICAvLyBzdGVwcyAxLTUgYXJlIGhhbmRsZWQgYnkgcmVzb3VyY2UgYnVuZGxlIGZhbGxiYWNrIG1lY2hhbmlzbS4gCiAgLy8gaG93ZXZlciwgaW4gYSB2ZXJ5IHVucHJvYmFibGUgc2l0dWF0aW9uIHRoYXQgbm8gcmVzb3VyY2UgYnVuZGxlCiAgLy8gZGF0YSBleGlzdHMsIHN0ZXAgNSBpcyByZXBlYXRlZCB3aXRoIGhhcmRjb2RlZCBkZWZhdWx0IHJ1bGVzLgoKICBjb25zdCBjaGFyICpsb2NOYW1lID0gY29uc3RydWN0RnJvbUJ1bmRsZShkZXNpcmVkTG9jYWxlLCBzdGF0dXMpOyAgLyohKi8KICBkYXRhLT5kZXNpcmVkTG9jYWxlID0gZGVzaXJlZExvY2FsZTsKICAKICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpIHsKICAgIGRhdGEtPnJlYWxMb2NhbGVOYW1lID0gbG9jTmFtZTsKICAgIGlmKHN0YXR1cyAhPSBVX1VTSU5HX0RFRkFVTFRfRVJST1IpIHsKICAgICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpOT19PUCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgY29uc3RydWN0RnJvbUNhY2hlKFJlc291cmNlQnVuZGxlOjprRGVmYXVsdEZpbGVuYW1lLCBpbnRTdGF0dXMpOwogICAgaWYoVV9GQUlMVVJFKGludFN0YXR1cykpIHsKICAgICAgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAgICBjb25zdHJ1Y3RGcm9tUnVsZXMoUnVsZUJhc2VkQ29sbGF0b3I6OkRFRkFVTFRSVUxFUywgaW50U3RhdHVzKTsKICAgICAgaWYgKGludFN0YXR1cyA9PSBVX1pFUk9fRVJST1IpIHsKCXN0YXR1cyA9IFVfVVNJTkdfREVGQVVMVF9FUlJPUjsKICAgICAgfSBlbHNlIHsKCXN0YXR1cyA9IGludFN0YXR1czsgICAgIC8vIGJ1YmJsZSBiYWNrCiAgICAgIH0KICAgIAogICAgICBpZiAoc3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpIHsKCXJldHVybjsKICAgICAgfQogICAgfQogICAgZGF0YS0+cmVhbExvY2FsZU5hbWUgPSBSZXNvdXJjZUJ1bmRsZTo6a0RlZmF1bHRGaWxlbmFtZTsKICAgIHNldERlY29tcG9zaXRpb24oTm9ybWFsaXplcjo6Tk9fT1ApOwogICAgYWRkVG9DYWNoZShSZXNvdXJjZUJ1bmRsZTo6a0RlZmF1bHRGaWxlbmFtZSk7CiAgfQogIHJldHVybjsKfQoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29uc3RydWN0RnJvbUZpbGUoICAgY29uc3QgTG9jYWxlJiAgICAgICAgICAgbG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBsb2NhbGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wgICAgICAgICAgICAgICAgICB0cnlCaW5hcnlGaWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgc3RhdHVzKQp7CiAgLy8gY29uc3RydWN0RnJvbUZpbGUgY3JlYXRlcyBhIGNvbGxhdGlvbiBvYmplY3QgYnkgcmVhZGluZyBmcm9tIGEKICAvLyBmaWxlLiAgSXQgZG9lcyBub3QgZW1wbG95IHRoZSB1c3VhbCBGSUxFIHNlYXJjaCBtZWNoYW5pc20gd2l0aAogIC8vIGxvY2FsZXMsIGRlZmF1bHQgbG9jYWxlcywgYW5kIGJhc2UgbG9jYWxlcy4gIEluc3RlYWQsIGl0IHRyaWVzIHRvCiAgLy8gbG9vayBvbmx5IGluIGZpbGVzIHdpdGggdGhlIGdpdmVuIGxvY2FsRmlsZU5hbWUuICBJdCBkb2VzLAogIC8vIGhvd2V2ZXIsIGVtcGxveSB0aGUgTE9DQUxFIHNlYXJjaCBtZWNoYW5pc20uCiAgCiAgLy8gVGhpcyBtZXRob2QgbWFpbnRhaW5zIHRoZSBiaW5hcnkgY29sbGF0aW9uIGZpbGVzLiAgSWYgYSBjb2xsYXRpb24KICAvLyBpcyBub3QgcHJlc2VudCBpbiBiaW5hcnkgZm9ybSwgYnV0IGlzIHByZXNlbnQgaW4gdGV4dCBmb3JtIChpbiBhCiAgLy8gcmVzb3VyY2UgYnVuZGxlIGZpbGUpLCBpdCB3aWxsIGJlIGxvYWRlZCBpbiB0ZXh0IGZvcm0sIGFuZCB0aGVuCiAgLy8gd3JpdHRlbiB0byBkaXNrLgogIAogIC8vIElmIHRyeUJpbmFyeUZpbGUgaXMgdHJ1ZSwgdGhlbiB0cnkgdG8gbG9hZCBmcm9tIHRoZSBiaW5hcnkgZmlsZSBmaXJzdC4KCiAgaWYoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgIHJldHVybjsKICB9CiAgCiAgaWYoZGF0YUlzT3duZWQpIHsKICAgIGRlbGV0ZSBkYXRhOwogICAgZGF0YSA9IDA7CiAgfQogIAogICAgaWYodHJ5QmluYXJ5RmlsZSkgewogICAgICBjaGFyICpiaW5hcnlGaWxlUGF0aCA9IGNyZWF0ZVBhdGhOYW1lKFVuaWNvZGVTdHJpbmcodV9nZXREYXRhRGlyZWN0b3J5KCksIiIpLCAKCQkJCQkgICAgbG9jYWxlRmlsZU5hbWUsIFVuaWNvZGVTdHJpbmcoa0ZpbGVuYW1lU3VmZml4LCIiKSk7CiAgCiAgICAgICAgLy8gVHJ5IHRvIGxvYWQgdXAgdGhlIGNvbGxhdGlvbiBmcm9tIGEgYmluYXJ5IGZpbGUgZmlyc3QKICAgICAgICBjb25zdHJ1Y3RGcm9tRmlsZShiaW5hcnlGaWxlUGF0aCwgc3RhdHVzKTsKICAgICAgICAjaWZkZWYgQ09MTERFQlVHCiAgICAgICAgICAgIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgIDw8IGtGaWxlbmFtZVN1ZmZpeCA8PCAiIGJpbmFyeSBsb2FkICIgPDwgdV9lcnJvck5hbWUoc3RhdHVzKSA8PCBlbmRsOwogICAgICAgICNlbmRpZgogICAgICAgIGlmKFVfU1VDQ0VTUyhzdGF0dXMpIHx8IHN0YXR1cyA9PSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSB7CiAgICAgICAgICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZihzdGF0dXMgPT0gVV9GSUxFX0FDQ0VTU19FUlJPUikgewogICAgICAgICAgICBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgfQogICAgICAgIGRlbGV0ZSBbXSBiaW5hcnlGaWxlUGF0aDsKICAgIH0KCiAgLy8gTm93IHRyeSB0byBsb2FkIGl0IHVwIGZyb20gYSByZXNvdXJjZSBidW5kbGUgdGV4dCBzb3VyY2UgZmlsZQogIFVuaWNvZGVTdHJpbmcgZGF0YURpciA9IFVuaWNvZGVTdHJpbmcodV9nZXREYXRhRGlyZWN0b3J5KCksIiIpOwoKICAgIGNoYXIgKmNoOwogICAgY2ggPSBuZXcgY2hhcltsb2NhbGVGaWxlTmFtZS5zaXplKCkgKyAxXTsKICAgIGNoW2xvY2FsZUZpbGVOYW1lLmV4dHJhY3QoMCwgMHg3ZmZmZmZmZiwgY2gsICIiKV0gPSAwOwogICAgUmVzb3VyY2VCdW5kbGUgYnVuZGxlKGRhdGFEaXIsIGNoLCBzdGF0dXMpOwogIAogICAgZGVsZXRlIFtdIGNoOwogIAogIC8vIGlmIHRoZXJlIGlzIG5vIHJlc291cmNlIGJ1bmRsZSBmaWxlIGZvciB0aGUgZ2l2ZSBsb2NhbGUsIGJyZWFrIG91dAogIGlmKFVfRkFJTFVSRShzdGF0dXMpKQogIHsKICAgICAgcmV0dXJuOwogIH0KCiAgICAjaWZkZWYgQ09MTERFQlVHCiAgICAgICAgY2VyciA8PCBsb2NhbGVGaWxlTmFtZSA8PCAiIGFzY2lpIGxvYWQgIiA8PCB1X2Vycm9yTmFtZShzdGF0dXMpIDw8IGVuZGw7CiAgICAjZW5kaWYKCiAgICAvLyBjaGVjayBhbmQgc2VlIGlmIHRoaXMgcmVzb3VyY2UgYnVuZGxlIGNvbnRhaW5zIGNvbGxhdGlvbiBkYXRhCiAgCiAgICBVbmljb2RlU3RyaW5nIGNvbFN0cmluZzsKICAgIFVFcnJvckNvZGUgaW50U3RhdHVzID0gVV9aRVJPX0VSUk9SOwovKiBSRURPICovCiAgICBjb25zdCBVbmljb2RlU3RyaW5nICp0ID0gYnVuZGxlLmdldFN0cmluZygiQ29sbGF0aW9uRWxlbWVudHMiLCBpbnRTdGF0dXMpOwoKICAgIGlmKHQgIT0gTlVMTCkgewogICAgICAgIGNvbFN0cmluZyA9ICp0OwogICAgfSAKCiAgICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogIC8vIGlmIHRoaXMgYnVuZGxlIGRvZXNuJ3QgY29udGFpbiBjb2xsYXRpb24gZGF0YSwgYnJlYWsgb3V0CiAgaWYoVV9GQUlMVVJFKGludFN0YXR1cykpIHsKICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgIHJldHVybjsKICB9CgogIC8vIEhhdmluZyBsb2FkZWQgdGhlIGNvbGxhdGlvbiBmcm9tIHRoZSByZXNvdXJjZSBidW5kbGUgdGV4dCBmaWxlLAogIC8vIG5vdyByZXRyaWV2ZSB0aGUgQ29sbGF0aW9uRWxlbWVudHMgdGFnZ2VkIGRhdGEsIG1lcmdlZCB3aXRoIHRoZQogIC8vIGRlZmF1bHQgcnVsZXMuICBJZiB0aGF0IGZhaWxzLCB1c2UgdGhlIGRlZmF1bHQgcnVsZXMgYWxvbmUuCgogIGNvbFN0cmluZy5pbnNlcnQoMCwgREVGQVVMVFJVTEVTKTsKICBpZihjb2xTdHJpbmcuaXNCb2d1cygpKSB7CiAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgcmV0dXJuOwogIH0KICAgIAogIGNvbnN0cnVjdEZyb21SdWxlcyhjb2xTdHJpbmcsIGludFN0YXR1cyk7CiAgaWYoaW50U3RhdHVzID09IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpIHsKICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICByZXR1cm47CiAgfQogIAogIGlmKGludFN0YXR1cyAhPSBVX1pFUk9fRVJST1IpICB7CiAgICBzdGF0dXMgPSBVX1VTSU5HX0RFRkFVTFRfRVJST1I7CiAgICAgIAogICAgLy8gcHJlZGVmaW5lZCB0YWJsZXMgc2hvdWxkIGNvbnRhaW4gY29ycmVjdCBncmFtbWFyCiAgICBpbnRTdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBjb25zdHJ1Y3RGcm9tUnVsZXMoREVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwogICAgaWYoaW50U3RhdHVzICE9IFVfWkVST19FUlJPUikgewogICAgICBzdGF0dXMgPSBpbnRTdGF0dXM7CiAgICB9CiAgfSAKICAKI2lmZGVmIENPTExERUJVRwogIGNlcnIgPDwgbG9jYWxlRmlsZU5hbWUgPDwgIiBhc2NpaSBsb2FkICIgPDwgKFVfU1VDQ0VTUyhzdGF0dXMpID8gIk9LIiA6ICJGYWlsZWQiKSA8PCAiIC0gdHJ5PSAiIDw8ICh0cnlCaW5hcnlGaWxlPyJ0cnVlIjoiZmFsc2UiKSA8PCBlbmRsOwojZW5kaWYKCn0KClJ1bGVCYXNlZENvbGxhdG9yOjp+UnVsZUJhc2VkQ29sbGF0b3IoKQp7CiAgICBpZiAoZGF0YUlzT3duZWQpCiAgICB7CiAgICAgICAgZGVsZXRlIGRhdGE7CiAgICB9CgogICAgZGF0YSA9IDA7CgogICAgLy8gICAgZGVsZXRlIHNvdXJjZUN1cnNvcjsKICAgIC8vICAgIHNvdXJjZUN1cnNvciA9IDA7CgogICAgLy8gICAgZGVsZXRlIHRhcmdldEN1cnNvcjsKICAgIC8vICAgIHRhcmdldEN1cnNvciA9IDA7CgogICAgaWYgKGN1cnNvcjEgIT0gTlVMTCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3IxOwogICAgICAgIGN1cnNvcjEgPSAwOwogICAgfQogICAgaWYgKGN1cnNvcjIgIT0gTlVMTCkgewogICAgICAgIGRlbGV0ZSBjdXJzb3IyOwogICAgICAgIGN1cnNvcjIgPSAwOwogICAgfQoKICAgIGRlbGV0ZSBtUGF0dGVybjsKICAgIG1QYXR0ZXJuID0gMDsKfQoKQ29sbGF0b3IqClJ1bGVCYXNlZENvbGxhdG9yOjpjbG9uZSgpIGNvbnN0CnsKICAgIHJldHVybiBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoKnRoaXMpOwp9CgovLyBDcmVhdGUgYSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3Igb2JqZWN0IHRoYXQgd2lsbCBpdGVyYXRvciBvdmVyIHRoZSBlbGVtZW50cwovLyBpbiBhIHN0cmluZywgdXNpbmcgdGhlIGNvbGxhdGlvbiBydWxlcyBkZWZpbmVkIGluIHRoaXMgUnVsZUJhc2VkQ29sbGF0b3IKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSkgY29uc3QKewogICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgKm5ld0N1cnNvciA9IDA7CgogICAgbmV3Q3Vyc29yID0gbmV3IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihzb3VyY2UsIHRoaXMsIHN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIG5ld0N1cnNvcjsKfQoKLy8gQ3JlYXRlIGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIG9iamVjdCB0aGF0IHdpbGwgaXRlcmF0b3Igb3ZlciB0aGUgZWxlbWVudHMKLy8gaW4gYSBzdHJpbmcsIHVzaW5nIHRoZSBjb2xsYXRpb24gcnVsZXMgZGVmaW5lZCBpbiB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlKSBjb25zdAp7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciAqbmV3Q3Vyc29yID0gMDsKCiAgICBuZXdDdXJzb3IgPSBuZXcgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKHNvdXJjZSwgdGhpcywgc3RhdHVzKTsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gbmV3Q3Vyc29yOwp9CgovLyBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBjb2xsYXRvcidzIHJ1bGVzLgovLyBUaGUgc3RyaW5nIGNhbiBsYXRlciBiZSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yIHRoYXQgdGFrZXMgYQovLyBVbmljb2RlU3RyaW5nIGFyZ3VtZW50LCB3aGljaCB3aWxsIGNvbnN0cnVjdCBhIGNvbGxhdG9yIHRoYXQncwovLyBmdW5jdGlvbmFsbHkgaWRlbnRpY2FsIHRvIHRoaXMgb25lLgovLyBZb3UgY2FuIGFsc28gYWxsb3cgdXNlcnMgdG8gZWRpdCB0aGUgc3RyaW5nIGluIG9yZGVyIHRvIGNoYW5nZQovLyB0aGUgY29sbGF0aW9uIGRhdGEsIG9yIHlvdSBjYW4gcHJpbnQgaXQgb3V0IGZvciBpbnNwZWN0aW9uLCBvciB3aGF0ZXZlci4KCmNvbnN0IFVuaWNvZGVTdHJpbmcmClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRSdWxlcygpIGNvbnN0CnsKICAgIGlmIChtUGF0dGVybiAhPSAwKQogICAgewogICAgICAgIE1lcmdlQ29sbGF0aW9uKiYgbm9uQ29uc3RNUGF0dGVybiA9ICooTWVyZ2VDb2xsYXRpb24qKikmbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4tPmVtaXRQYXR0ZXJuKGRhdGEtPnJ1bGVUYWJsZSk7CiAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwogICAgICAgIGRlbGV0ZSBub25Db25zdE1QYXR0ZXJuOwogICAgICAgIG5vbkNvbnN0TVBhdHRlcm4gPSAwOwogICAgfQogICAgZWxzZSBpZiAoIWRhdGEtPmlzUnVsZVRhYmxlTG9hZGVkKQogICAgewogICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIGNhbGxlciB3YW50cyB0aGUgcnVsZXMsIGJ1dCB0aGUgcnVsZSB0YWJsZSBkYXRhCiAgICAgICAgLy8gaXMgbm90IGxvYWRlZC4gIEZ1cnRoZXJtb3JlLCB0aGVyZSBpcyBubyBtUGF0dGVybiBvYmplY3QgdG8gbG9hZAogICAgICAgIC8vIHRoZSBydWxlcyBmcm9tLiAgVGhlcmVmb3JlLCB3ZSBmZXRjaCB0aGUgcnVsZXMgb2ZmIHRoZSBkaXNrLgogICAgICAgIC8vIE5vdGljZSB0aGF0IHdlIHBhc3MgaW4gYSB0cnlCaW5hcnlGaWxlIHZhbHVlIG9mIEZBTFNFLCBzaW5jZQogICAgICAgIC8vIGJ5IGRlc2lnbiB0aGUgYmluYXJ5IGZpbGUgaGFzIE5PIHJ1bGVzIGluIGl0IQogICAgICAgIC8vVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgLy9SdWxlQmFzZWRDb2xsYXRvciB0ZW1wKGRhdGEtPnJlYWxMb2NhbGVOYW1lLCBzdGF0dXMpOwogICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yIHRlbXA7CiAgICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgdGVtcC5jb25zdHJ1Y3RGcm9tRmlsZShkYXRhLT5kZXNpcmVkTG9jYWxlLCBkYXRhLT5yZWFsTG9jYWxlTmFtZSwgRkFMU0UsIHN0YXR1cyk7CgogICAgICAgIC8vIFdlIG11c3QgY2hlY2sgdGhhdCBtUGF0dGVybiBpcyBub256ZXJvIGhlcmUsIG9yIHdlIHJ1biB0aGUgcmlzawogICAgICAgIC8vIG9mIGFuIGluZmluaXRlIGxvb3AuCiAgICAgICAgaWYgKFVfU1VDQ0VTUyhzdGF0dXMpICYmIHRlbXAubVBhdHRlcm4gIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEtPnJ1bGVUYWJsZSA9IHRlbXAuZ2V0UnVsZXMoKTsKICAgICAgICAgICAgZGF0YS0+aXNSdWxlVGFibGVMb2FkZWQgPSBUUlVFOwojaWZkZWYgX0RFQlVHCi8vICAgICAgICAgICAgICAvLyB0aGUgZm9sbG93aW5nIGlzIHVzZWZ1bCBmb3Igc3BlY2lmaWMgZGVidWdnaW5nIHB1cnBvc2VzCi8vICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBuYW1lOwovLyAgICAgICAgICAgICAgIGNlcnIgPDwgIlRhYmxlIGNvbGxhdGlvbiBydWxlcyBsb2FkZWQgZHluYW1pY2FsbHkgZm9yICIKLy8gICAgICAgICAgICAgICAgICAgPDwgZGF0YS0+ZGVzaXJlZExvY2FsZS5nZXROYW1lKG5hbWUpCi8vICAgICAgICAgICAgICAgICAgIDw8ICIgYXQgIgovLyAgICAgICAgICAgICAgICAgICA8PCBkYXRhLT5yZWFsTG9jYWxlTmFtZQovLyAgICAgICAgICAgICAgICAgICA8PCAiLCAiIDw8IGRlYyA8PCBkYXRhLT5ydWxlVGFibGUuc2l6ZSgpIDw8ICIgY2hhcmFjdGVycyIKLy8gICAgICAgICAgICAgICAgICAgPDwgZW5kbDsKI2VuZGlmCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiNpZmRlZiBfREVCVUcKLy8gICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgbmFtZTsKLy8gICAgICAgICAgICAgIGNlcnIgPDwgIlVuYWJsZSB0byBsb2FkIHRhYmxlIGNvbGxhdGlvbiBydWxlcyBkeW5hbWljYWxseSBmb3IgIgovLyAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPmRlc2lyZWRMb2NhbGUuZ2V0TmFtZShuYW1lKQovLyAgICAgICAgICAgICAgICAgIDw8ICIgYXQgIgovLyAgICAgICAgICAgICAgICAgIDw8IGRhdGEtPnJlYWxMb2NhbGVOYW1lCi8vICAgICAgICAgICAgICAgICAgPDwgZW5kbDsKLy8gICAgICAgICAgICAgIGNlcnIgPDwgIlN0YXR1cyAiIDw8IHVfZXJyb3JOYW1lKHN0YXR1cykgPDwgIiwgbVBhdHRlcm4gIiA8PCB0ZW1wLm1QYXR0ZXJuIDw8IGVuZGw7CiNlbmRpZgoJICAgIC8qIFNSTCBoYXZlIHRvIGFkZCB0aGlzIGJlY2F1c2Ugd2Ugbm93IGhhdmUgdGhlIHNpdHVhdGlvbiB3aGVyZQoJICAgICAgIERFRkFVTFQgaXMgbG9hZGVkIGZyb20gYSBiaW5hcnkgZmlsZSB3LyBubyBydWxlcy4gKi8KCSAgICBVRXJyb3JDb2RlIGludFN0YXR1cyA9IFVfWkVST19FUlJPUjsKCSAgICB0ZW1wLmNvbnN0cnVjdEZyb21SdWxlcyhSdWxlQmFzZWRDb2xsYXRvcjo6REVGQVVMVFJVTEVTLCBpbnRTdGF0dXMpOwoJICAgIAoJICAgIGlmKFVfU1VDQ0VTUyhpbnRTdGF0dXMpICYmICh0ZW1wLm1QYXR0ZXJuICE9IDApKQoJICAgICAgewoJCWRhdGEtPnJ1bGVUYWJsZSA9IHRlbXAuZ2V0UnVsZXMoKTsKCQlkYXRhLT5pc1J1bGVUYWJsZUxvYWRlZCA9IFRSVUU7CgkgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBkYXRhLT5ydWxlVGFibGU7Cn0KCgpDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdAp7CiAgICBVbmljb2RlU3RyaW5nIHNvdXJjZV90b2dvOwogICAgVW5pY29kZVN0cmluZyB0YXJnZXRfdG9nbzsKICAgIFVUZXh0T2Zmc2V0IGJlZ2luPTA7CgogICAgc291cmNlLmV4dHJhY3QoYmVnaW4sIHVwcnZfbWluKGxlbmd0aCxzb3VyY2UubGVuZ3RoKCkpLCBzb3VyY2VfdG9nbyk7CiAgICB0YXJnZXQuZXh0cmFjdChiZWdpbiwgdXBydl9taW4obGVuZ3RoLHRhcmdldC5sZW5ndGgoKSksIHRhcmdldF90b2dvKTsKICAgIHJldHVybiAoUnVsZUJhc2VkQ29sbGF0b3I6OmNvbXBhcmUoc291cmNlX3RvZ28sIHRhcmdldF90b2dvKSk7Cn0KCkNvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCAgIApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tcGFyZShjb25zdCAgIFVDaGFyKiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVDaGFyKiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpIGNvbnN0CnsKICAgIC8vIGNoZWNrIGlmIHNvdXJjZSBhbmQgdGFyZ2V0IGFyZSB2YWxpZCBzdHJpbmdzCiAgICBpZiAoKChzb3VyY2UgPT0gMCkgJiYgKHRhcmdldCA9PSAwKSkgfHwKICAgICAgICAoKHNvdXJjZUxlbmd0aCA9PSAwKSAmJiAodGFyZ2V0TGVuZ3RoID09IDApKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKCiAgICBpZiAoY3Vyc29yMSA9PSBOVUxMKQogICAgewogICAgICAgICgoUnVsZUJhc2VkQ29sbGF0b3IgKil0aGlzKS0+Y3Vyc29yMSA9IG5ldyBOb3JtYWxpemVySXRlcmF0b3Ioc291cmNlLCBzb3VyY2VMZW5ndGgsIGdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgY3Vyc29yMS0+c2V0TW9kZUFuZFRleHQoZ2V0RGVjb21wb3NpdGlvbigpLCBzb3VyY2UsIHNvdXJjZUxlbmd0aCwgc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoIC8qY3Vyc29yMS0+Y3Vyc29yID09IE5VTEwgfHwqLyBVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgfQoKICAgIGlmIChjdXJzb3IyID09IE5VTEwpCiAgICB7CiAgICAgICAgKChSdWxlQmFzZWRDb2xsYXRvciAqKXRoaXMpLT5jdXJzb3IyID0gbmV3IE5vcm1hbGl6ZXJJdGVyYXRvcih0YXJnZXQsIHRhcmdldExlbmd0aCwgZ2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBjdXJzb3IyLT5zZXRNb2RlQW5kVGV4dChnZXREZWNvbXBvc2l0aW9uKCksIHRhcmdldCwgdGFyZ2V0TGVuZ3RoLCBzdGF0dXMpOwogICAgfQoKICAgIGlmICgvKmN1cnNvcjIgPT0gTlVMTCB8fCovIFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICB9CgogICAgaW50MzJfdCBzT3JkZXIsIHRPcmRlcjsKICAgIC8vICAgIGludDMyX3Qgc09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIsIHRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSOwogICAgVUJvb2wgZ2V0cyA9IFRSVUUsIGdldHQgPSBUUlVFOwogICAgVUJvb2wgaW5pdGlhbENoZWNrU2VjVGVyID0gZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6U0VDT05EQVJZOwogICAgVUJvb2wgY2hlY2tTZWNUZXIgPSBpbml0aWFsQ2hlY2tTZWNUZXI7CiAgICBVQm9vbCBjaGVja1RlcnRpYXJ5ID0gZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6VEVSVElBUlk7CiAgICBVQm9vbCBpc0ZyZW5jaFNlYyA9IGRhdGEtPmlzRnJlbmNoU2VjOwogICAgdWludDMyX3QgcFNPcmRlciwgcFRPcmRlcjsKCiAgICB3aGlsZShUUlVFKQogICAgewogICAgICAgIC8vIEdldCB0aGUgbmV4dCBjb2xsYXRpb24gZWxlbWVudCBpbiBlYWNoIG9mIHRoZSBzdHJpbmdzLCB1bmxlc3MKICAgICAgICAvLyB3ZSd2ZSBiZWVuIHJlcXVlc3RlZCB0byBza2lwIGl0LgogICAgICAgIGlmIChnZXRzKQogICAgICAgIHsKICAgICAgICAgICAgc09yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcigoTm9ybWFsaXplckl0ZXJhdG9yKiljdXJzb3IxLCBzdGF0dXMpOwoKICAgICAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkVRVUFMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBnZXRzID0gVFJVRTsKCiAgICAgICAgaWYgKGdldHQpCiAgICAgICAgewogICAgICAgICAgICB0T3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKChOb3JtYWxpemVySXRlcmF0b3IqKWN1cnNvcjIsIHN0YXR1cyk7CgogICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZ2V0dCA9IFRSVUU7CgogICAgICAgIC8vIElmIHdlJ3ZlIGhpdCB0aGUgZW5kIG9mIG9uZSBvZiB0aGUgc3RyaW5ncywganVtcCBvdXQgb2YgdGhlIGxvb3AKICAgICAgICBpZiAoKHNPcmRlciA9PSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUil8fAogICAgICAgICAgICAodE9yZGVyID09IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKSkKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLy8gSWYgdGhlcmUncyBubyBkaWZmZXJlbmNlIGF0IHRoaXMgcG9zaXRpb24sIHdlIGNhbiBza2lwIHRvIHRoZQogICAgICAgIC8vIG5leHQgb25lLgogICAgICAgIHBTT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcihzT3JkZXIpOwogICAgICAgIHBUT3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcih0T3JkZXIpOwogICAgICAgIGlmIChzT3JkZXIgPT0gdE9yZGVyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlzRnJlbmNoU2VjICYmIHBTT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBpbiBmcmVuY2gsIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UgbW9yZSB0byB0aGUgcmlnaHQgaXMgc3Ryb25nZXIsCiAgICAgICAgICAgICAgICAgICAgLy8gc28gYWNjZW50cyBoYXZlIHRvIGJlIGNoZWNrZWQgd2l0aCBlYWNoIGJhc2UgZWxlbWVudAogICAgICAgICAgICAgICAgICAgIGNoZWNrU2VjVGVyID0gaW5pdGlhbENoZWNrU2VjVGVyOwoKICAgICAgICAgICAgICAgICAgICAvLyBidXQgdGVydGlhcnkgZGlmZmVyZW5jZXMgYXJlIGxlc3MgaW1wb3J0YW50IHRoYW4gdGhlIGZpcnN0IAogICAgICAgICAgICAgICAgICAgIC8vIHNlY29uZGFyeSBkaWZmZXJlbmNlLCBzbyBjaGVja2luZyB0ZXJ0aWFyeSByZW1haW5zIGRpc2FibGVkCiAgICAgICAgICAgICAgICAgICAgY2hlY2tUZXJ0aWFyeSA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIC8vIENvbXBhcmUgcHJpbWFyeSBkaWZmZXJlbmNlcyBmaXJzdC4KICAgICAgICBpZiAocFNPcmRlciAhPSBwVE9yZGVyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHNPcmRlciA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBUaGUgZW50aXJlIHNvdXJjZSBlbGVtZW50IGlzIGlnbm9yYWJsZS4KICAgICAgICAgICAgICAgIC8vIFNraXAgdG8gdGhlIG5leHQgc291cmNlIGVsZW1lbnQsIGJ1dCBkb24ndCBmZXRjaCBhbm90aGVyIHRhcmdldCBlbGVtZW50LgogICAgICAgICAgICAgICAgZ2V0dCA9IEZBTFNFOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0T3JkZXIgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ2V0cyA9IEZBTFNFOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRoZSBzb3VyY2UgYW5kIHRhcmdldCBlbGVtZW50cyBhcmVuJ3QgaWdub3JhYmxlLCBidXQgaXQncyBzdGlsbCBwb3NzaWJsZQogICAgICAgICAgICAvLyBmb3IgdGhlIHByaW1hcnkgY29tcG9uZW50IG9mIG9uZSBvZiB0aGUgZWxlbWVudHMgdG8gYmUgaWdub3JhYmxlLi4uLgogICAgICAgICAgICBpZiAocFNPcmRlciA9PSAwKSAgLy8gcHJpbWFyeSBvcmRlciBpbiBzb3VyY2UgaXMgaWdub3JhYmxlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBzb3VyY2UncyBwcmltYXJ5IGlzIGlnbm9yYWJsZSwgYnV0IHRoZSB0YXJnZXQncyBpc24ndC4gIFdlIHRyZWF0IGlnbm9yYWJsZXMKICAgICAgICAgICAgICAgIC8vIGFzIGEgc2Vjb25kYXJ5IGRpZmZlcmVuY2UsIHNvIHJlbWVtYmVyIHRoYXQgd2UgZm91bmQgb25lLgogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFNraXAgdG8gdGhlIG5leHQgc291cmNlIGVsZW1lbnQsIGJ1dCBkb24ndCBmZXRjaCBhbm90aGVyIHRhcmdldCBlbGVtZW50LgogICAgICAgICAgICAgICAgZ2V0dCA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHBUT3JkZXIgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gcmVjb3JkIGRpZmZlcmVuY2VzIC0gc2VlIHRoZSBjb21tZW50IGFib3ZlLgogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFNraXAgdG8gdGhlIG5leHQgdGFyZ2V0IGVsZW1lbnQsIGJ1dCBkb24ndCBmZXRjaCBhbm90aGVyIHNvdXJjZSBlbGVtZW50LgogICAgICAgICAgICAgICAgZ2V0cyA9IEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gTmVpdGhlciBvZiB0aGUgb3JkZXJzIGlzIGlnbm9yYWJsZSwgYW5kIHdlIGFscmVhZHkga25vdyB0aGF0IHRoZSBwcmltYXJ5CiAgICAgICAgICAgICAgICAvLyBvcmRlcnMgYXJlIGRpZmZlcmVudCBiZWNhdXNlIG9mIHRoZSAocFNPcmRlciAhPSBwVE9yZGVyKSB0ZXN0IGFib3ZlLgogICAgICAgICAgICAgICAgLy8gUmVjb3JkIHRoZSBkaWZmZXJlbmNlIGFuZCBzdG9wIHRoZSBjb21wYXJpc29uLgogICAgICAgICAgICAgICAgaWYgKHBTT3JkZXIgPCBwVE9yZGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6TEVTUzsgIC8vIChzdHJlbmd0aCBpcyBQUklNQVJZKQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsgIC8vIChzdHJlbmd0aCBpcyBQUklNQVJZKQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7IC8vIGVsc2Ugb2YgaWYgKCBwU09yZGVyICE9IHBUT3JkZXIgKQogICAgICAgICAgICAvLyBwcmltYXJ5IG9yZGVyIGlzIHRoZSBzYW1lLCBidXQgY29tcGxldGUgb3JkZXIgaXMgZGlmZmVyZW50LiBTbyB0aGVyZQogICAgICAgICAgICAvLyBhcmUgbm8gYmFzZSBlbGVtZW50cyBhdCB0aGlzIHBvaW50LCBvbmx5IGlnbm9yYWJsZXMgKFNpbmNlIHRoZSBzdHJpbmdzIGFyZQogICAgICAgICAgICAvLyBub3JtYWxpemVkKQoKICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBhIHNlY29uZGFyeSBvciB0ZXJ0aWFyeSBkaWZmZXJlbmNlIG1heSBzdGlsbCBtYXR0ZXIKICAgICAgICAgICAgICAgIHVpbnQzMl90IHNlY1NPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIoc09yZGVyKTsKICAgICAgICAgICAgICAgIHVpbnQzMl90IHNlY1RPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIodE9yZGVyKTsKCiAgICAgICAgICAgICAgICBpZiAoc2VjU09yZGVyICE9IHNlY1RPcmRlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZSBpcyBhIHNlY29uZGFyeSBkaWZmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHNlY1NPcmRlciA8IHNlY1RPcmRlcikgPyBDb2xsYXRvcjo6TEVTUyA6IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsgCiAgICAgICAgICAgICAgICAgICAgLy8gKGV2ZW4gaW4gZnJlbmNoLCBvbmx5IHRoZSBmaXJzdCBzZWNvbmRhcnkgZGlmZmVyZW5jZSB3aXRoaW4KICAgICAgICAgICAgICAgICAgICAvLyAgYSBiYXNlIGNoYXJhY3RlciBtYXR0ZXJzKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChjaGVja1RlcnRpYXJ5KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIG1heSBzdGlsbCBtYXR0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgdGVyU09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKHNPcmRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IHRlclRPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcih0T3JkZXIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlclNPcmRlciAhPSB0ZXJUT3JkZXIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZXJlIGlzIGEgdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHRlclNPcmRlciA8IHRlclRPcmRlcikgPyBDb2xsYXRvcjo6TEVTUyA6IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIChzdHJlbmd0aCBpcyBURVJUSUFSWSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrVGVydGlhcnkgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAvLyBpZiAoY2hlY2tTZWNUZXIpCgogICAgICAgIH0gIC8vIGlmICggcFNPcmRlciAhPSBwVE9yZGVyICkKICAgIH0gLy8gd2hpbGUoKQoKICAgIGlmIChzT3JkZXIgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpCiAgICB7CiAgICAgICAgLy8gKHRPcmRlciBtdXN0IGJlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSLAogICAgICAgIC8vICBzaW5jZSB0aGlzIHBvaW50IGlzIG9ubHkgcmVhY2hlZCB3aGVuIHNPcmRlciBvciB0T3JkZXIgaXMgTlVMTE9SREVSLikKICAgICAgICAvLyBUaGUgc291cmNlIHN0cmluZyBoYXMgbW9yZSBlbGVtZW50cywgYnV0IHRoZSB0YXJnZXQgc3RyaW5nIGhhc24ndC4KICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgaWYgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKHNPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gV2UgZm91bmQgYW4gYWRkaXRpb25hbCBub24taWdub3JhYmxlIGJhc2UgY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHByaW1hcnkgZGlmZmVyZW5jZSwgc28gdGhlIHNvdXJjZSBpcyBncmVhdGVyCiAgICAgICAgICAgICAgICByZXR1cm4gQ29sbGF0b3I6OkdSRUFURVI7IC8vIChzdHJlbmd0aCBpcyBQUklNQVJZKQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihzT3JkZXIpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEFkZGl0aW9uYWwgc2Vjb25kYXJ5IGVsZW1lbnRzIG1lYW4gdGhlIHNvdXJjZSBzdHJpbmcgaXMgZ3JlYXRlcgogICAgICAgICAgICAgICAgaWYgKGNoZWNrU2VjVGVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOyAgLy8gKHN0cmVuZ3RoIGlzIFNFQ09OREFSWSkKICAgICAgICAgICAgICAgICAgICBjaGVja1NlY1RlciA9IEZBTFNFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IAogICAgICAgIH0KICAgICAgICB3aGlsZSAoKHNPcmRlciA9IGdldFN0cmVuZ3RoT3JkZXIoY3Vyc29yMSwgc3RhdHVzKSkgIT0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpOVUxMT1JERVIpOwogICAgfQogICAgZWxzZSBpZiAodE9yZGVyICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKQogICAgewogICAgICAgIC8vIFRoZSB0YXJnZXQgc3RyaW5nIGhhcyBtb3JlIGVsZW1lbnRzLCBidXQgdGhlIHNvdXJjZSBzdHJpbmcgaGFzbid0LgogICAgICAgIGRvCiAgICAgICAgewogICAgICAgICAgICBpZiAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIodE9yZGVyKSAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBhbiBhZGRpdGlvbmFsIG5vbi1pZ25vcmFibGUgYmFzZSBjaGFyYWN0ZXIgaW4gdGhlIHRhcmdldCBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgcHJpbWFyeSBkaWZmZXJlbmNlLCBzbyB0aGUgc291cmNlIGlzIGxlc3MKICAgICAgICAgICAgICAgIHJldHVybiBDb2xsYXRvcjo6TEVTUzsgLy8gKHN0cmVuZ3RoIGlzIFBSSU1BUlkpCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKHRPcmRlcikgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBzZWNvbmRhcnkgZWxlbWVudHMgaW4gdGhlIHRhcmdldCBtZWFuIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGxlc3MKICAgICAgICAgICAgICAgIGlmIChjaGVja1NlY1RlcikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6TEVTUzsgIC8vIChzdHJlbmd0aCBpcyBTRUNPTkRBUlkpCiAgICAgICAgICAgICAgICAgICAgY2hlY2tTZWNUZXIgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSAKICAgICAgICB9CiAgICAgICAgd2hpbGUgKCh0T3JkZXIgPSBnZXRTdHJlbmd0aE9yZGVyKGN1cnNvcjIsIHN0YXR1cykpICE9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSKTsKICAgIH0KCgogICAgLy8gRm9yIElERU5USUNBTCBjb21wYXJpc29ucywgd2UgdXNlIGEgYml0d2lzZSBjaGFyYWN0ZXIgY29tcGFyaXNvbgogICAgLy8gYXMgYSB0aWVicmVha2VyIGlmIGFsbCBlbHNlIGlzIGVxdWFsCiAgICAvLyBOT1RFOiBUaGUgamF2YSBjb2RlIGNvbXBhcmVzIHJlc3VsdCB3aXRoIDAsIGFuZCAKICAgIC8vIHB1dHMgdGhlIHJlc3VsdCBvZiB0aGUgc3RyaW5nIGNvbXBhcmlzb24gZGlyZWN0bHkgaW50byByZXN1bHQKICAgIGlmIChyZXN1bHQgPT0gQ29sbGF0b3I6OkVRVUFMICYmIGdldFN0cmVuZ3RoKCkgPT0gSURFTlRJQ0FMKQogICAgewojaWYgMAogICAgICAvLyAqKioqKioqKiBmb3IgdGhlICBVQ2hhciBub3JtYWxpemF0aW9uIGludGVyZmFjZS4KICAgICAgLy8gSXQgZG9lc24ndCB3b3JrIG11Y2ggZmFzdGVyLCBhbmQgdGhlIGNvZGUgd2FzIGJyb2tlbgogICAgICAvLyBzbyBpdCdzIGNvbW1lbnRlZCBvdXQuIC0tc3JsCi8vICAgICAgICAgIFVDaGFyIHNvdXJjZURlY29tcFsxMDI0XSwgdGFyZ2V0RGVjb21wWzEwMjRdOwovLyAgCWludDMyX3Qgc291cmNlRGVjb21wTGVuZ3RoID0gMTAyNDsKLy8gIAlpbnQzMl90IHRhcmdldERlY29tcExlbmd0aCA9IDEwMjQ7CgkKLy8gICAgICAgICAgaW50OF90IGNvbXBhcmlzb247Ci8vICAJTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wTW9kZSA9IGdldERlY29tcG9zaXRpb24oKTsKICAgICAgICAKLy8gIAlpZiAoZGVjb21wTW9kZSAhPSBOb3JtYWxpemVyOjpOT19PUCkKLy8gIAkgIHsKLy8gIAkgICAgTm9ybWFsaXplcjo6bm9ybWFsaXplKHNvdXJjZSwgc291cmNlTGVuZ3RoLCBkZWNvbXBNb2RlLAovLyAgCQkJCSAgMCwgc291cmNlRGVjb21wLCBzb3VyY2VEZWNvbXBMZW5ndGgsIHN0YXR1cyk7CgkgICAgCi8vICAJICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZSh0YXJnZXQsIHRhcmdldExlbmd0aCwgZGVjb21wTW9kZSwKLy8gIAkJCQkgIDAsIHRhcmdldERlY29tcCwgdGFyZ2V0RGVjb21wTGVuZ3RoLCBzdGF0dXMpOwoJICAgIAovLyAgCSAgICBjb21wYXJpc29uID0gdV9zdHJjbXAoc291cmNlRGVjb21wLHRhcmdldERlY29tcCk7Ci8vICAJICB9Ci8vICAJZWxzZQovLyAgCSAgewovLyAgCSAgICBjb21wYXJpc29uID0gdV9zdHJjbXAoc291cmNlLCB0YXJnZXQpOyAvKiAhICovCi8vICAJICB9CgojZWxzZQoKCVVuaWNvZGVTdHJpbmcgc291cmNlRGVjb21wLCB0YXJnZXREZWNvbXA7CgogICAgICAgIGludDhfdCBjb21wYXJpc29uOwogICAgICAgIAogICAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZShzb3VyY2UsIGdldERlY29tcG9zaXRpb24oKSwgCiAgICAgICAgICAgICAgICAgICAgICAwLCBzb3VyY2VEZWNvbXAsICBzdGF0dXMpOwoKICAgICAgICBOb3JtYWxpemVyOjpub3JtYWxpemUodGFyZ2V0LCBnZXREZWNvbXBvc2l0aW9uKCksIAogICAgICAgICAgICAgICAgICAgICAgMCwgdGFyZ2V0RGVjb21wLCAgc3RhdHVzKTsKICAgICAgICAKICAgICAgICBjb21wYXJpc29uID0gc291cmNlRGVjb21wLmNvbXBhcmUodGFyZ2V0RGVjb21wKTsKI2VuZGlmCgogICAgICAgIGlmIChjb21wYXJpc29uIDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpMRVNTOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChjb21wYXJpc29uID09IDApCiAgICAgICAgewogICAgICAgICAgICByZXN1bHQgPSBDb2xsYXRvcjo6RVFVQUw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3VsdCA9IENvbGxhdG9yOjpHUkVBVEVSOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgoKaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6bmV4dENvbnRyYWN0Q2hhcihOb3JtYWxpemVySXRlcmF0b3IgKmN1cnNvciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0CnsKICAgIC8vIEZpcnN0IGdldCB0aGUgb3JkZXJpbmcgb2YgdGhpcyBzaW5nbGUgY2hhcmFjdGVyCiAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqbGlzdCA9IGdldENvbnRyYWN0VmFsdWVzKGNoKTsKICAgIEVudHJ5UGFpciAqcGFpciA9IChFbnRyeVBhaXIgKilsaXN0LT5hdCgwKTsKICAgIGludDMyX3Qgb3JkZXIgPSBwYWlyLT52YWx1ZTsKCiAgICAvLyBOb3cgaXRlcmF0ZSB0aHJvdWdoIHRoZSBjaGFycyBmb2xsb3dpbmcgaXQgYW5kCiAgICAvLyBsb29rIGZvciB0aGUgbG9uZ2VzdCBtYXRjaAogICAgKChVbmljb2RlU3RyaW5nJilrZXkpLnJlbW92ZSgpOwogICAgKChVbmljb2RlU3RyaW5nJilrZXkpICs9IGNoOwoKICAgIHdoaWxlICgoY2ggPSBjdXJzb3ItPmN1cnJlbnQoKSkgIT0gTm9ybWFsaXplcjo6RE9ORSkKICAgIHsKICAgICAgICAoKFVuaWNvZGVTdHJpbmcmKWtleSkgKz0gY2g7CgogICAgICAgIGludDMyX3QgbiA9IGdldEVudHJ5KGxpc3QsIGtleSwgVFJVRSk7CgogICAgICAgIGlmIChuID09IFVOTUFQUEVEKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGN1cnNvci0+bmV4dCgpOwoKICAgICAgICBwYWlyID0gKEVudHJ5UGFpciAqKWxpc3QtPmF0KG4pOwogICAgICAgIG9yZGVyID0gcGFpci0+dmFsdWU7CiAgICB9CgogICAgcmV0dXJuIG9yZGVyOwp9CgovLyBDb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoaXMgY29sbGF0b3IKQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0ClJ1bGVCYXNlZENvbGxhdG9yOjpjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdAp7CiAgICByZXR1cm4gY29tcGFyZShzb3VyY2UuZ2V0VUNoYXJzKCksIHNvdXJjZS5sZW5ndGgoKSwgdGFyZ2V0LmdldFVDaGFycygpLCB0YXJnZXQubGVuZ3RoKCkpOwp9CgovLyBSZXRyaWV2ZSBhIGNvbGxhdGlvbiBrZXkgZm9yIHRoZSBzcGVjaWZpZWQgc3RyaW5nCi8vIFRoZSBrZXkgY2FuIGJlIGNvbXBhcmVkIHdpdGggb3RoZXIgY29sbGF0aW9uIGtleXMgdXNpbmcgYSBiaXR3aXNlIGNvbXBhcmlzb24KLy8gKGUuZy4gbWVtY21wKSB0byBmaW5kIHRoZSBvcmRlcmluZyBvZiB0aGVpciByZXNwZWN0aXZlIHNvdXJjZSBzdHJpbmdzLgovLyBUaGlzIGlzIGhhbmR5IHdoZW4gZG9pbmcgYSBzb3J0LCB3aGVyZSBlYWNoIHNvcnQga2V5IG11c3QgYmUgY29tcGFyZWQKLy8gbWFueSB0aW1lcy4KLy8KLy8gVGhlIGJhc2ljIGFsZ29yaXRobSBoZXJlIGlzIHRvIGZpbmQgYWxsIG9mIHRoZSBjb2xsYXRpb24gZWxlbWVudHMgZm9yIGVhY2gKLy8gY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLCBjb252ZXJ0IHRoZW0gdG8gYW4gQVNDSUkgcmVwcmVzZW50YXRpb24sCi8vIGFuZCBwdXQgdGhlbSBpbnRvIHRoZSBjb2xsYXRpb24ga2V5LiAgQnV0IGl0J3MgdHJpY2tpZXIgdGhhbiB0aGF0LgovLyBFYWNoIGNvbGxhdGlvbiBlbGVtZW50IGluIGEgc3RyaW5nIGhhcyB0aHJlZSBjb21wb25lbnRzOiBwcmltYXJ5ICgnQScgdnMgJ0InKSwKLy8gc2Vjb25kYXJ5ICgndScgdnMgJ/wnKSwgYW5kIHRlcnRpYXJ5ICgnQScgdnMgJ2EnKSwgYW5kIGEgcHJpbWFyeSBkaWZmZXJlbmNlCi8vIGF0IHRoZSBlbmQgb2YgYSBzdHJpbmcgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGEgc2Vjb25kYXJ5IG9yIHRlcnRpYXJ5Ci8vIGRpZmZlcmVuY2UgZWFybGllciBpbiB0aGUgc3RyaW5nLgovLwovLyBUbyBhY2NvdW50IGZvciB0aGlzLCB3ZSBwdXQgYWxsIG9mIHRoZSBwcmltYXJ5IG9yZGVycyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZQovLyBzdHJpbmcsIGZvbGxvd2VkIGJ5IHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IG9yZGVycy4gRWFjaCBzZXQgb2Ygb3JkZXJzIGlzCi8vIHRlcm1pbmF0ZWQgYnkgbnVsbHMgc28gdGhhdCBhIGtleSBmb3IgYSBzdHJpbmcgd2hpY2ggaXMgYSBpbml0aWFsIHN1YnN0cmluZyBvZgovLyBhbm90aGVyIGtleSB3aWxsIGNvbXBhcmUgbGVzcyB3aXRob3V0IGFueSBzcGVjaWFsIGNhc2UuCi8vCi8vIEhlcmUncyBhIGh5cG90aGV0aWNhbCBleGFtcGxlLCB3aXRoIHRoZSBjb2xsYXRpb24gZWxlbWVudCByZXByZXNlbnRlZCBhcwovLyBhIHRocmVlLWRpZ2l0IG51bWJlciwgb25lIGRpZ2l0IGZvciBwcmltYXJ5LCBvbmUgZm9yIHNlY29uZGFyeSwgZXRjLgovLwovLyBTdHJpbmc6ICAgICAgICAgICAgICBBICAgICBhICAgICBCICAgIMkKLy8gQ29sbGF0aW9uIEVsZW1lbnRzOiAxMDEgICAxMDAgICAyMDEgIDUxMQovLyBDb2xsYXRpb24gS2V5OiAgICAgIDExMjU8bnVsbD4wMDAxPG51bGw+MTAxMTxudWxsPgovLwovLyBUbyBtYWtlIHRoaW5ncyBldmVuIHRyaWNraWVyLCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMgKGFjY2VudCBtYXJrcykgYXJlIGNvbXBhcmVkCi8vIHN0YXJ0aW5nIGF0IHRoZSAqZW5kKiBvZiB0aGUgc3RyaW5nIGluIGxhbmd1YWdlcyB3aXRoIEZyZW5jaCBzZWNvbmRhcnkgb3JkZXJpbmcuCi8vIEJ1dCB3aGVuIGNvbXBhcmluZyB0aGUgYWNjZW50IG1hcmtzIG9uIGEgc2luZ2xlIGJhc2UgY2hhcmFjdGVyLCB0aGV5IGFyZSBjb21wYXJlZAovLyBmcm9tIHRoZSBiZWdpbm5pbmcuICBUbyBoYW5kbGUgdGhpcywgd2UgcmV2ZXJzZSBhbGwgb2YgdGhlIGFjY2VudHMgdGhhdCBiZWxvbmcKLy8gdG8gZWFjaCBiYXNlIGNoYXJhY3RlciwgdGhlbiB3ZSByZXZlcnNlIHRoZSBlbnRpcmUgc3RyaW5nIG9mIHNlY29uZGFyeSBvcmRlcmluZ3MKLy8gYXQgdGhlIGVuZC4KLy8KQ29sbGF0aW9uS2V5JgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29sbGF0aW9uS2V5KCBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QKewogICAgcmV0dXJuIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb2xsYXRpb25LZXkoc291cmNlLmdldFVDaGFycygpLCBzb3VyY2UubGVuZ3RoKCksIHNvcnRrZXksIHN0YXR1cyk7Cn0KCkNvbGxhdGlvbktleSYKUnVsZUJhc2VkQ29sbGF0b3I6OmdldENvbGxhdGlvbktleSggY29uc3QgICBVQ2hhciogIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBzb3J0a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUjsKICAgICAgICByZXR1cm4gc29ydGtleS5zZXRUb0JvZ3VzKCk7CiAgICB9CiAgICAKICAgIGlmICgoIXNvdXJjZSkgfHwgKHNvdXJjZUxlbiA9PSAwKSkKICAgIHsKICAgICAgICByZXR1cm4gc29ydGtleS5yZXNldCgpOwogICAgfQoKICAgIGlmIChjdXJzb3IxID09IE5VTEwpCiAgICB7CiAgICAgICgoUnVsZUJhc2VkQ29sbGF0b3IgKil0aGlzKS0+Y3Vyc29yMSA9IG5ldyBOb3JtYWxpemVySXRlcmF0b3Ioc291cmNlLCBzb3VyY2VMZW4sIGdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIGN1cnNvcjEtPnNldE1vZGVBbmRUZXh0KGdldERlY29tcG9zaXRpb24oKSwgc291cmNlLHNvdXJjZUxlbiwgc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIHNvcnRrZXkuc2V0VG9Cb2d1cygpOwogICAgfQoKICAgIFVCb29sICBjb21wYXJlU2VjICAgPSAoZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6U0VDT05EQVJZKTsKICAgIFVCb29sICBjb21wYXJlVGVyICAgPSAoZ2V0U3RyZW5ndGgoKSA+PSBDb2xsYXRvcjo6VEVSVElBUlkpOwogICAgVUJvb2wgIGNvbXBhcmVJZGVudCA9IChnZXRTdHJlbmd0aCgpID09IENvbGxhdG9yOjpJREVOVElDQUwpOwogICAgaW50MzJfdCBvcmRlciAgICAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbFByaW1hcnkgPSAwOwogICAgaW50MzJfdCB0b3RhbFNlYyAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbFRlciAgICAgPSAwOwogICAgaW50MzJfdCB0b3RhbElkZW50ICAgICA9IDA7CiAgICBVbmljb2RlU3RyaW5nIGRlY29tcDsKCiAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIHNvdXJjZSwgY291bnRpbmcgcHJpbWFyeSwgc2Vjb25kYXJ5LCBhbmQgdGVydGlhcnkgZW50cmllcwogICAgd2hpbGUoKG9yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcigoTm9ybWFsaXplckl0ZXJhdG9yKiljdXJzb3IxLCBzdGF0dXMpKSAhPQoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikKICAgIHsKICAgICAgICBpbnQzMl90IHNlY09yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihvcmRlcik7CiAgICAgICAgaW50MzJfdCB0ZXJPcmRlciA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihvcmRlcik7CgogICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBzb3J0a2V5LnNldFRvQm9ndXMoKTsKICAgICAgICB9CgogICAgICAgIGlmICghIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNJZ25vcmFibGUob3JkZXIpKQogICAgICAgIHsKICAgICAgICAgICAgdG90YWxQcmltYXJ5ICs9IDE7CgogICAgICAgICAgICBpZiAoY29tcGFyZVNlYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxTZWMgKz0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRvdGFsVGVyICs9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbXBhcmVTZWMgJiYgc2VjT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxTZWMgKz0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBhcmVUZXIgJiYgdGVyT3JkZXIgIT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdG90YWxUZXIgKz0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBjb3VudCB0aGUgbnVsbCBieXRlcyBhZnRlciB0aGUgZW50aXJlcwogICAgdG90YWxQcmltYXJ5ICs9IDE7CgogICAgaWYgKGNvbXBhcmVTZWMpCiAgICB7CiAgICAgICAgdG90YWxTZWMgKz0gMTsKICAgIH0KCiAgICBpZiAoY29tcGFyZVRlcikKICAgIHsKICAgICAgICB0b3RhbFRlciArPSAxOwogICAgfQoKICAgIGlmIChjb21wYXJlSWRlbnQpCiAgICB7CiAgICAgIE5vcm1hbGl6ZXI6Om5vcm1hbGl6ZShzb3VyY2UsIGdldERlY29tcG9zaXRpb24oKSwgLy8gU1JMOiA/PwogICAgICAgICAgICAgICAgMCwgZGVjb21wLCBzdGF0dXMpOwoKICAgICAgICBpZiAoVV9TVUNDRVNTKHN0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICB0b3RhbElkZW50ID0gZGVjb21wLmxlbmd0aCgpICsgMTsKICAgICAgICB9CiAgICB9CgogICAgLy8gQ29tcHV0ZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgdG8gaG9sZCB0aGUgZW50cmllcwogICAgLy8gYW5kIG1ha2Ugc3VyZSB0aGUga2V5IGNhbiBob2xkIHRoZW0KICAgIHVpbnQzMl90IHNpemUgICA9IDIgKiAodG90YWxQcmltYXJ5ICsgdG90YWxTZWMgKyB0b3RhbFRlciArIHRvdGFsSWRlbnQpOwoKICAgIHNvcnRrZXkuZW5zdXJlQ2FwYWNpdHkoc2l6ZSk7CgogICAgaWYgKHNvcnRrZXkuaXNCb2d1cygpKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgcmV0dXJuIHNvcnRrZXk7CiAgICB9CgogICAgaW50MzJfdCBwcmltYXJ5Q3Vyc29yID0gMDsKICAgIGludDMyX3Qgc2VjQ3Vyc29yICAgICA9IDIgKiB0b3RhbFByaW1hcnk7CiAgICBpbnQzMl90IHNlY0Jhc2UgICAgICAgPSBzZWNDdXJzb3I7CiAgICBpbnQzMl90IHByZVNlY0lnbm9yZSAgPSBzZWNCYXNlOwogICAgaW50MzJfdCB0ZXJDdXJzb3IgICAgID0gc2VjQ3Vyc29yICsgKDIgKiB0b3RhbFNlYyk7CiAgICBpbnQzMl90IGlkZW50Q3Vyc29yICAgICAgPSB0ZXJDdXJzb3IgKyAoMiAqIHRvdGFsVGVyKTsKCiAgICAvLyByZXNldCBzb3VyY2UgdG8gdGhlIGJlZ2lubmluZwogICAgY3Vyc29yMS0+cmVzZXQoKTsKCiAgICAvLyBub3cgaXRlcmF0ZSBvdmVyIHRoZSBzb3VyY2UgY29tcHV0aW5nIHRoZSBhY3R1YWwgZW50cmllcwogICAgd2hpbGUoKG9yZGVyID0gZ2V0U3RyZW5ndGhPcmRlcigoTm9ybWFsaXplckl0ZXJhdG9yKiljdXJzb3IxLCBzdGF0dXMpKSAhPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUikKICAgIHsKICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc29ydGtleS5yZXNldCgpOwogICAgICAgIH0KCiAgICAgICAgaW50MzJfdCBwcmltYXJ5T3JkZXIgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcihvcmRlcik7CiAgICAgICAgaW50MzJfdCBzZWNPcmRlciAgICAgPSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKG9yZGVyKTsKICAgICAgICBpbnQzMl90IHRlck9yZGVyICAgICA9IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihvcmRlcik7CgogICAgICAgIGlmICghIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNJZ25vcmFibGUob3JkZXIpKQogICAgICAgIHsKICAgICAgICAgICAgcHJpbWFyeUN1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyhwcmltYXJ5Q3Vyc29yLCBwcmltYXJ5T3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKCiAgICAgICAgICAgIGlmIChjb21wYXJlU2VjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZGF0YS0+aXNGcmVuY2hTZWMgJiYgKHByZVNlY0lnbm9yZSA8IHNlY0N1cnNvcikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc29ydGtleS5yZXZlcnNlQnl0ZXMocHJlU2VjSWdub3JlLCBzZWNDdXJzb3IpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHNlY0N1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyhzZWNDdXJzb3IsIHNlY09yZGVyICsgU09SVEtFWU9GRlNFVCk7CgogICAgICAgICAgICAgICAgcHJlU2VjSWdub3JlID0gc2VjQ3Vyc29yOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcGFyZVRlcikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVyQ3Vyc29yID0gc29ydGtleS5zdG9yZUJ5dGVzKHRlckN1cnNvciwgdGVyT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZiAoY29tcGFyZVNlYyAmJiBzZWNPcmRlciAhPSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZWNDdXJzb3IgPSBzb3J0a2V5LnN0b3JlQnl0ZXMoc2VjQ3Vyc29yLCBzZWNPcmRlciArIGRhdGEtPm1heFNlY09yZGVyICsgU09SVEtFWU9GRlNFVCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb21wYXJlVGVyICYmIHRlck9yZGVyICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRlckN1cnNvciA9IHNvcnRrZXkuc3RvcmVCeXRlcyh0ZXJDdXJzb3IsIHRlck9yZGVyICsgZGF0YS0+bWF4VGVyT3JkZXIgKyBTT1JUS0VZT0ZGU0VUKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBhcHBlbmQgMCBhdCB0aGUgZW5kIG9mIGVhY2ggcG9ydGlvbi4KICAgIHNvcnRrZXkuc3RvcmVCeXRlcyhwcmltYXJ5Q3Vyc29yLCAwKTsKCiAgICBpZiAoY29tcGFyZVNlYykKICAgIHsKICAgICAgICBpZiAoZGF0YS0+aXNGcmVuY2hTZWMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocHJlU2VjSWdub3JlIDwgc2VjQ3Vyc29yKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzb3J0a2V5LnJldmVyc2VCeXRlcyhwcmVTZWNJZ25vcmUsIHNlY0N1cnNvcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNvcnRrZXkucmV2ZXJzZUJ5dGVzKHNlY0Jhc2UsIHNlY0N1cnNvcik7CiAgICAgICAgfQoKICAgICAgICBzb3J0a2V5LnN0b3JlQnl0ZXMoc2VjQ3Vyc29yLCAwKTsKICAgIH0KCiAgICBpZiAoY29tcGFyZVRlcikKICAgIHsKICAgICAgICBzb3J0a2V5LnN0b3JlQnl0ZXModGVyQ3Vyc29yLCAwKTsKICAgIH0KCiAgICBpZiAoY29tcGFyZUlkZW50KQogICAgewogICAgICAgIHNvcnRrZXkuc3RvcmVVbmljb2RlU3RyaW5nKGlkZW50Q3Vyc29yLCBkZWNvbXApOwogICAgfQoKICAgIC8vICAgIERlYnVnZ2luZyAtIHByaW50IG91dCB0aGUgc29ydGtleSBbLS1zcmxdCi8vICAgICAgewovLyAgICAgICAgY29uc3QgdWludDhfdCAqYnl0ZXM7Ci8vICAgICAgICBpbnQzMl90IHhjb3VudDsKLy8gICAgICAgIGJ5dGVzID0gc29ydGtleS5nZXRCeXRlQXJyYXkoeGNvdW50KTsKLy8gICAgICAgIC8vICAgICAgZnByaW50ZihzdGRlcnIsICJcblxuLSAgWyUwMlhdIFslMDJYXVxuXG4iLCAoaW50KShieXRlc1swXSYweEZGKSwgKGludCkoYnl0ZXNbMV0mMHhGRikgKTsKLy8gICAgICB9CgogICAgcmV0dXJuIHNvcnRrZXk7Cn0KCgovLyBCdWlsZCB0aGlzIGNvbGxhdG9yJ3MgcnVsZSB0YWJsZXMgYmFzZWQgb24gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHJ1bGVzCi8vIFNlZSB0aGUgYmlnIGRpYWdyYW0gYXQgdGhlIHRvcCBvZiB0aGlzIGZpbGUgZm9yIGFuIG92ZXJ2aWV3IG9mIGhvdyB0aGUgdGFibGVzCi8vIGFyZSBvcmdhbml6ZWQuCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmJ1aWxkKGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgcGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIFRoaXMgYXJyYXkgbWFwcyBVbmljb2RlIGNoYXJhY3RlcnMgdG8gdGhlaXIgY29sbGF0aW9uIG9yZGVyaW5nCiAgICBkYXRhLT5tYXBwaW5nID0gdWNtcDMyX29wZW4oVU5NQVBQRUQpOwoKICAgIGlmIChkYXRhLT5tYXBwaW5nLT5mQm9ndXMpCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBhU3RyZW5ndGggPSBDb2xsYXRvcjo6SURFTlRJQ0FMOwogICAgVUJvb2wgaXNTb3VyY2UgPSBUUlVFOwogICAgaW50MzJfdCBpID0gMDsKICAgIFVuaWNvZGVTdHJpbmcgbGFzdEdyb3VwQ2hhcnM7CiAgICBVbmljb2RlU3RyaW5nIGV4cENoYXJzOwogICAgVW5pY29kZVN0cmluZyBncm91cENoYXJzOwoKICAgIGlmIChwYXR0ZXJuLmxlbmd0aCgpID09IDApCiAgICB7CiAgICAgICAgc3RhdHVzID0gVV9JTlZBTElEX0ZPUk1BVF9FUlJPUjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gQnVpbGQgdGhlIG1lcmdlZCBjb2xsYXRpb24gZW50cmllcwogICAgLy8gU2luY2UgcnVsZXMgY2FuIGJlIHNwZWNpZmllZCBpbiBhbnkgb3JkZXIgaW4gdGhlIHN0cmluZwogICAgLy8gKGUuZy4gImMgLCBDIDwgZCAsIEQgPCBlICwgRSAuLi4uIEMgPCBDSCIpCiAgICAvLyB0aGlzIHNwbGl0cyBhbGwgb2YgdGhlIHJ1bGVzIGluIHRoZSBzdHJpbmcgb3V0IGludG8gc2VwYXJhdGUKICAgIC8vIG9iamVjdHMgYW5kIHRoZW4gc29ydHMgdGhlbS4gIEluIHRoZSBhYm92ZSBleGFtcGxlLCBpdCBtZXJnZXMgdGhlCiAgICAvLyAiQyA8IENIIiBydWxlIGluIGp1c3QgYmVmb3JlIHRoZSAiQyA8IEQiIHJ1bGUuCgogICAgbVBhdHRlcm4gPSBuZXcgTWVyZ2VDb2xsYXRpb24ocGF0dGVybiwgZ2V0RGVjb21wb3NpdGlvbigpLCBzdGF0dXMpOwogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHVjbXAzMl9jbG9zZShkYXRhLT5tYXBwaW5nKTsKICAgICAgICBkYXRhLT5tYXBwaW5nID0gMDsKICAgICAgICBkZWxldGUgbVBhdHRlcm47CiAgICAgICAgbVBhdHRlcm4gPSAwOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpbnQzMl90IG9yZGVyID0gMDsKCiAgICAvLyBXYWxrIHRocm91Z2ggZWFjaCBlbnRyeQogICAgZm9yIChpID0gMDsgaSA8IG1QYXR0ZXJuLT5nZXRDb3VudCgpOyArK2kpCiAgICB7CiAgICAgICAgY29uc3QgUGF0dGVybkVudHJ5KiBlbnRyeSA9IG1QYXR0ZXJuLT5nZXRJdGVtQXQoaSk7CiAgICAgICAgZ3JvdXBDaGFycy5yZW1vdmUoKTsKICAgICAgICBleHBDaGFycy5yZW1vdmUoKTsKCiAgICAgICAgLy8gaWYgZW50cnkgaXMgdmFsaWQKICAgICAgICBpZiAoZW50cnkgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIGVudHJ5LT5nZXRDaGFycyhncm91cENoYXJzKTsKCiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGZyZW5jaCBzZWNvbmRhcnkgbmVlZHMgdG8gYmUgdHVybmVkIG9uCiAgICAgICAgICAgIGlmICgoZ3JvdXBDaGFycy5sZW5ndGgoKSA+IDEpICYmCiAgICAgICAgICAgICAgICAoZ3JvdXBDaGFyc1tncm91cENoYXJzLmxlbmd0aCgpLShUX0lOVDMyKDEpKV0gPT0gMHgwMDQwKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGF0YS0+aXNGcmVuY2hTZWMgPSBUUlVFOwogICAgICAgICAgICAgICAgZ3JvdXBDaGFycy5yZW1vdmUoZ3JvdXBDaGFycy5sZW5ndGgoKS0oVF9JTlQzMigxKSkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBvcmRlciA9IGluY3JlbWVudCgoQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCllbnRyeS0+Z2V0U3RyZW5ndGgoKSwgb3JkZXIpOwoKICAgICAgICAgICAgaWYgKGVudHJ5LT5nZXRFeHRlbnNpb24oZXhwQ2hhcnMpLmxlbmd0aCgpICE9IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIsIHdoZXJlIG9uZSBjaGFyYWN0ZXIgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGV4cGFuZHMgdG8gc2V2ZXJhbCBzb3J0IGVsZW1lbnRzIChlLmcuICf2JyAtLT4gJ28nICdlJykKICAgICAgICAgICAgICAgIGFkZEV4cGFuZE9yZGVyKGdyb3VwQ2hhcnMsIGV4cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoZ3JvdXBDaGFycy5sZW5ndGgoKSA+IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIGVuY291bnRlcmVkIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyLCB3aGVyZSBzZXZlcmFsIGNoYXJhY3RlcnMgb24gaW5wdXQKICAgICAgICAgICAgICAgIC8vIGNvbnRyYWN0IGludG8gb25lIHNvcnQgb3JkZXIuICBGb3IgZXhhbXBsZSwgImNoIiBpcyB0cmVhdGVkIGFzIGEgc2luZ2xlCiAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIgaW4gdHJhZGl0aW9uYWwgU3BhbmlzaCBzb3J0aW5nLgogICAgICAgICAgICAgICAgYWRkQ29udHJhY3RPcmRlcihncm91cENoYXJzLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIG91dCBvZiB0aGUgb3JkaW5hcnkgLS0gb25lIGNoYXJhY3RlciBtYXBzIHRvIG9uZSBzb3J0IG9yZGVyCiAgICAgICAgICAgICAgICBhZGRPcmRlcihncm91cENoYXJzWzBdLCBvcmRlciwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gYWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgY2hhcmFjdGVycwogICAgYWRkQ29tcG9zZWRDaGFycygpOwoKICAgIC8vIEZpbGwgaW4gYWxsIHRoZSBleHBhbmRpbmcgY2hhcnMgdmFsdWVzCiAgICBjb21taXQoKTsKCiAgICAvLyBDb21wYWN0IHRoZSBkYXRhIG1hcHBpbmcgdGFibGUKICAgIHVjbXAzMl9jb21wYWN0KGRhdGEtPm1hcHBpbmcsIDEpOwp9CgovKioKICogQWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgdW5pY29kZSBjaGFyYWN0ZXJzIHNvIHRoYXQgdGhpcwogKiBjb2xsYXRvciBjYW4gYmUgdXNlZCByZWFzb25hYmx5IHdlbGwgd2l0aCBkZWNvbXBvc2l0aW9uIHR1cm5lZCBvZmYuCiAqLwogdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29tcG9zZWRDaGFycygpCiB7CiAgICBVbmljb2RlU3RyaW5nIGJ1ZjsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgb2YgdGhlIHByZS1jb21wb3NlZCBjaGFyYWN0ZXJzIGluIFVuaWNvZGUKICAgIENvbXBvc2VkQ2hhckl0ZXIgaXRlcjsKICAgIFVuaWNvZGVTdHJpbmcgZGVjb21wOwoKICAgIHdoaWxlIChpdGVyLmhhc05leHQoKSkKICAgIHsKICAgICAgICBVQ2hhciBjID0gaXRlci5uZXh0KCk7CiAgICAgICAgCiAgICAgICAgaWYgKGdldENoYXJPcmRlcihjKSA9PSBVTk1BUFBFRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIAogICAgICAgICAgICAvLyBXZSBkb24ndCBhbHJlYWR5IGhhdmUgYW4gb3JkZXJpbmcgZm9yIHRoaXMgcHJlLWNvbXBvc2VkIGNoYXJhY3Rlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gRmlyc3QsIHNlZSBpZiB0aGUgZGVjb21wb3NlZCBzdHJpbmcgaXMgYWxyZWFkeSBpbiBvdXIKICAgICAgICAgICAgLy8gdGFibGVzIGFzIGEgc2luZ2xlIGNvbnRyYWN0aW5nLXN0cmluZyBvcmRlcmluZy4KICAgICAgICAgICAgLy8gSWYgc28sIGp1c3QgbWFwIHRoZSBwcmVjb21wb3NlZCBjaGFyYWN0ZXIgdG8gdGhhdCBvcmRlci4KICAgICAgICAgICAgLy8KICAgICAgICAgICAgLy8gVE9ETzogV2hhdCB3ZSBzaG91bGQgcmVhbGx5IGJlIGRvaW5nIGhlcmUgaXMgdHJ5aW5nIHRvIGZpbmQgdGhlCiAgICAgICAgICAgIC8vIGxvbmdlc3QgaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlIGRlY29tcG9zaXRpb24gdGhhdCBpcyBwcmVzZW50CiAgICAgICAgICAgIC8vIGluIHRoZSB0YWJsZXMgYXMgYSBjb250cmFjdGluZyBjaGFyYWN0ZXIgc2VxdWVuY2UsIGFuZCBmaW5kIGl0cwogICAgICAgICAgICAvLyBvcmRlcmluZy4gIFRoZW4gZG8gdGhpcyByZWN1cnNpdmVseSB3aXRoIHRoZSByZW1haW5pbmcgY2hhcnMKICAgICAgICAgICAgLy8gc28gdGhhdCB3ZSBidWlsZCBhIGxpc3Qgb2Ygb3JkZXJpbmdzLCBhbmQgYWRkIHRoYXQgbGlzdCB0bwogICAgICAgICAgICAvLyB0aGUgZXhwYW5zaW9uIHRhYmxlLiAKICAgICAgICAgICAgLy8gVGhhdCB3b3VsZCBiZSBtb3JlIGNvcnJlY3QgYnV0IGFsc28gc2lnbmlmaWNhbnRseSBzbG93ZXIsIHNvCiAgICAgICAgICAgIC8vIEknbSBub3QgdG90YWxseSBzdXJlIGl0J3Mgd29ydGggZG9pbmcuCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIGl0ZXIuZ2V0RGVjb21wb3NpdGlvbihkZWNvbXApOwogICAgICAgICAgICBpbnQgY29udHJhY3RPcmRlciA9IGdldENvbnRyYWN0T3JkZXIoZGVjb21wKTsKCiAgICAgICAgICAgIGlmIChjb250cmFjdE9yZGVyICE9IFVOTUFQUEVEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhZGRPcmRlcihjLCBjb250cmFjdE9yZGVyLCBzdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIFdlIGRvbid0IGhhdmUgYSBjb250cmFjdGluZyBvcmRlcmluZyBmb3IgdGhlIGVudGlyZSBzdHJpbmcKICAgICAgICAgICAgICAgIC8vIHRoYXQgcmVzdWx0cyBmcm9tIHRoZSBkZWNvbXBvc2l0aW9uLCBidXQgaWYgd2UgaGF2ZSBvcmRlcnMKICAgICAgICAgICAgICAgIC8vIGZvciBlYWNoIGluZGl2aWR1YWwgY2hhcmFjdGVyLCB3ZSBjYW4gYWRkIGFuIGV4cGFuZGluZwogICAgICAgICAgICAgICAgLy8gdGFibGUgZW50cnkgZm9yIHRoZSBwcmUtY29tcG9zZWQgY2hhcmFjdGVyIAogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIFVCb29sIGFsbFRoZXJlID0gVFJVRTsKICAgICAgICAgICAgICAgIGludDMyX3QgaTsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGVjb21wLmxlbmd0aCgpOyBpICs9IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGdldENoYXJPcmRlcihkZWNvbXBbaV0pID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWxsVGhlcmUgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhbGxUaGVyZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBidWYucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IGM7CiAgICAgICAgICAgICAgICAgICAgYWRkRXhwYW5kT3JkZXIoYnVmLCBkZWNvbXAsIFVOTUFQUEVELCBzdGF0dXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CiAgICAKLy8gV2hlbiB0aGUgZXhwYW5kaW5nIGNoYXJhY3RlciB0YWJsZXMgYXJlIGJ1aWx0IGJ5IGFkZEV4cGFuZE9yZGVyLAovLyBpdCBkb2Vzbid0IGtub3cgd2hhdCB0aGUgZmluYWwgb3JkZXJpbmcgb2YgZWFjaCBjaGFyYWN0ZXIKLy8gaW4gdGhlIGV4cGFuc2lvbiB3aWxsIGJlLiAgSW5zdGVhZCwgaXQganVzdCBwdXRzIHRoZSByYXcgY2hhcmFjdGVyCi8vIGNvZGUgaW50byB0aGUgdGFibGUsIGFkZGluZyBDSEFSSU5ERVggYXMgYSBmbGFnLiAgTm93IHRoYXQgd2UndmUKLy8gZmluaXNoZWQgYnVpbGRpbmcgdGhlIG1hcHBpbmcgdGFibGUsIHdlIGNhbiBnbyBiYWNrIGFuZCBsb29rIHVwCi8vIHRoYXQgY2hhcmFjdGVyIHRvIHNlZSB3aGF0IGl0cyByZWFsIGNvbGxhdGlvbiBvcmRlciBpcyBhbmQKLy8gc3RpY2sgdGhhdCBpbnRvIHRoZSBleHBhbnNpb24gdGFibGUuICBUaGF0IGxldHMgdXMgYXZvaWQgZG9pbmcKLy8gYSB0d28tc3RhZ2UgbG9va3VwIGxhdGVyLgoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y29tbWl0KCkKewogICAgLy8gaWYgdGhlcmUgYXJlIGFueSBleHBhbmRpbmcgY2hhcmFjdGVycwogICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgaW50MzJfdCBpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOyBpICs9IDEpCiAgICAgICAgewogICAgICAgICAgICBWZWN0b3JPZkludCogdmFsdWVMaXN0ID0gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KGkpOwogICAgICAgICAgICBpbnQzMl90IGo7CiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB2YWx1ZUxpc3QtPnNpemUoKTsgaisrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIGV4cGFuZGluZyBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIC8vIHRoZSBleHBhbmRpbmcgY2hhciB2YWx1ZSBpcyBub3QgZmlsbGVkIGluIHlldAogICAgICAgICAgICAgICAgaWYgKCh2YWx1ZUxpc3QtPmF0KGopIDwgRVhQQU5EQ0hBUklOREVYKSAmJgogICAgICAgICAgICAgICAgICAgICh2YWx1ZUxpc3QtPmF0KGopID4gQ0hBUklOREVYKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHJlYWwgdmFsdWVzIGZvciB0aGUgbm9uLWZpbGxlZCBlbnRyeQogICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoID0gKFVDaGFyKSh2YWx1ZUxpc3QtPmF0KGopIC0gQ0hBUklOREVYKTsKICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHJlYWxWYWx1ZSA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocmVhbFZhbHVlID09IFVOTUFQUEVEKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlYWwgdmFsdWUgaXMgc3RpbGwgdW5tYXBwZWQsIG1heWJlIGl0J3NpZ25vcmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChqLCBJR05PUkFCTEVNQVNLICYgY2gpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBmaWxsIGluIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlTGlzdC0+YXRQdXQoaiwgcmVhbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiB9CgovKioKICogIEluY3JlbWVudCBvZiB0aGUgbGFzdCBvcmRlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbC4KICovCmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmluY3JlbWVudChDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIGFTdHJlbmd0aCwgaW50MzJfdCBsYXN0VmFsdWUpCnsKICAgIHN3aXRjaChhU3RyZW5ndGgpCiAgICB7CiAgICBjYXNlIENvbGxhdG9yOjpQUklNQVJZOgogICAgICAgIC8vIGluY3JlbWVudCBwcmlhbXJ5IG9yZGVyICBhbmQgbWFzayBvZmYgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgbGFzdFZhbHVlICs9IFBSSU1BUllPUkRFUklOQ1JFTUVOVDsKICAgICAgICBsYXN0VmFsdWUgJj0gUFJJTUFSWU9SREVSTUFTSzsKICAgICAgICBpc092ZXJJZ25vcmUgPSBUUlVFOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ29sbGF0b3I6OlNFQ09OREFSWToKICAgICAgICAvLyBpbmNyZW1lbnQgc2Vjb25kYXJ5IG9yZGVyIGFuZCBtYXNrIG9mZiB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgICAgbGFzdFZhbHVlICs9IFNFQ09OREFSWU9SREVSSU5DUkVNRU5UOwogICAgICAgIGxhc3RWYWx1ZSAmPSBTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKCiAgICAgICAgLy8gcmVjb3JkIG1heCAjIG9mIGlnbm9yYWJsZSBjaGFycyB3aXRoIHNlY29uZGFyeSBkaWZmZXJlbmNlCiAgICAgICAgaWYgKGlzT3Zlcklnbm9yZSA9PSBGQUxTRSkKICAgICAgICB7CiAgICAgICAgICAgIGRhdGEtPm1heFNlY09yZGVyICs9IDE7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ29sbGF0b3I6OlRFUlRJQVJZOgogICAgICAgIC8vIGluY3JlbWVudCB0ZXJ0aWFyeSBvcmRlcgogICAgICAgIGxhc3RWYWx1ZSArPSBURVJUSUFSWU9SREVSSU5DUkVNRU5UOwoKICAgICAgICAvLyByZWNvcmQgbWF4ICMgb2YgaWdub3JhYmxlIGNoYXJzIHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZQogICAgICAgIGlmIChpc092ZXJJZ25vcmUgPT0gRkFMU0UpCiAgICAgICAgewogICAgICAgICAgICBkYXRhLT5tYXhUZXJPcmRlciArPSAxOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgLy8gY2FzZSBJREVOVElDQUw/ICAKICAgIH0KCiAgICByZXR1cm4gbGFzdFZhbHVlOwp9CgovLyBBZGRzIGEgY2hhcmFjdGVyIGFuZCBpdHMgZGVzaWduYXRlZCBvcmRlciBpbnRvIHRoZSBjb2xsYXRpb24gdGFibGUuCi8vIFRoaXMgaXMgdGhlIHNpbXBsZSBjYXNlLCB3aXRoIG5vIGV4cGFuc2lvbiBvciBjb250cmFjdGlvbgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRPcmRlcihVQ2hhciBjaCwKICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyB0cnkgdG8gZmluZCB0aGUgb3JkZXIgb2YgdGhlIGNoYXIgaW4gdGhlIG1hcHBpbmcgdGFibGUKICAgIGludDMyX3Qgb3JkZXIgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKCiAgICBpZiAob3JkZXIgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICB7CiAgICAgICAgLy8gVGhlcmUncyBhbHJlYWR5IGFuIGVudHJ5IGZvciB0aGlzIGNoYXJhY3RlciB0aGF0IHBvaW50cyB0byBhIGNvbnRyYWN0aW5nCiAgICAgICAgLy8gY2hhcmFjdGVyIHRhYmxlLiAgSW5zdGVhZCBvZiBhZGRpbmcgdGhlIGNoYXJhY3RlciBkaXJlY3RseSB0byB0aGUgbWFwcGluZwogICAgICAgIC8vIHRhYmxlLCB3ZSBtdXN0IGFkZCBpdCB0byB0aGUgY29udHJhY3QgdGFibGUgaW5zdGVhZC4KICAgICAgICBrZXkucmVtb3ZlKCk7CiAgICAgICAga2V5ICs9IGNoOwogICAgICAgIGlmIChrZXkuaXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgYWRkQ29udHJhY3RPcmRlcihrZXksIGFuT3JkZXIsIHN0YXR1cyk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy8gYWRkIHRoZSBlbnRyeSB0byB0aGUgbWFwcGluZyB0YWJsZSwgdGhlIHNhbWUgbGF0ZXIgZW50cnkgcmVwbGFjZXMgdGhlIHByZXZpb3VzIG9uZQogICAgICAgIHVjbXAzMl9zZXQoZGF0YS0+bWFwcGluZywgY2gsIGFuT3JkZXIpOwogICAgfQp9CgovLyBBZGQgYW4gZXhwYW5kaW5nLWNoYXJhY3RlciBlbnRyeSB0byB0aGUgdGFibGUuCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmFkZEV4cGFuZE9yZGVyKCAgY29uc3QgICBVbmljb2RlU3RyaW5nJiBjb250cmFjdENoYXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgZXhwYW5kQ2hhcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvLyBDcmVhdGUgYW4gZXhwYW5zaW9uIHRhYmxlIGVudHJ5CiAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBhZGRFeHBhbnNpb24oYW5PcmRlciwgZXhwYW5kQ2hhcnMpOwogICAgCiAgICAvLyBBbmQgYWRkIGl0cyBpbmRleCBpbnRvIHRoZSBtYWluIG1hcHBpbmcgdGFibGUKICAgIGlmIChjb250cmFjdENoYXJzLmxlbmd0aCgpID4gMSkKICAgIHsKICAgICAgICBhZGRDb250cmFjdE9yZGVyKGNvbnRyYWN0Q2hhcnMsIHRhYmxlSW5kZXgsIHN0YXR1cyk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYWRkT3JkZXIoY29udHJhY3RDaGFyc1swXSwgdGFibGVJbmRleCwgc3RhdHVzKTsKICAgIH0KfQoKaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6YWRkRXhwYW5zaW9uKGludDMyX3QgYW5PcmRlciwgY29uc3QgVW5pY29kZVN0cmluZyAmZXhwYW5kQ2hhcnMpCnsKICAgIGlmIChkYXRhLT5leHBhbmRUYWJsZSA9PSBOVUxMKQogICAgewogICAgICAgIGRhdGEtPmV4cGFuZFRhYmxlID0gbmV3IFZlY3Rvck9mUFRvRXhwYW5kVGFibGUoKTsKCiAgICAgICAgaWYgKGRhdGEtPmV4cGFuZFRhYmxlID09IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8vIElmIGFuT3JkZXIgaXMgdmFsaWQsIHdlIHdhbnQgdG8gYWRkIGl0IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3QKICAgIGludDMyX3Qgb2Zmc2V0ID0gKGFuT3JkZXIgPT0gVU5NQVBQRUQpID8gMCA6IDE7CiAgICAKICAgIFZlY3Rvck9mSW50ICp2YWx1ZUxpc3QgPSBuZXcgVmVjdG9yT2ZJbnQoZXhwYW5kQ2hhcnMubGVuZ3RoKCkgKyBvZmZzZXQpOwoKICAgIGlmIChvZmZzZXQgPT0gMSkKICAgIHsKICAgICAgICB2YWx1ZUxpc3QtPmF0UHV0KDAsIGFuT3JkZXIpOwogICAgfQoKICAgIGludDMyX3QgaTsKICAgIGZvciAoaSA9IDA7IGkgPCBleHBhbmRDaGFycy5sZW5ndGgoKTsgaSArPSAxKQogICAgewogICAgICAgIFVDaGFyIGNoID0gZXhwYW5kQ2hhcnNbaV07CiAgICAgICAgaW50MzJfdCBtYXBWYWx1ZSA9IGdldENoYXJPcmRlcihjaCk7CiAgICAgICAgCiAgICAgICAgaWYgKG1hcFZhbHVlICE9IFVOTUFQUEVEKQogICAgICAgIHsKICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChpICsgb2Zmc2V0LCBtYXBWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8vIGNhbid0IGZpbmQgaXQgaW4gdGhlIHRhYmxlLCB3aWxsIGJlIGZpbGxlZCBpbiBieSBjb21taXQoKS4KICAgICAgICAgICAgdmFsdWVMaXN0LT5hdFB1dChpICsgb2Zmc2V0LCBDSEFSSU5ERVggKyAoaW50MzJfdCljaCk7CiAgICAgICAgfQogICAgfQoKICAgIC8vIEFkZCB0aGUgZXhwYW5kaW5nIGNoYXIgbGlzdCBpbnRvIHRoZSBleHBhbnNpb24gdGFibGUuCiAgICBpbnQzMl90IHRhYmxlSW5kZXggPSBFWFBBTkRDSEFSSU5ERVggKyBkYXRhLT5leHBhbmRUYWJsZS0+c2l6ZSgpOwogICAgZGF0YS0+ZXhwYW5kVGFibGUtPmF0UHV0KGRhdGEtPmV4cGFuZFRhYmxlLT5zaXplKCksIHZhbHVlTGlzdCk7CiAgICAKICAgIHJldHVybiB0YWJsZUluZGV4Owp9CgovLyBBZGQgYSBzdHJpbmcgb2YgY2hhcmFjdGVycyB0aGF0IGNvbnRyYWN0cyBpbnRvIGEgc2luZ2xlIG9yZGVyaW5nLgp2b2lkClJ1bGVCYXNlZENvbGxhdG9yOjphZGRDb250cmFjdE9yZGVyKGNvbnN0ICAgVW5pY29kZVN0cmluZyYgZ3JvdXBDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCBmd2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZSA9PSBOVUxMKQogICAgewogICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBuZXcgVmVjdG9yT2ZQVG9Db250cmFjdFRhYmxlKCk7CiAgICAgICAgaWYgKGRhdGEtPmNvbnRyYWN0VGFibGUtPmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBTZWUgaWYgdGhlIGluaXRpYWwgY2hhcmFjdGVyIG9mIHRoZSBzdHJpbmcgYWxyZWFkeSBoYXMgYSBjb250cmFjdCB0YWJsZS4KICAgIC8vIGUuZy4gZm9yICJjaCIsIGxvb2sgZm9yICdjJy4KICAgIGludDMyX3QgZW50cnkgPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGdyb3VwQ2hhcnNbMF0pOwogICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmVudHJ5VGFibGUgPSBnZXRDb250cmFjdFZhbHVlcyhlbnRyeSAtIENPTlRSQUNUQ0hBUklOREVYKTsKCiAgICBpZiAoZW50cnlUYWJsZSA9PSBOVUxMKQogICAgewogICAgICAgIC8vIFdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IHRhYmxlIG9mIGNvbnRyYWN0IGVudHJpZXMgZm9yIHRoaXMgYmFzZSBjaGFyCiAgICAgICAgaW50MzJfdCB0YWJsZUluZGV4ID0gQ09OVFJBQ1RDSEFSSU5ERVggKyBkYXRhLT5jb250cmFjdFRhYmxlLT5zaXplKCk7CiAgICAgICAgRW50cnlQYWlyICpwYWlyID0gTlVMTDsKICAgICAgICBVbmljb2RlU3RyaW5nIHN1YnN0cmluZzsKCiAgICAgICAgZW50cnlUYWJsZSA9IG5ldyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCgpOwogICAgICAgIGlmIChlbnRyeVRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlLT5hdFB1dChkYXRhLT5jb250cmFjdFRhYmxlLT5zaXplKCksIGVudHJ5VGFibGUpOwogICAgICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgICAgICAKCiAgICAgICAgLy8gQWRkIHRoZSBpbml0aWFsIGNoYXJhY3RlcidzIGN1cnJlbnQgb3JkZXJpbmcgZmlyc3QuIHRoZW4KICAgICAgICAvLyB1cGRhdGUgaXRzIG1hcHBpbmcgdG8gcG9pbnQgdG8gdGhpcyBjb250cmFjdCB0YWJsZQogICAgICAgIGdyb3VwQ2hhcnMuZXh0cmFjdCgwLCAxLCBzdWJzdHJpbmcpOwogICAgICAgIGlmIChzdWJzdHJpbmcuaXNCb2d1cygpKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGVudHJ5VGFibGU7CiAgICAgICAgICAgIGRlbGV0ZSBkYXRhLT5jb250cmFjdFRhYmxlOwogICAgICAgICAgICBkYXRhLT5jb250cmFjdFRhYmxlID0gTlVMTDsKICAgICAgICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcGFpciA9IG5ldyBFbnRyeVBhaXIoc3Vic3RyaW5nLCBlbnRyeSk7CgogICAgICAgIGVudHJ5VGFibGUtPmF0UHV0KDAsIHBhaXIpOwogICAgICAgIGlmIChlbnRyeVRhYmxlLT5pc0JvZ3VzKCkpCiAgICAgICAgewogICAgICAgICAgICBkZWxldGUgZW50cnlUYWJsZTsKICAgICAgICAgICAgZGVsZXRlIGRhdGEtPmNvbnRyYWN0VGFibGU7CiAgICAgICAgICAgIGRhdGEtPmNvbnRyYWN0VGFibGUgPSBOVUxMOwogICAgICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB1Y21wMzJfc2V0KGRhdGEtPm1hcHBpbmcsIGdyb3VwQ2hhcnNbMF0sIHRhYmxlSW5kZXgpOwogICAgfQoKICAgIC8vIE5vdyBhZGQgKG9yIHJlcGxhY2UpIHRoaXMgc3RyaW5nIGluIHRoZSB0YWJsZQogICAgaW50MzJfdCBpbmRleCA9IGdldEVudHJ5KGVudHJ5VGFibGUsIGdyb3VwQ2hhcnMsIGZ3ZCk7CgogICAgaWYgKGluZGV4ICE9IFVOTUFQUEVEKQogICAgewogICAgICAgIEVudHJ5UGFpciAqcGFpciA9IChFbnRyeVBhaXIgKikgZW50cnlUYWJsZS0+YXQoaW5kZXgpOwogICAgICAgIHBhaXItPnZhbHVlID0gYW5PcmRlcjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBFbnRyeVBhaXIgKnBhaXIgPSBuZXcgRW50cnlQYWlyKGdyb3VwQ2hhcnMsIGFuT3JkZXIsIGZ3ZCk7CgogICAgICAgIGVudHJ5VGFibGUtPmF0UHV0KGVudHJ5VGFibGUtPnNpemUoKSwgcGFpcik7CiAgICB9CiAgICAKICAgIC8vIElmIHRoaXMgd2FzIGEgZm9yd2FyZCBtYXBwaW5nIGZvciBhIGNvbnRyYWN0aW5nIHN0cmluZywgYWxzbyBhZGQgYQogICAgLy8gcmV2ZXJzZSBtYXBwaW5nIGZvciBpdCwgc28gdGhhdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzCiAgICAvLyBjYW4gd29yayByaWdodAogICAgaWYgKGZ3ZCkKICAgIHsKICAgICAgICBVbmljb2RlU3RyaW5nIHJldmVyc2UoZ3JvdXBDaGFycyk7CgogICAgICAgIGlmIChyZXZlcnNlLmlzQm9ndXMoKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlbGV0ZSBlbnRyeVRhYmxlOwogICAgICAgICAgICBkZWxldGUgZGF0YS0+Y29udHJhY3RUYWJsZTsKICAgICAgICAgICAgZGF0YS0+Y29udHJhY3RUYWJsZSA9IE5VTEw7CiAgICAgICAgICAgIHN0YXR1cyA9IFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGFkZENvbnRyYWN0T3JkZXIocmV2ZXJzZS5yZXZlcnNlKCksIGFuT3JkZXIsIEZBTFNFLCBzdGF0dXMpOwogICAgfQp9CgovKioKICogSWYgdGhlIGdpdmVuIHN0cmluZyBoYXMgYmVlbiBzcGVjaWZpZWQgYXMgYSBjb250cmFjdGluZyBzdHJpbmcKICogaW4gdGhpcyBjb2xsYXRpb24gdGFibGUsIHJldHVybiBpdHMgb3JkZXJpbmcuCiAqIE90aGVyd2lzZSByZXR1cm4gVU5NQVBQRUQuCiAqLwogaW50MzJfdCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29udHJhY3RPcmRlcihjb25zdCBVbmljb2RlU3RyaW5nICZncm91cENoYXJzKSBjb25zdAp7CiAgICBpbnQzMl90IHJlc3VsdCA9IFVOTUFQUEVEOwoKICAgIGlmIChkYXRhLT5jb250cmFjdFRhYmxlICE9IE5VTEwpCiAgICB7CiAgICAgICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmVudHJ5VGFibGUgPSBnZXRDb250cmFjdFZhbHVlcyhncm91cENoYXJzWzBdKTsKCiAgICAgICAgaWYgKGVudHJ5VGFibGUgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIGludDMyX3QgaW5kZXggPSBnZXRFbnRyeShlbnRyeVRhYmxlLCBncm91cENoYXJzLCBUUlVFKTsKCiAgICAgICAgICAgIGlmIChpbmRleCAhPSBVTk1BUFBFRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRW50cnlQYWlyICpwYWlyID0gZW50cnlUYWJsZS0+YXQoaW5kZXgpOwoKICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBhaXItPnZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCmludDMyX3QgUnVsZUJhc2VkQ29sbGF0b3I6OmdldENoYXJPcmRlcihVQ2hhciBjaCkgY29uc3QKewogICAgaW50MzJfdCBvcmRlciA9IHVjbXAzMl9nZXQoZGF0YS0+bWFwcGluZywgY2gpOwogICAgCiAgICBpZiAob3JkZXIgPj0gQ09OVFJBQ1RDSEFSSU5ERVgpCiAgICB7CiAgICAgICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmdyb3VwTGlzdCA9IGdldENvbnRyYWN0VmFsdWVzKG9yZGVyIC0gQ09OVFJBQ1RDSEFSSU5ERVgpOwogICAgICAgIEVudHJ5UGFpciAqcGFpciA9IGdyb3VwTGlzdC0+YXQoMCk7CgogICAgICAgIG9yZGVyID0gcGFpci0+dmFsdWU7CiAgICB9CgogICAgcmV0dXJuIG9yZGVyOwp9CiAgICAKLy8gQ3JlYXRlIGEgaGFzaCBjb2RlIGZvciB0aGlzIGNvbGxhdGlvbi4gIEp1c3QgaGFzaCB0aGUgbWFpbiBydWxlIHRhYmxlIC0tCi8vIHRoYXQgc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBhbG1vc3QgYW55IHVzZS4KaW50MzJfdApSdWxlQmFzZWRDb2xsYXRvcjo6aGFzaENvZGUoKSBjb25zdAp7CiAgICBpbnQzMl90ICAgICAgICAgdmFsdWUgPSAwOwogICAgaW50MzJfdCAgICAgICAgIGM7CiAgICBpbnQzMl90ICAgICAgICAgY291bnQgPSBnZXRSdWxlcygpLmxlbmd0aCgpOwogICAgVVRleHRPZmZzZXQgICAgICBwb3MgPSBjb3VudCAtIDE7CgogICAgaWYgKGNvdW50ID4gNjQpCiAgICB7CiAgICAgICAgY291bnQgPSA2NDsgLy8gb25seSBoYXNoIHVwdG8gbGltaXQKICAgIH0KCiAgICBpbnQxNl90IGkgPSAwOwoKICAgIHdoaWxlIChpIDwgY291bnQpCiAgICB7CiAgICAgICAgYyA9IGRhdGEtPnJ1bGVUYWJsZVtwb3NdOwogICAgICAgIHZhbHVlID0gKCh2YWx1ZSA8PCAoYyAmIDB4MGYpKSBeIChjIDw8IDgpKSArIChjIF4gdmFsdWUpOwogICAgICAgIGkgKz0gMTsKICAgICAgICBwb3MgLT0gMTsKICAgIH0KCiAgICBpZiAodmFsdWUgPT0gMCkKICAgIHsKICAgICAgICB2YWx1ZSA9IDE7CiAgICB9CgogICAgcmV0dXJuIHZhbHVlOwp9CgovLyBmaW5kIHRoZSBjb250cmFjdGluZyBjaGFyIGVudHJ5IGluIHRoZSBsaXN0CmludDMyX3QKUnVsZUJhc2VkQ29sbGF0b3I6OmdldEVudHJ5KFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiBsaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGZ3ZCkKewogICAgaW50MzJfdCBpOwoKICAgIGlmIChsaXN0ICE9IE5VTEwpCiAgICB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3QtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgRW50cnlQYWlyICpwYWlyID0gbGlzdC0+YXQoaSk7CgogICAgICAgICAgICBpZiAoKHBhaXIgIT0gTlVMTCkgJiYgKHBhaXItPmZ3ZCA9PSBmd2QpICYmIChwYWlyLT5lbnRyeU5hbWUgPT0gbmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQ7Cn0KCi8vIGxvb2sgZm9yIHRoZSBjb250cmFjdGluZyBsaXN0IGVudHJ5IHdpdGggdGhlIGJlZ2lubmluZyBjaGFyClZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KgpSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0Q29udHJhY3RWYWx1ZXMoVUNoYXIgY2gpIGNvbnN0CnsKICAgIGludDMyX3QgaW5kZXggPSB1Y21wMzJfZ2V0KGRhdGEtPm1hcHBpbmcsIGNoKTsKICAgIHJldHVybiBnZXRDb250cmFjdFZhbHVlcyhpbmRleCAtIENPTlRSQUNUQ0hBUklOREVYKTsKfQoKLy8gbG9vayBmb3IgdGhlIGNvbnRyYWN0aW5nIGxpc3QgZW50cnkgd2l0aCB0aGUgaW5kZXgKVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQqClJ1bGVCYXNlZENvbGxhdG9yOjpnZXRDb250cmFjdFZhbHVlcyhpbnQzMl90ICAgIGluZGV4KSBjb25zdAp7CiAgICBpZiAoZGF0YS0+Y29udHJhY3RUYWJsZSAhPSBOVUxMKQogICAgewogICAgICAgIGlmIChpbmRleCA+PSAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGRhdGEtPmNvbnRyYWN0VGFibGUtPmF0KGluZGV4KTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqCiAgKiBSZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2VzIHRoYXQgZW5kCiAgKiB3aXRoIHRoZSBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICAqCiAgKiBAcGFyYW0gb3JkZXIgYSBjb2xsYXRpb24gb3JkZXIgcmV0dXJuZWQgYnkgcHJldmlvdXMgb3IgbmV4dC4KICAqIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2V1ZW5jZXMgZW5kaW5nCiAgKiAgICAgICAgIHdpdGggdGhlIHNwZWNpZmllZCBvcmRlci4KICAqCiAgKiBAc2VlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciNnZXRNYXhFeHBhbnNpb24KICAqLwppbnQzMl90IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogICAgaW50MzJfdCByZXN1bHQgPSAxOwogICAgCiAgICBpZiAoZGF0YS0+ZXhwYW5kVGFibGUgIT0gTlVMTCkKICAgIHsKICAgICAgICAvLyBSaWdodCBub3cgdGhpcyBkb2VzIGEgbGluZWFyIHNlYXJjaCB0aHJvdWdoIHRoZSBlbnRpcmUKICAgICAgICAvLyBleHBhbmRzaW9uIHRhYmxlLiAgSWYgYSBjb2xsYXRvciBoYWQgYSBsYXJnZSBudW1iZXIgb2YgZXhwYW5zaW9ucywKICAgICAgICAvLyB0aGlzIGNvdWxkIGNhdXNlIGEgcGVyZm9ybWFuY2UgcHJvYmxlbSwgYnV0IGluIHByYWN0aWNlIHRoYXQKICAgICAgICAvLyByYXJlbHkgaGFwcGVucwogICAgICAgIGludDMyX3QgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZGF0YS0+ZXhwYW5kVGFibGUtPnNpemUoKTsgaSArPSAxKQogICAgICAgIHsKICAgICAgICAgICAgVmVjdG9yT2ZJbnQgKnZhbHVlTGlzdCA9IGRhdGEtPmV4cGFuZFRhYmxlLT5hdChpKTsKICAgICAgICAgICAgaW50MzJfdCBsZW5ndGggPSB2YWx1ZUxpc3QtPnNpemUoKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChsZW5ndGggPiByZXN1bHQgJiYgdmFsdWVMaXN0LT5hdChsZW5ndGgtMSkgPT0gb3JkZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IGxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CiAgICAKLyoqCiAqICBHZXQgdGhlIGVudHJ5IG9mIGhhc2ggdGFibGUgb2YgdGhlIGV4cGFuZGluZyBzdHJpbmcgaW4gdGhlIGNvbGxhdGlvbgogKiAgdGFibGUuCiAqICBAcGFyYW0gb2Zmc2V0IHRoZSBpbmRleCBvZiB0aGUgZXhwYW5kaW5nIHN0cmluZyB2YWx1ZSBsaXN0CiAqLwpWZWN0b3JPZkludCAqUnVsZUJhc2VkQ29sbGF0b3I6OmdldEV4cGFuZFZhbHVlTGlzdChpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgICByZXR1cm4gZGF0YS0+ZXhwYW5kVGFibGUtPmF0KG9yZGVyIC0gRVhQQU5EQ0hBUklOREVYKTsKfQoKCgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbUluKFJ1bGVCYXNlZENvbGxhdG9yKiBjb2xsYXRvciwgVU1lbW9yeVN0cmVhbSogaXMpCnsKICAgIGlmICghdXBydl9tc3RybV9lcnJvcihpcykpCiAgICB7CiAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGlzIGlzIHRoZSBjb3JyZWN0IGZpbGUgdHlwZQogICAgICAgIGludDE2X3QgaWQ7CgogICAgICAgIHVwcnZfbXN0cm1fcmVhZChpcywgJmlkLCBzaXplb2YoaWQpKTsKICAgICAgICBpZiAoaWQgIT0gY29sbGF0b3ItPkZJTEVJRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRoaXMgaXNuJ3QgdGhlIHJpZ2h0IHR5cGUgb2YgZmlsZS4gIE1hcmsgdGhlIGlvcwogICAgICAgICAgICAvLyBhcyBmYWlsaW5nIGFuZCByZXR1cm4uCiAgICAgICAgICAgIHVwcnZfbXN0cm1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBTdHJlYW0gaW4gbGFyZ2Ugb2JqZWN0cwogICAgICAgIGNoYXIgaXNOdWxsOwoKICAgICAgICB1cHJ2X21zdHJtX3JlYWQoaXMsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKICAgICAgICBpZiAoaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5kYXRhOwogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YSA9PSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IG5ldyBUYWJsZUNvbGxhdGlvbkRhdGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhLT5zdHJlYW1Jbihpcyk7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YS0+aXNCb2d1cygpKSB7CiAgICAgICAgICAgICAgICB1cHJ2X21zdHJtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGVuZCBtYXJrZXIgaXMgcHJlc2VudAogICAgICAgIHVwcnZfbXN0cm1fcmVhZChpcywgJmlkLCBzaXplb2YoaWQpKTsKICAgICAgICBpZiAoaWQgIT0gY29sbGF0b3ItPkZJTEVJRCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFRoaXMgaXNuJ3QgdGhlIHJpZ2h0IHR5cGUgb2YgZmlsZS4gIE1hcmsgdGhlIGlvcwogICAgICAgICAgICAvLyBhcyBmYWlsaW5nIGFuZCByZXR1cm4uCiAgICAgICAgICAgIHVwcnZfbXN0cm1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBSZXNldCBvdGhlciBkYXRhIG1lbWJlcnMKICAgICAgICBjb2xsYXRvci0+aXNPdmVySWdub3JlID0gRkFMU0U7CiAgICAgICAgY29sbGF0b3ItPmxhc3RDaGFyID0gMDsKICAgICAgICBkZWxldGUgY29sbGF0b3ItPm1QYXR0ZXJuOwogICAgICAgIGNvbGxhdG9yLT5tUGF0dGVybiA9IDA7CiAgICAgICAgY29sbGF0b3ItPmtleS5yZW1vdmUoKTsKICAgICAgICBjb2xsYXRvci0+ZGF0YUlzT3duZWQgPSBUUlVFOwogICAgfQp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dChjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIFVNZW1vcnlTdHJlYW0qIG9zKQp7CiAgICBpZiAoIXVwcnZfbXN0cm1fZXJyb3Iob3MpKQogICAgewogICAgICAgIC8vIFdlIHVzZSBhIDE2LWJpdCBJRCBjb2RlIHRvIGlkZW50aWZ5IHRoaXMgZmlsZS4KICAgICAgICBpbnQxNl90IGlkID0gY29sbGF0b3ItPkZJTEVJRDsKICAgICAgICB1cHJ2X21zdHJtX3dyaXRlKG9zLCAodWludDhfdCAqKSZpZCwgc2l6ZW9mKGlkKSk7CgogICAgICAgIC8vIFN0cmVhbSBvdXQgdGhlIGRhdGEKICAgICAgICBjaGFyIGlzTnVsbDsKICAgICAgICBpc051bGwgPSAoY29sbGF0b3ItPmRhdGEgPT0gMCk7CiAgICAgICAgdXBydl9tc3RybV93cml0ZShvcywgKHVpbnQ4X3QqKSZpc051bGwsIHNpemVvZihpc051bGwpKTsKCiAgICAgICAgaWYgKCFpc051bGwpCiAgICAgICAgewogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtT3V0KG9zKTsKICAgICAgICB9CgogICAgICAgIC8vIFdyaXRlIG91dCB0aGUgSUQgdG8gaW5kaWNhdGUgdGhlIGVuZAogICAgICAgIHVwcnZfbXN0cm1fd3JpdGUob3MsICh1aW50OF90ICopJmlkLCBzaXplb2YoaWQpKTsKICAgIH0KfQoKdm9pZCBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1JbihSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIGlzKQp7CiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihpcykpCiAgICB7CiAgICAgICAgLy8gQ2hlY2sgdGhhdCB0aGlzIGlzIHRoZSBjb3JyZWN0IGZpbGUgdHlwZQogICAgICAgIGludDE2X3QgaWQ7CgogICAgICAgIFRfRmlsZVN0cmVhbV9yZWFkKGlzLCAmaWQsIHNpemVvZihpZCkpOwogICAgICAgIGlmIChpZCAhPSBjb2xsYXRvci0+RklMRUlEKQogICAgICAgIHsKICAgICAgICAgICAgLy8gVGhpcyBpc24ndCB0aGUgcmlnaHQgdHlwZSBvZiBmaWxlLiAgTWFyayB0aGUgaW9zCiAgICAgICAgICAgIC8vIGFzIGZhaWxpbmcgYW5kIHJldHVybi4KICAgICAgICAgICAgVF9GaWxlU3RyZWFtX3NldEVycm9yKGlzKTsgLy8gZm9yY2UgdGhlIHN0cmVhbSB0byBzZXQgaXRzIGVycm9yIGZsYWcKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLy8gU3RyZWFtIGluIGxhcmdlIG9iamVjdHMKICAgICAgICBjaGFyIGlzTnVsbDsKCiAgICAgICAgVF9GaWxlU3RyZWFtX3JlYWQoaXMsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKICAgICAgICBpZiAoaXNOdWxsKQogICAgICAgIHsKICAgICAgICAgICAgZGVsZXRlIGNvbGxhdG9yLT5kYXRhOwogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YSA9PSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb2xsYXRvci0+ZGF0YSA9IG5ldyBUYWJsZUNvbGxhdGlvbkRhdGE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGNvbGxhdG9yLT5kYXRhLT5zdHJlYW1Jbihpcyk7CiAgICAgICAgICAgIGlmIChjb2xsYXRvci0+ZGF0YS0+aXNCb2d1cygpKSB7CiAgICAgICAgICAgICAgICBUX0ZpbGVTdHJlYW1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBWZXJpZnkgdGhhdCB0aGUgZW5kIG1hcmtlciBpcyBwcmVzZW50CiAgICAgICAgVF9GaWxlU3RyZWFtX3JlYWQoaXMsICZpZCwgc2l6ZW9mKGlkKSk7CiAgICAgICAgaWYgKGlkICE9IGNvbGxhdG9yLT5GSUxFSUQpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGlzIGlzbid0IHRoZSByaWdodCB0eXBlIG9mIGZpbGUuICBNYXJrIHRoZSBpb3MKICAgICAgICAgICAgLy8gYXMgZmFpbGluZyBhbmQgcmV0dXJuLgogICAgICAgICAgICBUX0ZpbGVTdHJlYW1fc2V0RXJyb3IoaXMpOyAvLyBmb3JjZSB0aGUgc3RyZWFtIHRvIHNldCBpdHMgZXJyb3IgZmxhZwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBSZXNldCBvdGhlciBkYXRhIG1lbWJlcnMKICAgICAgICBjb2xsYXRvci0+aXNPdmVySWdub3JlID0gRkFMU0U7CiAgICAgICAgY29sbGF0b3ItPmxhc3RDaGFyID0gMDsKICAgICAgICBkZWxldGUgY29sbGF0b3ItPm1QYXR0ZXJuOwogICAgICAgIGNvbGxhdG9yLT5tUGF0dGVybiA9IDA7CiAgICAgICAgY29sbGF0b3ItPmtleS5yZW1vdmUoKTsKICAgICAgICBjb2xsYXRvci0+ZGF0YUlzT3duZWQgPSBUUlVFOwogICAgfQp9Cgp2b2lkIFJ1bGVCYXNlZENvbGxhdG9yU3RyZWFtZXI6OnN0cmVhbU91dChjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogY29sbGF0b3IsIEZpbGVTdHJlYW0qIG9zKQp7CiAgICBpZiAoIVRfRmlsZVN0cmVhbV9lcnJvcihvcykpCiAgICB7CiAgICAgICAgLy8gV2UgdXNlIGEgMTYtYml0IElEIGNvZGUgdG8gaWRlbnRpZnkgdGhpcyBmaWxlLgogICAgICAgIGludDE2X3QgaWQgPSBjb2xsYXRvci0+RklMRUlEOwogICAgICAgIFRfRmlsZVN0cmVhbV93cml0ZShvcywgJmlkLCBzaXplb2YoaWQpKTsKCiAgICAgICAgLy8gU3RyZWFtIG91dCB0aGUgZGF0YQogICAgICAgIGNoYXIgaXNOdWxsOwogICAgICAgIGlzTnVsbCA9IChjb2xsYXRvci0+ZGF0YSA9PSAwKTsKICAgICAgICBUX0ZpbGVTdHJlYW1fd3JpdGUob3MsICZpc051bGwsIHNpemVvZihpc051bGwpKTsKCiAgICAgICAgaWYgKCFpc051bGwpCiAgICAgICAgewogICAgICAgICAgICBjb2xsYXRvci0+ZGF0YS0+c3RyZWFtT3V0KG9zKTsKICAgICAgICB9CgogICAgICAgIC8vIFdyaXRlIG91dCB0aGUgSUQgdG8gaW5kaWNhdGUgdGhlIGVuZAogICAgICAgIFRfRmlsZVN0cmVhbV93cml0ZShvcywgJmlkLCBzaXplb2YoaWQpKTsKICAgIH0KfQoKVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6OndyaXRlVG9GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lKSBjb25zdAp7CiAgICBGaWxlU3RyZWFtKiBvZnMgPSBUX0ZpbGVTdHJlYW1fb3BlbihmaWxlTmFtZSwgIndiIik7CiAgICBpZiAob2ZzICE9IDApCiAgICB7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtT3V0KHRoaXMsIG9mcyk7CiAgICB9CgojaWZkZWYgQ09MTERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgImJpbmFyeSB3cml0ZSAlcyBzaXplICVkICVzXG4iLCBmaWxlTmFtZSwgVF9GaWxlU3RyZWFtX3NpemUob2ZzKSwKICAgICAgICAoIVRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID8gIiwgT0siIDogIiwgRkFJTCIpKTsKI2VuZGlmCgogICAgVUJvb2wgZXJyID0gVF9GaWxlU3RyZWFtX2Vycm9yKG9mcykgPT0gMDsKCiAgICBUX0ZpbGVTdHJlYW1fY2xvc2Uob2ZzKTsKICAgIHJldHVybiBlcnI7Cn0KLyoKVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6OnByZXBhcmVGb3JCdW5kbGUoKSBjb25zdAp7CiAgICBVTWVtb3J5U3RyZWFtKiBvZnMgPSB1cHJ2X21zdHJtX29wZW5OZXcoMCk7CiAgICBpZiAob2ZzICE9IDApCiAgICB7CiAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjo6c3RyZWFtT3V0KHRoaXMsIG9mcyk7CiAgICB9CgojaWZkZWYgQ09MTERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgImJpbmFyeSB3cml0ZSAlcyBzaXplICVkICVzXG4iLCBmaWxlTmFtZSwgVF9GaWxlU3RyZWFtX3NpemUob2ZzKSwKICAgICAgICAoIVRfRmlsZVN0cmVhbV9lcnJvcihvZnMpID8gIiwgT0siIDogIiwgRkFJTCIpKTsKI2VuZGlmCgogICAgVUJvb2wgZXJyID0gdXBydl9tc3RybV9lcnJvcihvZnMpID09IDA7CgogICAgdXBydl9tc3RybV9jbG9zZShvZnMpOwoKICAgIHJldHVybiBlcnI7Cn0KKi8KCnZvaWQgUnVsZUJhc2VkQ29sbGF0b3I6OmFkZFRvQ2FjaGUoY29uc3QgVW5pY29kZVN0cmluZyYga2V5KQp7CiAgICAvLyBUaGlzIG1ldGhvZCBkb2Vzbid0IGFkZCB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgaXRzZWxmIHRvIHRoZSBjYWNoZS4gIEluc3RlYWQsCiAgICAvLyBpdCBhZGRzIHRoZSBnaXZlbiBSdWxlQmFzZWRDb2xsYXRvcidzIGRhdGEgb2JqZWN0IHRvIHRoZSBUYWJsZUNvbGxhdGlvbkRhdGEKICAgIC8vIGNhY2hlLCBhbmQgbWFya3MgaXQgYXMgbm9uLW93bmVkIGluIHRoZSBnaXZlbiBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QuCiAgICBUYWJsZUNvbGxhdGlvbkRhdGE6OmFkZFRvQ2FjaGUoa2V5LCBkYXRhKTsKICAgIGRhdGFJc093bmVkID0gRkFMU0U7Cn0KCnZvaWQKUnVsZUJhc2VkQ29sbGF0b3I6OmNvbnN0cnVjdEZyb21DYWNoZShjb25zdCBVbmljb2RlU3RyaW5nJiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBBdHRlbXB0IHRvIGNvbnN0cnVjdCB0aGlzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tIGNhY2hlZCBUYWJsZUNvbGxhdGlvbkRhdGEuCiAgICAvLyBJZiBubyBzdWNoIGRhdGEgaXMgaW4gdGhlIGNhY2hlLCByZXR1cm4gZmFsc2UuCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgIGlmIChkYXRhSXNPd25lZCkKICAgIHsKICAgICAgICBkZWxldGUgZGF0YTsKICAgICAgICBkYXRhID0gTlVMTDsKICAgIH0KCiAgICBpc092ZXJJZ25vcmUgPSBGQUxTRTsKICAgIGxhc3RDaGFyID0gMDsKICAgIG1QYXR0ZXJuID0gMDsKICAgIHNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CgogICAgZGF0YUlzT3duZWQgPSBGQUxTRTsKICAgIGRhdGEgPSBUYWJsZUNvbGxhdGlvbkRhdGE6OmZpbmRJbkNhY2hlKGtleSk7CiAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgewogICAgICAgIHN0YXR1cyA9IFVfTUlTU0lOR19SRVNPVVJDRV9FUlJPUjsKICAgIH0KfQoKY2hhcioKUnVsZUJhc2VkQ29sbGF0b3I6OmNyZWF0ZVBhdGhOYW1lKCAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgcHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgc3VmZml4KQp7CiAgICAvLyBDb25jYXRlbmF0ZSB0aHJlZSBlbGVtZW50cyB0byBmb3JtIGEgZmlsZSBuYW1lLCBhbmQgcmV0dXJuIGl0LgoKICAgIFVuaWNvZGVTdHJpbmcgICB3b3JraW5nTmFtZShwcmVmaXgpOwogICAgaW50MzJfdCAgICAgICAgIHNpemU7CiAgICBjaGFyKiAgICAgICAgICAgcmV0dXJuVmFsOwoKICAgIHdvcmtpbmdOYW1lICs9IG5hbWU7CiAgICB3b3JraW5nTmFtZSArPSBzdWZmaXg7CgogICAgc2l6ZSA9IHdvcmtpbmdOYW1lLmxlbmd0aCgpOwogICAgcmV0dXJuVmFsID0gbmV3IGNoYXJbc2l6ZSArIDFdOwogICAgd29ya2luZ05hbWUuZXh0cmFjdCgwLCBzaXplLCByZXR1cm5WYWwsICIiKTsKICAgIHJldHVyblZhbFtzaXplXSA9IDA7CgogICAgcmV0dXJuIHJldHVyblZhbDsKfQoKdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6Y2hvcExvY2FsZShVbmljb2RlU3RyaW5nJiBsb2NhbGVOYW1lKQp7CiAgICAvLyBjaG9wTG9jYWxlIHJlbW92ZXMgdGhlIGZpbmFsIGVsZW1lbnQgZnJvbSBhIGxvY2FsZSBzdHJpbmcuCiAgICAvLyBGb3IgaW5zdGFuY2UsICJkZV9DSCIgYmVjb21lcyAiZGUiLCBhbmQgImRlIiBiZWNvbWVzICIiLgogICAgLy8gIiIgcmVtYWlucyAiIi4KCiAgICBpbnQzMl90ICAgICBzaXplID0gbG9jYWxlTmFtZS5sZW5ndGgoKTsKICAgIGludDMyX3QgICAgIGk7CgogICAgZm9yIChpID0gc2l6ZSAtIDE7IGkgPiAwOyBpLS0pCiAgICB7CiAgICAgICAgaWYgKGxvY2FsZU5hbWVbaV0gPT0gMHgwMDVGKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChpIDwgMCkKICAgIHsKICAgICAgIGkgPSAwOwogICAgfQoKICAgIGxvY2FsZU5hbWUucmVtb3ZlKGksIHNpemUgLSBpKTsKfQoKCnVpbnQ4X3QgKgpSdWxlQmFzZWRDb2xsYXRvcjo6Y2xvbmVSdWxlRGF0YShpbnQzMl90ICZsZW5ndGgsIFVFcnJvckNvZGUgJnN0YXR1cykKewogIFVNZW1vcnlTdHJlYW0gKm1lbWRhdGEgPSAwOwogIHVpbnQ4X3QgKmRhdGEgPSAwOwoKICBpZihVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICAgICAgbWVtZGF0YSA9IHVwcnZfbXN0cm1fb3Blbk5ldygwKTsKCiAgICAgIGlmIChtZW1kYXRhICE9IDApIHsKICAgICAgICBSdWxlQmFzZWRDb2xsYXRvclN0cmVhbWVyOjpzdHJlYW1PdXQodGhpcywgbWVtZGF0YSk7CiAgICAgIH0KCiAgICAgIFVCb29sIGVyciA9IHVwcnZfbXN0cm1fZXJyb3IobWVtZGF0YSkgPT0gMDsKCgogICAgZGF0YSA9ICh1aW50OF90ICopdXBydl9tYWxsb2MobWVtZGF0YS0+ZlBvcyk7CiAgICBpZihkYXRhID09IDApIHsKICAgICAgc3RhdHVzID0gVV9NRU1PUllfQUxMT0NBVElPTl9FUlJPUjsKICAgICAgdXBydl9tc3RybV9jbG9zZShtZW1kYXRhKTsKICAgICAgbGVuZ3RoID0gMDsKICAgICAgcmV0dXJuIDA7CiAgICB9IGVsc2UgewogICAgICB1cHJ2X21lbWNweShkYXRhLCBtZW1kYXRhLT5mU3RhcnQsIG1lbWRhdGEtPmZQb3MpOwogICAgICBsZW5ndGggPSBtZW1kYXRhLT5mUG9zOwogICAgICB1cHJ2X21zdHJtX2Nsb3NlKG1lbWRhdGEpOwogICAgICByZXR1cm4gZGF0YTsKICAgIH0KfQoKCi8vZW9mCg==